libMesh
multi_evaluable_pred_test.C
Go to the documentation of this file.
1 #include <libmesh/partitioner.h>
2 #include <libmesh/mesh.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/equation_systems.h>
5 #include <libmesh/elem.h>
6 #include <libmesh/system.h>
7 #include <libmesh/dof_map.h>
8 #include <timpi/communicator.h>
9 
10 #include "test_comm.h"
11 #include "libmesh_cppunit.h"
12 
13 #include <memory>
14 
15 using namespace libMesh;
16 
18 {
19 public:
20  ContrivedPartitioner() = default;
21  ContrivedPartitioner(const ContrivedPartitioner &) = default;
23  ContrivedPartitioner & operator=(const ContrivedPartitioner &) = default;
24  ContrivedPartitioner & operator=(ContrivedPartitioner &&) = default;
25  virtual ~ContrivedPartitioner() = default;
26 
27  std::unique_ptr<Partitioner> clone() const override
28  {
29  return std::make_unique<ContrivedPartitioner>(*this);
30  }
31 
32 protected:
33  void _do_partition(MeshBase & mesh, const unsigned int n) override
34  {
35  libmesh_assert(n > 1);
36 
37  unsigned int n_interior_elems = 0;
38  for (Elem * const elem : as_range(mesh.elements_begin(), mesh.elements_end()))
39  {
40  bool internal_elem = true;
41  for (const Elem * const neighbor : elem->neighbor_ptr_range())
42  if (!neighbor)
43  {
44  internal_elem = false;
45  break;
46  }
47 
48  // The interior element will go on processor 1. Other elements will go on processor 0. For a
49  // system/DofMap that has all nodal variables all elements on processor 0 will appear
50  // evaluable. However, for a system/DofMap that has any elemental variables the interior
51  // element will not appear evaluable on processor 0
52  n_interior_elems += internal_elem;
53  elem->processor_id() = internal_elem;
54  }
55 
56  // This test is hand-crafted for one interior element
57  CPPUNIT_ASSERT_EQUAL(n_interior_elems, 1u);
58  }
59 };
60 
61 class MultiEvaluablePredTest : public CppUnit::TestCase
62 {
63 public:
64  LIBMESH_CPPUNIT_TEST_SUITE(MultiEvaluablePredTest);
65 
66  CPPUNIT_TEST(test);
67 
68  CPPUNIT_TEST_SUITE_END();
69 
70 public:
71  void setUp() {}
72 
73  void tearDown() {}
74 
75  void test()
76  {
77  LOG_UNIT_TEST;
78  const auto rank = TestCommWorld->rank();
80  mesh.partitioner() = std::make_unique<ContrivedPartitioner>();
82 
84  auto & nodal_system = es.add_system<System>("nodal_system");
85  nodal_system.add_variable("nodal", FIRST, LAGRANGE);
86  auto & nodal_dof_map = nodal_system.get_dof_map();
87  nodal_dof_map.remove_default_ghosting();
88  auto & elem_system = es.add_system<System>("elem_system");
89  elem_system.add_variable("elem", CONSTANT, MONOMIAL);
90  auto & elem_dof_map = elem_system.get_dof_map();
91  elem_dof_map.remove_default_ghosting();
92 
93  es.init();
94 
95  {
96  auto n_evaluable = std::distance(mesh.evaluable_elements_begin(nodal_dof_map),
97  mesh.evaluable_elements_end(nodal_dof_map));
98  typedef decltype(n_evaluable) comp_type;
99  switch (rank)
100  {
101  case 0:
102  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(9));
103  break;
104 
105  case 1:
106  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(1));
107  break;
108 
109  default:
110  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(0));
111  break;
112  }
113  }
114 
115  {
116  auto n_evaluable = std::distance(mesh.evaluable_elements_begin(elem_dof_map),
117  mesh.evaluable_elements_end(elem_dof_map));
118  typedef decltype(n_evaluable) comp_type;
119  switch (rank)
120  {
121  case 0:
122  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(TestCommWorld->size() == 1 ? 9 : 8));
123  break;
124 
125  case 1:
126  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(1));
127  break;
128 
129  default:
130  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(0));
131  break;
132  }
133  }
134 
135  {
136  std::vector<const DofMap *> dof_maps = {&nodal_dof_map, &elem_dof_map};
137  auto n_evaluable = std::distance(mesh.multi_evaluable_elements_begin(dof_maps),
138  mesh.multi_evaluable_elements_end(dof_maps));
139  typedef decltype(n_evaluable) comp_type;
140  switch (rank)
141  {
142  case 0:
143  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(TestCommWorld->size() == 1 ? 9 : 8));
144  break;
145 
146  case 1:
147  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(1));
148  break;
149 
150  default:
151  CPPUNIT_ASSERT_EQUAL(n_evaluable, comp_type(0));
152  break;
153  }
154  }
155  }
156 };
157 
This is the EquationSystems class.
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each prepare_for_use()
Definition: mesh_base.h:160
processor_id_type rank() const
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
The libMesh namespace provides an interface to certain functionality in the library.
Real distance(const Point &p)
This is the MeshBase class.
Definition: mesh_base.h:75
The Partitioner class provides a uniform interface for partitioning algorithms.
Definition: partitioner.h:51
processor_id_type size() const
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
CPPUNIT_TEST_SUITE_REGISTRATION(MultiEvaluablePredTest)
libmesh_assert(ctx)
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.
Definition: system.C:1357
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:3503
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.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
void _do_partition(MeshBase &mesh, const unsigned int n) override
This is the actual partitioning method which must be overridden in derived classes.
std::unique_ptr< Partitioner > clone() const override