How can I filter all nodes / elements above a certain result threshold using DPF / PyDPF?
Ayush Kumar
Member, Moderator, Employee Posts: 467
✭✭✭✭
in Structures
Comments
-
The following script filters all nodes above a value of 0.3mm total deformation and finds all the elements connected to those nodes.
PyDPF
from ansys.dpf import core as dpf rst_path = r"\Path\to\file.rst" ds = dpf.DataSources(rst_path) crit_disp = 0.3 model = dpf.Model(ds) mesh = model.metadata.meshed_region mesh.plot() all_elems = mesh.elements.scoping.ids 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.get_data()[0].scoping.ids elements = [] mesh_con = mesh.property_field("reverse_connectivity") for node in nodes_crit: elements.append(mesh_con.get_entity_data_by_id(node)) # Flatten the list # elem_crit_indexes = list(set([element for nested_elements in elements for element in nested_elements])) elem_crit_ids = [mesh.elements.scoping.ids[eid] for eid in elem_crit_indexes] elem_crit_scop = dpf.Scoping() elem_crit_scop.ids = elem_crit_ids crit_mesh = dpf.operators.mesh.from_scoping(mesh=mesh, scoping=elem_crit_scop).outputs.mesh.get_data() crit_mesh.plot()
Mechanical DPF (IronPython)
import mech_dpf import Ans.DataProcessing as dpf mech_dpf.setExtAPI(ExtAPI) analysis = Model.Analyses[0] ds = dpf.DataSources(analysis.ResultFileName) crit_disp = 0.3 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: elements.append(mesh_con.GetEntityDataById(node)) 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
0 -
To add to @Ayush Kumar 's solution, if you want to plot the filtered element numbers back to the model in Mechanical, this can be done in a Python Result Object.
Edit Property Provider as follows:
def reload_props():
this.PropertyProvider = None
# Create the property instance
provider = Provider() group = provider.AddGroup("Inputs")
double_prop = group.AddProperty("Threshold", 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 = providerEdit Script as follows:
def define_dpf_workflow(analysis):
import mech_dpf
import Ans.DataProcessing as dpf
mech_dpf.setExtAPI(ExtAPI) ds = dpf.DataSources(analysis.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:
elements.append(mesh_con.GetEntityDataById(node))
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
# create new field and assign values
my_field = dpf.FieldsFactory.CreateScalarField(numEntities=0, location='Elemental')
my_field.MeshedRegionSupport = mesh
for elem_id in elem_crit_scop.Ids:
my_field.Add(elem_id,[float(elem_id)])
my_field.ScopingIds = elem_crit_scop.Ids
output = dpf.operators.utility.forward()
output.inputs.any.Connect(my_field)
dpf_workflow = dpf.Workflow()
dpf_workflow.Add(output)
dpf_workflow.SetOutputContour(output,dpf.enums.GFXContourType.FEElementalScoping)
dpf_workflow.Record('wf_id', False)
this.WorkflowId = dpf_workflow.GetRecordedId()Reload properties and evaluate result:
This will plot the element number on the filtered elements:
0