Filter elements with deformation above a value and change their material properties

Pernelle Marone-Hitz
Pernelle Marone-Hitz Member, Moderator, Employee Posts: 596
100 Answers 250 Likes 100 Comments First Anniversary

How can I find elements that have a deformation value above a specified threshold and change their material properties for a subsequent analysis?



  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 596
    100 Answers 250 Likes 100 Comments First Anniversary

    Here's an example.

    First analysis

    Insert a Python Code object in the Results and change the callback to After Post:

    Code for Property provider:

    def reload_props():
    this.PropertyProvider = None # comment the following return to allow the rest of the function definition to be executed and add properties

    Some sample code is provided below that shows how to:
    1. Create an instance of the Provider. The Provider class is used to add custom properties to the details.
    2. Use the Provider instance to add custom properties.
    3. Configure those custom properties.

    # Create the property instance
    provider = Provider()

    group = provider.AddGroup("Inputs")

    double_prop = group.AddProperty("Threshold", Control.Double)

    this.PropertyProvider = provider

    Code for script:

    def after_post(this, solution):# Do not edit this line
    Called after post processing.
    Keyword Arguments :
    this -- the datamodel object instance of the python code object you are currently editing in the tree
    solution -- Solution
    """ # To access properties created using the Property Provider, please use the following command.
    # this.GetCustomPropertyByPath("your_property_group_name/your_property_name")

    # To access scoping properties use the following to access geometry scoping and named selection respectively:
    # this.GetCustomPropertyByPath("your_property_group_name/your_property_name/Geometry Selection")
    # this.GetCustomPropertyByPath("your_property_group_name/your_property_name/Named Selection")

    import mech_dpf
    import Ans.DataProcessing as dpf
    import json
    import os

    ds = dpf.DataSources(solution.Parent.ResultFileName)

    crit_disp = this.GetCustomPropertyByPath("Inputs/Threshold").Value

    model = dpf.Model(ds)
    mesh = model.Mesh
    all_elems = mesh.ElementIds

    disp = model.results.displacement()
    disp_norm = dpf.operators.math.norm_fc(disp)

    filt_disp = dpf.operators.filter.field_high_pass_fc(fields_container=disp_norm, threshold=crit_disp)
    nodes_crit = filt_disp.outputs.fields_container.GetData()[0].ScopingIds

    elements = []

    mesh_con = mesh.NodalConnectivityPropertyField
    for node in nodes_crit:

    elem_crit = list(set([all_elems[elem_index] for elem_list in elements for elem_index in elem_list]))

    elem_crit_scop = dpf.Scoping()
    elem_crit_scop.Ids = elem_crit

    # delete named selection if it already exists
    ns = ExtAPI.DataModel.GetObjectsByName('FILTERED_ELEMS')[0]

    if len(elem_crit) != 0:
    # create named selection of filtered elements
    ns_filtered_elems = Model.AddNamedSelection()
    ns_filtered_elems.Name = "FILTERED_ELEMS"
    ns_filtered_elems.ScopingMethod = GeometryDefineByType.Worksheet
    criteria = ns_filtered_elems.GenerationCriteria
    for i in range(len(elem_crit)):
    criteria[i].EntityType = SelectionType.MeshElement
    criteria[i].Criterion = SelectionCriterionType.ElementNumber
    criteria[i].Operator = SelectionOperatorType.Equal
    criteria[i].Value = elem_crit[i]

    This will create a named selection of the elements that are above the specified threshold:

    See also this post that explains the code behind filtering and shows a Python Result plot of them:

    Second analysis

    Insert a Python Code object in the analysis, with callback set to "Get solve commands".

    Code for property provider:

    def reload_props():
    this.PropertyProvider = None # Create the property instance
    provider = Provider()

    group = provider.AddGroup("Inputs")

    # Create a property with control type Expression and a property with control type Double, and add it to the Group 1
    scale_value = group.AddProperty("Coefficient factor for Young Modulus", Control.Double)

    # Connects the provider instance back to the object by setting the PropertyProvider member on this, 'this' being the
    # current instance of the Python Code object.
    this.PropertyProvider = provider

    Code for script:

    scale_factor =  this.GetCustomPropertyByPath("Inputs/Coefficient factor for Young Modulus").Value
    import materials
    first_body = Model.GetChildren(DataModelObjectCategory.Body, True)[0]
    material = ExtAPI.DataModel.GetObjectsByName(first_body.Material)[0]
    mat_enginerring_data = material.GetEngineeringDataMaterial()
    elasticity = materials.GetMaterialPropertyByName(mat_enginerring_data,"Elasticity")
    density = materials.GetMaterialPropertyByName(mat_enginerring_data,"Density")
    young_modulus = elasticity["Young's Modulus"][1]
    poisson_ratio = elasticity["Poisson's Ratio"][1]
    density = density["Density"][1] new_modulus = scale_factor*young_modulus solver_input_file.WriteLine("/PREP7")
    solver_input_file.WriteLine("MP,EX,999," + str(new_modulus) )
    solver_input_file.WriteLine("MP,NUXY,999," + str(poisson_ratio) )
    solver_input_file.WriteLine("MP,DENS,999," + str(density) ) solver_input_file.WriteLine("cmsel,s,FILTERED_ELEMS")

    This code combines retrieving the material properties initially assigned to the first body in the tree, and using MAPDL commands to modify the Young Modulus assigned to the filtered elements.

    Important note. Material properties retrieved through materials library are in MKS units. For robustness of the code, the solver unit system of the second analysis has to be in MKS:

    Here's also the complete model.