How to get stress results on a node closest to a given coordinate?

Jimmy He
Jimmy He Member, Employee Posts: 20
10 Comments First Answer First Anniversary Name Dropper
✭✭✭✭

If I have a set of coordinates, how can I locate the node closest to this coordinate and extract the stress results on it? What happens if this node happens to be a mid-side node?

Comments

  • Jimmy He
    Jimmy He Member, Employee Posts: 20
    10 Comments First Answer First Anniversary Name Dropper
    ✭✭✭✭

    You can use the following script to get the nodes closest to a set of given coordinates and extract the nodal-averaged stress at those nodes. To handle stress results at mid-side nodes (if those are requested), the elemental nodal stresses at the surrounding elements are first extracted. Those stress values are then extended to the mid-side nodes, and finally averaged to the nodes based on connectivity.

    import mech_dpf
    import Ans.DataProcessing as dpf
    mech_dpf.setExtAPI(ExtAPI)
    
    #Data sources
    dataSources = mech_dpf.GetDataSources(0)
    
    # Get Mesh
    op = dpf.operators.mesh.mesh_provider() # operator instanciation 
    op.inputs.data_sources.Connect(dataSources) 
    my_mesh = op.outputs.mesh.GetData() 
    mesh_info = op.outputs.getmesh()
    
    # Create 10 coordinates to get nearest nodes
    point_field=dpf.FieldsFactory.CreateVectorField(10,3,"Nodal")
    for n in range( 10 ):
        c = 0.1 + n * 0.05
        point_field.Add( n+1 , [c,c,c] )
    point_field.Unit = "mm"
    
    # Find nearest nodes
    op = dpf.operators.mesh.point_cloud_search() # operator instantiation
    op.inputs.search_domain.Connect(point_field)
    op.inputs.reference_domain.Connect(my_mesh)
    op.inputs.exclusive_search.Connect(True)
    my_search_indices = op.outputs.search_indices.GetData()
    relevant_node_ids = list( op.outputs.reference_indices.GetData().Ids )
    print( relevant_node_ids )
    
    
    # Get Connected Elements for all nodes requested
    all_involved_elements = []
    EIDS = mesh_info.ElementIds
    NCPF = mesh_info.NodalConnectivityPropertyField
    for nid in relevant_node_ids:
        eidx = NCPF.GetEntityDataById(nid)
        all_involved_elements += [ EIDS[_] for _ in eidx ]
    print( len(all_involved_elements) )
    
    
    # Get element nodal stress results
    scoping = dpf.Scoping()
    scoping.Ids = all_involved_elements
    scoping.Location = 'ElementalNodal'
    
    # Stress X direction
    stressXOp = dpf.operators.result.stress_X()
    stressXOp.inputs.mesh_scoping.Connect(scoping)
    stressXOp.inputs.data_sources.Connect(dataSources)
    sX = stressXOp.outputs.fields_container.GetData()
    
    #Extend stress result also to mid side nodes
    mid_op = dpf.operators.averaging.extend_to_mid_nodes_fc()
    mid_op.inputs.fields_container.Connect(sX)
    s_field_corner_mid = mid_op.outputs.fields_container.GetData()
    
    # Average to all nodes
    op = dpf.operators.averaging.elemental_nodal_to_nodal_fc() # operator instantiation
    op.inputs.fields_container.Connect(s_field_corner_mid)
    op.inputs.extend_to_mid_nodes.Connect(True)# optional
    s_field_nodal = op.outputs.fields_container.GetData()
    
    
    # Get the averaged stress at the requested nodes
    Stress_data = []
    for nid in relevant_node_ids:
        S = [ s_field_nodal[_].GetEntityDataById( nid )[0] for _ in range(n_time_step) ]
        Stress_data.append(S)
    
  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 345
    25 Answers 100 Comments 25 Likes First Anniversary
    ✭✭✭✭

    FYI an alternate way for only a few points is to use a worksheet named selection where you use the smallest distance to a local CS. You can then scope a stress object to that single-node NS.