Get successive elements with max stress in depth of structure
Pernelle Marone-Hitz
Member, Moderator, Employee Posts: 871
✭✭✭✭
I'd like to select an element, and based on that starting point get the successive N elements with max stress in the depth of the solid body.
Tagged:
0
Answers
-
Here is an example of Python Result that :
- allows the user to :
- select an element "start_elem" on the surface of a solid body
- define the number of in-depth layers that should be considered
- calculates and plots a result as follow:
- retrieve the stress on start_elem
- select the elements connected to start_elem, but only the elements in the depth of the structure, and identify the element with max stress on the selected elements
- iterate this procedure N number of times, N being the number of layers defined by the user
- plot the identified elements and evaluate the average stress on these elements
This is achieved by editing the Property Provider of the Python Result as follows:
def reload_props(): this.PropertyProvider = None # Create the property instance provider = Provider() input_group = provider.AddGroup("Input") ns_prop = input_group.AddProperty("Elemental Named Selection Name", Control.Expression) nb_layer_prop = input_group.AddProperty("Number of Layers", Control.Double) output_group = provider.AddGroup("Output") output_prop = output_group.AddProperty("Average stress over selected elements", Control.Double) output_prop.CanParameterize = True output_prop.ParameterType = ParameterType.Output # 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
As a result, the properies of the Python Result should look like this:
And the Script to use in the Python Result is:
def post_started(sender, analysis):# Do not edit this line define_dpf_workflow(analysis) def define_dpf_workflow(analysis): # import DPF import mech_dpf import Ans.DataProcessing as dpf mech_dpf.setExtAPI(ExtAPI) # Connect to result file dataSource = dpf.DataSources(analysis.ResultFileName) # Retrieve property values selection_name = str(this.GetCustomPropertyByPath("Input/Elemental Named Selection Name").Value) n_layers = int(this.GetCustomPropertyByPath("Input/Number of Layers").Value) # Retrieve mesh model=dpf.Model(dataSource) mesh=model.Mesh # whole mesh skin_mesh=dpf.operators.mesh.skin(mesh) # skin mesh skin_nodes=skin_mesh.outputs.getnodes_mesh_scoping() # get nodes of skin mesh conv_to_elems=dpf.operators.scoping.transpose(mesh_scoping=skin_nodes,meshed_region=mesh) # convert to elements skin_elems_scoping=conv_to_elems.outputs.getmesh_scoping_as_scoping() # create a scoping with skin elements # Retrieve Von Mises stress on elements s = dpf.operators.result.stress_von_mises() s.inputs.requested_location.Connect('Elemental') s.inputs.data_sources.Connect(dataSource) # Get starting element from named selection selection_name=selection_name.upper() # Start element elem=dpf.operators.scoping.on_named_selection(named_selection_name=selection_name, requested_location='Elemental',data_sources=dataSource) elem_scoping=elem.outputs.getmesh_scoping() # Retrieve max stress on selected element s.inputs.mesh_scoping.Connect(elem_scoping) s_max=dpf.operators.min_max.min_max(s.outputs.getfields_container()[0]) # Collect element id and stress values elem_ids=[elem.outputs.getmesh_scoping().Ids[0]] smax=[s_max.outputs.field_max.GetData().Data[0]] # Find next n elements with highest stresses but don't take into account any element with free surface (i.e. linked to outer skin) for i in range(0,n_layers): conv_to_nodes=dpf.operators.scoping.transpose(mesh_scoping=elem_scoping,meshed_region=mesh) # get nodes of selected element neighbour_mesh_op= dpf.operators.mesh.from_scoping(scoping=conv_to_nodes,mesh=mesh) # get elements attached to nodes # Remove skin related elements diff_scoping=dpf.operators.scoping.intersect(scopingA=neighbour_mesh_op.outputs.getmesh().ElementScoping,scopingB=skin_elems_scoping) inside_elements_scoping=diff_scoping.outputs.scopingA_min_intersection.GetData() # Remove any of the previously identified elements from the scoping el_ids=list(inside_elements_scoping.Ids) for el in elem_ids: try: el_ids.remove(el) except: pass inside_elements_scoping.Ids=el_ids # Find element with highest stress value s.inputs.mesh_scoping.Connect(inside_elements_scoping) s_max=dpf.operators.min_max.min_max(s.outputs.getfields_container()[0]) # Collect element id and stress values next_elem_id=s_max.outputs.field_max.GetData().ScopingIds[0] elem_ids.append(next_elem_id) smax.append(s_max.outputs.field_max.GetData().Data[0]) # Before ending the loop, update start element to be last one found elem_scoping.Ids=[next_elem_id] # Set output value this.GetCustomPropertyByPath("Output/Average stress over selected elements").Value=sum(smax)/len(smax) # Display mesh will be only selected elements selected_scoping=dpf.Scoping() selected_scoping.Ids=elem_ids selected_scoping.Location='Elemental' s.inputs.mesh_scoping.Connect(selected_scoping) display_mesh=dpf.operators.mesh.from_scoping(scoping=selected_scoping,mesh=mesh) dpf_workflow = dpf.Workflow() dpf_workflow.Add(s) dpf_workflow.SetOutputMesh(display_mesh.outputs.getmesh()) dpf_workflow.SetOutputContour(s) dpf_workflow.Record('wf_id', False) this.WorkflowId = dpf_workflow.GetRecordedId()
The starting element should be defined thanks to a named selection (and by providing the name of said NS in the property of the Python Result):
With an standard equivalent stress plot as follows:
This is how the Python Result will look like for 2 layers defined:
0 - allows the user to :