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.
 
////////////////////////////////////////////////////////////////////// //////////////////////////////...