libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | List of all members
AllRBBTest Class Reference
Inheritance diagram for AllRBBTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (AllRBBTest)
 The goal of this test is to verify proper operation of the all_rbb() mesh modification, by converting meshes of classic "isogeometric" types from Lagrange interpolants to Rational Bezier-Bernstein splines, then verifying that the converted geometry is exact to within floating-point error (for point radii) or quadrature error (for element volume).
 
 CPPUNIT_TEST (testAllRBBNodeElem)
 
 CPPUNIT_TEST (testAllRBBEdge)
 
 CPPUNIT_TEST (testAllRBBEdge3)
 
 CPPUNIT_TEST (testAllRBBTri)
 
 CPPUNIT_TEST (testAllRBBTri6)
 
 CPPUNIT_TEST (testAllRBBQuad)
 
 CPPUNIT_TEST (testAllRBBQuad8)
 
 CPPUNIT_TEST (testAllRBBQuad9)
 
 CPPUNIT_TEST (testAllRBBCircle4)
 
 CPPUNIT_TEST (testAllRBBCircle8)
 
 CPPUNIT_TEST (testAllRBBCircle16)
 
 CPPUNIT_TEST (testAllRBBDisk5)
 
 CPPUNIT_TEST (testAllRBBDisk20)
 
 CPPUNIT_TEST (testAllRBBDisk80)
 
 CPPUNIT_TEST (testAllRBBTri6Disk10)
 
 CPPUNIT_TEST (testAllRBBTri6Disk40)
 
 CPPUNIT_TEST (testAllRBBTri6Disk160)
 
 CPPUNIT_TEST (testAllRBBTet)
 
 CPPUNIT_TEST (testAllRBBTet10)
 
 CPPUNIT_TEST (testAllRBBHex)
 
 CPPUNIT_TEST (testAllRBBHex20)
 
 CPPUNIT_TEST (testAllRBBHex27)
 
 CPPUNIT_TEST (testAllRBBCylinder10)
 
 CPPUNIT_TEST (testAllRBBCylinder80)
 
 CPPUNIT_TEST (testAllRBBSphere6)
 
 CPPUNIT_TEST (testAllRBBSphere24)
 
 CPPUNIT_TEST (testAllRBBSphere96)
 
 CPPUNIT_TEST (testAllRBBTri6Sphere12)
 
 CPPUNIT_TEST (testAllRBBTri6Sphere48)
 
 CPPUNIT_TEST (testAllRBBTri6Sphere192)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testAllRBBNodeElem ()
 
void testAllRBBEdge ()
 
void testAllRBBEdge3 ()
 
void testAllRBBTri ()
 
void testAllRBBTri6 ()
 
void testAllRBBQuad ()
 
void testAllRBBQuad8 ()
 
void testAllRBBQuad9 ()
 
void testAllRBBTet ()
 
void testAllRBBTet10 ()
 
void testAllRBBHex ()
 
void testAllRBBHex20 ()
 
void testAllRBBHex27 ()
 
void testAllRBBCircle4 ()
 
void testAllRBBCircle8 ()
 
void testAllRBBCircle16 ()
 
void testAllRBBDisk5 ()
 
void testAllRBBDisk20 ()
 
void testAllRBBDisk80 ()
 
void testAllRBBTri6Disk10 ()
 
void testAllRBBTri6Disk40 ()
 
void testAllRBBTri6Disk160 ()
 
void testAllRBBCylinder10 ()
 
void testAllRBBCylinder80 ()
 
void testAllRBBSphere6 ()
 
void testAllRBBSphere24 ()
 
void testAllRBBSphere96 ()
 
void testAllRBBTri6Sphere12 ()
 
void testAllRBBTri6Sphere48 ()
 
void testAllRBBTri6Sphere192 ()
 

Protected Member Functions

void test_box (ElemType elem_type)
 
void test_circle (unsigned int n_refinements)
 
void test_disk (unsigned int n_refinements, const ElemType type=QUAD9)
 
void test_cylinder (unsigned int n_refinements, const ElemType type=HEX27)
 
void test_sphere (unsigned int n_refinements, const ElemType type=QUAD9)
 

Detailed Description

Definition at line 17 of file all_rbb.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBCircle16  )

◆ CPPUNIT_TEST() [2/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBCircle4  )

◆ CPPUNIT_TEST() [3/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBCircle8  )

◆ CPPUNIT_TEST() [4/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBCylinder10  )

◆ CPPUNIT_TEST() [5/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBCylinder80  )

◆ CPPUNIT_TEST() [6/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBDisk20  )

◆ CPPUNIT_TEST() [7/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBDisk5  )

◆ CPPUNIT_TEST() [8/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBDisk80  )

◆ CPPUNIT_TEST() [9/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBEdge  )

◆ CPPUNIT_TEST() [10/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBEdge3  )

◆ CPPUNIT_TEST() [11/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBHex  )

◆ CPPUNIT_TEST() [12/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBHex20  )

◆ CPPUNIT_TEST() [13/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBHex27  )

◆ CPPUNIT_TEST() [14/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBNodeElem  )

◆ CPPUNIT_TEST() [15/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBQuad  )

◆ CPPUNIT_TEST() [16/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBQuad8  )

◆ CPPUNIT_TEST() [17/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBQuad9  )

◆ CPPUNIT_TEST() [18/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBSphere24  )

◆ CPPUNIT_TEST() [19/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBSphere6  )

◆ CPPUNIT_TEST() [20/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBSphere96  )

◆ CPPUNIT_TEST() [21/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTet  )

◆ CPPUNIT_TEST() [22/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTet10  )

◆ CPPUNIT_TEST() [23/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri  )

◆ CPPUNIT_TEST() [24/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6  )

◆ CPPUNIT_TEST() [25/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Disk10  )

◆ CPPUNIT_TEST() [26/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Disk160  )

◆ CPPUNIT_TEST() [27/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Disk40  )

◆ CPPUNIT_TEST() [28/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Sphere12  )

◆ CPPUNIT_TEST() [29/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Sphere192  )

◆ CPPUNIT_TEST() [30/30]

AllRBBTest::CPPUNIT_TEST ( testAllRBBTri6Sphere48  )

◆ CPPUNIT_TEST_SUITE_END()

AllRBBTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

AllRBBTest::LIBMESH_CPPUNIT_TEST_SUITE ( AllRBBTest  )

The goal of this test is to verify proper operation of the all_rbb() mesh modification, by converting meshes of classic "isogeometric" types from Lagrange interpolants to Rational Bezier-Bernstein splines, then verifying that the converted geometry is exact to within floating-point error (for point radii) or quadrature error (for element volume).

◆ setUp()

void AllRBBTest::setUp ( )
inline

Definition at line 518 of file all_rbb.C.

518{}

◆ tearDown()

void AllRBBTest::tearDown ( )
inline

Definition at line 520 of file all_rbb.C.

520{}

◆ test_box()

void AllRBBTest::test_box ( ElemType  elem_type)
inlineprotected

Definition at line 91 of file all_rbb.C.

92 {
93 Mesh mesh(*TestCommWorld);
94
95 auto dim = Elem::type_to_dim_map[elem_type];
96
98 dim > 0 ? 2 : 0, dim > 1 ? 1 : 0, dim > 2 ? 1 : 0,
99 0., 1.,
100 0., 1.,
101 0., 1.,
102 elem_type);
103
104 const auto n_orig_elem = mesh.n_elem();
105 CPPUNIT_ASSERT_EQUAL(n_orig_elem, mesh.max_elem_id());
106
107 const Real orig_volume = MeshTools::volume(mesh) / n_orig_elem;
108
109 std::vector<Real> orig_hmin(n_orig_elem), orig_hmax(n_orig_elem);
110
111 // In the tet case our elements all have the same volume but
112 // they're stretched differently and have different hmin/hmax
113 for (auto & elem : mesh.element_ptr_range())
114 {
115 orig_hmin[elem->id()] = elem->hmin();
116 orig_hmax[elem->id()] = elem->hmax();
117 }
118
120
121 CPPUNIT_ASSERT_EQUAL(n_orig_elem, mesh.n_elem());
122 CPPUNIT_ASSERT_EQUAL(n_orig_elem, mesh.max_elem_id());
123
124 unsigned char weight_index = mesh.default_mapping_data();
125
126 for (auto & elem : mesh.element_ptr_range())
127 {
128 CPPUNIT_ASSERT_EQUAL(elem->mapping_type(),
130 CPPUNIT_ASSERT(elem->has_affine_map());
131
132 // Tri6 has this much FP error??
133 LIBMESH_ASSERT_FP_EQUAL(elem->volume(), orig_volume,
135 LIBMESH_ASSERT_FP_EQUAL(elem->hmax(), orig_hmax[elem->id()],
137 LIBMESH_ASSERT_FP_EQUAL(elem->hmin(), orig_hmin[elem->id()],
139 }
140
141 for (auto & node : mesh.node_ptr_range())
142 {
143 const Real w = node->get_extra_datum<Real>(weight_index);
144
145 CPPUNIT_ASSERT_EQUAL(Real(1), w);
146 }
147 }
unsigned int dim
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
Definition elem.h:628
virtual dof_id_type n_elem() const =0
virtual dof_id_type max_elem_id() const =0
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
Definition mesh_base.h:959
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
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.
void all_rbb(MeshBase &mesh)
Converts all element geometric mappings from the default Lagrange to the more flexible Rational-Bezie...
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...
@ RATIONAL_BERNSTEIN_MAP
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::MeshTools::Modification::all_rbb(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshBase::default_mapping_data(), dim, libMesh::MeshBase::max_elem_id(), mesh, libMesh::MeshBase::n_elem(), libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, TestCommWorld, libMesh::TOLERANCE, libMesh::Elem::type_to_dim_map, and libMesh::MeshTools::volume().

Referenced by testAllRBBEdge(), testAllRBBEdge3(), testAllRBBHex(), testAllRBBHex20(), testAllRBBHex27(), testAllRBBNodeElem(), testAllRBBQuad(), testAllRBBQuad8(), testAllRBBQuad9(), testAllRBBTet(), testAllRBBTet10(), testAllRBBTri(), and testAllRBBTri6().

◆ test_circle()

void AllRBBTest::test_circle ( unsigned int  n_refinements)
inlineprotected

Definition at line 149 of file all_rbb.C.

150 {
151 Mesh interior_mesh(*TestCommWorld),
152 boundary_mesh(*TestCommWorld);
153
154 const Real radius = 1;
155 const Real circumference = 2 * pi * radius;
156 const Real tol = TOLERANCE*TOLERANCE;
157
158 // Build a filled circle
160 n_refinements, QUAD9);
161
162 // Get just the outer EDGE3 circle mesh
163 interior_mesh.get_boundary_info().sync(boundary_mesh);
164
165 const dof_id_type n_edges = 4 << n_refinements;
166
167 CPPUNIT_ASSERT_EQUAL(boundary_mesh.n_elem(), n_edges);
168 CPPUNIT_ASSERT_EQUAL(boundary_mesh.n_nodes(), n_edges*2);
169
170 for (auto & node : boundary_mesh.node_ptr_range())
171 {
172 const Point p = *node;
173 LIBMESH_ASSERT_FP_EQUAL(p.norm(), radius, tol);
174 }
175
176 // We just did Lagrange interpolation, so our mesh measure
177 // shouldn't be *quite* right. Empirically, we converge from
178 // beneath, and our error looks like Ch^4.
179 const Real max_lagrange_error =
180 radius * 5e-2 / (1 << (4*n_refinements));
181 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(boundary_mesh),
182 circumference, max_lagrange_error);
183
185
186 for (auto & elem : boundary_mesh.element_ptr_range())
187 {
188 CPPUNIT_ASSERT_EQUAL(RATIONAL_BERNSTEIN_MAP, elem->mapping_type());
189
190 // We can no longer assert that each Node is at a specified
191 // radius from the circle center, because these are now spline
192 // control nodes, but we can assert that physical points
193 // within the element are at the desired radius.
194 constexpr int n_intervals = 4;
195 Point master_pt;
196 for (master_pt(0) = -1; master_pt(0) <= 1 + TOLERANCE;
197 master_pt(0) += Real(2)/n_intervals)
198 {
199 const Point p = FEMap::map(elem->dim(), elem, master_pt);
200 LIBMESH_ASSERT_FP_EQUAL(radius, p.norm(), tol);
201 }
202 }
203
204 // We're using quadrature for volume approximation, so we still
205 // have error, but our quadrature error looks something like Ch^6
206 // with a much smaller C.
207 const Real max_rbb_error =
208 radius * 1e-3 / (1 << (6*n_refinements));
209 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(boundary_mesh),
210 circumference, max_rbb_error);
211 }
static Point map(const unsigned int dim, const Elem *elem, const Point &reference_point)
Definition fe_map.C:1954
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
auto norm() const
void build_sphere(UnstructuredMesh &mesh, const Real radius=1, const unsigned int n_refinements=2, const ElemType type=INVALID_ELEM, const unsigned int n_smooth=2, const bool flat=true)
Fills mesh with a mesh discretizing a ball (||x||<= radius) or sphere (||x|| = radius) domain.
const Real pi
.
Definition libmesh.h:292
uint8_t dof_id_type
Definition id_types.h:67
const Real radius

References libMesh::MeshTools::Modification::all_rbb(), libMesh::MeshTools::Generation::build_sphere(), libMesh::FEMap::map(), libMesh::DistributedMesh::n_elem(), libMesh::DistributedMesh::n_nodes(), libMesh::TypeVector< T >::norm(), libMesh::pi, libMesh::QUAD9, radius, libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, TestCommWorld, libMesh::TOLERANCE, and libMesh::MeshTools::volume().

Referenced by testAllRBBCircle16(), testAllRBBCircle4(), and testAllRBBCircle8().

◆ test_cylinder()

void AllRBBTest::test_cylinder ( unsigned int  n_refinements,
const ElemType  type = HEX27 
)
inlineprotected

Definition at line 278 of file all_rbb.C.

279 {
280 Mesh disk_mesh(*TestCommWorld), mesh(*TestCommWorld);
281
282 const Real radius = 1;
283 const Real height = 3;
284 const Real volume = pi * radius * radius * height;
285 const Real tol = TOLERANCE*TOLERANCE;
286
287 // We're extruding a circle from side 0 up
288 const ElemType side_type = Elem::build(type)->side_type(0);
289
290 // Build a filled circle
292 n_refinements, side_type);
293
294 // Then extrude it into a cylinder
295 const unsigned int nz = 2;
296 const RealVectorValue extrusion_vector{0,0,height};
297 MeshTools::Generation::build_extrusion (mesh, disk_mesh, nz, extrusion_vector);
298
299 const dof_id_type n_elem =
300 (5 << (n_refinements*2)) * (side_type == QUAD9 ? 1 : 2) * nz;
301
302 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), n_elem);
303
304 // We just did Lagrange interpolation, so our mesh measure
305 // shouldn't be *quite* right, but we should converge similarly to
306 // how we did with the filled disk.
307 const Real max_lagrange_error =
308 radius * 5e-2 / (1 << (4*n_refinements)) *
309 radius * radius * height;
310
311 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
312 volume, max_lagrange_error);
313
315
316 std::unique_ptr<const Elem> elem_side;
317 constexpr int n_intervals = 4;
318 auto qrule = QBase::build(QGRID, /*dim=*/2, Order(n_intervals));
319
320 for (const Elem * elem : mesh.element_ptr_range())
321 {
322 CPPUNIT_ASSERT_EQUAL(RATIONAL_BERNSTEIN_MAP, elem->mapping_type());
323
324 // We cannot assert that each Node is at a specified radius
325 // from the cylinder axis, because these are now spline
326 // control nodes, but we can assert that physical points
327 // within the rounded surface are at the desired radius.
328 for (auto s : make_range(elem->n_sides()))
329 {
330 if (elem->neighbor_ptr(s))
331 continue;
332
333 const Point side_normal =
334 elem->side_vertex_average_normal(s);
335
336 // We ought to either be on the rounded surface or the end
337 // caps
338 if (std::abs(side_normal(2)) > TOLERANCE*TOLERANCE)
339 {
340 LIBMESH_ASSERT_FP_EQUAL(side_normal(0), 0, TOLERANCE*TOLERANCE);
341 LIBMESH_ASSERT_FP_EQUAL(side_normal(1), 0, TOLERANCE*TOLERANCE);
342 continue;
343 }
344
345 elem->build_side_ptr(elem_side, s);
346 qrule->init(*elem_side);
347
348 for (auto i : make_range(qrule->n_points()))
349 {
350 Point p = FEMap::map(elem_side->dim(), elem_side.get(), qrule->qp(i));
351 p(2) = 0; // Just look at r in cylindrical coordinates
352 LIBMESH_ASSERT_FP_EQUAL(radius, p.norm(), tol);
353 }
354 }
355 }
356
357 // We're using quadrature for volume approximation, so we still
358 // have error, but our quadrature error looks like Ch^6 with a
359 // much smaller C.
360 const Real max_rbb_error =
361 radius * 2e-3 / (1 << (6*n_refinements)) *
362 radius * radius * height;
363 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
364 volume, max_rbb_error);
365 }
This is the base class from which all geometric element types are derived.
Definition elem.h:96
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
static std::unique_ptr< QBase > build(std::string_view name, const unsigned int dim, const Order order=INVALID_ORDER)
Builds a specific quadrature rule based on the name string.
void build_extrusion(UnstructuredMesh &mesh, const MeshBase &cross_section, const unsigned int nz, RealVectorValue extrusion_vector, QueryElemSubdomainIDBase *elem_subdomain=nullptr)
Meshes the tensor product of a 1D and a 1D-or-2D domain.
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).
ElemType
Defines an enum for geometric element types.
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176

References libMesh::MeshTools::Modification::all_rbb(), libMesh::Elem::build(), libMesh::QBase::build(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::MeshTools::Generation::build_sphere(), libMesh::make_range(), libMesh::FEMap::map(), mesh, libMesh::MeshBase::n_elem(), libMesh::TypeVector< T >::norm(), libMesh::pi, libMesh::QGRID, libMesh::QUAD9, radius, libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, TestCommWorld, libMesh::TOLERANCE, and libMesh::MeshTools::volume().

Referenced by testAllRBBCylinder10(), and testAllRBBCylinder80().

◆ test_disk()

void AllRBBTest::test_disk ( unsigned int  n_refinements,
const ElemType  type = QUAD9 
)
inlineprotected

Definition at line 213 of file all_rbb.C.

214 {
215 Mesh mesh(*TestCommWorld);
216
217 const Real radius = 1;
218 const Real area = pi * radius * radius;
219 const Real tol = TOLERANCE*TOLERANCE;
220
221 // Build a filled circle
223 n_refinements, type);
224
225 const dof_id_type n_elem =
226 (5 << (n_refinements*2)) * (type == QUAD9 ? 1 : 2);
227
228 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), n_elem);
229
230 // We just did Lagrange interpolation, so our mesh measure
231 // shouldn't be *quite* right. Empirically, we converge from
232 // beneath, and our error looks like Ch^4.
233 const Real max_lagrange_error =
234 radius * 5e-2 / (1 << (4*n_refinements));
235
236 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
237 area, max_lagrange_error);
238
240
241 for (const Elem * elem : mesh.element_ptr_range())
242 {
243 CPPUNIT_ASSERT_EQUAL(RATIONAL_BERNSTEIN_MAP, elem->mapping_type());
244
245 // We can no longer assert that each Node is at a specified
246 // radius from the circle center, because these are now spline
247 // control nodes, but we can assert that physical points
248 // within the element are at the desired radius.
249 for (auto s : make_range(elem->n_sides()))
250 {
251 if (elem->neighbor_ptr(s))
252 continue;
253
254 constexpr int n_intervals = 4;
255 Point master_pt = elem->master_point(s);
256 const Point step =
257 (elem->master_point((s+1)%elem->n_sides()) - master_pt)
258 / n_intervals;
259 for (auto i : make_range(n_intervals+1))
260 {
262 const Point p = FEMap::map(elem->dim(), elem, master_pt);
263 LIBMESH_ASSERT_FP_EQUAL(radius, p.norm(), tol);
264 master_pt += step;
265 }
266 }
267 }
268
269 // We're using quadrature for volume approximation, so we still
270 // have error, but our quadrature error looks like Ch^6 with a
271 // much smaller C.
272 const Real max_rbb_error =
273 radius * 2e-3 / (1 << (6*n_refinements));
274 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
275 area, max_rbb_error);
276 }
void libmesh_ignore(const Args &...)

References libMesh::MeshTools::Modification::all_rbb(), libMesh::MeshTools::Generation::build_sphere(), libMesh::libmesh_ignore(), libMesh::make_range(), libMesh::FEMap::map(), mesh, libMesh::MeshBase::n_elem(), libMesh::TypeVector< T >::norm(), libMesh::pi, libMesh::QUAD9, radius, libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, TestCommWorld, libMesh::TOLERANCE, and libMesh::MeshTools::volume().

Referenced by testAllRBBDisk20(), testAllRBBDisk5(), testAllRBBDisk80(), testAllRBBTri6Disk10(), testAllRBBTri6Disk160(), and testAllRBBTri6Disk40().

◆ test_sphere()

void AllRBBTest::test_sphere ( unsigned int  n_refinements,
const ElemType  type = QUAD9 
)
inlineprotected

Definition at line 367 of file all_rbb.C.

368 {
369 Mesh interior_mesh(*TestCommWorld),
370 boundary_mesh(*TestCommWorld);
371
372 const Real radius = 1;
373 const Real surface_area = 4 * pi * radius * radius;
374 const Real tol = TOLERANCE*TOLERANCE;
375
376 // Build a filled sphere. We're going to avoid using the `flat`
377 // direct 2D option here because that only currently supports
378 // TRI3.
380 n_refinements, HEX27);
381
382 // Get just the outer QUAD9 sphere mesh
383 interior_mesh.get_boundary_info().sync(boundary_mesh);
384
385 const dof_id_type n_faces = 6 << (2*n_refinements);
386
387 CPPUNIT_ASSERT_EQUAL(boundary_mesh.n_elem(), n_faces);
388
389 auto check_radii = [&boundary_mesh, radius, type](Real radius_tol) {
390 constexpr int n_intervals = 4;
391
392 Real max_radius_error = 0;
393 for (auto & elem : boundary_mesh.element_ptr_range())
394 {
395 // We can't necessarily assert that each Node is at a
396 // specified radius from the circle center, because these
397 // may be spline control nodes. We want physical points
398 // within an element to all be at the desired radius, but on
399 // rational quadratics that's only possible for "latitude /
400 // longitude" quad edges, so we need a non-trivial tolerance
401 // here.
402 Point master_pt;
403 if (type == TRI6)
404 {
405 for (master_pt(0) = 0; master_pt(0) <= 1 + TOLERANCE;
406 master_pt(0) += Real(1)/n_intervals)
407 {
408 for (master_pt(1) = 0; master_pt(1) <= 1 - master_pt(0) + TOLERANCE;
409 master_pt(1) += Real(1)/n_intervals)
410 {
411 const Point p = FEMap::map(elem->dim(), elem, master_pt);
412 max_radius_error = std::max(max_radius_error, std::abs(radius-p.norm()));
413 }
414 }
415 }
416 else
417 {
418 libmesh_assert_equal_to(type, QUAD9);
419 for (master_pt(0) = -1; master_pt(0) <= 1 + TOLERANCE;
420 master_pt(0) += Real(2)/n_intervals)
421 {
422 for (master_pt(1) = -1; master_pt(1) <= 1 + TOLERANCE;
423 master_pt(1) += Real(2)/n_intervals)
424 {
425 const Point p = FEMap::map(elem->dim(), elem, master_pt);
426 max_radius_error = std::max(max_radius_error, std::abs(radius-p.norm()));
427 }
428 }
429 }
430 LIBMESH_ASSERT_FP_EQUAL(max_radius_error, 0, radius_tol);
431 }
432 };
433
434 auto verify_equispaced_midnodes = [&boundary_mesh, type]()
435 {
436 std::unique_ptr<Elem> side_ptr;
437 for (auto & elem : boundary_mesh.element_ptr_range())
438 {
439 // We expect midnodes to be and to remain equispaced on
440 // quad edges. But our QUAD9 elements can be curved
441 // trapezoids, so we don't expect "diagonal" edges to have
442 // an equispaced mid-face node.
443 if (type != TRI6)
444 for (auto s : elem->side_index_range())
445 {
446 elem->build_side_ptr(side_ptr, s);
447
448 auto c02 = side_ptr->point(2) - side_ptr->point(0);
449 auto c12 = side_ptr->point(2) - side_ptr->point(1);
450 LIBMESH_ASSERT_FP_EQUAL
451 (c02.norm_sq(), c12.norm_sq(), TOLERANCE*TOLERANCE);
452 }
453 }
454 };
455
456 verify_equispaced_midnodes();
457
458 if (type == TRI6)
459 {
461 verify_equispaced_midnodes();
462 }
463 else
464 libmesh_assert_equal_to(type, QUAD9);
465
466 // For our sphere construction, all of our Lagrange nodes should
467 // be at exactly the right radius.
468 for (auto & node : boundary_mesh.node_ptr_range())
469 {
470 const Point p = *node;
471 LIBMESH_ASSERT_FP_EQUAL(p.norm(), radius, tol);
472 }
473
474 // But Lagrange isn't isogeometric, so non-nodes should have
475 // radius error. Empirically, our error looks like Ch^3
476 const Real max_lagrange_rad_error =
477 radius * 0.2 / (1 << (3*n_refinements));
478 check_radii(max_lagrange_rad_error);
479
480 // We just did Lagrange interpolation, so our mesh measure
481 // shouldn't be *quite* right. Empirically, we converge from
482 // beneath, and our error looks like Ch^4.
483 const Real max_lagrange_vol_error =
484 radius * radius * 1.5 / (1 << (4*n_refinements));
485 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(boundary_mesh),
486 surface_area, max_lagrange_vol_error);
487
489
490 // All of our vertices should still be at exactly the right
491 // radius; for these the control point is the point.
492 for (auto & elem : boundary_mesh.element_ptr_range())
493 {
494 CPPUNIT_ASSERT_EQUAL(RATIONAL_BERNSTEIN_MAP, elem->mapping_type());
495
496 for (auto v : make_range(elem->n_vertices()))
497 {
498 const Point & p = elem->point(v);
499 LIBMESH_ASSERT_FP_EQUAL(p.norm(), radius, tol);
500 }
501 }
502
503 // We're not building a stereographic mesh on the sphere, so we
504 // still have error ... of only slightly better magnitude?
505 const Real max_rbb_rad_error =
506 radius * 0.2 / (1 << (3*n_refinements));
507 check_radii(max_rbb_rad_error);
508
509 // And we also get about the same order on volume():
510 const Real max_rbb_vol_error =
511 radius * radius * 1.5 / (1 << (4*n_refinements));
512 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(boundary_mesh),
513 surface_area, max_rbb_vol_error);
514 }
void all_tri(MeshBase &mesh)
Subdivides any non-simplex elements in a Mesh to produce simplex (triangular in 2D,...

References libMesh::MeshTools::Modification::all_rbb(), libMesh::MeshTools::Modification::all_tri(), libMesh::MeshTools::Generation::build_sphere(), libMesh::HEX27, libMesh::make_range(), libMesh::FEMap::map(), libMesh::DistributedMesh::n_elem(), libMesh::TypeVector< T >::norm(), libMesh::pi, libMesh::QUAD9, radius, libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, TestCommWorld, libMesh::TOLERANCE, libMesh::TRI6, and libMesh::MeshTools::volume().

Referenced by testAllRBBSphere24(), testAllRBBSphere6(), testAllRBBSphere96(), testAllRBBTri6Sphere12(), testAllRBBTri6Sphere192(), and testAllRBBTri6Sphere48().

◆ testAllRBBCircle16()

void AllRBBTest::testAllRBBCircle16 ( )
inline

Definition at line 546 of file all_rbb.C.

546{ LOG_UNIT_TEST; test_circle(2); }
void test_circle(unsigned int n_refinements)
Definition all_rbb.C:149

References test_circle().

◆ testAllRBBCircle4()

void AllRBBTest::testAllRBBCircle4 ( )
inline

Definition at line 544 of file all_rbb.C.

544{ LOG_UNIT_TEST; test_circle(0); }

References test_circle().

◆ testAllRBBCircle8()

void AllRBBTest::testAllRBBCircle8 ( )
inline

Definition at line 545 of file all_rbb.C.

545{ LOG_UNIT_TEST; test_circle(1); }

References test_circle().

◆ testAllRBBCylinder10()

void AllRBBTest::testAllRBBCylinder10 ( )
inline

Definition at line 560 of file all_rbb.C.

560{ LOG_UNIT_TEST; test_cylinder(0); }
void test_cylinder(unsigned int n_refinements, const ElemType type=HEX27)
Definition all_rbb.C:278

References test_cylinder().

◆ testAllRBBCylinder80()

void AllRBBTest::testAllRBBCylinder80 ( )
inline

Definition at line 561 of file all_rbb.C.

561{ LOG_UNIT_TEST; test_cylinder(1); }

References test_cylinder().

◆ testAllRBBDisk20()

void AllRBBTest::testAllRBBDisk20 ( )
inline

Definition at line 551 of file all_rbb.C.

551{ LOG_UNIT_TEST; test_disk(1); }
void test_disk(unsigned int n_refinements, const ElemType type=QUAD9)
Definition all_rbb.C:213

References test_disk().

◆ testAllRBBDisk5()

void AllRBBTest::testAllRBBDisk5 ( )
inline

Definition at line 550 of file all_rbb.C.

550{ LOG_UNIT_TEST; test_disk(0); }

References test_disk().

◆ testAllRBBDisk80()

void AllRBBTest::testAllRBBDisk80 ( )
inline

Definition at line 552 of file all_rbb.C.

552{ LOG_UNIT_TEST; test_disk(2); }

References test_disk().

◆ testAllRBBEdge()

void AllRBBTest::testAllRBBEdge ( )
inline

Definition at line 523 of file all_rbb.C.

523{ LOG_UNIT_TEST; test_box(EDGE2); }
void test_box(ElemType elem_type)
Definition all_rbb.C:91

References libMesh::EDGE2, and test_box().

◆ testAllRBBEdge3()

void AllRBBTest::testAllRBBEdge3 ( )
inline

Definition at line 524 of file all_rbb.C.

524{ LOG_UNIT_TEST; test_box(EDGE3); }

References libMesh::EDGE3, and test_box().

◆ testAllRBBHex()

void AllRBBTest::testAllRBBHex ( )
inline

Definition at line 532 of file all_rbb.C.

532{ LOG_UNIT_TEST; test_box(HEX8); }

References libMesh::HEX8, and test_box().

◆ testAllRBBHex20()

void AllRBBTest::testAllRBBHex20 ( )
inline

Definition at line 533 of file all_rbb.C.

533{ LOG_UNIT_TEST; test_box(HEX20); }

References libMesh::HEX20, and test_box().

◆ testAllRBBHex27()

void AllRBBTest::testAllRBBHex27 ( )
inline

Definition at line 534 of file all_rbb.C.

534{ LOG_UNIT_TEST; test_box(HEX27); }

References libMesh::HEX27, and test_box().

◆ testAllRBBNodeElem()

void AllRBBTest::testAllRBBNodeElem ( )
inline

Definition at line 522 of file all_rbb.C.

522{ LOG_UNIT_TEST; test_box(NODEELEM); }

References libMesh::NODEELEM, and test_box().

◆ testAllRBBQuad()

void AllRBBTest::testAllRBBQuad ( )
inline

Definition at line 527 of file all_rbb.C.

527{ LOG_UNIT_TEST; test_box(QUAD4); }

References libMesh::QUAD4, and test_box().

◆ testAllRBBQuad8()

void AllRBBTest::testAllRBBQuad8 ( )
inline

Definition at line 528 of file all_rbb.C.

528{ LOG_UNIT_TEST; test_box(QUAD8); }

References libMesh::QUAD8, and test_box().

◆ testAllRBBQuad9()

void AllRBBTest::testAllRBBQuad9 ( )
inline

Definition at line 529 of file all_rbb.C.

529{ LOG_UNIT_TEST; test_box(QUAD9); }

References libMesh::QUAD9, and test_box().

◆ testAllRBBSphere24()

void AllRBBTest::testAllRBBSphere24 ( )
inline

Definition at line 566 of file all_rbb.C.

566{ LOG_UNIT_TEST; test_sphere(1); }
void test_sphere(unsigned int n_refinements, const ElemType type=QUAD9)
Definition all_rbb.C:367

References test_sphere().

◆ testAllRBBSphere6()

void AllRBBTest::testAllRBBSphere6 ( )
inline

Definition at line 565 of file all_rbb.C.

565{ LOG_UNIT_TEST; test_sphere(0); }

References test_sphere().

◆ testAllRBBSphere96()

void AllRBBTest::testAllRBBSphere96 ( )
inline

Definition at line 567 of file all_rbb.C.

567{ LOG_UNIT_TEST; test_sphere(2); }

References test_sphere().

◆ testAllRBBTet()

void AllRBBTest::testAllRBBTet ( )
inline

Definition at line 530 of file all_rbb.C.

530{ LOG_UNIT_TEST; test_box(TET4); }

References test_box(), and libMesh::TET4.

◆ testAllRBBTet10()

void AllRBBTest::testAllRBBTet10 ( )
inline

Definition at line 531 of file all_rbb.C.

531{ LOG_UNIT_TEST; test_box(TET10); }

References test_box(), and libMesh::TET10.

◆ testAllRBBTri()

void AllRBBTest::testAllRBBTri ( )
inline

Definition at line 525 of file all_rbb.C.

525{ LOG_UNIT_TEST; test_box(TRI3); }

References test_box(), and libMesh::TRI3.

◆ testAllRBBTri6()

void AllRBBTest::testAllRBBTri6 ( )
inline

Definition at line 526 of file all_rbb.C.

526{ LOG_UNIT_TEST; test_box(TRI6); }

References test_box(), and libMesh::TRI6.

◆ testAllRBBTri6Disk10()

void AllRBBTest::testAllRBBTri6Disk10 ( )
inline

Definition at line 554 of file all_rbb.C.

554{ LOG_UNIT_TEST; test_disk(0, TRI6); }

References test_disk(), and libMesh::TRI6.

◆ testAllRBBTri6Disk160()

void AllRBBTest::testAllRBBTri6Disk160 ( )
inline

Definition at line 556 of file all_rbb.C.

556{ LOG_UNIT_TEST; test_disk(2, TRI6); }

References test_disk(), and libMesh::TRI6.

◆ testAllRBBTri6Disk40()

void AllRBBTest::testAllRBBTri6Disk40 ( )
inline

Definition at line 555 of file all_rbb.C.

555{ LOG_UNIT_TEST; test_disk(1, TRI6); }

References test_disk(), and libMesh::TRI6.

◆ testAllRBBTri6Sphere12()

void AllRBBTest::testAllRBBTri6Sphere12 ( )
inline

Definition at line 569 of file all_rbb.C.

569{ LOG_UNIT_TEST; test_sphere(0, TRI6); }

References test_sphere(), and libMesh::TRI6.

◆ testAllRBBTri6Sphere192()

void AllRBBTest::testAllRBBTri6Sphere192 ( )
inline

Definition at line 571 of file all_rbb.C.

571{ LOG_UNIT_TEST; test_sphere(2, TRI6); }

References test_sphere(), and libMesh::TRI6.

◆ testAllRBBTri6Sphere48()

void AllRBBTest::testAllRBBTri6Sphere48 ( )
inline

Definition at line 570 of file all_rbb.C.

570{ LOG_UNIT_TEST; test_sphere(1, TRI6); }

References test_sphere(), and libMesh::TRI6.


The documentation for this class was generated from the following file: