PyDPF - Remove midside nodes

TommasoMarella
TommasoMarella Member Posts: 4
First Comment Name Dropper
**
edited February 2023 in General Language Questions

Hi guys,

Can I remove midside nodes from the extracted nodes, using Pydpf?

Tagged:

Comments

  • Pierre Thieffry
    Pierre Thieffry Member, Moderator, Employee Posts: 107
    5 Likes Name Dropper First Comment First Answer
    ✭✭✭✭
    edited February 2023

    Hi @TommasoMarella what are you trying to achieve? Is this to scope a result to just corner nodes?

  • TommasoMarella
    TommasoMarella Member Posts: 4
    First Comment Name Dropper
    **

    Hi @Pierre Thieffry ,

    Yes, it is.

    I need to analyse a rst file extracting (for a specific component) nodal stress. In the model are presents also midside nodes, so when I get the results I have all nodes (corner + midside).

    I'm not interested in midside, so I would like to removed them during the extraction, or extract only corner nodes (it is the same). Is it possible?


    Thanks for the help,

    Tommaso

  • Pierre Thieffry
    Pierre Thieffry Member, Moderator, Employee Posts: 107
    5 Likes Name Dropper First Comment First Answer
    ✭✭✭✭

    Two things: when you extract stresses at nodes (location='Nodal' or converting from 'ElementalNodal' to 'Nodal' with the elemental_nodal_to_nodal operator), they should only be scoped to corner nodes - to get the midside nodes, you will need to use the extend_to_mid_nodes operator.

    Now, if one wants the list of corner nodes, I can propose this function. We have requested our developers to create specific operators for this, but in the meantime, this should work for 10 noded tets and 20 noded hex:


    def get_corner_nodes(mesh,scoping=None):
      corner_nodes=[]
      type_info={1:[20,8],0:[10,4]} # Element type with number of nodes and number of corner nodes
       
      # scope to few elements if scoping is defined
      if scoping!=None:
        mscope = dpf.operators.mesh.from_scoping(scoping=scoping,mesh=mesh)
        scopedmesh=mscope.outputs.mesh.get_data()
      else:
        scopedmesh=mesh
         
      # Loop over element type to extract corner nodes
      eltypes=scopedmesh.property_field('eltype').data   
      elements=scopedmesh.elements
      nodes=scopedmesh.nodes
      # Look over element type
      for iprop in range(len(eltypes)):
        if not(eltypes[iprop] in type_info.keys()):
          # we assume linear element, send back all nodes
          el_nodes=elements.element_by_index(iprop).connectivity
          for idx in el_nodes:
            corner_nodes.append(nodes.node_by_index(idx).id)
        else:
          # quadratic element, send back corner nodes (first in the connectivity)
          num_corner_nodes=type_info[eltypes[iprop]][1]
          el_nodes=elements.element_by_index(iprop).connectivity
          for i in range(0,num_corner_nodes):
            corner_nodes.append(nodes.node_by_index(el_nodes[i]).id)
      corner_nodes=list(dict.fromkeys(corner_nodes))
       
      return corner_nodes   
    
    mesh=model.metadata.meshed_region
    # get corner nodes for element 1
    scoping=dpf.Scoping(location='Elemental')
    scoping.ids=[1]
    cn_scoped=get_corner_nodes(mesh,scoping)     
    # get corner nodes for all elements
    cn_all=get_corner_nodes(mesh)     
    
  • Pierre Thieffry
    Pierre Thieffry Member, Moderator, Employee Posts: 107
    5 Likes Name Dropper First Comment First Answer
    ✭✭✭✭

    Here's another option with the take_mid_nodes option on scoping.connectivity_ids operator


    from ansys.dpf import core as dpf 
    from ansys.dpf.core import examples 
    model = dpf.Model(examples.download_all_kinds_of_complexity()) 
    
    all_node_ids = model.metadata.meshed_region.nodes.scoping.ids 
    print("Nb of nodes:", len(all_node_ids)) 
    
    # Instantiate operator and connect inputs in one line 
    op = dpf.operators.scoping.connectivity_ids(mesh_scoping=model.metadata.meshed_region.elements.scoping,
    mesh=model.metadata.meshed_region, take_mid_nodes=False, ) 
    
    # Get output data 
    corner_node_ids = list(set(op.outputs.mesh_scoping().ids))
    
    print("Nb of corner nodes:", len(corner_node_ids)) 
    
    mid_node_ids = list(set(all_node_ids).symmetric_difference(set(corner_node_ids))) 
    
    print("Nb of middle nodes:", len(mid_node_ids)) 
    print(f"Check total: {len(corner_node_ids) + len(mid_node_ids)}")
    
  • dafedin
    dafedin Member Posts: 21
    First Anniversary 10 Comments Name Dropper
    **

    Hi @Pierre Thieffry!

    I have the reversed task. I'd like to have the capability to get stresses from any nodes in model, not only corner nodes. It's well known, that result file doesn't store stresses for mid-side nodes. Mechanical does averaging on-fly when user ask for them. So, I wonder if we have another way to get stresses in mid-side nodes using DPF instead of using node connectivity operator and manual averaging stress values in neighbor corner nides?