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);
    70             const std::string& element_file_name,
    71             const std::string& face_file_name,
    72             TimeStepper* time_stepper_pt=
    73             &Mesh::Default_TimeStepper,
    74             const bool &use_attributes=
false) 
    79    MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
    85    Time_stepper_pt = time_stepper_pt;
    89     TetgenScaffoldMesh(node_file_name,element_file_name,face_file_name);
    99    unsigned nb=nboundary();
   100    for (
unsigned b=0;b<nb;b++)
   102      bool switch_normal=
false;
   103      setup_boundary_coordinates<ELEMENT>(b,switch_normal); 
   110             TimeStepper* time_stepper_pt=
   111             &Mesh::Default_TimeStepper,
   112             const bool &use_attributes=
false)
   116    MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
   122    Time_stepper_pt = time_stepper_pt;
   130     TetgenScaffoldMesh(tetgen_data);
   140    unsigned nb=nboundary();
   141    for (
unsigned b=0;b<nb;b++)
   143      bool switch_normal=
false;
   144      setup_boundary_coordinates<ELEMENT>(b,switch_normal); 
   159             const std::string& element_file_name,
   160             const std::string& face_file_name,
   161             const bool& split_corner_elements,
   162             TimeStepper* time_stepper_pt=
   163             &Mesh::Default_TimeStepper,
   164             const bool &use_attributes=
false)
   168    MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
   174    Time_stepper_pt = time_stepper_pt;
   182     TetgenScaffoldMesh(node_file_name,element_file_name,face_file_name);
   192    if (split_corner_elements)
   194      split_elements_in_corners<ELEMENT>();
   198    unsigned nb=nboundary();
   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,
   217             TimeStepper* time_stepper_pt=
   218             &Mesh::Default_TimeStepper,
   219             const bool &use_attributes=
false)
   223    MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
   229    Time_stepper_pt = time_stepper_pt;
   246    if (split_corner_elements)
   248      split_elements_in_corners<ELEMENT>();
   252    unsigned nb=nboundary();
   253    for (
unsigned b=0;b<nb;b++)
   255      bool switch_normal=
false;
   256      setup_boundary_coordinates<ELEMENT>(b,switch_normal); 
   265   TetgenMesh(TetMeshFacetedClosedSurface* 
const &outer_boundary_pt,
   266              Vector<TetMeshFacetedSurface*>& internal_surface_pt,
   267              const double &element_volume,           
   268              TimeStepper* time_stepper_pt=
   269              &Mesh::Default_TimeStepper,
   270              const bool &use_attributes=
false,
   271              const bool& split_corner_elements = 
false) 
   274     MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
   280     Time_stepper_pt = time_stepper_pt;
   283     Outer_boundary_pt=outer_boundary_pt;
   287      unsigned n_facet=Outer_boundary_pt->nfacet();
   288      for (
unsigned f=0;f<n_facet;f++)
   290        unsigned b=Outer_boundary_pt->one_based_facet_boundary_id(f);
   293          Tet_mesh_faceted_surface_pt[b-1]=Outer_boundary_pt;
   294          Tet_mesh_facet_pt[b-1]=Outer_boundary_pt->facet_pt(f);
   298          std::ostringstream error_message;
   299          error_message << 
"Boundary IDs have to be one-based. Yours is "    301          throw OomphLibError(error_message.str(),
   302                              OOMPH_CURRENT_FUNCTION,
   303                              OOMPH_EXCEPTION_LOCATION);
   310     Internal_surface_pt = internal_surface_pt;
   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);
   323            Tet_mesh_faceted_surface_pt[b-1]=Internal_surface_pt[i];   
   324            Tet_mesh_facet_pt[b-1]=Internal_surface_pt[i]->facet_pt(f);
   328            std::ostringstream error_message;
   329            error_message << 
"Boundary IDs have to be one-based. Yours is "    331            throw OomphLibError(error_message.str(),
   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 = 
   357      outer_boundary_pt->boundaries_can_be_split_in_tetgen();
   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++)
   389        TetMeshFacetedClosedSurface* srf_pt=
   390         dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[i]);
   393          unsigned n_int_pts=srf_pt->ninternal_point_for_tetgen();
   394          for (
unsigned j=0;j<n_int_pts;j++)
   397            srf_pt->internal_point_identifies_region_for_tetgen(j); 
   404     if(regions_exist) {Use_attributes=
true;}
   414     if (split_corner_elements)
   416       split_elements_in_corners<ELEMENT>();
   420     unsigned nb=nboundary();
   421     for (
unsigned b=0;b<nb;b++)
   423       bool switch_normal=
false;
   424       setup_boundary_coordinates<ELEMENT>(b,switch_normal); 
   429     snap_nodes_onto_geometric_objects();
   435                       Vector<TetMeshFacetedSurface*>& internal_surface_pt,
   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;
   456    Vector<unsigned> n_internal_vertex(n_internal);
   457    Vector<unsigned> internal_vertex_offset(n_internal);
   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] = 
   474         outer_boundary_pt->vertex_coordinate(n,i);
   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] = 
   498       outer_boundary_pt->one_based_vertex_boundary_id(n); 
   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;
   516    Vector<unsigned> n_inner_facet(n_internal);
   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];
   538      Vector<unsigned> facet = outer_boundary_pt->vertex_index_in_tetgen(n); 
   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] = 
   550       outer_boundary_pt->one_based_facet_boundary_id(n); 
   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];
   573        Vector<unsigned> facet=internal_surface_pt[h]->vertex_index_in_tetgen(n);
   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); 
   589      TetMeshFacetedClosedSurface* srf_pt=
   590       dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
   593        unsigned n_int_pts=srf_pt->ninternal_point_for_tetgen();
   594        for (
unsigned j=0;j<n_int_pts;j++)
   596          if (srf_pt->internal_point_identifies_hole_for_tetgen(j))
   598            ++tetgen_io.numberofholes;
   603            if (srf_pt->internal_point_identifies_region_for_tetgen(j))
   605              ++tetgen_io.numberofregions;
   613    tetgen_io.holelist = 
new double[3*tetgen_io.numberofholes];
   617    for(
unsigned h=0;h<n_internal;++h)
   619      TetMeshFacetedClosedSurface* srf_pt=
   620       dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
   623        unsigned n_int_pts=srf_pt->ninternal_point_for_tetgen();
   624        for (
unsigned j=0;j<n_int_pts;j++)
   626          if (srf_pt->internal_point_identifies_hole_for_tetgen(j))
   628            for(
unsigned i=0;i<3;++i)
   630              tetgen_io.holelist[counter] = 
   631               srf_pt->internal_point_for_tetgen(j,i); 
   640    tetgen_io.regionlist = 
new double[5*tetgen_io.numberofregions];
   643    for(
unsigned h=0;h<n_internal;++h)
   645      TetMeshFacetedClosedSurface* srf_pt=
   646       dynamic_cast<TetMeshFacetedClosedSurface*
>(internal_surface_pt[h]);
   649        unsigned n_int_pts=srf_pt->ninternal_point_for_tetgen();
   650        for (
unsigned j=0;j<n_int_pts;j++)
   652          if (srf_pt->internal_point_identifies_region_for_tetgen(j)) 
   654            for(
unsigned i=0;i<3;++i)
   656              tetgen_io.regionlist[counter] = 
   657               srf_pt->internal_point_for_tetgen(j,i);
   660            tetgen_io.regionlist[counter] =
   661             static_cast<double>(srf_pt->region_id_for_tetgen(j)); 
   664            tetgen_io.regionlist[counter] = 0.0;
   686                                   const bool &preserve_existing_data)
   687  {this->Time_stepper_pt = time_stepper_pt;}
   712                             tetgenio* &output_pt);
   721                           const bool &use_attributes);
   751 template<
class ELEMENT>
   753  public virtual SolidMesh 
   761                const std::string& element_file_name,
   762                const std::string& face_file_name,
   763                const bool& split_corner_elements,
   764                TimeStepper* time_stepper_pt=
   765                &Mesh::Default_TimeStepper,
   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();
   779                const std::string& element_file_name,
   780                const std::string& face_file_name,
   781                const bool& split_corner_elements,
   782                const bool& switch_normal,
   783                TimeStepper* time_stepper_pt=
   784                &Mesh::Default_TimeStepper,
   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();
   795    unsigned nb=this->nboundary();
   796    for (
unsigned b=0;b<nb;b++)
   798      this->
template setup_boundary_coordinates<ELEMENT>(b,switch_normal);
 
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. 
 
TetgenScaffoldMesh * Tmp_mesh_pt
Temporary scaffold mesh. 
 
bool Use_attributes
Boolean flag to indicate whether to use attributes or not (required for multidomain meshes) ...
 
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 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 ...
 
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...
 
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. 
 
virtual ~SolidTetgenMesh()
Empty Destructor. 
 
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. 
 
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 ...
 
tetgenio * Tetgenio_pt
Tetgen representation of mesh.