DPF operators like NSEL/ESEL
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.
Answers
-
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:
0 -
@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.
0 -
@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.
0 -
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.
0 -
@Paul Profizi , @Ramdane , it this something you could consider developping? Many thanks.
0 -
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.
0 -
@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)0