7#include <libmesh/enum_elem_type.h>
8#include <libmesh/enum_fe_family.h>
9#include <libmesh/enum_order.h>
10#include <libmesh/fe_map.h>
11#include <libmesh/fe_type.h>
12#include <libmesh/parallel_implementation.h>
13#include <libmesh/remote_elem.h>
26typedef std::pair<unsigned int, unsigned int>
Entity;
31template <Order order, FEFamily family>
48 _mesh->complete_preparation();
93 const FEType fe_type(order, family);
96 unsigned int n_compared = 0;
98 for (
auto * elem :
_mesh->active_local_element_ptr_range())
100 QGauss qrule(elem->dim(), order);
102 const std::vector<Point> & points = qrule.
get_points();
105 std::map<Entity, std::map<unsigned int, std::vector<Real>>> seen;
108 for (
const auto p :
make_range(elem->n_permutations()))
113 unsigned int dof = 0;
115 for (
const auto n : elem->node_index_range())
123 shapes(fe_type, *elem, dof, n_dofs, points),
132 shapes(fe_type, *elem, dof, n_interior, points), n_compared);
137 _mesh->comm().sum(n_compared);
138 CPPUNIT_ASSERT(n_compared > 0);
145 const FEType fe_type(order, family);
153 unsigned int n_compared = 0;
159 for (
auto * elem :
_mesh->element_ptr_range())
160 elem->permute((round + elem->id()) % elem->n_permutations());
162 for (
const auto * elem :
_mesh->active_local_element_ptr_range())
164 std::vector<dof_id_type> dofs;
167 for (
const auto s :
make_range(elem->n_sides()))
173 std::vector<dof_id_type> neighbor_dofs;
176 std::unique_ptr<const Elem> side = elem->build_side_ptr(s);
177 QGauss side_rule(side->dim(), order);
178 side_rule.
init(*side);
180 for (
const auto & side_point : side_rule.
get_points())
182 const Point physical =
FEMap::map(side->dim(), side.get(), side_point);
188 const Point neighbor_point =
194 std::find(neighbor_dofs.begin(), neighbor_dofs.end(), dofs[i]);
195 if (it == neighbor_dofs.end())
198 const auto j = std::distance(neighbor_dofs.begin(), it);
200 LIBMESH_ASSERT_FP_EQUAL(
212 _mesh->comm().sum(n_compared);
213 CPPUNIT_ASSERT(n_compared > 0);
223 unsigned int rounds = 0;
224 for (
const auto * elem :
_mesh->element_ptr_range())
225 rounds = std::max(rounds, elem->n_permutations());
226 _mesh->comm().max(rounds);
233 const unsigned int first,
234 const unsigned int n_dofs,
235 const std::vector<Point> & points)
237 std::vector<Real> values;
239 for (
const auto & point : points)
247 void record(std::map<
unsigned int, std::vector<Real>> & seen,
248 const unsigned int orientation,
249 const std::vector<Real> & values,
250 unsigned int & n_compared)
252 const auto [entry, inserted] = seen.emplace(orientation, values);
256 CPPUNIT_ASSERT_EQUAL(entry->second.size(), values.size());
268template <ElemType elem_type, Order order, FEFamily family>
276 0., 1., 0., 1., 0., 1., elem_type);
286template <Order order, FEFamily family>
296 const std::vector<Point> points =
297 {{0,0,0}, {1,0,0}, {0,1,0}, {0,0,1}, {1,0,1}, {0,1,1},
298 {0,-1,0}, {1,-1,0}, {0,-1,1}, {1,-1,1},
304 const std::vector<std::pair<ElemType, std::vector<dof_id_type>>> elems =
305 {{
PRISM6, {0, 1, 2, 3, 4, 5}},
306 {
HEX8, {6, 7, 1, 0, 8, 9, 4, 3}},
307 {
PRISM6, {0, 10, 3, 2, 11, 5}},
308 {
TET4, {3, 4, 5, 12}}};
309 for (
const auto & [type, nodes] : elems)
321#define ORIENTATIONTEST \
322 CPPUNIT_TEST( test_orientation_determines_shapes ); \
323 CPPUNIT_TEST( test_conformity_across_sides )
325#define INSTANTIATE_FEORIENTATIONTEST(elemtype, order, family) \
326 class FEOrientationTest_##family##_##order##_##elemtype : \
327 public FEOrientationTest<elemtype, order, family> { \
329 FEOrientationTest_##family##_##order##_##elemtype() : \
330 FEOrientationTest<elemtype, order, family>() { \
331 if (unitlog->summarized_logs_enabled()) \
332 this->libmesh_suite_name = "FEOrientationTest"; \
334 this->libmesh_suite_name = \
335 "FEOrientationTest_" #family "_" #order "_" #elemtype; \
337 CPPUNIT_TEST_SUITE( FEOrientationTest_##family##_##order##_##elemtype ); \
339 CPPUNIT_TEST_SUITE_END(); \
342 CPPUNIT_TEST_SUITE_REGISTRATION( FEOrientationTest_##family##_##order##_##elemtype )
345#define INSTANTIATE_FECONFORMITYTEST(elemtype, order, family) \
346 class FEConformityTest_##family##_##order##_##elemtype : \
347 public FEOrientationTest<elemtype, order, family> { \
349 FEConformityTest_##family##_##order##_##elemtype() : \
350 FEOrientationTest<elemtype, order, family>() { \
351 if (unitlog->summarized_logs_enabled()) \
352 this->libmesh_suite_name = "FEConformityTest"; \
354 this->libmesh_suite_name = \
355 "FEConformityTest_" #family "_" #order "_" #elemtype; \
357 CPPUNIT_TEST_SUITE( FEConformityTest_##family##_##order##_##elemtype ); \
358 CPPUNIT_TEST( test_conformity_across_sides ); \
359 CPPUNIT_TEST_SUITE_END(); \
362 CPPUNIT_TEST_SUITE_REGISTRATION( FEConformityTest_##family##_##order##_##elemtype )
376#define INSTANTIATE_FEHYBRIDORIENTATIONTEST(order, family) \
377 class FEHybridOrientationTest_##family##_##order : \
378 public FEHybridOrientationTest<order, family> { \
380 FEHybridOrientationTest_##family##_##order() : \
381 FEHybridOrientationTest<order, family>() { \
382 if (unitlog->summarized_logs_enabled()) \
383 this->libmesh_suite_name = "FEHybridOrientationTest"; \
385 this->libmesh_suite_name = \
386 "FEHybridOrientationTest_" #family "_" #order; \
388 CPPUNIT_TEST_SUITE( FEHybridOrientationTest_##family##_##order ); \
390 CPPUNIT_TEST_SUITE_END(); \
393 CPPUNIT_TEST_SUITE_REGISTRATION( FEHybridOrientationTest_##family##_##order )
The orientation tests on a mesh mixing element types, where each pair of neighbors shares a face that...
void build_mesh() override
Builds the mesh the tests run on, before it is skewed.
The orientation tests, on a mesh that a subclass builds.
virtual void build_mesh()=0
Builds the mesh the tests run on, before it is skewed.
unsigned int entity_orientation(const Elem &elem, const Entity &entity)
The orientation index that the shape functions of entity follow.
static constexpr Real map_tolerance
The tolerance for inverse_map()
void test_conformity_across_sides()
std::unique_ptr< Mesh > _mesh
std::string libmesh_suite_name
Entity node_entity(const Elem &elem, const unsigned int n)
The entity of elem that owns the degrees of freedom sitting on node n.
void test_orientation_determines_shapes()
std::vector< Real > shapes(const FEType &fe_type, const Elem &elem, const unsigned int first, const unsigned int n_dofs, const std::vector< Point > &points)
The values of shape functions first through first + n_dofs - 1 at points.
void record(std::map< unsigned int, std::vector< Real > > &seen, const unsigned int orientation, const std::vector< Real > &values, unsigned int &n_compared)
Record values for orientation, or check them against those already recorded.
unsigned int n_rounds() const
Rounds of permutation, which vary the relative numbering of shared sides.
The orientation tests on a cube of elem_type elements.
void build_mesh() override
Builds the mesh the tests run on, before it is skewed.
This class handles the numbering of degrees of freedom on a mesh.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
This is the base class from which all geometric element types are derived.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
virtual Node *& set_node(const unsigned int i)
bool positive_edge_orientation(const unsigned int i) const
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual bool is_face(const unsigned int i) const =0
virtual unsigned short dim() const =0
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...
virtual bool is_edge(const unsigned int i) const =0
virtual unsigned int n_faces() const =0
virtual bool is_vertex(const unsigned int i) const =0
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
virtual unsigned int n_edges() const =0
const Elem * neighbor_ptr(unsigned int i) const
unsigned int face_orientation(const unsigned int i) const
This is the EquationSystems class.
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
static Point map(const unsigned int dim, const Elem *elem, const Point &reference_point)
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
virtual const Node * node_ptr(const dof_id_type i) const =0
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.
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 void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
A Point defines a location in LIBMESH_DIM dimensional Real space.
const std::vector< Point > & get_points() const
virtual void init(const Elem &e, unsigned int p_level=invalid_uint)
Initializes the data structures for a quadrature rule for the element e.
This class implements specific orders of Gauss quadrature.
Manages consistently variables, degrees of freedom, and coefficient vectors.
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
const DofMap & get_dof_map() const
Communicator * TestCommWorld
INSTANTIATE_FEORIENTATIONTEST(TRI6, THIRD, HIERARCHIC)
INSTANTIATE_FEHYBRIDORIENTATIONTEST(THIRD, HIERARCHIC)
EntityKind
The entity of an element that owns a degree of freedom, as a kind and an index within that kind.
std::pair< unsigned int, unsigned int > Entity
INSTANTIATE_FECONFORMITYTEST(HEX27, THIRD, SIDE_HIERARCHIC)
The libMesh namespace provides an interface to certain functionality in the library.
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 RemoteElem * remote_elem
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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...