How can I get the nodal result for a single material if the node is shared between two materials?

M
M Member, Employee Posts: 241
50 Answers 100 Comments 100 Likes Second Anniversary
✭✭✭✭
edited July 30 in Structures

I have a model with two materials and shared topology. So the nodes between the two bodies are shared.

Node 13 is a corner node between the two geometries.

Due to material props, you can get different strains at the node so Mechanical returns two values for a equivalent strain at node 13.

**My goal is to get the value for equivalent strain at node 13 for material 1 (or 2). **

I tried to use a named selection w/ boolean (material - convert to nodes - filter to node 13 and scope to that name selection but that gives the same results as node 13 direct).

The result I want is best demonstrated by picking a non shared topo node where a single value is returned because there is only one material.

The op = dpf.operators.scoping.split_on_property_type() should allow me to scope to a material (by number) but I don't have it working yet.

first attempts with dpf which get me the averaged nodal result:

def post_started(sender, analysis):# Do not edit this line
    define_dpf_workflow(analysis)

# Uncomment this function to enable retrieving results from the table/chart
# def table_retrieve_result(value):# Do not edit this line
    # import mech_dpf
    # import Ans.DataProcessing as dpf
    # wf = dpf.Workflow(this.WorkflowId)
    # wf.Connect('contour_selector', value)
    # this.Evaluate()

def define_dpf_workflow(analysis):
    import mech_dpf
    import Ans.DataProcessing as dpf

    node = 13
    my_data_sources = dpf.DataSources(analysis.ResultFileName)
    my_time_scoping = dpf.Scoping()
    my_time_scoping.Ids = [1] # the first set

    my_scoping = dpf.Scoping()
    my_scoping.Location = "Nodal" #optional
    my_scoping.Ids = [node]

    st_eqv_op = dpf.operators.result.elastic_strain_eqv()
    st_eqv_op.inputs.requested_location.Connect('Nodal')
    st_eqv_op.inputs.data_sources.Connect(my_data_sources)
    st_eqv_op.inputs.time_scoping.Connect(my_time_scoping)

    st_eqv_op.inputs.mesh_scoping.Connect(my_scoping)

    #mesh_op = dpf.operators.mesh.mesh_provider() 
    #mesh_op.inputs.data_sources.Connect(my_data_sources) 
    #mesh = mesh_op.outputs.mesh.GetData() 

    op = dpf.operators.scoping.split_on_property_type() # operator instantiation
    #op.inputs.mesh_scoping.Connect(st_eqv_op)# optional
    #op.inputs.mesh.Connect(mesh)
    #op.inputs.requested_location.Connect(13)

    dpf_workflow = dpf.Workflow()
    dpf_workflow.Add(st_eqv_op)
    dpf_workflow.SetOutputContour(st_eqv_op)
    dpf_workflow.Record('wf_id', True)
    this.WorkflowId = dpf_workflow.GetRecordedId()

@Vishnu @Pierre Thieffry @Ayush Kumar

Best Answer

  • Ayush Kumar
    Ayush Kumar Member, Moderator, Employee Posts: 456
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭
    Answer ✓

    Below is an example based on the idea from @Mike.Thompson

    import Ans.DataProcessing as dpf
    
    rst_path = Model.Analyses[0].ResultFileName
    
    nid = 134
    
    model = dpf.Model(rst_path)
    mesh = model.Mesh
    
    mesh_split = dpf.operators.mesh.split_mesh(mesh=mesh, property="mat")
    meshes = mesh_split.outputs.meshes.GetData()
    
    for index in range(meshes.Length):
        mat_id = meshes.GetLabelSpace(index)["mat"]
        ms = dpf.operators.scoping.from_mesh(mesh=meshes.Get(index), requested_location="Elemental")
        ms_f = ms.outputs.scoping.GetData()
    
        sx = model.CreateOperator("SX")
        sx.inputs.requested_location.Connect("Nodal")
        sx.inputs.mesh_scoping.Connect(ms_f)
        sx_f = sx.outputs.fields_container.GetData()[0]
    
        s_nid = sx_f.GetEntityDataById(nid)[0]
        print("Material ID %s Averaged Stress for Node ID %s: %s" % (mat_id, nid, s_nid ))
    
    model.ReleaseStreams()
    

Answers

  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 345
    25 Answers 100 Comments 25 Likes First Anniversary
    ✭✭✭✭

    @M, What you need is to use an elemental scoping for only the elements of interest (in your case mat 1 or 2). You can get this in a number of ways. This will mean the results operator getting the data will only pull information from those nodes and ignore the others. You can still have requested location = nodal, and the operator will do the element nodal to nodal averaging, but only per the elements in the elemental scoping.

    I hope this makes sense the difference between the mesh scoping being elemental and the requested location being nodal.

  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 345
    25 Answers 100 Comments 25 Likes First Anniversary
    ✭✭✭✭

    FYI, this is also very helpful when you have things like mixed dimensional modeling. I first ran into this when I wanted to extract stress from a surface coating and the nodes were attached to the surface shells as well as the solids. The data being extracted was decomposed into two types, one for each. I made an elemental mesh scoping for only the shell coatings and all was fixed to get only the results per the coating elements as desired.