NodeReordering Namespace Reference

Contains helper function to reorganise nodes. More...

Functions

bool node_global_position_comparison (Node *nd1_pt, Node *nd2_pt)
 
void get_node_reordering (Mesh *mesh_pt, Vector< Node * > &reordering, const bool &use_old_ordering)
 
void reorder_nodes (Mesh *mesh_pt, const bool &use_old_ordering)
 

Detailed Description

Contains helper function to reorganise nodes.

///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

Function Documentation

◆ get_node_reordering()

void NodeReordering::get_node_reordering ( Mesh mesh_pt,
Vector< Node * > &  reordering,
const bool use_old_ordering 
)

Get a vector of the nodes in the order in which they are encountered when stepping through the elements (similar to reorder_nodes() but without changing the mesh's node vector).

332  {
333  // If the user wants to use the original ordering
334  if (use_old_ordering)
335  {
336  // Setup map to check if nodes have been done yet
337  std::map<Node*,bool> done;
338 
339  // Loop over all nodes
340  unsigned nnod=mesh_pt->nnode();
341 
342  // Initialise the vector
343  reordering.assign(nnod,0);
344 
345  // Return immediately if there are no nodes: Note assumption:
346  // Either all the elements' nodes stored here or none. If only a subset
347  // is stored in the Node_pt vector we'll get a range checking error below
348  // (only if run with range checking, of course).
349  if (nnod==0)
350  {
351  // Return immediately
352  return;
353  }
354 
355  // Loop over the nodes in the mesh
356  for (unsigned j=0; j<nnod; j++)
357  {
358  // Indicate whether or not the node has been swapped
359  done[mesh_pt->node_pt(j)]=false;
360  }
361 
362  // Initialise counter for number of nodes
363  unsigned long count=0;
364 
365  // Get the number of elements in the mesh
366  unsigned nel=mesh_pt->nelement();
367 
368  // Loop over all elements
369  for (unsigned e=0; e<nel; e++)
370  {
371  // Upcase FiniteElement (or derived) class object
372  FiniteElement* el_pt=mesh_pt->finite_element_pt(e);
373 
374  // If the upcast was successful
375  if (el_pt!=0)
376  {
377  // Get the number of nodes in this element
378  unsigned nnod=el_pt->nnode();
379 
380  // Loop over nodes in element
381  for (unsigned j=0; j<nnod; j++)
382  {
383  // Get a pointer to the j-th node in the element
384  Node* nod_pt=el_pt->node_pt(j);
385 
386  // Has node been done yet?
387  if (!done[nod_pt])
388  {
389  // Insert into node vector. NOTE: If you get a seg fault/range
390  // checking error here then you probably haven't added all the
391  // elements' nodes to the Node_pt vector -- this is most likely
392  // to arise in the case of meshes of face elements (though they
393  // usually don't store the nodes at all so if you have any
394  // problems here there's something unusual/not quite right in
395  // any case... For this reason we don't range check here by
396  // default (not even under paranoia) but force you turn on proper
397  // (costly) range checking to track this down...
398  reordering[count]=nod_pt;
399 
400  // Indicate that the node has been done
401  done[nod_pt]=true;
402 
403  // Increase counter
404  count++;
405  }
406  } // for (unsigned j=0;j<nnod;j++)
407  } // if (el_pt!=0)
408  } // for (unsigned e=0;e<nel;e++)
409 
410  // Sanity check
411  if (count!=nnod)
412  {
413  // Create an error message
414  std::string error_message="Trouble: Number of nodes hasn't stayed ";
415 
416  // Finish off the message
417  error_message+="constant during reordering!\n";
418 
419  // Throw an error
420  throw OomphLibError(error_message,
423  }
424  }
425  else
426  {
427  // Copy node vector out
428  unsigned n_node=mesh_pt->nnode();
429 
430  // Resize the node ordering vector
431  reordering.resize(n_node);
432 
433  // Loop over the nodes
434  for (unsigned i=0; i<n_node; i++)
435  {
436  // Assign the i-th node pointer entry
437  reordering[i]=mesh_pt->node_pt(i);
438  }
439 
440  // Now sort the nodes lexicographically
441  std::sort(reordering.begin(),reordering.end(),
443  } // if (use_old_ordering)
444  } // End of get_node_reordering
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
Definition: nodes.h:906
Definition: oomph_definitions.h:222
bool node_global_position_comparison(Node *nd1_pt, Node *nd2_pt)
Definition: space_time_oscillating_cylinder.cc:255
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References e(), oomph::Mesh::finite_element_pt(), i, j, oomph::Mesh::nelement(), oomph::FiniteElement::nnode(), oomph::Mesh::nnode(), node_global_position_comparison(), oomph::FiniteElement::node_pt(), oomph::Mesh::node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and oomph::Global_string_for_annotation::string().

Referenced by reorder_nodes().

◆ node_global_position_comparison()

bool NodeReordering::node_global_position_comparison ( Node nd1_pt,
Node nd2_pt 
)
inline

Function for ordering nodes. Return true if first node's position is "before" second nodes. Dimension 0 checked first, then... until they are different (by more than tol=1e-10). If they are both in exactly the same place an error is thrown.

256  {
257  // If we're comparing a node with itself
258  if (nd1_pt==nd2_pt)
259  {
260  // Don't do anything (passing true makes std::sort break...)
261  return false;
262  }
263 
264  // Get the number of dimensions stored by the node
265  unsigned n_dim=nd1_pt->ndim();
266 
267  // A vector containing the indices in the order to check them. Order by
268  // time slices first, then order the nodes in each time-slice by their x
269  // position and finally order the nodes by their y-position (3D version)
270  unsigned chosen_index[]= {2,0,1};
271 
272  // The coordinate indices in the order to check them (2D version)
273  unsigned chosen_index_2d[]= {0,1};
274 
275  // Allocate space for the index we're going to order by
276  unsigned j=0;
277 
278  // Loop over the spatial coordinates
279  for (unsigned i=0; i<n_dim; i++)
280  {
281  // If we're in 3D (space-time)
282  if (n_dim==3)
283  {
284  // The index we're going to order by
285  j=chosen_index[i];
286  }
287  else
288  {
289  // The index we're going to order by
290  j=chosen_index_2d[i];
291  }
292 
293  // Check to see if the points occupy the same position (in index j)
294  if (std::abs(nd1_pt->x(j)-nd2_pt->x(j))>1e-10)
295  {
296  // Check to see if node 1 is before node 2
297  if (nd1_pt->x(j)<nd2_pt->x(j))
298  {
299  // Node 1 is before node 2 so return true
300  return true;
301  }
302  // If node 2 is after node 1
303  else
304  {
305  // Node 1 isn't before node 2 so return false
306  return false;
307  }
308  } // if (std::abs(nd1_pt->x(j)-nd2_pt->x(j))>1e-10)
309  } // for (unsigned i=0;i<n_dim;i++)
310 
311  // Create an output stream
312  std::ostringstream error_message_stream;
313 
314  // Construct the error message
315  error_message_stream << "Nodes are at the same point to ~1e-10! "
316  << "The difference is "
317  << std::abs(nd1_pt->x(j)-nd2_pt->x(j)) << std::endl;
318 
319  // Throw the error message
320  throw OomphLibError(error_message_stream.str(),
323  } // End of node_global_position_comparison
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054

References abs(), e(), i, j, oomph::Node::ndim(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and oomph::Node::x().

Referenced by get_node_reordering().

◆ reorder_nodes()

void NodeReordering::reorder_nodes ( Mesh mesh_pt,
const bool use_old_ordering 
)

Reorder nodes in the order in which they are encountered when stepping through the elements

450  {
451  // Create storage for the reordered nodes
452  Vector<Node*> reordering;
453 
454  // Get the reordered nodes (without altering the mesh's node vector)
455  get_node_reordering(mesh_pt,reordering,use_old_ordering);
456 
457  // Get the number of nodes in the mesh
458  unsigned n_node=mesh_pt->nnode();
459 
460  // Loop over all of the nodes
461  for (unsigned i=0; i<n_node; i++)
462  {
463  // Replace the Mesh's i-th node pointer with the reordered node pointer
464  mesh_pt->node_pt(i)=reordering[i];
465  }
466  } // End of reorder_nodes
void get_node_reordering(Mesh *mesh_pt, Vector< Node * > &reordering, const bool &use_old_ordering)
Definition: space_time_oscillating_cylinder.cc:329

References get_node_reordering(), i, oomph::Mesh::nnode(), and oomph::Mesh::node_pt().

Referenced by NavierStokesProblem< ELEMENT >::create_spacetime_mesh().