libMesh
Loading...
Searching...
No Matches
Functions
miscellaneous_ex6.C File Reference

Go to the source code of this file.

Functions

void triangulate_domain (const Parallel::Communicator &comm)
 
void tetrahedralize_domain (const Parallel::Communicator &comm)
 
void add_cube_convex_hull_to_mesh (MeshBase &mesh, Point lower_limit, Point upper_limit)
 
int main (int argc, char **argv)
 

Function Documentation

◆ add_cube_convex_hull_to_mesh()

void add_cube_convex_hull_to_mesh ( MeshBase mesh,
Point  lower_limit,
Point  upper_limit 
)

Definition at line 255 of file miscellaneous_ex6.C.

258{
259#ifdef LIBMESH_HAVE_TETGEN
260 ReplicatedMesh cube_mesh(mesh.comm(), 3);
261
262 unsigned n_elem = 1;
263
265 n_elem, n_elem, n_elem, // n. elements in each direction
266 lower_limit(0), upper_limit(0),
267 lower_limit(1), upper_limit(1),
268 lower_limit(2), upper_limit(2),
269 HEX8);
270
271 // The pointset_convexhull() algorithm will ignore the Hex8s
272 // in the Mesh, and just construct the triangulation
273 // of the convex hull.
274 TetGenMeshInterface t(cube_mesh);
275 t.pointset_convexhull();
276
277 // Now add all nodes from the boundary of the cube_mesh to the input mesh.
278
279 // Map from "node id in cube_mesh" -> "node id in mesh". Initially inserted
280 // with a dummy value, later to be assigned a value by the input mesh.
281 std::map<unsigned, unsigned> node_id_map;
282 typedef std::map<unsigned, unsigned>::iterator iterator;
283
284 for (auto & elem : cube_mesh.element_ptr_range())
285 for (auto s : elem->side_index_range())
286 if (elem->neighbor_ptr(s) == nullptr)
287 {
288 // Add the node IDs of this side to the set
289 std::unique_ptr<Elem> side = elem->side_ptr(s);
290
291 for (auto n : side->node_index_range())
292 node_id_map.emplace(side->node_id(n), /*dummy_value=*/0);
293 }
294
295 // For each node in the map, insert it into the input mesh and keep
296 // track of the ID assigned.
297 for (iterator it=node_id_map.begin(); it != node_id_map.end(); ++it)
298 {
299 // Id of the node in the cube mesh
300 unsigned id = (*it).first;
301
302 // Pointer to node in the cube mesh
303 Node & old_node = cube_mesh.node_ref(id);
304
305 // Add geometric point to input mesh
306 Node * new_node = mesh.add_point (old_node);
307
308 // Track ID value of new_node in map
309 (*it).second = new_node->id();
310 }
311
312 // With the points added and the map data structure in place, we are
313 // ready to add each TRI3 element of the cube_mesh to the input Mesh
314 // with proper node assignments
315 for (auto & old_elem : cube_mesh.element_ptr_range())
316 if (old_elem->type() == TRI3)
317 {
318 Elem * new_elem = mesh.add_elem(Elem::build(TRI3));
319
320 // Assign nodes in new elements. Since this is an example,
321 // we'll do it in several steps.
322 for (auto i : old_elem->node_index_range())
323 {
324 // Mapping to node ID in input mesh
325 unsigned int new_node_id = libmesh_map_find(node_id_map, old_elem->node_id(i));
326
327 // Node pointer assigned from input mesh
328 new_elem->set_node(i, mesh.node_ptr(new_node_id));
329 }
330 }
331#else
332 // Avoid compiler warnings
333 libmesh_ignore(mesh, lower_limit, upper_limit);
334#endif // LIBMESH_HAVE_TETGEN
335}
dof_id_type id() const
Definition dof_object.h:819
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
A Node is like a Point, but with more information.
Definition node.h:55
const Parallel::Communicator & comm() const
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Class TetGenMeshInterface provides an interface for tetrahedralization of meshes using the TetGen lib...
MeshBase & mesh
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).
void libmesh_ignore(const Args &...)

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::Elem::build(), libMesh::MeshTools::Generation::build_cube(), libMesh::ParallelObject::comm(), libMesh::HEX8, libMesh::DofObject::id(), libMesh::libmesh_ignore(), mesh, libMesh::MeshBase::node_ptr(), libMesh::MeshBase::node_ref(), libMesh::TetGenMeshInterface::pointset_convexhull(), libMesh::Elem::set_node(), and libMesh::TRI3.

Referenced by tetrahedralize_domain().

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 55 of file miscellaneous_ex6.C.

56{
57 // Initialize libMesh and any dependent libraries, like in example 2.
58 LibMeshInit init (argc, argv);
59
60 libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
61
62 libMesh::out << "Triangulating an L-shaped domain with holes" << std::endl;
63
64 // 1.) 2D triangulation of L-shaped domain with three holes of different shape
66
67 libmesh_example_requires(3 <= LIBMESH_DIM, "3D support");
68
69 libMesh::out << "Tetrahedralizing a prismatic domain with a hole" << std::endl;
70
71 // 2.) 3D tetrahedralization of rectangular domain with hole.
73
74 return 0;
75}
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
void triangulate_domain(const Parallel::Communicator &comm)
void tetrahedralize_domain(const Parallel::Communicator &comm)
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
OStreamProxy out

References main(), libMesh::out, tetrahedralize_domain(), and triangulate_domain().

◆ tetrahedralize_domain()

void tetrahedralize_domain ( const Parallel::Communicator comm)

Definition at line 171 of file miscellaneous_ex6.C.

172{
173#ifdef LIBMESH_HAVE_TETGEN
174 // The algorithm is broken up into several steps:
175 // 1.) A convex hull is constructed for a rectangular hole.
176 // 2.) A convex hull is constructed for the domain exterior.
177 // 3.) Neighbor information is updated so TetGen knows there is a convex hull
178 // 4.) A vector of hole points is created.
179 // 5.) The domain is tetrahedralized, the mesh is written out, etc.
180
181 // The mesh we will eventually generate
182 ReplicatedMesh mesh(comm, 3);
183
184 // Lower and Upper bounding box limits for a rectangular hole within the unit cube.
185 Point hole_lower_limit(0.2, 0.2, 0.4);
186 Point hole_upper_limit(0.8, 0.8, 0.6);
187
188 // 1.) Construct a convex hull for the hole
189 add_cube_convex_hull_to_mesh(mesh, hole_lower_limit, hole_upper_limit);
190
191 // 2.) Generate elements comprising the outer boundary of the domain.
193 Point(0., 0., 0.),
194 Point(1., 1., 1.));
195
196 // 3.) Update neighbor information so that TetGen can verify there is a convex hull.
198
199 // 4.) Set up vector of hole points
200 std::vector<Point> hole(1);
201 hole[0] = Point(0.5*(hole_lower_limit + hole_upper_limit));
202
203 // 5.) Set parameters and tetrahedralize the domain
204
205 // 0 means "use TetGen default value"
206 double quality_constraint = 2.0;
207
208 // The volume constraint determines the max-allowed tetrahedral
209 // volume in the Mesh. TetGen will split cells which are larger than
210 // this size
211 double volume_constraint = 0.001;
212
213 // Construct the Delaunay tetrahedralization
215
216 // In debug mode, set the tetgen switches
217 // -V (verbose) and
218 // -CC (check consistency and constrained Delaunay)
219 // In optimized mode, only switch Q (quiet) is set.
220 // For more options, see tetgen website:
221 // (http://wias-berlin.de/software/tetgen/1.5/doc/manual/manual005.html#cmd-m)
222#ifdef DEBUG
223 t.set_switches("VCC");
224#endif
225 t.triangulate_conformingDelaunayMesh_carvehole(hole,
226 quality_constraint,
227 volume_constraint);
228
229 // Find neighbors, etc in preparation for writing out the Mesh
231
232 // Finally, write out the result
233#ifdef LIBMESH_HAVE_EXODUS_API
234 mesh.write("hole_3D.e");
235#endif
236
237#else
238 // Avoid compiler warnings
239 libmesh_ignore(comm);
240#endif // LIBMESH_HAVE_TETGEN
241}
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
Definition mesh_base.C:824
virtual void write(const std::string &name) const =0
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0
Locate element face (edge in 2D) neighbors.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
void add_cube_convex_hull_to_mesh(MeshBase &mesh, Point lower_limit, Point upper_limit)

References add_cube_convex_hull_to_mesh(), libMesh::MeshBase::find_neighbors(), libMesh::libmesh_ignore(), mesh, libMesh::MeshBase::prepare_for_use(), libMesh::TetGenMeshInterface::set_switches(), libMesh::TetGenMeshInterface::triangulate_conformingDelaunayMesh_carvehole(), and libMesh::MeshBase::write().

Referenced by main().

◆ triangulate_domain()

void triangulate_domain ( const Parallel::Communicator comm)

Definition at line 80 of file miscellaneous_ex6.C.

81{
82#ifdef LIBMESH_HAVE_TRIANGLE
83 // Use typedefs for slightly less typing.
84 typedef TriangleInterface::Hole Hole;
85 typedef TriangleInterface::PolygonHole PolygonHole;
86 typedef TriangleInterface::ArbitraryHole ArbitraryHole;
87
88 // Libmesh mesh that will eventually be created.
89 Mesh mesh(comm, 2);
90
91 // The points which make up the L-shape:
92 mesh.add_point(Point(0., 0.));
93 mesh.add_point(Point(0., -1.));
94 mesh.add_point(Point(-1., -1.));
95 mesh.add_point(Point(-1., 1.));
96 mesh.add_point(Point(1., 1.));
97 mesh.add_point(Point(1., 0.));
98
99 // Declare the TriangleInterface object. This is where
100 // we can set parameters of the triangulation and where the
101 // actual triangulate function lives.
103
104 // Customize the variables for the triangulation
105 t.desired_area() = .01;
106
107 // A Planar Straight Line Graph (PSLG) is essentially a list
108 // of segments which have to exist in the final triangulation.
109 // For an L-shaped domain, Triangle will compute the convex
110 // hull of boundary points if we do not specify the PSLG.
111 // The PSLG algorithm is also required for triangulating domains
112 // containing holes
113 t.triangulation_type() = TriangleInterface::PSLG;
114
115 // Turn on/off Laplacian mesh smoothing after generation.
116 // By default this is on.
117 t.smooth_after_generating() = true;
118
119 // Define holes...
120
121 // hole_1 is a circle (discretized by 50 points)
122 PolygonHole hole_1(Point(-0.5, 0.5), // center
123 0.25, // radius
124 50); // n. points
125
126 // hole_2 is itself a triangle
127 PolygonHole hole_2(Point(0.5, 0.5), // center
128 0.1, // radius
129 3); // n. points
130
131 // hole_3 is an ellipse of 100 points which we define here
132 Point ellipse_center(-0.5, -0.5);
133 const unsigned int n_ellipse_points=100;
134 std::vector<Point> ellipse_points(n_ellipse_points);
135 const Real
136 dtheta = 2*libMesh::pi / static_cast<Real>(n_ellipse_points),
137 a = .1,
138 b = .2;
139
140 for (unsigned int i=0; i<n_ellipse_points; ++i)
141 ellipse_points[i]= Point(ellipse_center(0)+a*cos(i*dtheta),
142 ellipse_center(1)+b*sin(i*dtheta));
143
144 ArbitraryHole hole_3(ellipse_center, ellipse_points);
145
146 // Create the vector of Hole*'s ...
147 std::vector<Hole *> holes;
148 holes.push_back(&hole_1);
149 holes.push_back(&hole_2);
150 holes.push_back(&hole_3);
151
152 // ... and attach it to the triangulator object
153 t.attach_hole_list(&holes);
154
155 // Triangulate!
156 t.triangulate();
157
158#ifdef LIBMESH_HAVE_EXODUS_API
159 // Write the result to file
160 mesh.write("delaunay_l_shaped_hole.e");
161#endif
162
163#else
164 // Avoid compiler warnings
165 libmesh_ignore(comm);
166#endif // LIBMESH_HAVE_TRIANGLE
167}
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
A C++ interface between LibMesh and the Triangle library written by J.R.
static const Real b
const Real pi
.
Definition libmesh.h:292
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::MeshBase::add_point(), libMesh::TriangulatorInterface::attach_hole_list(), b, libMesh::TriangulatorInterface::desired_area(), libMesh::libmesh_ignore(), mesh, libMesh::pi, libMesh::Real, libMesh::TriangulatorInterface::smooth_after_generating(), libMesh::TriangleInterface::triangulate(), libMesh::TriangulatorInterface::triangulation_type(), and libMesh::MeshBase::write().

Referenced by main().