refineable_tetgen_mesh.template.h
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-2023 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 #ifndef OOMPH_REFINEABLE_TETGEN_MESH_HEADER
28 #define OOMPH_REFINEABLE_TETGEN_MESH_HEADER
29 
30 // Config header generated by autoconfig
31 #ifdef HAVE_CONFIG_H
32 #include <oomph-lib-config.h>
33 #endif
34 
35 
36 #include "../generic/tetgen_scaffold_mesh.h"
37 #include "../generic/tet_mesh.h"
38 #include "../generic/refineable_mesh.h"
39 #include "tetgen_mesh.template.h"
40 
41 namespace oomph
42 {
43  //=========================================================================
44  // Unstructured refineable TetgenMesh
45  //=========================================================================
46  template<class ELEMENT>
47  class RefineableTetgenMesh : public virtual TetgenMesh<ELEMENT>,
48  public virtual RefineableTetMeshBase
49  {
50  public:
51  /// Build mesh, based on a TetMeshFacetedClosedSurface that specifies
52  /// the outer boundary of the domain and any number of internal
53  /// closed curves, specified by TetMeshFacetedSurfaces.
54  /// Also specify target volume for uniform element size.
56  TetMeshFacetedClosedSurface* const& outer_boundary_pt,
57  Vector<TetMeshFacetedSurface*>& internal_closed_surface_pt,
58  const double& element_volume,
59  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
60  const bool& use_attributes = false,
61  const bool& split_corner_elements = false,
62  Vector<double>* const& target_element_volume_in_region_pt = nullptr)
63  : TetgenMesh<ELEMENT>(outer_boundary_pt,
64  internal_closed_surface_pt,
65  element_volume,
66  time_stepper_pt,
67  use_attributes,
68  split_corner_elements,
69  target_element_volume_in_region_pt),
70  Corner_elements_must_be_split(split_corner_elements)
71  {
72  // Initialise the data associated with adaptation
74  }
75 
76 
77  protected:
78  /// Specialised constructor used during adaptation only.
79  /// Element sizes are specified by vector tetgen_io is passed in
80  /// from previous mesh (is then modified to build new mesh)
81  /// Ditto with use_attributes, which comes from the previous mesh
83  const Vector<double>& target_volume,
84  tetgenio* const& tetgen_io_pt,
85  TetMeshFacetedClosedSurface* const& outer_boundary_pt,
86  Vector<TetMeshFacetedSurface*>& internal_surface_pt,
87  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
88  const bool& use_attributes = false)
89  {
90  // NOTE THERE IS A CERTAIN AMOUNT OF DUPLICATION BETWEEN THE
91  // CODE IN HERE AND THE ONE IN THE CONSTRUCTOR OF THE TetgenMesh
92  // BUT THE FACT THAT WE HAVE TO MODIFY THE TETGENIO STRUCTURE
93  // MEANS WE CAN'T QUITE RECYCLE THIS.
94 
95  // Mesh can only be built with 3D Telements.
96  MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
97 
98  // Initialise the data associated with adaptation
100 
101  // Store Timestepper used to build elements
102  this->Time_stepper_pt = time_stepper_pt;
103 
104  // Triangulation has been created -- remember to wipe it!
105  this->Tetgenio_exists = true;
106  this->Tetgenio_pt = new tetgenio;
107 
108  // Add the volume constraints to the tetgenio data object.
109  // Note that since the tetgenio structure is referred to by pointer
110  // we're also modifying the one associated with the (still existing)
111  // original mesh. Bit naughty but shouldn't cause any problems
112  // since that mesh is already built and about to go out of scope
113  // anyway.
114 
115  // Create a local copy
116  tetgenio* tetgen_input_pt = new tetgenio;
117  ;
118  this->deep_copy_of_tetgenio(tetgen_io_pt, tetgen_input_pt);
119 
120  // Add volume constraints
121  tetgen_input_pt->tetrahedronvolumelist =
122  new double[tetgen_input_pt->numberoftetrahedra];
123  for (int e = 0; e < tetgen_input_pt->numberoftetrahedra; ++e)
124  {
125  tetgen_input_pt->tetrahedronvolumelist[e] = target_volume[e];
126  }
127 
128  // Input string
129  std::stringstream input_string_stream;
130  input_string_stream << "Vqra";
131 
132  // Convert to a *char
133  char tetswitches[100];
134  sprintf(tetswitches, "%s", input_string_stream.str().c_str());
135 
136  // Build triangulateio refined object
137  tetrahedralize(tetswitches, tetgen_input_pt, this->Tetgenio_pt);
138  // Build scaffold
139  this->Tmp_mesh_pt = new TetgenScaffoldMesh(*this->Tetgenio_pt);
140 
141  // Convert mesh from scaffold to actual mesh
142  this->build_from_scaffold(time_stepper_pt, use_attributes);
143 
144  // Kill the scaffold
145  delete this->Tmp_mesh_pt;
146  this->Tmp_mesh_pt = 0;
147 
148  // delete the input
149  delete tetgen_input_pt;
150 
151  // Store the boundary
152  this->Outer_boundary_pt = outer_boundary_pt;
153  // Setup the reverse lookup scheme
155  this->Outer_boundary_pt);
156  // Store the internal boundary
157  this->Internal_surface_pt = internal_surface_pt;
158  // Setup the reverse lookup schemes
159  {
160  unsigned n = this->Internal_surface_pt.size();
161  for (unsigned i = 0; i < n; i++)
162  {
164  this->Internal_surface_pt[i]);
165  }
166  }
167 
168  // Setup boundary coordinates for boundaries
169  unsigned nb = nboundary();
170  for (unsigned b = 0; b < nb; b++)
171  {
172  this->template setup_boundary_coordinates<ELEMENT>(b);
173  }
174 
175  // Now snap onto geometric objects associated with triangular facets
176  // (if any!)
177  this->snap_nodes_onto_geometric_objects();
178  }
179 
180 
181  public:
182  /// Empty Destructor
184 
185  /// Refine mesh uniformly and doc process
186  void refine_uniformly(DocInfo& doc_info)
187  {
188  // hierher do it
189  throw OomphLibError("refine_uniformly() not implemented yet",
190  OOMPH_CURRENT_FUNCTION,
191  OOMPH_EXCEPTION_LOCATION);
192  }
193 
194  /// Unrefine mesh uniformly: Return 0 for success,
195  /// 1 for failure (if unrefinement has reached the coarsest permitted
196  /// level)
198  {
199  // hierher do it
200  throw OomphLibError("unrefine_uniformly() not implemented yet",
201  OOMPH_CURRENT_FUNCTION,
202  OOMPH_EXCEPTION_LOCATION);
203  // dummy return
204  return 0;
205  }
206 
207  /// Adapt mesh, based on elemental error provided
208  void adapt(const Vector<double>& elem_error);
209 
210 
211  /// Is projection of old solution onto new mesh disabled?
213  {
214  return Projection_is_disabled;
215  }
216 
217  /// Disable projection of old solution onto new mesh
219  {
220  Projection_is_disabled = true;
221  }
222 
223  /// Disable projection of old solution onto new mesh
225  {
226  Projection_is_disabled = false;
227  }
228 
229 
230  protected:
231  /// Helper function to initialise data associated with adaptation
233  {
234  // Set max and min targets for adaptation
235  this->Max_element_size = 1.0;
236  this->Min_element_size = 0.001;
237  this->Max_permitted_edge_ratio = 2.0;
238 
239  /// By default we project solution onto new mesh during adaptation
240  Projection_is_disabled = false;
241  }
242 
243  // Update the surface
245  TetMeshFacetedSurface*& faceted_surface_pt);
246 
247  // Update the inner hole
249 
250  /// Snap the boundary nodes onto any curvilinear boundaries
252  const unsigned& b);
253 
254  /// Disable projection of solution onto new mesh during adaptation
256 
257  /// Corner elements which have all of their nodes on the outer
258  /// boundary are to be split into elements which have some non-boundary
259  /// nodes
261  };
262 
263  /// //////////////////////////////////////////////////////////////////////////
264  /// //////////////////////////////////////////////////////////////////////////
265  /// //////////////////////////////////////////////////////////////////////////
266 
267 
268  //=========================================================================
269  // Unstructured refineable Tetgen Mesh upgraded to solid mesh
270  //=========================================================================
271  template<class ELEMENT>
273  : public virtual RefineableTetgenMesh<ELEMENT>,
274  public virtual SolidMesh
275  {
276  public:
277  /// Build mesh, based on closed curve that specifies
278  /// the outer boundary of the domain and any number of internal
279  /// closed curves. Specify target area for uniform element size.
281  TetMeshFacetedClosedSurface* const& outer_boundary_pt,
282  Vector<TetMeshFacetedSurface*>& internal_closed_surface_pt,
283  const double& element_volume,
284  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
285  const bool& use_attributes = false,
286  const bool& split_corner_elements = false)
287  : TetgenMesh<ELEMENT>(outer_boundary_pt,
288  internal_closed_surface_pt,
289  element_volume,
290  time_stepper_pt,
291  use_attributes,
292  split_corner_elements),
293  RefineableTetgenMesh<ELEMENT>(outer_boundary_pt,
294  internal_closed_surface_pt,
295  element_volume,
296  time_stepper_pt,
297  use_attributes,
298  split_corner_elements)
299 
300  {
301  // Assign the Lagrangian coordinates
302  set_lagrangian_nodal_coordinates();
303  }
304 
305 
306  /// Build mesh from specified triangulation and
307  /// associated target areas for elements in it.
309  const Vector<double>& target_volume,
310  tetgenio* const& tetgen_io_pt,
311  TetMeshFacetedClosedSurface* const& outer_boundary_pt,
312  Vector<TetMeshFacetedSurface*>& internal_surface_pt,
313  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
314  const bool& use_attributes = false)
315  : RefineableTetgenMesh<ELEMENT>(target_volume,
316  tetgen_io_pt,
317  outer_boundary_pt,
318  internal_surface_pt,
319  time_stepper_pt,
320  use_attributes)
321 
322  {
323  // Assign the Lagrangian coordinates
324  set_lagrangian_nodal_coordinates();
325  }
326 
327  /// Empty Destructor
329  };
330 
331 
332 } // namespace oomph
333 
334 #endif
////////////////////////////////////////////////////////////////////////// //////////////////////////...
RefineableSolidTetgenMesh(const Vector< double > &target_volume, tetgenio *const &tetgen_io_pt, TetMeshFacetedClosedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_surface_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Build mesh from specified triangulation and associated target areas for elements in it.
RefineableSolidTetgenMesh(TetMeshFacetedClosedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_closed_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 closed curve that specifies the outer boundary of the domain and any number of i...
virtual ~RefineableSolidTetgenMesh()
Empty Destructor.
void surface_remesh_for_inner_hole_boundaries()
Generate a new faceted representation of the inner hole boundaries.
bool Projection_is_disabled
Disable projection of solution onto new mesh during adaptation.
bool projection_is_disabled()
Is projection of old solution onto new mesh disabled?
void update_faceted_surface_using_face_mesh(TetMeshFacetedSurface *&faceted_surface_pt)
Helper function that updates the input faceted surface by using the flattened elements from FaceMesh(...
void refine_uniformly(DocInfo &doc_info)
Refine mesh uniformly and doc process.
bool Corner_elements_must_be_split
Corner elements which have all of their nodes on the outer boundary are to be split into elements whi...
void initialise_adaptation_data()
Helper function to initialise data associated with adaptation.
void enable_projection()
Disable projection of old solution onto new mesh.
RefineableTetgenMesh(TetMeshFacetedClosedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_closed_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 TetMeshFacetedClosedSurface that specifies the outer boundary of the domain an...
virtual ~RefineableTetgenMesh()
Empty Destructor.
void snap_nodes_onto_boundary(RefineableTetgenMesh< ELEMENT > *&new_mesh_pt, const unsigned &b)
Snap the boundary nodes onto any curvilinear boundaries.
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.
unsigned unrefine_uniformly()
Unrefine mesh uniformly: Return 0 for success, 1 for failure (if unrefinement has reached the coarses...
RefineableTetgenMesh(const Vector< double > &target_volume, tetgenio *const &tetgen_io_pt, TetMeshFacetedClosedSurface *const &outer_boundary_pt, Vector< TetMeshFacetedSurface * > &internal_surface_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
Specialised constructor used during adaptation only. Element sizes are specified by vector tetgen_io ...
void disable_projection()
Disable projection of old solution onto new mesh.
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
tetgenio * Tetgenio_pt
Tetgen representation of mesh.
void setup_reverse_lookup_schemes_for_faceted_surface(TetMeshFacetedSurface *const &faceted_surface_pt)
Function to setup the reverse look-up schemes.
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 Tetgenio_exists
Boolean to indicate whether a tetgenio representation of the mesh exists.
TetgenScaffoldMesh * Tmp_mesh_pt
Temporary scaffold mesh.
////////////////////////////////////////////////////////////////////// //////////////////////////////...