31 #ifndef OOMPH_TETGEN_MESH_HEADER 32 #define OOMPH_TETGEN_MESH_HEADER 36 #include <oomph-lib-config.h> 45 #include "../generic/tetgen_scaffold_mesh.h" 46 #include "../generic/tet_mesh.h" 55 template <
class ELEMENT>
65 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
74 const bool &use_attributes=
false)
79 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
100 for (
unsigned b=0;b<nb;b++)
102 bool switch_normal=
false;
103 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
112 const bool &use_attributes=
false)
116 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
141 for (
unsigned b=0;b<nb;b++)
143 bool switch_normal=
false;
144 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
161 const bool& split_corner_elements,
164 const bool &use_attributes=
false)
168 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
192 if (split_corner_elements)
194 split_elements_in_corners<ELEMENT>();
199 for (
unsigned b=0;b<nb;b++)
201 bool switch_normal=
false;
202 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
216 const bool& split_corner_elements,
219 const bool &use_attributes=
false)
223 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
246 if (split_corner_elements)
248 split_elements_in_corners<ELEMENT>();
253 for (
unsigned b=0;b<nb;b++)
255 bool switch_normal=
false;
256 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
267 const double &element_volume,
270 const bool &use_attributes=
false,
271 const bool& split_corner_elements =
false)
274 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
288 for (
unsigned f=0;f<n_facet;f++)
298 std::ostringstream error_message;
299 error_message <<
"Boundary IDs have to be one-based. Yours is " 302 OOMPH_CURRENT_FUNCTION,
303 OOMPH_EXCEPTION_LOCATION);
314 unsigned n=Internal_surface_pt.size();
315 for (
unsigned i=0;
i<n;
i++)
317 unsigned n_facet=Internal_surface_pt[
i]->nfacet();
318 for (
unsigned f=0;f<n_facet;f++)
320 unsigned b=Internal_surface_pt[
i]->one_based_facet_boundary_id(f);
328 std::ostringstream error_message;
329 error_message <<
"Boundary IDs have to be one-based. Yours is " 332 OOMPH_CURRENT_FUNCTION,
333 OOMPH_EXCEPTION_LOCATION);
348 std::stringstream input_string;
349 input_string <<
"pAa" << element_volume;
356 bool can_boundaries_be_split =
359 unsigned n_internal=internal_surface_pt.size();
360 for(
unsigned i=0;
i<n_internal;
i++)
362 can_boundaries_be_split &=
363 internal_surface_pt[
i]->boundaries_can_be_split_in_tetgen();
368 if(can_boundaries_be_split==
false) {input_string <<
"Y";}
371 char tetswitches[100];
372 sprintf(tetswitches,
"%s",input_string.str().c_str());
377 tetrahedralize(tetswitches, &in, this->
Tetgenio_pt);
384 bool regions_exist =
false;
386 unsigned n_internal=internal_surface_pt.size();
387 for(
unsigned i=0;
i<n_internal;
i++)
394 for (
unsigned j=0;j<n_int_pts;j++)
404 if(regions_exist) {Use_attributes=
true;}
414 if (split_corner_elements)
416 split_elements_in_corners<ELEMENT>();
421 for (
unsigned b=0;b<nb;b++)
423 bool switch_normal=
false;
424 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
441 tetgenio::polygon *p;
444 tetgen_io.firstnumber = 1;
446 tetgen_io.useindex =
true;
449 const unsigned n_internal = internal_surface_pt.size();
452 const unsigned n_outer_vertex = outer_boundary_pt->
nvertex();
453 tetgen_io.numberofpoints = n_outer_vertex;
458 for(
unsigned h=0;h<n_internal;++h)
460 n_internal_vertex[h] = internal_surface_pt[h]->nvertex();
461 internal_vertex_offset[h] = tetgen_io.numberofpoints;
462 tetgen_io.numberofpoints += n_internal_vertex[h];
466 tetgen_io.pointlist =
new double[tetgen_io.numberofpoints * 3];
467 tetgen_io.pointmarkerlist =
new int[tetgen_io.numberofpoints];
469 for(
unsigned n=0;n<n_outer_vertex;++n)
471 for(
unsigned i=0;
i<3;++
i)
473 tetgen_io.pointlist[counter] =
478 for(
unsigned h=0;h<n_internal;++h)
480 const unsigned n_inner = n_internal_vertex[h];
481 for(
unsigned n=0;n<n_inner;++n)
483 for(
unsigned i=0;
i<3;++
i)
485 tetgen_io.pointlist[counter] =
486 internal_surface_pt[h]->vertex_coordinate(n,
i);
495 for(
unsigned n=0;n<n_outer_vertex;++n)
497 tetgen_io.pointmarkerlist[counter] =
501 for(
unsigned h=0;h<n_internal;++h)
503 const unsigned n_inner = n_internal_vertex[h];
504 for(
unsigned n=0;n<n_inner;++n)
506 tetgen_io.pointmarkerlist[counter] =
507 internal_surface_pt[h]->one_based_vertex_boundary_id(n);
514 unsigned n_outer_facet = outer_boundary_pt->
nfacet();
515 tetgen_io.numberoffacets = n_outer_facet;
517 for(
unsigned h=0;h<n_internal;++h)
519 n_inner_facet[h] = internal_surface_pt[h]->nfacet();
520 tetgen_io.numberoffacets += n_inner_facet[h];
523 tetgen_io.facetlist =
new tetgenio::facet[tetgen_io.numberoffacets];
524 tetgen_io.facetmarkerlist =
new int[tetgen_io.numberoffacets];
528 for(
unsigned n=0;n<n_outer_facet;++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];
540 p->numberofvertices = facet.size();
541 p->vertexlist =
new int[p->numberofvertices];
542 for(
int i=0;
i<p->numberofvertices;++
i)
545 p->vertexlist[
i] = facet[
i] + 1;
549 tetgen_io.facetmarkerlist[counter] =
556 tetgen_io.numberofholes=0;
558 tetgen_io.numberofregions=0;
561 for(
unsigned h=0;h<n_internal;++h)
563 for(
unsigned n=0;n<n_inner_facet[h];++n)
566 f = &tetgen_io.facetlist[counter];
567 f->numberofpolygons = 1;
568 f->polygonlist =
new tetgenio::polygon[f->numberofpolygons];
569 f->numberofholes = 0;
571 p = &f->polygonlist[0];
575 p->numberofvertices = facet.size();
576 p->vertexlist =
new int[p->numberofvertices];
577 for(
int i=0;
i<p->numberofvertices;++
i)
580 p->vertexlist[
i] = facet[
i] + internal_vertex_offset[h] + 1;
583 tetgen_io.facetmarkerlist[counter] =
584 internal_surface_pt[h]->one_based_facet_boundary_id(n);
594 for (
unsigned j=0;j<n_int_pts;j++)
598 ++tetgen_io.numberofholes;
605 ++tetgen_io.numberofregions;
613 tetgen_io.holelist =
new double[3*tetgen_io.numberofholes];
617 for(
unsigned h=0;h<n_internal;++h)
624 for (
unsigned j=0;j<n_int_pts;j++)
628 for(
unsigned i=0;
i<3;++
i)
630 tetgen_io.holelist[counter] =
640 tetgen_io.regionlist =
new double[5*tetgen_io.numberofregions];
643 for(
unsigned h=0;h<n_internal;++h)
650 for (
unsigned j=0;j<n_int_pts;j++)
654 for(
unsigned i=0;
i<3;++
i)
656 tetgen_io.regionlist[counter] =
660 tetgen_io.regionlist[counter] =
664 tetgen_io.regionlist[counter] = 0.0;
686 const bool &preserve_existing_data)
712 tetgenio* &output_pt);
721 const bool &use_attributes);
751 template<
class ELEMENT>
763 const bool& split_corner_elements,
766 const bool &use_attributes=
false) :
767 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
768 face_file_name, split_corner_elements,
769 time_stepper_pt, use_attributes)
772 set_lagrangian_nodal_coordinates();
781 const bool& split_corner_elements,
782 const bool& switch_normal,
785 const bool &use_attributes=
false) :
786 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
787 face_file_name, split_corner_elements,
788 time_stepper_pt, use_attributes)
791 set_lagrangian_nodal_coordinates();
796 for (
unsigned b=0;b<nb;b++)
798 this->
template setup_boundary_coordinates<ELEMENT>(b,switch_normal);
bool boundaries_can_be_split_in_tetgen()
Test whether boundary can be split in tetgen.
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors. ...
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
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...
TetgenMesh()
Empty constructor.
unsigned nvertex() const
Number of vertices.
TimeStepper * Time_stepper_pt
Timestepper used to build nodes.
TetgenScaffoldMesh * Tmp_mesh_pt
Temporary scaffold mesh.
bool Use_attributes
Boolean flag to indicate whether to use attributes or not (required for multidomain meshes) ...
Base class for tet meshes (meshes made of 3D tet elements).
TetMeshFacet * facet_pt(const unsigned &j) const
Pointer to j-th facet.
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.
~TetgenMesh()
Empty destructor.
TetgenMesh(tetgenio &tetgen_data, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Constructor with tetgenio data structure.
bool internal_point_identifies_region_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a region?
void snap_nodes_onto_geometric_objects()
Move the nodes on boundaries with associated GeomObjects so that they exactly coincide with the geome...
bool Tetgenio_exists
Boolean to indicate whether a tetgenio representation of the mesh exists.
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
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 build_tetgenio(TetMeshFacetedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface *> &internal_surface_pt, tetgenio &tetgen_io)
Build tetgenio object from the TetMeshFacetedSurfaces.
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 ...
unsigned one_based_vertex_boundary_id(const unsigned &j) const
First (of possibly multiple) one-based boundary id of j-th vertex.
TetMeshFacetedClosedSurface * Outer_boundary_pt
Faceted surface that defines outer boundaries.
unsigned nboundary() const
Return number of boundaries.
std::map< unsigned, TetMeshFacetedSurface * > Tet_mesh_faceted_surface_pt
Reverse lookup scheme: Pointer to faceted surface (if any!) associated with boundary b...
void deep_copy_of_tetgenio(tetgenio *const &input_pt, tetgenio *&output_pt)
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...
bool internal_point_identifies_hole_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a hole?
tetgenio *& tetgenio_pt()
Access to the triangulateio representation of the mesh.
bool tetgenio_exists() const
Boolen defining whether tetgenio object has been built or not.
unsigned nfacet() const
Number of facets.
const int & region_id_for_tetgen(const unsigned &j) const
Return the (zero-based) region ID of j-th internal point for tetgen. Negative if it's actually a hole...
Vector< unsigned > vertex_index_in_tetgen(const unsigned &f)
Facet connectivity: vertex_index[j] is the index of the j-th vertex (in the Vertex_pt vector) in face...
virtual ~SolidTetgenMesh()
Empty Destructor.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
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.
unsigned one_based_facet_boundary_id(const unsigned &j) const
One-based boundary id of j-th facet.
Mesh that is based on input files generated by the tetrahedra mesh generator tetgen.
double vertex_coordinate(const unsigned &j, const unsigned &i) const
i-th coordinate of j-th vertex
void set_deep_copy_tetgenio_pt(tetgenio *const &tetgenio_pt)
Set the tetgen pointer by a deep copy.
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)
Build mesh, based on a TetgenMeshFactedClosedSurface that specifies the outer boundary of the domain ...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Vector to faceted surfaces that define internal boundaries.
std::map< unsigned, TetMeshFacet * > Tet_mesh_facet_pt
Reverse lookup scheme: Pointer to facet (if any!) associated with boundary b.
unsigned ninternal_point_for_tetgen()
Number of internal points (identifying either regions or holes) for tetgen.
const double & internal_point_for_tetgen(const unsigned &j, const unsigned &i) const
i=th coordinate of the j-th internal point for tetgen
tetgenio * Tetgenio_pt
Tetgen representation of mesh.