Skip to content

More static maps #4164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions include/geom/elem.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,15 @@ class Elem : public ReferenceCountedObject<Elem>,
*/
virtual ElemType type () const = 0;

/**
* This array maps the integer representation of the \p ElemType enum
* to the geometric dimension of the element.
*
* This is currently usable even for complicated subclasses with
* runtime-varying topology.
*/
static const unsigned int type_to_dim_map[INVALID_ELEM];

/**
* \returns The dimensionality of the object.
*/
Expand Down Expand Up @@ -964,8 +973,17 @@ class Elem : public ReferenceCountedObject<Elem>,
void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;

/**
* \returns The default approximation order for this element type.
* This is the order that will be used to compute the map to the
* This array maps the integer representation of the \p ElemType enum
* to the default approximation order of elements of that type.
*
* This is currently usable even for complicated subclasses with
* runtime-varying topology.
*/
static const Order type_to_default_order_map[INVALID_ELEM];

/**
* \returns The default approximation order for this element. This
* is the order that will be used to compute the map to the
* reference element.
*/
virtual Order default_order () const = 0;
Expand Down
120 changes: 120 additions & 0 deletions src/geom/elem.C
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,66 @@ Threads::spin_mutex parent_bracketing_nodes_mutex;
const subdomain_id_type Elem::invalid_subdomain_id = std::numeric_limits<subdomain_id_type>::max();

// Initialize static member variables
const unsigned int Elem::type_to_dim_map [] =
{
1, // EDGE2
1, // EDGE3
1, // EDGE4

2, // TRI3
2, // TRI6

2, // QUAD4
2, // QUAD8
2, // QUAD9

3, // TET4
3, // TET10

3, // HEX8
3, // HEX20
3, // HEX27

3, // PRISM6
3, // PRISM15
3, // PRISM18

3, // PYRAMID5
3, // PYRAMID13
3, // PYRAMID14

1, // INFEDGE2

2, // INFQUAD4
2, // INFQUAD6

3, // INFHEX8
3, // INFHEX16
3, // INFHEX18

3, // INFPRISM6
3, // INFPRISM12

0, // NODEELEM

0, // REMOTEELEM

2, // TRI3SUBDIVISION
2, // TRISHELL3
2, // QUADSHELL4
2, // QUADSHELL8

2, // TRI7
3, // TET14
3, // PRISM20
3, // PRISM21
3, // PYRAMID18

2, // QUADSHELL9

2, // C0POLYGON
};

const unsigned int Elem::max_n_nodes;

const unsigned int Elem::type_to_n_nodes_map [] =
Expand Down Expand Up @@ -282,6 +342,66 @@ const unsigned int Elem::type_to_n_edges_map [] =
invalid_uint, // C0POLYGON
};

const Order Elem::type_to_default_order_map [] =
{
FIRST, // EDGE2
SECOND, // EDGE3
THIRD, // EDGE4

FIRST, // TRI3
SECOND, // TRI6

FIRST, // QUAD4
SECOND, // QUAD8
SECOND, // QUAD9

FIRST, // TET4
SECOND, // TET10

FIRST, // HEX8
SECOND, // HEX20
SECOND, // HEX27

FIRST, // PRISM6
SECOND, // PRISM15
SECOND, // PRISM18

FIRST, // PYRAMID5
SECOND, // PYRAMID13
SECOND, // PYRAMID14

FIRST, // INFEDGE2

FIRST, // INFQUAD4
SECOND, // INFQUAD6

FIRST, // INFHEX8
SECOND, // INFHEX16
SECOND, // INFHEX18

FIRST, // INFPRISM6
SECOND, // INFPRISM12

CONSTANT, // NODEELEM

INVALID_ORDER, // REMOTEELEM

FIRST, // TRI3SUBDIVISION
FIRST, // TRISHELL3
FIRST, // QUADSHELL4
SECOND, // QUADSHELL8

THIRD, // TRI7
THIRD, // TET14
THIRD, // PRISM20
THIRD, // PRISM21
THIRD, // PYRAMID18

SECOND, // QUADSHELL9

FIRST, // C0POLYGON
};

// ------------------------------------------------------------
// Elem class member functions
std::unique_ptr<Elem> Elem::disconnected_clone() const
Expand Down
3 changes: 1 addition & 2 deletions tests/fe/fe_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,7 @@ class FETestBase : public CppUnit::TestCase {
void setUp()
{
_mesh = std::make_unique<Mesh>(*TestCommWorld);
const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
_dim = test_elem->dim();
_dim = Elem::type_to_dim_map[elem_type];
const unsigned int build_ny = (_dim > 1) * build_nx;
const unsigned int build_nz = (_dim > 2) * build_nx;

Expand Down
8 changes: 7 additions & 1 deletion tests/geom/elem_test.C
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,16 @@ public:
{
CPPUNIT_ASSERT(elem->n_nodes() <= Elem::max_n_nodes);

const ElemType etype = elem->type();

CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(elem->dim()),
Elem::type_to_dim_map[etype]);
CPPUNIT_ASSERT_EQUAL(elem->default_order(),
Elem::type_to_default_order_map[etype]);

// If we have an element type with topology defined solely by
// the type, then that should match the runtime topology. If
// not, then we should be aware of it.
const ElemType etype = elem->type();
if (!elem->runtime_topology())
{
CPPUNIT_ASSERT_EQUAL(elem->n_nodes(), Elem::type_to_n_nodes_map[etype]);
Expand Down
2 changes: 1 addition & 1 deletion tests/mesh/mesh_input.C
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ public:
ny = added_sides_nxyz[1],
nz = added_sides_nxyz[2];

const unsigned int dim = Elem::build(elem_type)->dim();
const unsigned int dim = Elem::type_to_dim_map[elem_type];
const bool is_tensor = (Elem::build(elem_type)->n_sides() == dim * 2);

// Figure out how many fake and true elements to expect
Expand Down
17 changes: 7 additions & 10 deletions tests/systems/systems_test.C
Original file line number Diff line number Diff line change
Expand Up @@ -777,9 +777,7 @@ public:
TransientExplicitSystem &sys =
es.add_system<TransientExplicitSystem> ("SimpleSystem");

auto generic_elem = Elem::build(elem_type);

auto u_var = sys.add_variable("u", generic_elem->default_order(), LAGRANGE_VEC);
auto u_var = sys.add_variable("u", Elem::type_to_default_order_map[elem_type], LAGRANGE_VEC);

MeshTools::Generation::build_square (mesh,
1, 1,
Expand All @@ -792,7 +790,7 @@ public:
// function projection code right now
for (const auto & node : mesh.local_node_ptr_range())
{
for (unsigned int i = 0; i < generic_elem->dim(); ++i)
for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
{
auto dof_index = node->dof_number(sys.number(), u_var, i);
sys.solution->set(dof_index, (*node)(i));
Expand All @@ -812,7 +810,7 @@ public:
for (const auto & node : mesh.local_node_ptr_range())
{
// 2D element here
for (unsigned int i = 0; i < generic_elem->dim(); ++i)
for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
{
auto dof_index = node->dof_number(sys.number(), u_var, i);
auto value = (*sys.solution)(dof_index);
Expand All @@ -829,9 +827,8 @@ public:
TransientExplicitSystem &sys =
es.add_system<TransientExplicitSystem> ("SimpleSystem");

auto generic_elem = Elem::build(elem_type);

auto u_var = sys.add_variable("u", generic_elem->default_order(), LAGRANGE_VEC);
auto u_var = sys.add_variable
("u", Elem::type_to_default_order_map[elem_type], LAGRANGE_VEC);

MeshTools::Generation::build_cube (mesh,
1, 1, 1,
Expand All @@ -844,7 +841,7 @@ public:
// function projection code right now
for (const auto & node : mesh.local_node_ptr_range())
{
for (unsigned int i = 0; i < generic_elem->dim(); ++i)
for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
{
auto dof_index = node->dof_number(sys.number(), u_var, i);
sys.solution->set(dof_index, (*node)(i));
Expand All @@ -863,7 +860,7 @@ public:

for (const auto & node : mesh.local_node_ptr_range())
{
for (unsigned int i = 0; i < generic_elem->dim(); ++i)
for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
{
auto dof_index = node->dof_number(sys.number(), u_var, i);
auto value = (*sys.solution)(dof_index);
Expand Down
6 changes: 3 additions & 3 deletions tests/utils/point_locator_test.C
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public:
Mesh mesh(*TestCommWorld);

const unsigned int n_elem_per_side = 5;
const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
const unsigned int ymax = test_elem->dim() > 1;
const unsigned int zmax = test_elem->dim() > 2;
const unsigned int dim = Elem::type_to_dim_map[elem_type];
const unsigned int ymax = dim > 1;
const unsigned int zmax = dim > 2;
const unsigned int ny = ymax * n_elem_per_side;
const unsigned int nz = zmax * n_elem_per_side;

Expand Down