27 #ifndef OOMPH_TETGEN_MESH_HEADER
28 #define OOMPH_TETGEN_MESH_HEADER
32 #include <oomph-lib-config.h>
41 #include "../generic/tetgen_scaffold_mesh.h"
42 #include "../generic/tet_mesh.h"
50 template<
class ELEMENT>
58 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
63 const std::string& element_file_name,
64 const std::string& face_file_name,
65 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
66 const bool& use_attributes =
false)
70 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
76 Time_stepper_pt = time_stepper_pt;
80 node_file_name, element_file_name, face_file_name);
90 unsigned nb = nboundary();
91 for (
unsigned b = 0; b < nb; b++)
93 bool switch_normal =
false;
94 setup_boundary_coordinates<ELEMENT>(b, switch_normal);
101 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
102 const bool& use_attributes =
false)
106 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
112 Time_stepper_pt = time_stepper_pt;
129 unsigned nb = nboundary();
130 for (
unsigned b = 0; b < nb; b++)
132 bool switch_normal =
false;
133 setup_boundary_coordinates<ELEMENT>(b, switch_normal);
148 const std::string& element_file_name,
149 const std::string& face_file_name,
150 const bool& split_corner_elements,
151 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
152 const bool& use_attributes =
false)
156 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
162 Time_stepper_pt = time_stepper_pt;
170 node_file_name, element_file_name, face_file_name);
180 if (split_corner_elements)
182 split_elements_in_corners<ELEMENT>();
186 unsigned nb = nboundary();
187 for (
unsigned b = 0; b < nb; b++)
189 bool switch_normal =
false;
190 setup_boundary_coordinates<ELEMENT>(b, switch_normal);
204 const bool& split_corner_elements,
205 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
206 const bool& use_attributes =
false)
210 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
216 Time_stepper_pt = time_stepper_pt;
233 if (split_corner_elements)
235 split_elements_in_corners<ELEMENT>();
239 unsigned nb = nboundary();
240 for (
unsigned b = 0; b < nb; b++)
242 bool switch_normal =
false;
243 setup_boundary_coordinates<ELEMENT>(b, switch_normal);
254 TetMeshFacetedClosedSurface*
const& outer_boundary_pt,
255 Vector<TetMeshFacetedSurface*>& internal_surface_pt,
256 const double& element_volume,
257 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
258 const bool& use_attributes =
false,
259 const bool& split_corner_elements =
false,
260 Vector<double>*
const& target_element_volume_in_region_pt =
nullptr)
263 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
269 Time_stepper_pt = time_stepper_pt;
272 Outer_boundary_pt = outer_boundary_pt;
276 Internal_surface_pt = internal_surface_pt;
279 unsigned n = this->Internal_surface_pt.size();
280 for (
unsigned i = 0; i < n; i++)
283 Internal_surface_pt[i]);
291 target_element_volume_in_region_pt,
306 std::stringstream input_string;
307 input_string <<
"pq2.0aAa" << element_volume;
314 bool can_boundaries_be_split =
315 outer_boundary_pt->boundaries_can_be_split_in_tetgen();
317 unsigned n_internal = internal_surface_pt.size();
318 for (
unsigned i = 0; i < n_internal; i++)
320 can_boundaries_be_split &=
321 internal_surface_pt[i]->boundaries_can_be_split_in_tetgen();
326 if (can_boundaries_be_split ==
false)
332 char tetswitches[100];
333 sprintf(tetswitches,
"%s", input_string.str().c_str());
338 tetrahedralize(tetswitches, &in, this->
Tetgenio_pt);
345 bool regions_exist =
false;
347 unsigned n_internal = internal_surface_pt.size();
348 for (
unsigned i = 0; i < n_internal; i++)
350 TetMeshFacetedClosedSurface* srf_pt =
351 dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[i]);
354 unsigned n_int_pts = srf_pt->ninternal_point_for_tetgen();
355 for (
unsigned j = 0; j < n_int_pts; j++)
358 srf_pt->internal_point_identifies_region_for_tetgen(j);
378 if (split_corner_elements)
380 split_elements_in_corners<ELEMENT>();
384 unsigned nb = nboundary();
385 for (
unsigned b = 0; b < nb; b++)
387 bool switch_normal =
false;
388 setup_boundary_coordinates<ELEMENT>(b, switch_normal);
393 snap_nodes_onto_geometric_objects();
398 TetMeshFacetedSurface*
const& outer_boundary_pt,
399 Vector<TetMeshFacetedSurface*>& internal_surface_pt,
400 Vector<double>*
const& target_element_volume_in_region_pt,
406 tetgenio::polygon* p;
409 tetgen_io.firstnumber = 1;
411 tetgen_io.useindex =
true;
414 const unsigned n_internal = internal_surface_pt.size();
417 const unsigned n_outer_vertex = outer_boundary_pt->nvertex();
418 tetgen_io.numberofpoints = n_outer_vertex;
421 Vector<unsigned> n_internal_vertex(n_internal);
422 Vector<unsigned> internal_vertex_offset(n_internal);
423 for (
unsigned h = 0; h < n_internal; ++h)
425 n_internal_vertex[h] = internal_surface_pt[h]->nvertex();
426 internal_vertex_offset[h] = tetgen_io.numberofpoints;
427 tetgen_io.numberofpoints += n_internal_vertex[h];
431 tetgen_io.pointlist =
new double[tetgen_io.numberofpoints * 3];
432 tetgen_io.pointmarkerlist =
new int[tetgen_io.numberofpoints];
433 unsigned counter = 0;
434 for (
unsigned n = 0; n < n_outer_vertex; ++n)
436 for (
unsigned i = 0; i < 3; ++i)
438 tetgen_io.pointlist[counter] =
439 outer_boundary_pt->vertex_coordinate(n, i);
443 for (
unsigned h = 0; h < n_internal; ++h)
445 const unsigned n_inner = n_internal_vertex[h];
446 for (
unsigned n = 0; n < n_inner; ++n)
448 for (
unsigned i = 0; i < 3; ++i)
450 tetgen_io.pointlist[counter] =
451 internal_surface_pt[h]->vertex_coordinate(n, i);
460 for (
unsigned n = 0; n < n_outer_vertex; ++n)
462 tetgen_io.pointmarkerlist[counter] =
463 outer_boundary_pt->one_based_vertex_boundary_id(n);
466 for (
unsigned h = 0; h < n_internal; ++h)
468 const unsigned n_inner = n_internal_vertex[h];
469 for (
unsigned n = 0; n < n_inner; ++n)
471 tetgen_io.pointmarkerlist[counter] =
472 internal_surface_pt[h]->one_based_vertex_boundary_id(n);
479 unsigned n_outer_facet = outer_boundary_pt->nfacet();
480 tetgen_io.numberoffacets = n_outer_facet;
481 Vector<unsigned> n_inner_facet(n_internal);
482 for (
unsigned h = 0; h < n_internal; ++h)
484 n_inner_facet[h] = internal_surface_pt[h]->nfacet();
485 tetgen_io.numberoffacets += n_inner_facet[h];
488 tetgen_io.facetlist =
new tetgenio::facet[tetgen_io.numberoffacets];
489 tetgen_io.facetmarkerlist =
new int[tetgen_io.numberoffacets];
493 for (
unsigned n = 0; n < n_outer_facet; ++n)
496 f = &tetgen_io.facetlist[counter];
497 f->numberofpolygons = 1;
498 f->polygonlist =
new tetgenio::polygon[f->numberofpolygons];
499 f->numberofholes = 0;
501 p = &f->polygonlist[0];
503 Vector<unsigned> facet = outer_boundary_pt->vertex_index_in_tetgen(n);
505 p->numberofvertices = facet.size();
506 p->vertexlist =
new int[p->numberofvertices];
507 for (
int i = 0; i < p->numberofvertices; ++i)
510 p->vertexlist[i] = facet[i] + 1;
514 tetgen_io.facetmarkerlist[counter] =
515 outer_boundary_pt->one_based_facet_boundary_id(n);
521 tetgen_io.numberofholes = 0;
523 tetgen_io.numberofregions = 0;
526 for (
unsigned h = 0; h < n_internal; ++h)
528 for (
unsigned n = 0; n < n_inner_facet[h]; ++n)
531 f = &tetgen_io.facetlist[counter];
532 f->numberofpolygons = 1;
533 f->polygonlist =
new tetgenio::polygon[f->numberofpolygons];
534 f->numberofholes = 0;
536 p = &f->polygonlist[0];
538 Vector<unsigned> facet =
539 internal_surface_pt[h]->vertex_index_in_tetgen(n);
541 p->numberofvertices = facet.size();
542 p->vertexlist =
new int[p->numberofvertices];
543 for (
int i = 0; i < p->numberofvertices; ++i)
546 p->vertexlist[i] = facet[i] + internal_vertex_offset[h] + 1;
549 tetgen_io.facetmarkerlist[counter] =
550 internal_surface_pt[h]->one_based_facet_boundary_id(n);
555 TetMeshFacetedClosedSurface* srf_pt =
556 dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
559 unsigned n_int_pts = srf_pt->ninternal_point_for_tetgen();
560 for (
unsigned j = 0; j < n_int_pts; j++)
562 if (srf_pt->internal_point_identifies_hole_for_tetgen(j))
564 ++tetgen_io.numberofholes;
569 if (srf_pt->internal_point_identifies_region_for_tetgen(j))
571 ++tetgen_io.numberofregions;
579 tetgen_io.holelist =
new double[3 * tetgen_io.numberofholes];
583 for (
unsigned h = 0; h < n_internal; ++h)
585 TetMeshFacetedClosedSurface* srf_pt =
586 dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
589 unsigned n_int_pts = srf_pt->ninternal_point_for_tetgen();
590 for (
unsigned j = 0; j < n_int_pts; j++)
592 if (srf_pt->internal_point_identifies_hole_for_tetgen(j))
594 for (
unsigned i = 0; i < 3; ++i)
596 tetgen_io.holelist[counter] =
597 srf_pt->internal_point_for_tetgen(j, i);
606 tetgen_io.regionlist =
new double[5 * tetgen_io.numberofregions];
610 for (
unsigned h = 0; h < n_internal; ++h)
612 TetMeshFacetedClosedSurface* srf_pt =
613 dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
616 unsigned n_int_pts = srf_pt->ninternal_point_for_tetgen();
617 for (
unsigned j = 0; j < n_int_pts; j++)
619 if (srf_pt->internal_point_identifies_region_for_tetgen(j))
621 for (
unsigned i = 0; i < 3; ++i)
623 tetgen_io.regionlist[counter] =
624 srf_pt->internal_point_for_tetgen(j, i);
627 tetgen_io.regionlist[counter] =
628 static_cast<double>(srf_pt->region_id_for_tetgen(j));
632 if (target_element_volume_in_region_pt ==
nullptr)
634 tetgen_io.regionlist[counter] = 0;
640 tetgen_io.regionlist[counter] =
641 (*target_element_volume_in_region_pt)[unsigned(counter / 5)];
665 const bool& preserve_existing_data)
667 this->Time_stepper_pt = time_stepper_pt;
706 const bool& use_attributes);
710 TetMeshFacetedSurface*
const& faceted_surface_pt);
738 template<
class ELEMENT>
740 public virtual SolidMesh
746 const std::string& element_file_name,
747 const std::string& face_file_name,
748 const bool& split_corner_elements,
749 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
750 const bool& use_attributes =
false)
754 split_corner_elements,
759 set_lagrangian_nodal_coordinates();
766 const std::string& element_file_name,
767 const std::string& face_file_name,
768 const bool& split_corner_elements,
769 const bool& switch_normal,
770 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
771 const bool& use_attributes =
false)
775 split_corner_elements,
780 set_lagrangian_nodal_coordinates();
784 unsigned nb = this->nboundary();
785 for (
unsigned b = 0; b < nb; b++)
787 this->
template setup_boundary_coordinates<ELEMENT>(b, switch_normal);
/////////////////////////////////////////////////////////////// /////////////////////////////////////...
SolidTetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, const bool &split_corner_elements, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor. Boundary coordinates are setup automatically.
SolidTetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, const bool &split_corner_elements, const bool &switch_normal, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor. Boundary coordinates are re-setup automatically, with the orientation of the outer unit ...
virtual ~SolidTetgenMesh()
Empty Destructor.
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
tetgenio *& tetgenio_pt()
Access to the triangulateio representation of the mesh.
TetgenMesh(tetgenio &tetgen_data, const bool &split_corner_elements, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor with tetgen data structure Setting the boolean flag to true splits "corner" elements,...
TetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor with the input files.
TetgenMesh()
Empty constructor.
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
tetgenio * Tetgenio_pt
Tetgen representation of mesh.
TetgenMesh(TetMeshFacetedClosedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_surface_pt, const double &element_volume, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false, const bool &split_corner_elements=false, Vector< double > *const &target_element_volume_in_region_pt=nullptr)
Build mesh, based on a TetgenMeshFactedClosedSurface that specifies the outer boundary of the domain ...
void setup_reverse_lookup_schemes_for_faceted_surface(TetMeshFacetedSurface *const &faceted_surface_pt)
Function to setup the reverse look-up schemes.
TetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, const bool &split_corner_elements, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor with the input files. Setting the boolean flag to true splits "corner" elements,...
void set_deep_copy_tetgenio_pt(tetgenio *const &tetgenio_pt)
Set the tetgen pointer by a deep copy.
void deep_copy_of_tetgenio(tetgenio *const &input_pt, tetgenio *&output_pt)
Transfer tetgenio data from the input to the output The output is assumed to have been constructed an...
bool Use_attributes
Boolean flag to indicate whether to use attributes or not (required for multidomain meshes)
~TetgenMesh()
Empty destructor.
void set_mesh_level_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Overload set_mesh_level_time_stepper so that the stored time stepper now corresponds to the new times...
void build_tetgenio(TetMeshFacetedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_surface_pt, Vector< double > *const &target_element_volume_in_region_pt, tetgenio &tetgen_io)
Build tetgenio object from the TetMeshFacetedSurfaces.
bool Tetgenio_exists
Boolean to indicate whether a tetgenio representation of the mesh exists.
TetgenScaffoldMesh * Tmp_mesh_pt
Temporary scaffold mesh.
TetgenMesh(tetgenio &tetgen_data, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor with tetgenio data structure.
bool tetgenio_exists() const
Boolen defining whether tetgenio object has been built or not.
////////////////////////////////////////////////////////////////////// //////////////////////////////...