oomph::TriangleScaffoldMesh Class Reference

#include <triangle_scaffold_mesh.h>

+ Inheritance diagram for oomph::TriangleScaffoldMesh:

Public Member Functions

 TriangleScaffoldMesh ()
 Empty constructor. More...
 
 TriangleScaffoldMesh (const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name)
 Constructor: Pass the filenames of the triangle files. More...
 
 TriangleScaffoldMesh (const TriangleScaffoldMesh &)=delete
 Broken copy constructor. More...
 
void operator= (const TriangleScaffoldMesh &)=delete
 Broken assignment operator. More...
 
 ~TriangleScaffoldMesh ()
 Empty destructor. More...
 
unsigned global_node_number (const unsigned &i)
 
unsigned edge_boundary (const unsigned &e, const unsigned &i) const
 
unsigned nglobal_edge ()
 Return the number of internal edges. More...
 
unsigned edge_index (const unsigned &e, const unsigned &i) const
 
double element_attribute (const unsigned &e) const
 Return the attribute of the element e. More...
 
Vector< Vector< double > > & internal_point ()
 Vectors of hole centre coordinates. More...
 
- Public Member Functions inherited from oomph::Mesh
 Mesh ()
 Default constructor. More...
 
 Mesh (const Vector< Mesh * > &sub_mesh_pt)
 
void merge_meshes (const Vector< Mesh * > &sub_mesh_pt)
 
virtual void setup_boundary_element_info ()
 
virtual void setup_boundary_element_info (std::ostream &outfile)
 
virtual void reset_boundary_element_info (Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned >> &ntmp_boundary_elements_in_region, Vector< FiniteElement * > &deleted_elements)
 Virtual function to perform the reset boundary elements info rutines. More...
 
template<class BULK_ELEMENT >
void doc_boundary_coordinates (const unsigned &b, std::ofstream &the_file)
 
virtual void scale_mesh (const double &factor)
 
 Mesh (const Mesh &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const Mesh &)=delete
 Broken assignment operator. More...
 
virtual ~Mesh ()
 Virtual Destructor to clean up all memory. More...
 
void flush_element_and_node_storage ()
 
void flush_element_storage ()
 
void flush_node_storage ()
 
Node *& node_pt (const unsigned long &n)
 Return pointer to global node n. More...
 
Nodenode_pt (const unsigned long &n) const
 Return pointer to global node n (const version) More...
 
GeneralisedElement *& element_pt (const unsigned long &e)
 Return pointer to element e. More...
 
GeneralisedElementelement_pt (const unsigned long &e) const
 Return pointer to element e (const version) More...
 
const Vector< GeneralisedElement * > & element_pt () const
 Return reference to the Vector of elements. More...
 
Vector< GeneralisedElement * > & element_pt ()
 Return reference to the Vector of elements. More...
 
FiniteElementfinite_element_pt (const unsigned &e) const
 
Node *& boundary_node_pt (const unsigned &b, const unsigned &n)
 Return pointer to node n on boundary b. More...
 
Nodeboundary_node_pt (const unsigned &b, const unsigned &n) const
 Return pointer to node n on boundary b. More...
 
void set_nboundary (const unsigned &nbound)
 Set the number of boundaries in the mesh. More...
 
void remove_boundary_nodes ()
 Clear all pointers to boundary nodes. More...
 
void remove_boundary_nodes (const unsigned &b)
 
void remove_boundary_node (const unsigned &b, Node *const &node_pt)
 Remove a node from the boundary b. More...
 
void add_boundary_node (const unsigned &b, Node *const &node_pt)
 Add a (pointer to) a node to the b-th boundary. More...
 
void copy_boundary_node_data_from_nodes ()
 
bool boundary_coordinate_exists (const unsigned &i) const
 Indicate whether the i-th boundary has an intrinsic coordinate. More...
 
unsigned long nelement () const
 Return number of elements in the mesh. More...
 
unsigned long nnode () const
 Return number of nodes in the mesh. More...
 
unsigned ndof_types () const
 Return number of dof types in mesh. More...
 
unsigned elemental_dimension () const
 Return number of elemental dimension in mesh. More...
 
unsigned nodal_dimension () const
 Return number of nodal dimension in mesh. More...
 
void add_node_pt (Node *const &node_pt)
 Add a (pointer to a) node to the mesh. More...
 
void add_element_pt (GeneralisedElement *const &element_pt)
 Add a (pointer to) an element to the mesh. More...
 
virtual void node_update (const bool &update_all_solid_nodes=false)
 
virtual void reorder_nodes (const bool &use_old_ordering=true)
 
virtual void get_node_reordering (Vector< Node * > &reordering, const bool &use_old_ordering=true) const
 
template<class BULK_ELEMENT , template< class > class FACE_ELEMENT>
void build_face_mesh (const unsigned &b, Mesh *const &face_mesh_pt)
 
unsigned self_test ()
 Self-test: Check elements and nodes. Return 0 for OK. More...
 
void max_and_min_element_size (double &max_size, double &min_size)
 
double total_size ()
 
void check_inverted_elements (bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
 
void check_inverted_elements (bool &mesh_has_inverted_elements)
 
unsigned check_for_repeated_nodes (const double &epsilon=1.0e-12)
 
Vector< Node * > prune_dead_nodes ()
 
unsigned nboundary () const
 Return number of boundaries. More...
 
unsigned long nboundary_node (const unsigned &ibound) const
 Return number of nodes on a particular boundary. More...
 
FiniteElementboundary_element_pt (const unsigned &b, const unsigned &e) const
 Return pointer to e-th finite element on boundary b. More...
 
Nodeget_some_non_boundary_node () const
 
unsigned nboundary_element (const unsigned &b) const
 Return number of finite elements that are adjacent to boundary b. More...
 
int face_index_at_boundary (const unsigned &b, const unsigned &e) const
 
virtual void dump (std::ofstream &dump_file, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
void dump (const std::string &dump_file_name, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
virtual void read (std::ifstream &restart_file)
 Read solution from restart file. More...
 
void output_paraview (std::ofstream &file_out, const unsigned &nplot) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt) const
 
void output (std::ostream &outfile)
 Output for all elements. More...
 
void output (std::ostream &outfile, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output (FILE *file_pt)
 Output for all elements (C-style output) More...
 
void output (FILE *file_pt, const unsigned &nplot)
 Output at f(n_plot) points in each element (C-style output) More...
 
void output (const std::string &output_filename)
 Output for all elements. More...
 
void output (const std::string &output_filename, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
 Output a given Vector function at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt)
 
void output_boundaries (std::ostream &outfile)
 Output the nodes on the boundaries (into separate tecplot zones) More...
 
void output_boundaries (const std::string &output_filename)
 
void assign_initial_values_impulsive ()
 Assign initial values for an impulsive start. More...
 
void shift_time_values ()
 
void calculate_predictions ()
 
void set_nodal_and_elemental_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void set_mesh_level_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
void set_consistent_pinned_values_for_continuation (ContinuationStorageScheme *const &continuation_stepper_pt)
 Set consistent values for pinned data in continuation. More...
 
bool does_pointer_correspond_to_mesh_data (double *const &parameter_pt)
 Does the double pointer correspond to any mesh data. More...
 
void set_nodal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 Set the timestepper associated with the nodal data in the mesh. More...
 
void set_elemental_internal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void compute_norm (double &norm)
 
virtual void compute_norm (Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 Returns the norm of the error and that of the exact solution. More...
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
bool is_mesh_distributed () const
 Boolean to indicate if Mesh has been distributed. More...
 
OomphCommunicatorcommunicator_pt () const
 
void delete_all_external_storage ()
 Wipe the storage for all externally-based elements. More...
 

Protected Member Functions

void check_mesh_integrity ()
 
- Protected Member Functions inherited from oomph::Mesh
unsigned long assign_global_eqn_numbers (Vector< double * > &Dof_pt)
 Assign (global) equation numbers to the nodes. More...
 
void describe_dofs (std::ostream &out, const std::string &current_string) const
 
void describe_local_dofs (std::ostream &out, const std::string &current_string) const
 
void assign_local_eqn_numbers (const bool &store_local_dof_pt)
 Assign local equation numbers in all elements. More...
 
void convert_to_boundary_node (Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
 
void convert_to_boundary_node (Node *&node_pt)
 

Protected Attributes

unsigned Nglobal_edge
 Number of internal edges. More...
 
Vector< unsignedGlobal_node
 Storage for global node numbers listed element-by-element. More...
 
Vector< Vector< unsigned > > Edge_boundary
 
Vector< Vector< unsigned > > Edge_index
 Vector of vectors containing the global edge index of. More...
 
Vector< doubleElement_attribute
 Vector of double attributes for each element. More...
 
Vector< Vector< double > > Hole_centre
 Vectors of hole centre coordinates. More...
 
- Protected Attributes inherited from oomph::Mesh
Vector< Vector< Node * > > Boundary_node_pt
 
bool Lookup_for_elements_next_boundary_is_setup
 
Vector< Vector< FiniteElement * > > Boundary_element_pt
 
Vector< Vector< int > > Face_index_at_boundary
 
Vector< Node * > Node_pt
 Vector of pointers to nodes. More...
 
Vector< GeneralisedElement * > Element_pt
 Vector of pointers to generalised elements. More...
 
std::vector< boolBoundary_coordinate_exists
 

Additional Inherited Members

- Public Types inherited from oomph::Mesh
typedef void(FiniteElement::* SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)
 
typedef void(FiniteElement::* UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)
 
- Static Public Attributes inherited from oomph::Mesh
static Steady< 0 > Default_TimeStepper
 The Steady Timestepper. More...
 
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
 Static boolean flag to control warning about mesh level timesteppers. More...
 

Detailed Description

Triangle Mesh that is based on input files generated by the triangle mesh generator Triangle.

Constructor & Destructor Documentation

◆ TriangleScaffoldMesh() [1/3]

oomph::TriangleScaffoldMesh::TriangleScaffoldMesh ( )
inline

Empty constructor.

54 {}

◆ TriangleScaffoldMesh() [2/3]

oomph::TriangleScaffoldMesh::TriangleScaffoldMesh ( const std::string &  node_file_name,
const std::string &  ele_file_name,
const std::string &  poly_file_name 
)

Constructor: Pass the filenames of the triangle files.

Constructor: Pass the filenames of the triangle files The assumptions are that the nodes have been assigned boundary information which is used in the nodal construction to ensure that BoundaryNodes are indeed constructed when necessary. Additional boundary information is added from the segment boundaries.

87  {
88  // Process element file
89  //---------------------
90  std::ifstream element_file(ele_file_name.c_str(), std::ios_base::in);
91 
92  // Check that the file actually opened correctly
93  if (!element_file.is_open())
94  {
95  std::string error_msg("Failed to open element file: ");
96  error_msg += "\"" + ele_file_name + "\".";
97  throw OomphLibError(
99  }
100 
101  // Number of elements
102  unsigned n_element;
103  element_file >> n_element;
104 
105  // Number of nodes per element
106  unsigned n_local_node;
107  element_file >> n_local_node;
108  if (n_local_node != 3)
109  {
110  std::ostringstream error_stream;
111  error_stream
112  << "Triangle should only be used to generate 3-noded triangles!\n"
113  << "Your triangle input file, contains data for " << n_local_node
114  << "-noded triangles" << std::endl;
115 
116  throw OomphLibError(
117  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
118  }
119 
120  // Dummy nodal attributes
121  unsigned dummy_attribute;
122 
123  // Element attributes may be used if we have internal boundaries
124  Element_attribute.resize(n_element, 0.0);
125 
126  // Dummy storage for element numbers
127  unsigned dummy_element_number;
128 
129  // Resize stoorage for global node numbers listed element-by-element
130  Global_node.resize(n_element * n_local_node);
131 
132 #ifdef PARANOID
133  std::map<unsigned, bool> global_node_done;
134 #endif
135 
136  // Initialise counter
137  unsigned k = 0;
138 
139  // Are attributes specified?
140  unsigned attribute_flag;
141  element_file >> attribute_flag;
142 
143  // Read global node numbers for all elements
144  if (attribute_flag == 0)
145  {
146  for (unsigned i = 0; i < n_element; i++)
147  {
148  element_file >> dummy_element_number;
149  for (unsigned j = 0; j < n_local_node; j++)
150  {
151  element_file >> Global_node[k];
152 #ifdef PARANOID
153  global_node_done[Global_node[k] - 1] = true;
154 #endif
155  k++;
156  }
157  }
158  }
159  else
160  {
161  for (unsigned i = 0; i < n_element; i++)
162  {
163  element_file >> dummy_element_number;
164  for (unsigned j = 0; j < n_local_node; j++)
165  {
166  element_file >> Global_node[k];
167 #ifdef PARANOID
168  global_node_done[Global_node[k] - 1] = true;
169 #endif
170  k++;
171  }
172  element_file >> Element_attribute[i];
173  }
174  }
175  element_file.close();
176 
177 #ifdef PARANOID
178  // Determine if the node numbering starts at 0 or 1 (triangle can do
179  // either depending on input arguments). We can't (currently) handle
180  // 0-based indexing so throw an error if it is being used.
181  if (*std::min_element(Global_node.begin(), Global_node.end()) != 1)
182  {
183  std::string err("Triangle is using 0-based indexing, ");
184  err += "however the oomph-lib interface can only handle 1-based indexing "
185  "in Triangle.\n";
186  err +=
187  "This is likely to be due to the input file using 0-based indexing.";
188  err += "Alternatively you may have specified the -z flag when running "
189  "Triangle.";
190  throw OomphLibError(
192  }
193 #endif
194 
195  // Resize the Element vector
196  Element_pt.resize(n_element);
197 
198  // Process node file
199  // -----------------
200  std::ifstream node_file(node_file_name.c_str(), std::ios_base::in);
201 
202  // Check that the file actually opened correctly
203  if (!node_file.is_open())
204  {
205  std::string error_msg("Failed to open node file: ");
206  error_msg += "\"" + node_file_name + "\".";
207  throw OomphLibError(
209  }
210 
211  // Read number of nodes
212  unsigned n_node;
213  node_file >> n_node;
214 
215  // Create a vector of boolean so as not to create the same node twice
216  std::vector<bool> done(n_node, false);
217 
218  // Resize the Node vector
219  Node_pt.resize(n_node);
220 
221  // Spatial dimension of nodes
222  unsigned dimension;
223  node_file >> dimension;
224 
225 #ifdef PARANOID
226  if (dimension != 2)
227  {
228  throw OomphLibError("The dimension must be 2\n",
231  }
232 #endif
233 
234  // Flag for attributes
235  node_file >> attribute_flag;
236 
237  // Flag for boundary markers
238  unsigned boundary_markers_flag;
239  node_file >> boundary_markers_flag;
240 
241  // Dummy for node number
242  unsigned dummy_node_number;
243 
244  // Create storage for nodal posititions and boundary markers
245  Vector<double> x_node(n_node);
246  Vector<double> y_node(n_node);
247  Vector<unsigned> bound(n_node);
248 
249  // Check if there are attributes
250  if (attribute_flag == 0)
251  {
252  if (boundary_markers_flag == 1)
253  {
254  for (unsigned i = 0; i < n_node; i++)
255  {
256  node_file >> dummy_node_number;
257  node_file >> x_node[i];
258  node_file >> y_node[i];
259  node_file >> bound[i];
260  }
261  node_file.close();
262  }
263  else
264  {
265  for (unsigned i = 0; i < n_node; i++)
266  {
267  node_file >> dummy_node_number;
268  node_file >> x_node[i];
269  node_file >> y_node[i];
270  bound[i] = 0;
271  }
272  node_file.close();
273  }
274  }
275  else
276  {
277  if (boundary_markers_flag == 1)
278  {
279  for (unsigned i = 0; i < n_node; i++)
280  {
281  node_file >> dummy_node_number;
282  node_file >> x_node[i];
283  node_file >> y_node[i];
284  node_file >> dummy_attribute;
285  node_file >> bound[i];
286  }
287  node_file.close();
288  }
289  else
290  {
291  for (unsigned i = 0; i < n_node; i++)
292  {
293  node_file >> dummy_node_number;
294  node_file >> x_node[i];
295  node_file >> y_node[i];
296  node_file >> dummy_attribute;
297  bound[i] = 0;
298  }
299  node_file.close();
300  }
301  } // end
302 
303 
304  // Determine highest boundary index
305  // --------------------------------
306  unsigned n_bound = 0;
307  if (boundary_markers_flag == 1)
308  {
309  n_bound = bound[0];
310  for (unsigned i = 1; i < n_node; i++)
311  {
312  if (bound[i] > n_bound)
313  {
314  n_bound = bound[i];
315  }
316  }
317  }
318 
319  // Process poly file to extract edges
320  //-----------------------------------
321 
322  // Open poly file
323  std::ifstream poly_file(poly_file_name.c_str(), std::ios_base::in);
324 
325  // Check that the file actually opened correctly
326  if (!poly_file.is_open())
327  {
328  std::string error_msg("Failed to open poly file: ");
329  error_msg += "\"" + poly_file_name + "\".";
330  throw OomphLibError(
332  }
333 
334  // Number of nodes in poly file
335  unsigned n_node_poly;
336  poly_file >> n_node_poly;
337 
338  // Dimension
339  poly_file >> dimension;
340 
341  // Attribute flag
342  poly_file >> attribute_flag;
343 
344  // Boundary markers flag
345  poly_file >> boundary_markers_flag;
346 
347 
348  // Ignore node information: Note: No, we can't extract the
349  // actual nodes themselves from here!
350  unsigned dummy;
351  if (n_node_poly > 0)
352  {
353  if (attribute_flag == 0)
354  {
355  if (boundary_markers_flag == 1)
356  {
357  for (unsigned i = 0; i < n_node_poly; i++)
358  {
359  poly_file >> dummy;
360  poly_file >> dummy;
361  poly_file >> dummy;
362  poly_file >> dummy;
363  }
364  }
365  else
366  {
367  for (unsigned i = 0; i < n_node_poly; i++)
368  {
369  poly_file >> dummy;
370  poly_file >> dummy;
371  poly_file >> dummy;
372  }
373  }
374  }
375  else
376  {
377  if (boundary_markers_flag == 1)
378  {
379  for (unsigned i = 0; i < n_node_poly; i++)
380  {
381  poly_file >> dummy;
382  poly_file >> dummy;
383  poly_file >> dummy;
384  poly_file >> dummy;
385  poly_file >> dummy;
386  }
387  }
388  else
389  {
390  for (unsigned i = 0; i < n_node_poly; i++)
391  {
392  poly_file >> dummy;
393  poly_file >> dummy;
394  poly_file >> dummy;
395  poly_file >> dummy;
396  }
397  }
398  }
399  }
400 
401  // Now extract the segment information
402  // Segements are lines that lie on boundaries of the domain
403  //----------------------------------------------------------
404 
405  // Number of segments
406  unsigned n_segment;
407  poly_file >> n_segment;
408 
409  // Boundary marker flag
410  poly_file >> boundary_markers_flag;
411 
412  // Storage for the global node numbers (in the triangle 1-based
413  // numbering scheme!) of the first and second node in each segment
414  Vector<unsigned> first_node(n_segment);
415  Vector<unsigned> second_node(n_segment);
416 
417  // Storage for the boundary marker for each segment
418  Vector<unsigned> segment_boundary(n_segment);
419 
420  // Dummy for global segment number
421  unsigned dummy_segment_number;
422 
423  // Storage for the edges associated with each node. Nodes are indexed
424  // using the Triangle 1-based index which is why there is a +1 here.
425  Vector<std::set<unsigned>> node_on_edges(n_node + 1);
426 
427  // Extract information for each segment
428  for (unsigned i = 0; i < n_segment; i++)
429  {
430  poly_file >> dummy_segment_number;
431  poly_file >> first_node[i];
432  poly_file >> second_node[i];
433  poly_file >> segment_boundary[i];
434  // Check that we don't have a higher segment boundary number
435  if (segment_boundary[i] > n_bound)
436  {
437  n_bound = segment_boundary[i];
438  }
439  // Add the segment index to each node
440  node_on_edges[first_node[i]].insert(i);
441  node_on_edges[second_node[i]].insert(i);
442  }
443 
444  // Extract hole center information
445  unsigned nhole = 0;
446  poly_file >> nhole;
447  if (nhole != 0)
448  {
449  Hole_centre.resize(nhole);
450 
451  // Dummy for hole number
452  unsigned dummy_hole;
453  // Loop over the holes to get centre coords
454  for (unsigned ihole = 0; ihole < nhole; ihole++)
455  {
456  Hole_centre[ihole].resize(2);
457 
458  // Read the centre value
459  poly_file >> dummy_hole;
460  poly_file >> Hole_centre[ihole][0];
461  poly_file >> Hole_centre[ihole][1];
462  }
463  }
464  else
465  {
466  Hole_centre.resize(0);
467  }
468  poly_file.close();
469 
470  // Set the number of boundaries
471  if (n_bound > 0)
472  {
473  this->set_nboundary(n_bound);
474  }
475 
476 
477  // Create the elements
478  //--------------------
479 
480  // Counter for nodes in the vector that lists
481  // the global node numbers of the elements' local nodes
482  unsigned counter = 0;
483  for (unsigned e = 0; e < n_element; e++)
484  {
485  Element_pt[e] = new TElement<2, 2>;
486  for (unsigned j = 0; j < n_local_node; j++)
487  {
488  unsigned global_node_number = Global_node[counter];
489  if (done[global_node_number - 1] == false) //... -1 because node number
490  // begins at 1 in triangle
491  {
492  // If we are on the boundary
493  if ((boundary_markers_flag == 1) &&
494  (bound[global_node_number - 1] > 0))
495  {
496  // Construct a boundary node
499  // Add to the boundary node look-up scheme
500  add_boundary_node(bound[global_node_number - 1] - 1,
502  }
503  // Otherwise make an ordinary node
504  else
505  {
508  }
509  done[global_node_number - 1] = true;
510  Node_pt[global_node_number - 1]->x(0) =
511  x_node[global_node_number - 1];
512  Node_pt[global_node_number - 1]->x(1) =
513  y_node[global_node_number - 1];
514  }
515  else
516  {
518  }
519  counter++;
520  }
521  }
522 
523  // Resize the "matrix" that stores the boundary id for each
524  // edge in each element.
525  Edge_boundary.resize(n_element);
526  Edge_index.resize(n_element);
527 
528  // Storage for the global node numbers (in triangle's 1-based
529  // numbering scheme) for the zero-th, 1st, and 2nd node in each
530  // triangle.
531  unsigned glob_num[3] = {0, 0, 0};
532 
533  // 0-based index used to construct a global index-based lookup scheme
534  // for each edge that will be used to uniquely construct mid-side
535  // nodes.
536  // The segments (edges that lie on boundaries) have already
537  // been added to the scheme, so we start with the number of segments.
538  Nglobal_edge = n_segment;
539 
540  // Loop over the elements
541  for (unsigned e = 0; e < n_element; e++)
542  {
543  // Each element has three edges
544  Edge_boundary[e].resize(3);
545  Edge_index[e].resize(3);
546  // By default each edge is NOT on a boundary
547  for (unsigned i = 0; i < 3; i++)
548  {
549  Edge_boundary[e][i] = 0;
550  }
551 
552  // Read out the global node numbers from the triangle data structure
553  const unsigned element_offset = e * n_local_node;
554  for (unsigned i = 0; i < 3; i++)
555  {
556  glob_num[i] = Global_node[element_offset + i];
557  }
558 
559  // Now we know the global node numbers of the elements' three nodes
560  // in triangle's 1-based numbering.
561 
562  // Determine whether any of the elements edges have already been
563  // allocated an index. This may be because they are on boundaries
564  // (segments) or because they have already occured.
565  // The global index for the i-th edge will be stored in edge_index[i]
566  for (unsigned i = 0; i < 3; i++)
567  {
568  std::vector<unsigned> local_edge_index;
569 
570  // Find the common global edge index for the nodes on
571  // the i-th element edge (note the use of moular arithmetic here)
572  std::set_intersection(node_on_edges[glob_num[i]].begin(),
573  node_on_edges[glob_num[i]].end(),
574  node_on_edges[glob_num[(i + 1) % 3]].begin(),
575  node_on_edges[glob_num[(i + 1) % 3]].end(),
576  std::insert_iterator<std::vector<unsigned>>(
577  local_edge_index, local_edge_index.begin()));
578 
579  // If the nodes share more than one global edge index, then
580  // we have a problem
581  if (local_edge_index.size() > 1)
582  {
583  throw OomphLibError(
584  "Nodes in scaffold mesh share more than one global edge",
587  }
588 
589  // If the element's edge is not already allocated, the intersection
590  // will be empty
591  if (local_edge_index.size() == 0)
592  {
593  // Allocate the next global index
595  // Associate the new edge index with the nodes
596  node_on_edges[glob_num[i]].insert(Nglobal_edge);
597  node_on_edges[glob_num[(i + 1) % 3]].insert(Nglobal_edge);
598  // Increment the global edge index
599  ++Nglobal_edge;
600  }
601  // Otherwise we already have an edge
602  else if (local_edge_index.size() == 1)
603  {
604  // Set the edge index
605  Edge_index[e][i] = local_edge_index[0];
606  // Allocate the boundary index, if it is a segment
607  if (local_edge_index[0] < n_segment)
608  {
609  Edge_boundary[e][i] = segment_boundary[local_edge_index[0]];
610  // Add the nodes to the boundary look-up scheme in
611  // oomph-lib (0-based) index
612  add_boundary_node(segment_boundary[local_edge_index[0]] - 1,
613  Node_pt[glob_num[i] - 1]);
614  add_boundary_node(segment_boundary[local_edge_index[0]] - 1,
615  Node_pt[glob_num[(i + 1) % 3] - 1]);
616  }
617  }
618  }
619  }
620 
621 #ifdef PARANOID
622 
623  std::ostringstream error_stream;
624  bool broken = false;
625  unsigned nnod = nnode();
626  error_stream << "Checking presence of " << nnod << " global nodes\n";
627  for (unsigned j = 0; j < nnod; j++)
628  {
629  if (!global_node_done[j])
630  {
631  error_stream << "Global node " << j
632  << " was not listed in *.ele file\n";
633  broken = true;
634  }
635  }
636  if (broken)
637  {
638  throw OomphLibError(
639  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
640  }
641 
642  // Check things and throw if mesh is broken...
644 #endif
645  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
A insert(1, 2)=0
virtual Node * construct_node(const unsigned &n)
Definition: elements.h:2509
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
virtual Node * construct_boundary_node(const unsigned &n)
Definition: elements.h:2538
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition: mesh.cc:243
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition: mesh.h:505
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
unsigned global_node_number(const unsigned &i)
Definition: triangle_scaffold_mesh.h:80
Vector< unsigned > Global_node
Storage for global node numbers listed element-by-element.
Definition: triangle_scaffold_mesh.h:128
void check_mesh_integrity()
Definition: triangle_scaffold_mesh.cc:35
unsigned Nglobal_edge
Number of internal edges.
Definition: triangle_scaffold_mesh.h:125
Vector< double > Element_attribute
Vector of double attributes for each element.
Definition: triangle_scaffold_mesh.h:139
Vector< Vector< unsigned > > Edge_boundary
Definition: triangle_scaffold_mesh.h:132
Vector< Vector< double > > Hole_centre
Vectors of hole centre coordinates.
Definition: triangle_scaffold_mesh.h:142
Vector< Vector< unsigned > > Edge_index
Vector of vectors containing the global edge index of.
Definition: triangle_scaffold_mesh.h:136
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
char char char int int * k
Definition: level2_impl.h:374
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 oomph::Mesh::add_boundary_node(), check_mesh_integrity(), oomph::FiniteElement::construct_boundary_node(), oomph::FiniteElement::construct_node(), e(), Edge_boundary, Edge_index, Element_attribute, oomph::Mesh::Element_pt, Eigen::placeholders::end, oomph::Mesh::finite_element_pt(), Global_node, global_node_number(), Hole_centre, i, insert(), j, k, Nglobal_edge, oomph::Mesh::nnode(), oomph::FiniteElement::node_pt(), oomph::Mesh::Node_pt, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::Mesh::set_nboundary(), and oomph::Global_string_for_annotation::string().

◆ TriangleScaffoldMesh() [3/3]

oomph::TriangleScaffoldMesh::TriangleScaffoldMesh ( const TriangleScaffoldMesh )
delete

Broken copy constructor.

◆ ~TriangleScaffoldMesh()

oomph::TriangleScaffoldMesh::~TriangleScaffoldMesh ( )
inline

Empty destructor.

75 {}

Member Function Documentation

◆ check_mesh_integrity()

void oomph::TriangleScaffoldMesh::check_mesh_integrity ( )
protected

Check mesh integrity – performs some internal consistency checks and throws error if violated.

36  {
37  // Check that all nodes are attached to elements
38  std::map<Node*, bool> done;
39 
40  // Number of nodes per element
41  unsigned nnod_el = finite_element_pt(0)->nnode();
42 
43  // Loop over elements to visit their nodes
44  unsigned nelem = nelement();
45  for (unsigned e = 0; e < nelem; e++)
46  {
47  // Loop over all nodes in element
48  for (unsigned j = 0; j < nnod_el; j++)
49  {
50  // Pointer to node in the scaffold mesh
51  Node* node_pt = finite_element_pt(e)->node_pt(j);
52 
53  done[node_pt] = true;
54  }
55  }
56 
57  // Now check if all nodes have been visited
58  std::ostringstream error_stream;
59  bool broken = false;
60  unsigned nnod = nnode();
61  for (unsigned j = 0; j < nnod; j++)
62  {
63  if (!done[Node_pt[j]])
64  {
65  error_stream << "Scaffold node " << j
66  << " does not seem to be attached to any element";
67  broken = true;
68  }
69  }
70  if (broken)
71  {
72  throw OomphLibError(
74  }
75  }
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
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

References e(), oomph::Mesh::finite_element_pt(), j, oomph::Mesh::nelement(), oomph::FiniteElement::nnode(), oomph::Mesh::nnode(), oomph::FiniteElement::node_pt(), oomph::Mesh::Node_pt, oomph::Mesh::node_pt(), OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by TriangleScaffoldMesh().

◆ edge_boundary()

unsigned oomph::TriangleScaffoldMesh::edge_boundary ( const unsigned e,
const unsigned i 
) const
inline

Return the boundary id of the i-th edge in the e-th element: This is zero-based as in triangle. Zero means the edge is not on a boundary. Postive numbers identify the boundary. Will be reduced by one to identify the oomph-lib boundary.

90  {
91  return Edge_boundary[e][i];
92  }

References e(), Edge_boundary, and i.

Referenced by oomph::QuadFromTriangleMesh< ELEMENT >::build_from_scaffold().

◆ edge_index()

unsigned oomph::TriangleScaffoldMesh::edge_index ( const unsigned e,
const unsigned i 
) const
inline

Return the global index of the i-th edge in the e-th element: The global index starts from zero

103  {
104  return Edge_index[e][i];
105  }

References e(), Edge_index, and i.

◆ element_attribute()

double oomph::TriangleScaffoldMesh::element_attribute ( const unsigned e) const
inline

Return the attribute of the element e.

109  {
110  return Element_attribute[e];
111  }

References e(), and Element_attribute.

◆ global_node_number()

unsigned oomph::TriangleScaffoldMesh::global_node_number ( const unsigned i)
inline

Return the global node of each local node listed element-by-element e*n_local_node + n_local Note that the node numbers are indexed from 1

81  {
82  return Global_node[i];
83  }

References Global_node, and i.

Referenced by TriangleScaffoldMesh().

◆ internal_point()

Vector<Vector<double> >& oomph::TriangleScaffoldMesh::internal_point ( )
inline

Vectors of hole centre coordinates.

115  {
116  return Hole_centre;
117  }

References Hole_centre.

◆ nglobal_edge()

unsigned oomph::TriangleScaffoldMesh::nglobal_edge ( )
inline

Return the number of internal edges.

96  {
97  return Nglobal_edge;
98  }

References Nglobal_edge.

◆ operator=()

void oomph::TriangleScaffoldMesh::operator= ( const TriangleScaffoldMesh )
delete

Broken assignment operator.

Member Data Documentation

◆ Edge_boundary

Vector<Vector<unsigned> > oomph::TriangleScaffoldMesh::Edge_boundary
protected

Vector of vectors containing the boundary ids of the elements' edges

Referenced by edge_boundary(), and TriangleScaffoldMesh().

◆ Edge_index

Vector<Vector<unsigned> > oomph::TriangleScaffoldMesh::Edge_index
protected

Vector of vectors containing the global edge index of.

Referenced by edge_index(), and TriangleScaffoldMesh().

◆ Element_attribute

Vector<double> oomph::TriangleScaffoldMesh::Element_attribute
protected

Vector of double attributes for each element.

Referenced by element_attribute(), and TriangleScaffoldMesh().

◆ Global_node

Vector<unsigned> oomph::TriangleScaffoldMesh::Global_node
protected

Storage for global node numbers listed element-by-element.

Referenced by global_node_number(), and TriangleScaffoldMesh().

◆ Hole_centre

Vector<Vector<double> > oomph::TriangleScaffoldMesh::Hole_centre
protected

Vectors of hole centre coordinates.

Referenced by internal_point(), and TriangleScaffoldMesh().

◆ Nglobal_edge

unsigned oomph::TriangleScaffoldMesh::Nglobal_edge
protected

Number of internal edges.

Referenced by nglobal_edge(), and TriangleScaffoldMesh().


The documentation for this class was generated from the following files: