2 #include <libmesh/cell_c0polyhedron.h> 3 #include <libmesh/elem.h> 4 #include <libmesh/enum_elem_type.h> 5 #include <libmesh/face_c0polygon.h> 6 #include <libmesh/mesh_generation.h> 7 #include <libmesh/mesh_modification.h> 8 #include <libmesh/mesh.h> 9 #include <libmesh/reference_elem.h> 10 #include <libmesh/replicated_mesh.h> 11 #include <libmesh/node.h> 12 #include <libmesh/enum_to_string.h> 13 #include <libmesh/tensor_value.h> 14 #include <libmesh/enum_elem_quality.h> 15 #include <libmesh/fe_base.h> 16 #include <libmesh/quadrature_gauss.h> 32 CPPUNIT_TEST( testEdge2 );
33 CPPUNIT_TEST( testEdge3 );
34 CPPUNIT_TEST( testTris );
35 CPPUNIT_TEST( testQuads );
36 CPPUNIT_TEST( testTets );
37 CPPUNIT_TEST( testPyramids );
38 CPPUNIT_TEST( testPrisms );
39 CPPUNIT_TEST( testHexes );
40 CPPUNIT_TEST( testC0Polygon );
41 CPPUNIT_TEST( testC0Polyhedron );
42 #ifdef LIBMESH_ENABLE_AMR 43 CPPUNIT_TEST( testEdge3PRefine );
44 #endif // LIBMESH_ENABLE_AMR 45 CPPUNIT_TEST_SUITE_END();
74 std::vector<Point> pts = {
Point(1, 0, 0),
Point(1, 3, 0)};
75 auto [edge2, nodes] = this->construct_elem(pts,
EDGE2);
76 const Point n1 = edge2->side_vertex_average_normal(0);
78 const Point n2 = edge2->side_vertex_average_normal(1);
98 std::vector<Point> pts = {
Point(1, 0, 0),
Point(1, 3, 0),
Point(2.2344, 1.210293, 0)};
99 auto [edge3, nodes] = this->construct_elem(pts,
EDGE3);
102 const std::vector<Point> & normals = fe->get_normals();
103 for (
const auto s :
make_range(edge3->n_sides()))
105 const std::unique_ptr<const Elem> face = edge3->build_side_ptr(s);
106 fe->attach_quadrature_rule(&qface);
108 const Point n1 = edge3->side_vertex_average_normal(s);
115 #ifdef LIBMESH_ENABLE_AMR 122 std::vector<Point> pts = {
Point(0, 1, 0),
Point(0, 2, 0),
Point(0, 1.5, 0)};
123 auto [edge3, nodes] = this->construct_elem(pts,
EDGE3);
124 edge3->set_p_level(1);
125 const Point n1 = edge3->side_vertex_average_normal(0);
127 const Point n2 = edge3->side_vertex_average_normal(1);
131 #endif // LIBMESH_ENABLE_AMR 143 for (
const Elem * tri : tris)
145 const Point n1 = tri->side_vertex_average_normal(0);
147 const Point n2 = tri->side_vertex_average_normal(1);
149 const Point n3 = tri->side_vertex_average_normal(2);
155 std::vector<Point> pts = {
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 3, 1)};
156 auto [tri3, nodes] = this->construct_elem(pts,
TRI3);
157 const Point n1 = tri3->side_vertex_average_normal(0);
159 const Point n2 = tri3->side_vertex_average_normal(1);
161 const Point n3 = tri3->side_vertex_average_normal(2);
162 LIBMESH_ASSERT_REALVEC_EQUAL((-3*unit_x-2*unit_y+3*unit_z).unit(), n3,
TOLERANCE*
TOLERANCE);
175 for (
const Elem * quad : quads)
177 const Point n1 = quad->side_vertex_average_normal(0);
179 const Point n2 = quad->side_vertex_average_normal(1);
181 const Point n3 = quad->side_vertex_average_normal(2);
183 const Point n4 = quad->side_vertex_average_normal(3);
189 std::vector<Point> pts = {
Point(1, 0, 0),
Point(1, 3, 0),
Point(-1, -1, 0),
Point(0, -1, 0)};
190 auto [quad4, nodes] = this->construct_elem(pts,
QUAD4);
191 const Point n1 = quad4->side_vertex_average_normal(0);
193 const Point n2 = quad4->side_vertex_average_normal(1);
195 const Point n3 = quad4->side_vertex_average_normal(2);
197 const Point n4 = quad4->side_vertex_average_normal(3);
203 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 1),
Point(1, 1, 0),
Point(0, 1, 1)};
204 auto [quad4, nodes] = this->construct_elem(pts,
QUAD4);
205 const Point n1 = quad4->side_vertex_average_normal(0);
207 const Point n2 = quad4->side_vertex_average_normal(1);
209 const Point n3 = quad4->side_vertex_average_normal(2);
211 const Point n4 = quad4->side_vertex_average_normal(3);
217 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, -2, 3),
Point(1, 1, 0),
Point(0, 2, -10.5)};
218 auto [quad4, nodes] = this->construct_elem(pts,
QUAD4);
219 for (
const auto s :
make_range(quad4->n_sides()))
221 const Point n1 = quad4->side_vertex_average_normal(s);
222 const Point normal = quad4->Elem::side_vertex_average_normal(s);
238 for (
const Elem * tet : tets)
240 const Point n1 = tet->side_vertex_average_normal(0);
242 const Point n2 = tet->side_vertex_average_normal(1);
244 const Point n3 = tet->side_vertex_average_normal(2);
246 const Point n4 = tet->side_vertex_average_normal(3);
261 for (
const Elem * pyr : pyrs)
263 const Point n1 = pyr->side_vertex_average_normal(0);
265 const Point n2 = pyr->side_vertex_average_normal(1);
267 const Point n3 = pyr->side_vertex_average_normal(2);
269 const Point n4 = pyr->side_vertex_average_normal(3);
271 const Point n5 = pyr->side_vertex_average_normal(4);
287 for (
const Elem * pri : pris)
289 const Point n1 = pri->side_vertex_average_normal(0);
291 const Point n2 = pri->side_vertex_average_normal(1);
293 const Point n3 = pri->side_vertex_average_normal(2);
295 const Point n4 = pri->side_vertex_average_normal(3);
297 const Point n5 = pri->side_vertex_average_normal(4);
310 for (
const Elem * hex : hexes)
312 const Point n1 = hex->side_vertex_average_normal(0);
314 const Point n2 = hex->side_vertex_average_normal(1);
316 const Point n3 = hex->side_vertex_average_normal(2);
318 const Point n4 = hex->side_vertex_average_normal(3);
320 const Point n5 = hex->side_vertex_average_normal(4);
322 const Point n6 = hex->side_vertex_average_normal(5);
328 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 3),
Point(1, 1, 0),
Point(0, 2, 1),
329 Point(-2.2, 0, 4),
Point(-1, 0, 5),
Point(-0.5, 1, 4),
Point(-2.2, 2, 6)};
330 auto [hex8, nodes] = this->construct_elem(pts,
HEX8);
333 const std::vector<Point> & normals = fe->get_normals();
334 for (
const auto s :
make_range(hex8->n_sides()))
336 const std::unique_ptr<const Elem> face = hex8->build_side_ptr(s);
337 fe->attach_quadrature_rule(&qface);
339 const Point n1 = hex8->side_vertex_average_normal(s);
350 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0)};
351 auto [square, nodes] = this->construct_elem(pts,
C0POLYGON);
352 const Point n1 = square->side_vertex_average_normal(0);
354 const Point n2 = square->side_vertex_average_normal(1);
356 const Point n3 = square->side_vertex_average_normal(2);
358 const Point n4 = square->side_vertex_average_normal(3);
363 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 0),
Point(1.5, 1, 0),
Point(1, 2, 0),
Point(0, 2, 0) ,
Point(-0.5, 1, 0)};
364 auto [hexagon, nodes] = this->construct_elem(pts,
C0POLYGON);
365 const Point n1 = hexagon->side_vertex_average_normal(0);
367 const Point n2 = hexagon->side_vertex_average_normal(1);
369 const Point n3 = hexagon->side_vertex_average_normal(2);
371 const Point n4 = hexagon->side_vertex_average_normal(3);
373 const Point n5 = hexagon->side_vertex_average_normal(4);
375 const Point n6 = hexagon->side_vertex_average_normal(5);
381 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 3),
Point(1, 1, 0),
Point(0, 2, 1)};
382 auto [poly4, nodes] = this->construct_elem(pts,
C0POLYGON);
384 auto [quad4, nodes2] = this->construct_elem(pts,
QUAD4);
385 const std::unique_ptr<const Elem> face = quad4->build_side_ptr(0);
388 fe->attach_quadrature_rule(&qface);
389 const std::vector<Point> & normals = fe->get_normals();
390 for (
const auto s :
make_range(quad4->n_sides()))
392 const std::unique_ptr<const Elem> face = quad4->build_side_ptr(s);
393 fe->attach_quadrature_rule(&qface);
395 const Point n1 = quad4->side_vertex_average_normal(s);
406 std::vector<Point> points = {
Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
407 Point(0, 0, 1),
Point(1, 0, 1),
Point(1, 1, 1),
Point(0, 1, 1)};
410 const std::vector<std::vector<unsigned int>> nodes_on_side =
421 std::vector<std::unique_ptr<Node>> nodes(points.size());
426 std::vector<std::shared_ptr<Polygon>> sides(nodes_on_side.size());
430 const auto & nodes_on_s = nodes_on_side[s];
431 sides[s] = std::make_shared<C0Polygon>(nodes_on_s.size());
433 sides[s]->set_node(i, nodes[nodes_on_s[i]].
get());
436 std::unique_ptr<libMesh::Node> mid_elem_node;
437 std::unique_ptr<Elem> polyhedron = std::make_unique<C0Polyhedron>(sides, mid_elem_node);
438 const Point n1 = polyhedron->side_vertex_average_normal(0);
440 const Point n2 = polyhedron->side_vertex_average_normal(1);
442 const Point n3 = polyhedron->side_vertex_average_normal(2);
444 const Point n4 = polyhedron->side_vertex_average_normal(3);
446 const Point n5 = polyhedron->side_vertex_average_normal(4);
448 const Point n6 = polyhedron->side_vertex_average_normal(5);
454 std::vector<Point> pts = {
Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
455 Point(0, 0, 4),
Point(1, 0, 4),
Point(1, 1, 5),
Point(0, 1, 5)};
458 const std::vector<std::vector<unsigned int>> nodes_on_side =
467 std::vector<std::unique_ptr<Node>> nodes(pts.size());
472 std::vector<std::shared_ptr<Polygon>> sides(nodes_on_side.size());
476 const auto & nodes_on_s = nodes_on_side[s];
477 sides[s] = std::make_shared<C0Polygon>(nodes_on_s.size());
479 sides[s]->set_node(i, nodes[nodes_on_s[i]].
get());
482 std::unique_ptr<libMesh::Node> mid_elem_node;
483 std::unique_ptr<Elem> polyhedron = std::make_unique<C0Polyhedron>(sides, mid_elem_node);
486 auto [hex8, nodes2] = this->construct_elem(pts,
HEX8);
487 for (
const auto s :
make_range(hex8->n_sides()))
489 const Point n1 = polyhedron->side_vertex_average_normal(s);
490 const Point normal = hex8->Elem::side_vertex_average_normal(s);
502 std::pair<std::unique_ptr<Elem>, std::vector<std::unique_ptr<Node>>>
506 const unsigned int n_points = pts.size();
509 std::vector<std::unique_ptr<Node>> nodes(n_points);
510 for (
unsigned int i=0; i<n_points; i++)
514 std::unique_ptr<Elem> elem;
518 elem = std::make_unique<C0Polygon>(n_points);
521 libmesh_error_msg_if(elem->n_nodes() != n_points,
522 "Wrong number of points " 524 <<
" provided to build a " 527 for (
unsigned int i=0; i<n_points; i++)
528 elem->set_node(i, nodes[i].get());
531 return std::make_pair(std::move(elem), std::move(nodes));
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
ElemType
Defines an enum for geometric element types.
static constexpr Real TOLERANCE
This is the base class from which all geometric element types are derived.
CPPUNIT_TEST_SUITE_REGISTRATION(SideVertexAverageNormalTest)
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
std::pair< std::unique_ptr< Elem >, std::vector< std::unique_ptr< Node > > > construct_elem(const std::vector< Point > &pts, ElemType elem_type)
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
virtual Point side_vertex_average_normal(const unsigned int s) const
std::string enum_to_string(const T e)
static std::unique_ptr< Node > build(const Node &n)
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...
This class implements specific orders of Gauss quadrature.
A Point defines a location in LIBMESH_DIM dimensional Real space.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
const Elem & get(const ElemType type_in)