How to Access Neighbor Nodes and Elements
m (→Generating Neighbour Lists -- C++) |
|||
(5 intermediate revisions by 3 users not shown) | |||
Line 16: | Line 16: | ||
note that the order is NOT guaranteed. | note that the order is NOT guaranteed. | ||
− | == Containers == | + | == Creation of the Neighbour Lists == |
+ | The creation of a list of neighbour nodes and elements implies a non neglibible price in terms of memory occupation. | ||
+ | A "Process" is provided in order to ease the generation of the lists when needed. The procedure for the search of the neighbours is as follows: | ||
+ | |||
+ | === Generating Neighbour Lists -- C++ === | ||
+ | a minimal file to perform the calculation of neighbours inside C++ is as follows: | ||
+ | #include processes/find_nodal_neighbours_process.h | ||
+ | ... | ||
+ | //Generate the process | ||
+ | Process& neighbour_finder = FindNodalNeighboursProcess(model_part,avg_elems, avg_nodes); | ||
+ | ... | ||
+ | //regenerate the lists ... this should be done every time the connectivity changes | ||
+ | neighbour_finder.Execute(); | ||
+ | the user should note that two parameters are left to be specified: | ||
+ | * avg_elements -- represents the expected average number of elements around one node | ||
+ | * avg_nodes -- expected average number of nodes arouind one node | ||
+ | this is just for optimization. A wrong (or too little) guess will not lead to wrong results (just the search will be a little slower) | ||
+ | |||
+ | === Generating Neighbour Lists -- Python === | ||
+ | The Python interface follows very closely the C++. A minimal script looks like | ||
+ | from Kratos import * ##import all of the Kratos functions | ||
+ | ... | ||
+ | neighbour_finder = FindNodalNeighboursProcess(model_part,avg_elems, avg_nodes); | ||
+ | ... | ||
+ | neigbour_finder.Execute(); ##at wish ... when it is needed | ||
+ | |||
+ | |||
+ | === Troubleshooting === | ||
+ | The usage of the "neighbour_finder" is pretty straightforward and should not provide major problems. Some care should however be taken when different model parts share the same list of nodes. The problem is that a node contains A SINGLE list of neighbours which is calculated according to the connectivity stored in a given model part. If another model part (having the same nodes but a different connectivity) is used, the list of neighbours should be recalculated on the model part on which we are interested to work and recalculated every time one switches to one model part to the other. | ||
+ | |||
+ | This problem does not exist if the different model parts have different Nodes, nor if they have the same nodes but also the same connectivity. | ||
+ | |||
+ | |||
+ | |||
+ | == Format and usage of the Containers == | ||
The list of neighbour elements is stored in Kratos as a list of (Weak) Pointers to the nodes or elements. | The list of neighbour elements is stored in Kratos as a list of (Weak) Pointers to the nodes or elements. | ||
Given a pointer "pnode" to a Node, the list of its neighbour nodes can be obtained as | Given a pointer "pnode" to a Node, the list of its neighbour nodes can be obtained as | ||
Line 23: | Line 57: | ||
WeakPointerVector< Element >& rneigh_el = pnode->GetValue(NEIGHBOUR_ELEMENTS); | WeakPointerVector< Element >& rneigh_el = pnode->GetValue(NEIGHBOUR_ELEMENTS); | ||
− | The two containers are standard and can be treated as normal stl containers. A loop over nodes can thus be done by | + | The two containers are standard and can be treated as normal stl-style containers. A loop over nodes can thus be done by |
WeakPointerVector< Node<3> >& rneigh = pnode->GetValue(NEIGHBOUR_NODES); | WeakPointerVector< Node<3> >& rneigh = pnode->GetValue(NEIGHBOUR_NODES); | ||
for( WeakPointerVector<Node<3> >::iterator inode = rneigh.begin(); inode!=rneigh.end(); inode++) | for( WeakPointerVector<Node<3> >::iterator inode = rneigh.begin(); inode!=rneigh.end(); inode++) | ||
inode->Id(); //accesses to the Id of the node | inode->Id(); //accesses to the Id of the node | ||
+ | |||
+ | the user should note that "Weak" pointers are used instead of "Pointers". This is done to guarantee that if a node or element is removed from the list, it will be automatically set to null (but will not be preserved in the memory as it would happen using "Pointers"). | ||
+ | |||
+ | |||
+ | |||
+ | [[Category:How To]] |
Latest revision as of 08:09, 6 April 2016
In a finite element context it is often useful to have a fast access ( O(N) time with N number of nodes ) to the objects which are "around" a certain node. This can be achieved by storing on each node the list of all of the nodes and elements which are close to it.
Contents |
Definition
Before proceeding it is useful to clarify the meaning of the word "around". To do so, let's consider the mesh
we will define as "NEIGHBOUR NODES" of node 910 which share at least one element with node 910. To make an example
- Node 910 has the nodes {968 , 940 , 986 , 850 , 876 , 931 } as neighbours nodes
- Node 876 has the nodes {910, 850, 820, 843, 898, 931} as neighbours nodes
and the elements
- {2873, 2960, 2961, 2876, 2875, 2874} as NEIGHBOUR ELEMENTS of node 910
- {2876, 2877, 2849, 2848, 2865, 2875} as NEIGHBOUR ELEMENTS of node 876
note that the order is NOT guaranteed.
Creation of the Neighbour Lists
The creation of a list of neighbour nodes and elements implies a non neglibible price in terms of memory occupation. A "Process" is provided in order to ease the generation of the lists when needed. The procedure for the search of the neighbours is as follows:
Generating Neighbour Lists -- C++
a minimal file to perform the calculation of neighbours inside C++ is as follows:
#include processes/find_nodal_neighbours_process.h ... //Generate the process Process& neighbour_finder = FindNodalNeighboursProcess(model_part,avg_elems, avg_nodes); ... //regenerate the lists ... this should be done every time the connectivity changes neighbour_finder.Execute();
the user should note that two parameters are left to be specified:
- avg_elements -- represents the expected average number of elements around one node
- avg_nodes -- expected average number of nodes arouind one node
this is just for optimization. A wrong (or too little) guess will not lead to wrong results (just the search will be a little slower)
Generating Neighbour Lists -- Python
The Python interface follows very closely the C++. A minimal script looks like
from Kratos import * ##import all of the Kratos functions ... neighbour_finder = FindNodalNeighboursProcess(model_part,avg_elems, avg_nodes); ... neigbour_finder.Execute(); ##at wish ... when it is needed
Troubleshooting
The usage of the "neighbour_finder" is pretty straightforward and should not provide major problems. Some care should however be taken when different model parts share the same list of nodes. The problem is that a node contains A SINGLE list of neighbours which is calculated according to the connectivity stored in a given model part. If another model part (having the same nodes but a different connectivity) is used, the list of neighbours should be recalculated on the model part on which we are interested to work and recalculated every time one switches to one model part to the other.
This problem does not exist if the different model parts have different Nodes, nor if they have the same nodes but also the same connectivity.
Format and usage of the Containers
The list of neighbour elements is stored in Kratos as a list of (Weak) Pointers to the nodes or elements. Given a pointer "pnode" to a Node, the list of its neighbour nodes can be obtained as
WeakPointerVector< Node<3> >& rneigh = pnode->GetValue(NEIGHBOUR_NODES);
while the neighbour elements list can be accessed by
WeakPointerVector< Element >& rneigh_el = pnode->GetValue(NEIGHBOUR_ELEMENTS);
The two containers are standard and can be treated as normal stl-style containers. A loop over nodes can thus be done by
WeakPointerVector< Node<3> >& rneigh = pnode->GetValue(NEIGHBOUR_NODES); for( WeakPointerVector<Node<3> >::iterator inode = rneigh.begin(); inode!=rneigh.end(); inode++) inode->Id(); //accesses to the Id of the node
the user should note that "Weak" pointers are used instead of "Pointers". This is done to guarantee that if a node or element is removed from the list, it will be automatically set to null (but will not be preserved in the memory as it would happen using "Pointers").