DPF operators like NSEL/ESEL

Options
Mike.Thompson
Mike.Thompson Member, Employee Posts: 316
First Answer First Anniversary First Comment 5 Likes

Does DPF have any operators that work like the NSEL APDL commands? Specifically I want to point to a CS in Mechanical and get all nodes within a certain radius to the cyl system axis (filter by its local X).

I am looking for an efficient solution to work on large meshes with potentially thousands of these CSs.

Tagged:

Answers

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 831
    First Comment First Anniversary Ansys Employee Solution Developer Community of Practice Member
    Options

    Hi @Mike.Thompson , yes, there's:

    dpf.operators.scoping.transpose(mesh_scoping=elem_scoping,meshed_region=mesh) # get nodes of selected element

    and

    dpf.operators.mesh.from_scoping(scoping=conv_to_nodes,mesh=mesh) # get elements attached to nodes

    They are used in this example:

  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 316
    First Answer First Anniversary First Comment 5 Likes
    Options

    @Pernelle Marone-Hitz , thanks for that information and it is helpful, but not exactly what I am looking for. That is similar to the ESLN and NSLE commands. I am looking for the NSEL and ESEL commands where nodes/elems are selected based on coordinates based on a local or global CS.

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 831
    First Comment First Anniversary Ansys Employee Solution Developer Community of Practice Member
    Options

    @Mike.Thompson oups sorry seems I had a slight case of dyslexia here ;-) @Ayush Kumar and @Paul Profizi, any ideas here? If there isn't yet a function to do this, it would be a great addition for customers wanting to migrate their workflows from MAPDL to DPF.

  • Ayush Kumar
    Ayush Kumar Member, Moderator, Employee Posts: 419
    5 Likes First Anniversary Ansys Employee Solution Developer Community of Practice Member
    Options

    I am not aware of any equivalent functions in DPF, developing one would be a good idea.

    We can of course check the distance of each node / element to the CS origin and create a new scoping based on that, might be cumbersome though, if the model is big.

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 831
    First Comment First Anniversary Ansys Employee Solution Developer Community of Practice Member
    Options

    @Paul Profizi , @Ramdane , it this something you could consider developping? Many thanks.

  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 316
    First Answer First Anniversary First Comment 5 Likes
    Options

    To be clear, the main idea of this operator would be to scale well on large models with many such selection requests. For example, think of an assembly with 1000 beams as bolts and you want to get all surface nodes within an axial and radius tolerance of 2000 Cyl CS (one for each end of the 1000 beams).

    Ideally an operator would take as an input the 2000 CSs, the selection logic, and could return a data structure that identified the Ids of the nodes associated with each reference CS.

    A user might use this for connecting the beams to the assembly structure. We can do this in APDL with selection logic, but it would be nice to have a solution that can be done/viewed in mechanical. We can also do this with worksheet named selection, but it would be nice to be able to get this without the need of the NS object, and the WS logic doesn't scale very well as each object is generated independently.

  • Pierre Thieffry
    Pierre Thieffry Member, Moderator, Employee Posts: 103
    First Anniversary Ansys Employee Solution Developer Community of Practice Member Photogenic
    edited August 2023
    Options

    @Mike.Thompson the code below could be a starting point to create a new operator. This one is in Python, I guess we could achieve good performance with C++. The code below does a simple nsel,s,[xyz]loc in a cartesian system. Note that you can start the search from an initial set of nodes.

    Tested on a 3.2 mio node model, 3 searches take a total of 2-3 seconds

      def nsel(meshed_region,xloc=(),yloc=(),zloc=(),strictly=False,from_selection=[]):
    import numpy as np sel_nodes=from_selection

    if len(sel_nodes)==0:
    mesh=meshed_region
    else:
    n_scoping=dpf.Scoping(location='Nodal',ids=sel_nodes)
    m_scoping = dpf.operators.mesh.from_scoping(scoping=n_scoping,mesh=meshed_region)
    mesh=m_scoping.outputs.mesh()

    node_coords=mesh.nodes.coordinates_field.data
    node_to_index=mesh.nodes.mapping_id_to_index
    index_to_node={v: k for k, v in node_to_index.items()}
    node_keys=list(sorted(index_to_node.keys()))

    # provide xloc,yloc and zloc as tuple
    if xloc!=():
    if strictly:
    index_x = np.where((node_coords[:,0]>xloc[0]) & (node_coords[:,0]<xloc[1]))
    else:
    index_x = np.where((node_coords[:,0]>=xloc[0]) & (node_coords[:,0]<=xloc[1]))
    sel_nodes=[index_to_node[node_keys[i]] for i in index_x[0]]

    if yloc!=():
    if strictly:
    index_y = np.where((node_coords[:,1]>yloc[0]) & (node_coords[:,1]<yloc[1]))
    else:
    index_y = np.where((node_coords[:,1]>=yloc[0]) & (node_coords[:,1]<=yloc[1]))
    sel_nodes_y=[index_to_node[node_keys[i]] for i in index_y[0]]
    if len(sel_nodes)>0:
    sel_nodes=list(set(sel_nodes) & set(sel_nodes_y))
    else:
    sel_nodes=sel_nodes_y
    if zloc!=():
    if strictly:
    index_z = np.where((node_coords[:,2]>zloc[0]) & (node_coords[:,2]<zloc[1]))
    else:
    index_z = np.where((node_coords[:,2]>=zloc[0]) & (node_coords[:,2]<=zloc[1]))
    sel_nodes_z=[index_to_node[node_keys[i]] for i in index_z[0]]
    if len(sel_nodes)>0:
    sel_nodes=list(set(sel_nodes) & set(sel_nodes_z))
    else:
    sel_nodes=sel_nodes_z

    return sel_nodes #use nsel function rst_file=whichever file you want to use. dataSource = dpf.DataSources(rst_file) Retrieve model model=dpf.Model(dataSource) display_mesh=model.metadata.meshed_region node_sel=nsel(display_mesh,xloc=(300.,300.1)) node_sel2=nsel(display_mesh,yloc=(100.,200.),from_selection=node_sel) node_sel3=nsel(display_mesh,zloc=(0.,300.),from_selection=node_sel2)