triangle_mesh.cc
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2025 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26
27#include <algorithm>
28#include "map_matrix.h"
30#include "triangle_mesh.h"
31
32namespace oomph
33{
34#ifdef OOMPH_HAS_TRIANGLE_LIB
35
36 //==============================================================
37 /// Dump the triangulateio structure to a dump file and
38 /// record boundary coordinates of boundary nodes
39 //==============================================================
41 {
43
44#ifdef OOMPH_HAS_MPI
45 // If the mesh is not distributed then process what follows
46 if (!this->is_mesh_distributed())
47 {
48#endif // #ifdef OOMPH_HAS_MPI
49
50 // Loop over all boundary nodes and dump out boundary coordinates
51 // if they exist
53 unsigned nb = nboundary();
54 for (unsigned b = 0; b < nb; b++)
55 {
57 {
58 dump_file << "1 # Boundary coordinate for boundary " << b
59 << " does exist\n";
60 unsigned nnod = nboundary_node(b);
61 dump_file << nnod << " # Number of dumped boundary nodes\n";
62 for (unsigned j = 0; j < nnod; j++)
63 {
65 nod_pt->get_coordinates_on_boundary(b, zeta);
66 dump_file << zeta[0] << std::endl;
67 }
68 dump_file << "-999 # Done boundary coords for boundary " << b << "\n";
69 }
70 else
71 {
72 dump_file << "0 # Boundary coordinate for boundary " << b
73 << " does not exist\n";
74 }
75 }
76
77#ifdef OOMPH_HAS_MPI
78 }
79#endif // #ifdef OOMPH_HAS_MPI
80 }
81
82
83 //==============================================================
84 /// Regenerate the mesh from a dumped triangulateio file
85 /// and dumped boundary coordinates of boundary nodes
86 //==============================================================
88 {
89#ifdef PARANOID
90 // Record number of boundaries
91 unsigned nbound_old = nboundary();
92#endif
93
94 // Clear the existing triangulate io
96
97 // Read the data into the file
99
100 // Now remesh from the new data structure
102
103#ifdef OOMPH_HAS_MPI
104 // If the mesh is not distributed then process what follows
105 if (!this->is_mesh_distributed())
106 {
107#endif // #ifdef OOMPH_HAS_MPI
108
109#ifdef PARANOID
110 // Record number of boundary nodes after remesh
111 unsigned nbound_new = nboundary();
112 if (nbound_new != nbound_old)
113 {
114 std::ostringstream error_stream;
116 << "Number of boundaries before remesh from triangulateio, "
117 << nbound_new << ",\ndoesn't match number boundaries afterwards, "
118 << nbound_old
119 << ". Have you messed \naround with boundary nodes in the "
120 << "derived mesh constructor (or after calling \nit)? If so,"
121 << " the dump/restart won't work as written at the moment.";
122 throw OomphLibError(
124 }
125#endif
126
127
128 // Loop over all boundary nodes and read boundary coordinates
129 // if they exist
131 std::string input_string;
132 unsigned nb = nboundary();
133 for (unsigned b = 0; b < nb; b++)
134 {
135 // Read line up to termination sign
136 getline(restart_file, input_string, '#');
137
138 // Ignore rest of line
139 restart_file.ignore(80, '\n');
140
141 // Did boundary coordinate exist?
142 const unsigned bound_coord_exists = atoi(input_string.c_str());
143 if (bound_coord_exists == 1)
144 {
145 // Remember it!
147
148 // Read line up to termination sign
149 getline(restart_file, input_string, '#');
150
151 // Ignore rest of line
152 restart_file.ignore(80, '\n');
153
154 // How many nodes did we dump?
155 const unsigned nnod_dumped = atoi(input_string.c_str());
156
157 // Does it match?
158 unsigned nnod = nboundary_node(b);
159 if (nnod != nnod_dumped)
160 {
161 std::ostringstream error_stream;
162 error_stream << "Number of dumped boundary nodes " << nnod_dumped
163 << " doesn't match number of nodes on boundary " << b
164 << ": " << nnod << std::endl;
165 throw OomphLibError(error_stream.str(),
168 }
169
170 // Loop over all nodes
171 for (unsigned j = 0; j < nnod; j++)
172 {
173 // Read line up to termination sign
174 getline(restart_file, input_string);
175
176 // Boundary coordinate
177 zeta[0] = atof(input_string.c_str());
178
179 // Set it
181 nod_pt->set_coordinates_on_boundary(b, zeta);
182 }
183
184 // Read line up to termination sign
185 getline(restart_file, input_string, '#');
186
187 // Ignore rest of line
188 restart_file.ignore(80, '\n');
189
190 // Have we reached the end?
191 const int check = atoi(input_string.c_str());
192 if (check != -999)
193 {
194 std::ostringstream error_stream;
195 error_stream << "Haven't read all nodes on boundary " << b
196 << std::endl;
197 throw OomphLibError(error_stream.str(),
200 }
201 }
202 else
203 {
204 oomph_info << "Restart: Boundary coordinate for boundary " << b
205 << " does not exist.\n";
206 }
207 }
208#ifdef OOMPH_HAS_MPI
209 } // if (!this->is_mesh_distributed())
210#endif // #ifdef OOMPH_HAS_MPI
211 }
212
213
214 //==============================================================
215 /// Write a Triangulateio_object file of the TriangulateIO object
216 /// String s is add to assign a different value for
217 /// input and/or output structure.
218 /// The function give the same result of the "report" function
219 /// included in the tricall.c, esternal_src.
220 //==============================================================
222 std::string& s)
223 {
224 std::ofstream outfile;
225 char filename[100];
226
227 snprintf(
228 filename, sizeof(filename), "Triangulateio_object_%s.dat", s.c_str());
229 outfile.open(filename);
230 outfile << "# Triangulateio object values:\n\n" << std::endl;
231
232 // Write points coordinates
233 if (triangle.numberofpoints != 0)
234 {
235 outfile << "# Triangulateio number of points is:"
236 << triangle.numberofpoints << std::endl;
237 }
238 if (triangle.pointlist != NULL)
239 {
240 outfile << "# Vertex coordinates are:" << std::endl;
241 for (int k = 0; k < triangle.numberofpoints * 2; k += 2)
242 {
243 outfile << (k * 0.5) + 1 << " " << triangle.pointlist[k] << " "
244 << triangle.pointlist[k + 1] << std::endl;
245 }
246 }
247
248 // Write points attribute list
249 if (triangle.numberofpointattributes != 0)
250 {
251 outfile << "# Triangulateio number of points attributelist is:"
252 << triangle.numberofpointattributes << std::endl;
253 }
254 if (triangle.pointattributelist != NULL)
255 {
256 outfile << "# Vertex attribute are:" << std::endl;
257 for (int k = 0; k < triangle.numberofpointattributes; k++)
258 {
259 outfile << triangle.pointattributelist[k] << std::endl;
260 }
261 }
262
263 // Write point markers list
264 if (triangle.pointmarkerlist != NULL)
265 {
266 outfile << "# Vertex Markers are:" << std::endl;
267 for (int k = 0; k < triangle.numberofpoints; k++)
268 {
269 outfile << triangle.pointmarkerlist[k] << std::endl;
270 }
271 }
272
273 // Write the 1.node file used by the showme function
274 std::ofstream nodefile;
275 char nodename[100];
276
277 snprintf(nodename, sizeof(nodename), "file_%s.1.node", s.c_str());
278 nodefile.open(nodename);
279 nodefile << triangle.numberofpoints << " 2 "
280 << triangle.numberofpointattributes << " 0" << std::endl;
281 for (int j = 0; j < triangle.numberofpoints * 2; j += 2)
282 {
283 nodefile << (j / 2) + 1 << " " << triangle.pointlist[j] << " "
284 << triangle.pointlist[j + 1] << std::endl;
285 }
286 nodefile.close();
287
288
289 // Write segments edge elements
290 if (triangle.numberofsegments != 0)
291 {
292 outfile << "# The number of segments is:" << triangle.numberofsegments
293 << std::endl;
294 }
295 if (triangle.segmentlist != NULL)
296 {
297 outfile << "# Segments are:" << std::endl;
298 for (int k = 0; k < triangle.numberofsegments * 2; k += 2)
299 {
300 outfile << triangle.segmentlist[k] << " "
301 << triangle.segmentlist[k + 1] << std::endl;
302 }
303 }
304
305 // Write segments markers list
306 if (triangle.segmentmarkerlist != NULL)
307 {
308 outfile << "# Segments Markers are:" << std::endl;
309 for (int k = 0; k < triangle.numberofsegments; k++)
310 {
311 outfile << triangle.segmentmarkerlist[k] << std::endl;
312 }
313 }
314
315 // Write regions
316 if (triangle.numberofregions != 0)
317 {
318 outfile << "# The number of region is:" << triangle.numberofregions
319 << std::endl;
320 }
321
322 // Write holes
323 if (triangle.numberofholes != 0)
324 {
325 outfile << "# The number of holes is:" << triangle.numberofholes
326 << std::endl;
327 }
328 if (triangle.holelist != NULL)
329 {
330 outfile << "# Holes are:" << std::endl;
331 for (int k = 0; k < triangle.numberofholes * 2; k += 2)
332 {
333 outfile << triangle.holelist[k] << " " << triangle.holelist[k + 1]
334 << std::endl;
335 }
336 }
337
338 // Write triangles
339 if (triangle.numberoftriangles != 0)
340 {
341 outfile << "# Triangulateio number of triangles:"
342 << triangle.numberoftriangles << std::endl;
343 }
344 if (triangle.numberofcorners != 0)
345 {
346 outfile << "# Triangulateio number of corners:"
347 << triangle.numberofcorners << std::endl;
348 }
349 if (triangle.numberoftriangleattributes != 0)
350 {
351 outfile << "# Triangulateio number of triangles attributes:"
352 << triangle.numberoftriangleattributes << std::endl;
353 }
354 if (triangle.trianglelist != NULL)
355 {
356 outfile << "# Traingles are:" << std::endl;
357 for (int k = 0; k < triangle.numberoftriangles * 3; k += 3)
358 {
359 outfile << triangle.trianglelist[k] << " "
360 << triangle.trianglelist[k + 1] << " "
361 << triangle.trianglelist[k + 2] << std::endl;
362 }
363 }
364
365 if (triangle.trianglearealist != NULL)
366 {
367 outfile << "# Triangle's areas are:" << std::endl;
368 for (int k = 0; k < triangle.numberoftriangles; k++)
369 {
370 outfile << triangle.trianglearealist[k] << std::endl;
371 }
372 }
373
374 if (triangle.trianglelist != NULL)
375 {
376 // Write the 1.ele file used by the showme function
377 std::ofstream elefile;
378 char elename[100];
379
380 snprintf(elename, sizeof(elename), "file_%s.1.ele", s.c_str());
381 elefile.open(elename);
382 elefile << triangle.numberoftriangles << " 3 0" << std::endl;
383 for (int j = 0; j < triangle.numberoftriangles * 3; j += 3)
384 {
385 elefile << (j / 3) + 1 << " " << triangle.trianglelist[j] << " "
386 << triangle.trianglelist[j + 1] << " "
387 << triangle.trianglelist[j + 2] << std::endl;
388 }
389 elefile.close();
390 }
391
392 outfile.close();
393 }
394
395#endif
396
397 //================================================================
398 /// Setup lookup schemes which establish which elements are located
399 /// next to which boundaries (Doc to outfile if it's open).
400 //================================================================
402 {
403 // Should we document the output here
404 bool doc = false;
405
406 if (outfile) doc = true;
407
408 // Number of boundaries
409 unsigned nbound = nboundary();
410
411 // Wipe/allocate storage for arrays
412 Boundary_element_pt.clear();
416
417 // Temporary vector of vectors of pointers to elements on the boundaries:
418 // This is a vector to ensure that order is strictly preserved
421
422 // Matrix map for working out the fixed face for elements on boundary
424
425 // Loop over elements
426 //-------------------
427 unsigned nel = nelement();
428
429 // Get pointer to vector of boundaries that the
430 // node lives on
432
433 // Data needed to deal with edges through the
434 // interior of the domain
435 std::map<Edge, unsigned> edge_count;
436 std::map<Edge, TriangleBoundaryHelper::BCInfo> edge_bcinfo;
437 std::map<Edge, TriangleBoundaryHelper::BCInfo> face_info;
440
441 // When using internal boundaries, an edge can be related to more than
442 // one element (because of both sides of the internal boundaries)
443 std::map<Edge, Vector<TriangleBoundaryHelper::BCInfo>> edge_internal_bnd;
444
445 for (unsigned e = 0; e < nel; e++)
446 {
447 // Get pointer to element
449
450 if (doc)
451 {
452 outfile << "Element: " << e << " " << fe_pt << std::endl;
453 }
454
455 // Only include 2D elements! Some meshes contain interface elements too.
456 if (fe_pt->dim() == 2)
457 {
458 // Loop over the element's nodes and find out which boundaries they're
459 // on
460 // ----------------------------------------------------------------------
461
462 // We need only loop over the corner nodes
463 for (unsigned i = 0; i < 3; i++)
464 {
466 }
467
468 // Find the common boundaries of each edge
469 Vector<std::set<unsigned>> edge_boundary(3);
470
471 // Edge 0 connects points 1 and 2
472 //-----------------------------
473
474 if (boundaries_pt[1] && boundaries_pt[2])
475 {
476 // Create the corresponding edge
478
479 // Update infos about this edge
481 info.Face_id = 0;
482 info.FE_pt = fe_pt;
483
484 std::set_intersection(boundaries_pt[1]->begin(),
485 boundaries_pt[1]->end(),
486 boundaries_pt[2]->begin(),
487 boundaries_pt[2]->end(),
488 std::insert_iterator<std::set<unsigned>>(
489 edge_boundary[0], edge_boundary[0].begin()));
490 std::set<unsigned>::iterator it0 = edge_boundary[0].begin();
491
492 // Edge does exist:
493 if (edge_boundary[0].size() > 0)
494 {
495 info.Boundary = *it0;
496
497 // How many times this edge has been visited
498 edge_count[edge0]++;
499
500 // Update edge_bcinfo
501 edge_bcinfo.insert(std::make_pair(edge0, info));
502
503 // ... and also update the info associated with internal bnd
504 edge_internal_bnd[edge0].push_back(info);
505 }
506 }
507
508 // Edge 1 connects points 0 and 2
509 //-----------------------------
510
511 if (boundaries_pt[0] && boundaries_pt[2])
512 {
513 std::set_intersection(boundaries_pt[0]->begin(),
514 boundaries_pt[0]->end(),
515 boundaries_pt[2]->begin(),
516 boundaries_pt[2]->end(),
517 std::insert_iterator<std::set<unsigned>>(
518 edge_boundary[1], edge_boundary[1].begin()));
519
520 // Create the corresponding edge
522
523 // Update infos about this edge
525 info.Face_id = 1;
526 info.FE_pt = fe_pt;
527 std::set<unsigned>::iterator it1 = edge_boundary[1].begin();
528
529 // Edge does exist:
530 if (edge_boundary[1].size() > 0)
531 {
532 info.Boundary = *it1;
533
534 // How many times this edge has been visited
535 edge_count[edge1]++;
536
537 // Update edge_bcinfo
538 edge_bcinfo.insert(std::make_pair(edge1, info));
539
540 // ... and also update the info associated with internal bnd
541 edge_internal_bnd[edge1].push_back(info);
542 }
543 }
544
545 // Edge 2 connects points 0 and 1
546 //-----------------------------
547
548 if (boundaries_pt[0] && boundaries_pt[1])
549 {
550 std::set_intersection(boundaries_pt[0]->begin(),
551 boundaries_pt[0]->end(),
552 boundaries_pt[1]->begin(),
553 boundaries_pt[1]->end(),
554 std::insert_iterator<std::set<unsigned>>(
555 edge_boundary[2], edge_boundary[2].begin()));
556
557 // Create the corresponding edge
559
560 // Update infos about this edge
562 info.Face_id = 2;
563 info.FE_pt = fe_pt;
564 std::set<unsigned>::iterator it2 = edge_boundary[2].begin();
565
566 // Edge does exist:
567 if (edge_boundary[2].size() > 0)
568 {
569 info.Boundary = *it2;
570
571 // How many times this edge has been visited
572 edge_count[edge2]++;
573
574 // Update edge_bcinfo
575 edge_bcinfo.insert(std::make_pair(edge2, info));
576
577 // ... and also update the info associated with internal bnd
578 edge_internal_bnd[edge2].push_back(info);
579 }
580 }
581
582
583#ifdef PARANOID
584
585 // Check if edge is associated with multiple boundaries
586
587 // We now know whether any edges lay on the boundaries
588 for (unsigned i = 0; i < 3; i++)
589 {
590 // How many boundaries are there
591 unsigned count = 0;
592
593 // Loop over all the members of the set and add to the count
594 // and set the boundary
595 for (std::set<unsigned>::iterator it = edge_boundary[i].begin();
596 it != edge_boundary[i].end();
597 ++it)
598 {
599 ++count;
600 }
601
602 // If we're on more than one boundary, this is weird, so die
603 if (count > 1)
604 {
605 std::ostringstream error_stream;
606 error_stream << "Edge " << i << " is located on " << count
607 << " boundaries.\n";
608 error_stream << "This is rather strange, so I'm going to die\n";
609 throw OomphLibError(error_stream.str(),
612 }
613 }
614
615#endif
616
617 // Now we set the pointers to the boundary sets to zero
618 for (unsigned i = 0; i < 3; i++)
619 {
620 boundaries_pt[i] = 0;
621 }
622 }
623 } // end of loop over all elements
624
625 // Loop over all edges that are located on a boundary
626 typedef std::map<Edge, TriangleBoundaryHelper::BCInfo>::iterator ITE;
627 for (ITE it = edge_bcinfo.begin(); it != edge_bcinfo.end(); it++)
628 {
629 Edge current_edge = it->first;
630 unsigned bound = it->second.Boundary;
631
632 // If the edge has been visited only once
633 if (edge_count[current_edge] == 1)
634 {
635 // Count the edges that are on the same element and on the same boundary
636 face_count(static_cast<unsigned>(bound), it->second.FE_pt) =
637 face_count(static_cast<unsigned>(bound), it->second.FE_pt) + 1;
638
639 // If such edges exist, let store the corresponding element
640 if (face_count(bound, it->second.FE_pt) > 1)
641 {
642 // Update edge's infos
644 info.Face_id = it->second.Face_id;
645 info.FE_pt = it->second.FE_pt;
646 info.Boundary = it->second.Boundary;
647
648 // Add it to FIinfo, that stores infos of problematic elements
649 face_info.insert(std::make_pair(current_edge, info));
650
651 // How many edges on which boundary have to be added
652 bonus[bound]++;
653 }
654 else
655 {
656 // Add element and face to the appropriate vectors
657 // Does the pointer already exits in the vector
659 vector_of_boundary_element_pt[static_cast<unsigned>(bound)].begin(),
660 vector_of_boundary_element_pt[static_cast<unsigned>(bound)].end(),
661 it->second.FE_pt);
662
663 // Only insert if we have not found it (i.e. got to the end)
664 if (b_el_it ==
665 vector_of_boundary_element_pt[static_cast<unsigned>(bound)].end())
666 {
667 vector_of_boundary_element_pt[static_cast<unsigned>(bound)]
668 .push_back(it->second.FE_pt);
669 }
670
671 // set_of_boundary_element_pt[static_cast<unsigned>(bound)].insert(
672 // it->second.FE_pt);
673 face_identifier(static_cast<unsigned>(bound), it->second.FE_pt) =
674 it->second.Face_id;
675 }
676 }
677
678 } // End of "adding-boundaries"-loop
679
680
681 // Now copy everything across into permanent arrays
682 //-------------------------------------------------
683
684 // Loop over boundaries
685 for (unsigned i = 0; i < nbound; i++)
686 {
687 // Number of elements on this boundary that have to be added
688 // in addition to other elements
689 unsigned bonus1 = bonus[i];
690
691 // Number of elements on this boundary
693
694 // Allocate storage for the coordinate identifiers
696
697 unsigned e_count = 0;
701 it++)
702 {
703 // Recover pointer to element
705
706 // Add to permanent storage
707 Boundary_element_pt[i].push_back(fe_pt);
708
710
711 // Increment counter
712 e_count++;
713 }
714 // We add the elements that have two or more edges on this boundary
715 for (ITE itt = face_info.begin(); itt != face_info.end(); itt++)
716 {
717 if (itt->second.Boundary == i)
718 {
719 // Add to permanent storage
720 Boundary_element_pt[i].push_back(itt->second.FE_pt);
721
722 Face_index_at_boundary[i][e_count] = itt->second.Face_id;
723
724 e_count++;
725 }
726 }
727
728 } // End of loop over boundaries
729
730 // Doc?
731 //-----
732 if (doc)
733 {
734 // Loop over boundaries
735 for (unsigned i = 0; i < nbound; i++)
736 {
737 unsigned nel = Boundary_element_pt[i].size();
738 outfile << "Boundary: " << i << " is adjacent to " << nel << " elements"
739 << std::endl;
740
741 // Loop over elements on given boundary
742 for (unsigned e = 0; e < nel; e++)
743 {
745 outfile << "Boundary element:" << fe_pt
746 << " Face index of boundary is "
747 << Face_index_at_boundary[i][e] << std::endl;
748 }
749 }
750 }
751
752 // Lookup scheme has now been setup yet
754 }
755} // namespace oomph
e
Definition cfortran.h:571
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
Edge class.
Definition mesh.h:2700
A general Finite Element class.
Definition elements.h:1317
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition elements.h:2615
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition mesh.h:841
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Definition mesh.h:1596
Vector< Vector< FiniteElement * > > Boundary_element_pt
Vector of Vector of pointers to elements on the boundaries: Boundary_element_pt(b,...
Definition mesh.h:91
bool Lookup_for_elements_next_boundary_is_setup
Flag to indicate that the lookup schemes for elements that are adjacent to the boundaries has been se...
Definition mesh.h:87
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition mesh.h:477
Vector< Vector< int > > Face_index_at_boundary
For the e-th finite element on boundary b, this is the index of the face that lies along that boundar...
Definition mesh.h:95
unsigned nboundary() const
Return number of boundaries.
Definition mesh.h:835
void set_boundary_coordinate_exists(const unsigned &i)
Set boundary coordinate on the i-th boundary to be existing.
Definition mesh.h:584
bool boundary_coordinate_exists(const unsigned &i) const
Indicate whether the i-th boundary has an intrinsic coordinate.
Definition mesh.h:571
unsigned long nelement() const
Return number of elements in the mesh.
Definition mesh.h:598
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition mesh.h:497
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition nodes.h:906
virtual void get_boundaries_pt(std::set< unsigned > *&boundaries_pt)
Return a pointer to set of mesh boundaries that this node occupies; this will be overloaded by Bounda...
Definition nodes.h:1365
An OomphLibError object which should be thrown when an run-time error is encountered....
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
virtual void remesh_from_internal_triangulateio()
Virtual function that is used for specific remeshing from the triangulateio.
void dump_triangulateio(std::ostream &dump_file)
Dump the triangulateio structure to a dump file and record boundary coordinates of boundary nodes.
TriangulateIO Triangulateio
TriangulateIO representation of the mesh.
void remesh_from_triangulateio(std::istream &restart_file)
Regenerate the mesh from a dumped triangulateio file and dumped boundary coordinates of boundary node...
void setup_boundary_element_info()
Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to ...
void write_triangulateio(TriangulateIO &triangulate_io, std::string &s)
Helper function. Write a TriangulateIO object file with all the triangulateio fields....
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition Vector.h:58
void dump_triangulateio(TriangulateIO &triangle_io, std::ostream &dump_file)
Write all the triangulateio data to disk in a dump file that can then be used to restart simulations.
void read_triangulateio(std::istream &restart_file, TriangulateIO &triangle_io)
Read the triangulateio data from a dump file on disk, which can then be used to restart simulations.
void clear_triangulateio(TriangulateIO &triangulate_io, const bool &clear_hole_data)
Clear TriangulateIO structure.
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...
The Triangle data structure, modified from the triangle.h header supplied with triangle 1....