refineable_tetgen_mesh.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-2025 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
31#ifdef HAVE_CONFIG_H
32#include <oomph-lib-config.h>
33#endif
34
36#include "generic/tet_mesh.h"
38#include "tetgen_mesh.h"
39
40namespace oomph
41{
42 //=========================================================================
43 // Unstructured refineable TetgenMesh
44 //=========================================================================
45 template<class ELEMENT>
46 class RefineableTetgenMesh : public virtual TetgenMesh<ELEMENT>,
47 public virtual RefineableTetMeshBase
48 {
49 public:
50 /// Build mesh, based on a TetMeshFacetedClosedSurface that specifies
51 /// the outer boundary of the domain and any number of internal
52 /// closed curves, specified by TetMeshFacetedSurfaces.
53 /// Also specify target volume for uniform element size.
55 TetMeshFacetedClosedSurface* const& outer_boundary_pt,
57 const double& element_volume,
58 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
59 const bool& use_attributes = false,
60 const bool& split_corner_elements = false,
62 : TetgenMesh<ELEMENT>(outer_boundary_pt,
64 element_volume,
65 time_stepper_pt,
70 {
71 // Initialise the data associated with adaptation
73 }
74
75
76 protected:
77 /// Specialised constructor used during adaptation only.
78 /// Element sizes are specified by vector tetgen_io is passed in
79 /// from previous mesh (is then modified to build new mesh)
80 /// Ditto with use_attributes, which comes from the previous mesh
83 tetgenio* const& tetgen_io_pt,
84 TetMeshFacetedClosedSurface* const& outer_boundary_pt,
85 Vector<TetMeshFacetedSurface*>& internal_surface_pt,
86 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
87 const bool& use_attributes = false)
88 {
89 // NOTE THERE IS A CERTAIN AMOUNT OF DUPLICATION BETWEEN THE
90 // CODE IN HERE AND THE ONE IN THE CONSTRUCTOR OF THE TetgenMesh
91 // BUT THE FACT THAT WE HAVE TO MODIFY THE TETGENIO STRUCTURE
92 // MEANS WE CAN'T QUITE RECYCLE THIS.
93
94 // Mesh can only be built with 3D Telements.
95 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
96
97 // Initialise the data associated with adaptation
99
100 // Store Timestepper used to build elements
101 this->Time_stepper_pt = time_stepper_pt;
102
103 // Triangulation has been created -- remember to wipe it!
104 this->Tetgenio_exists = true;
105 this->Tetgenio_pt = new tetgenio;
106
107 // Add the volume constraints to the tetgenio data object.
108 // Note that since the tetgenio structure is referred to by pointer
109 // we're also modifying the one associated with the (still existing)
110 // original mesh. Bit naughty but shouldn't cause any problems
111 // since that mesh is already built and about to go out of scope
112 // anyway.
113
114 // Create a local copy
116 ;
117 this->deep_copy_of_tetgenio(tetgen_io_pt, tetgen_input_pt);
118
119 // Add volume constraints
120 tetgen_input_pt->tetrahedronvolumelist =
121 new double[tetgen_input_pt->numberoftetrahedra];
122 for (int e = 0; e < tetgen_input_pt->numberoftetrahedra; ++e)
123 {
124 tetgen_input_pt->tetrahedronvolumelist[e] = target_volume[e];
125 }
126
127 // Input string
128 std::stringstream input_string_stream;
129 input_string_stream << "Vqra";
130
131 // Convert to a *char
132 char tetswitches[100];
134 sizeof(tetswitches),
135 "%s",
136 input_string_stream.str().c_str());
137
138 // Build triangulateio refined object
140
141 // Build scaffold
142 this->Tmp_mesh_pt = new TetgenScaffoldMesh(*this->Tetgenio_pt);
143
144 // Convert mesh from scaffold to actual mesh
145 this->build_from_scaffold(time_stepper_pt, use_attributes);
146
147 // Kill the scaffold
148 delete this->Tmp_mesh_pt;
149 this->Tmp_mesh_pt = 0;
150
151 // delete the input
152 delete tetgen_input_pt;
153
154 // Store the boundary
155 this->Outer_boundary_pt = outer_boundary_pt;
156
157 // Setup reverse lookup scheme
158 {
159 unsigned n_facet = this->Outer_boundary_pt->nfacet();
160 for (unsigned f = 0; f < n_facet; f++)
161 {
162 unsigned b = this->Outer_boundary_pt->one_based_facet_boundary_id(f);
163 if (b != 0)
164 {
166 this->Tet_mesh_facet_pt[b - 1] =
167 this->Outer_boundary_pt->facet_pt(f);
168 }
169 else
170 {
171 std::ostringstream error_message;
172 error_message << "Boundary IDs have to be one-based. Yours is " << b
173 << "\n";
174 throw OomphLibError(error_message.str(),
177 }
178 }
179 }
180
181 // Store the internal boundary
182 this->Internal_surface_pt = internal_surface_pt;
183
184 // Setup reverse lookup scheme
185 {
186 unsigned n = this->Internal_surface_pt.size();
187 for (unsigned i = 0; i < n; i++)
188 {
189 unsigned n_facet = this->Internal_surface_pt[i]->nfacet();
190 for (unsigned f = 0; f < n_facet; f++)
191 {
192 unsigned b =
193 this->Internal_surface_pt[i]->one_based_facet_boundary_id(f);
194 if (b != 0)
195 {
196 this->Tet_mesh_faceted_surface_pt[b - 1] =
197 this->Internal_surface_pt[i];
198 this->Tet_mesh_facet_pt[b - 1] =
199 this->Internal_surface_pt[i]->facet_pt(f);
200 }
201 else
202 {
203 std::ostringstream error_message;
204 error_message << "Boundary IDs have to be one-based. Yours is "
205 << b << "\n";
206 throw OomphLibError(error_message.str(),
209 }
210 }
211 }
212 }
213
214 // Setup boundary coordinates for boundaries
215 unsigned nb = nboundary();
216 for (unsigned b = 0; b < nb; b++)
217 {
218 this->template setup_boundary_coordinates<ELEMENT>(b);
219 }
220
221 // Now snap onto geometric objects associated with triangular facets
222 // (if any!)
224 }
225
226 public:
227 /// Empty Destructor
229
230 /// Refine mesh uniformly and doc process
232 {
233 // hierher do it
234 throw OomphLibError("refine_uniformly() not implemented yet",
237 }
238
239 /// Unrefine mesh uniformly: Return 0 for success,
240 /// 1 for failure (if unrefinement has reached the coarsest permitted
241 /// level)
243 {
244 // hierher do it
245 throw OomphLibError("unrefine_uniformly() not implemented yet",
248 // dummy return
249 return 0;
250 }
251
252 /// Adapt mesh, based on elemental error provided
253 void adapt(const Vector<double>& elem_error);
254
255 /// Is projection of old solution onto new mesh disabled?
257 {
259 }
260
261 /// Disable projection of old solution onto new mesh
263 {
265 }
266
267 /// Disable projection of old solution onto new mesh
269 {
271 }
272
273 protected:
274 /// Helper function to initialise data associated with adaptation
276 {
277 // Set max and min targets for adaptation
278 this->Max_element_size = 1.0;
279 this->Min_element_size = 0.001;
280 this->Max_permitted_edge_ratio = 2.0;
281
282 /// By default we project solution onto new mesh during adaptation
284 }
285
286 // Update the surface
289
290 // Update the inner hole
292
293 /// Snap the boundary nodes onto any curvilinear boundaries
295 const unsigned& b);
296
297 /// Disable projection of solution onto new mesh during adaptation
299
300 /// Corner elements which have all of their nodes on the outer
301 /// boundary are to be split into elements which have some non-boundary
302 /// nodes
304 };
305
306 /////////////////////////////////////////////////////////////////////////////
307 /////////////////////////////////////////////////////////////////////////////
308 /////////////////////////////////////////////////////////////////////////////
309
310
311 //=========================================================================
312 // Unstructured refineable Tetgen Mesh upgraded to solid mesh
313 //=========================================================================
314 template<class ELEMENT>
316 : public virtual RefineableTetgenMesh<ELEMENT>,
317 public virtual SolidMesh
318 {
319 public:
320 /// Build mesh, based on closed curve that specifies
321 /// the outer boundary of the domain and any number of internal
322 /// closed curves. Specify target area for uniform element size.
324 TetMeshFacetedClosedSurface* const& outer_boundary_pt,
326 const double& element_volume,
327 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
328 const bool& use_attributes = false,
329 const bool& split_corner_elements = false)
330 : TetgenMesh<ELEMENT>(outer_boundary_pt,
332 element_volume,
333 time_stepper_pt,
336 RefineableTetgenMesh<ELEMENT>(outer_boundary_pt,
338 element_volume,
339 time_stepper_pt,
342
343 {
344 // Assign the Lagrangian coordinates
345 set_lagrangian_nodal_coordinates();
346 }
347
348
349 /// Build mesh from specified triangulation and
350 /// associated target areas for elements in it.
353 tetgenio* const& tetgen_io_pt,
354 TetMeshFacetedClosedSurface* const& outer_boundary_pt,
355 Vector<TetMeshFacetedSurface*>& internal_surface_pt,
356 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper,
357 const bool& use_attributes = false)
360 outer_boundary_pt,
361 internal_surface_pt,
362 time_stepper_pt,
364
365 {
366 // Assign the Lagrangian coordinates
367 set_lagrangian_nodal_coordinates();
368 }
369
370 /// Empty Destructor
372 };
373
374
375} // namespace oomph
376
378#endif
e
Definition cfortran.h:571
cstr elem_len * i
Definition cfortran.h:603
Information for documentation of results: Directory and file number to enable output in the form RESL...
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors.
Definition mesh.h:75
unsigned nboundary() const
Return number of boundaries.
Definition mesh.h:835
An OomphLibError object which should be thrown when an run-time error is encountered....
DocInfo doc_info()
Access fct for DocInfo.
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.
Base class for refineable tet meshes.
double Max_element_size
Max permitted element size.
double Min_element_size
Min permitted element size.
double Max_permitted_edge_ratio
Max edge ratio before remesh gets triggered.
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.
General SolidMesh class.
Definition mesh.h:2570
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
void snap_nodes_onto_geometric_objects()
Move the nodes on boundaries with associated GeomObjects so that they exactly coincide with the geome...
Definition tet_mesh.cc:638
TimeStepper * Time_stepper_pt
Timestepper used to build nodes.
Definition tet_mesh.h:1254
std::map< unsigned, TetMeshFacetedSurface * > Tet_mesh_faceted_surface_pt
Reverse lookup scheme: Pointer to faceted surface (if any!) associated with boundary b.
Definition tet_mesh.h:1242
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Vector to faceted surfaces that define internal boundaries.
Definition tet_mesh.h:1238
std::map< unsigned, TetMeshFacet * > Tet_mesh_facet_pt
Reverse lookup scheme: Pointer to facet (if any!) associated with boundary b.
Definition tet_mesh.h:1246
TetMeshFacetedClosedSurface * Outer_boundary_pt
Faceted surface that defines outer boundaries.
Definition tet_mesh.h:1235
Base class for closed tet mesh boundary bounded by polygonal planar facets.
Definition tet_mesh.h:724
Base class for tet mesh boundary defined by polygonal planar facets.
Definition tet_mesh.h:306
TetMeshFacet * facet_pt(const unsigned &j) const
Pointer to j-th facet.
Definition tet_mesh.h:373
unsigned nfacet() const
Number of facets.
Definition tet_mesh.h:325
unsigned one_based_facet_boundary_id(const unsigned &j) const
One-based boundary id of j-th facet.
Definition tet_mesh.h:331
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
Definition tetgen_mesh.h:51
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
tetgenio * Tetgenio_pt
Tetgen representation of mesh.
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.
Mesh that is based on input files generated by the tetrahedra mesh generator tetgen.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).