libMesh
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
NonManifoldGhostingFunctorTest Class Reference
Inheritance diagram for NonManifoldGhostingFunctorTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (NonManifoldGhostingFunctorTest)
 
 CPPUNIT_TEST (verifySendListEntries0)
 
 CPPUNIT_TEST (verifySendListEntries1)
 
 CPPUNIT_TEST (verifySendListEntries2)
 
 CPPUNIT_TEST (verifySendListEntries3)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void verifySendListEntries0 ()
 
void verifySendListEntries1 ()
 
void verifySendListEntries2 ()
 
void verifySendListEntries3 ()
 
void verify_send_list_entries_helper (const std::string &mesh_filename)
 

Protected Member Functions

void read_mesh (const std::string &mesh_filename)
 
void init_es ()
 

Protected Attributes

std::unique_ptr< MeshBase_mesh
 
std::unique_ptr< EquationSystems_es
 

Detailed Description

Definition at line 167 of file nonmanifold_coupling_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/4]

NonManifoldGhostingFunctorTest::CPPUNIT_TEST ( verifySendListEntries0  )

◆ CPPUNIT_TEST() [2/4]

NonManifoldGhostingFunctorTest::CPPUNIT_TEST ( verifySendListEntries1  )

◆ CPPUNIT_TEST() [3/4]

NonManifoldGhostingFunctorTest::CPPUNIT_TEST ( verifySendListEntries2  )

◆ CPPUNIT_TEST() [4/4]

NonManifoldGhostingFunctorTest::CPPUNIT_TEST ( verifySendListEntries3  )

◆ CPPUNIT_TEST_SUITE_END()

NonManifoldGhostingFunctorTest::CPPUNIT_TEST_SUITE_END ( )

◆ init_es()

void NonManifoldCouplingTestBase::init_es ( )
inlineprotectedinherited

Definition at line 142 of file nonmanifold_coupling_test.C.

References libMesh::DofMap::add_coupling_functor(), libMesh::System::add_variable(), libMesh::FIRST, libMesh::System::get_dof_map(), and libMesh::LAGRANGE.

143  {
144  _es = std::make_unique<EquationSystems>(*_mesh);
145 
146  // Add System with a single linear Lagrange variable on it.
147  LinearImplicitSystem & sys = _es->add_system<LinearImplicitSystem> ("SimpleSystem");
148  sys.add_variable("u", FIRST, LAGRANGE);
149 
150  // Attach ghosting functor to the System. We use the std::shared_ptr interface
151  // so that the DofMap takes ownership of the object. Note: if you comment out
152  // this line, then the test _can_ fail when run in parallel, but it depends on
153  // the number of processors used. For small numbers of procs, sometimes we can
154  // get "lucky" and wind up with all the non-manifold neighbor DOFs either local
155  // to or ghosted on all procs where they are needed. In practice, this test should
156  // be run on 3 or more procs to make it fail when the NonManifoldGhostingFunctor
157  // is not used.
158  auto ghosting_functor = std::make_shared<NonManifoldGhostingFunctor>(*_mesh);
159  sys.get_dof_map().add_coupling_functor(ghosting_functor, /*to_mesh=*/true);
160 
161  // Initialize the DofMap, etc. for all Systems
162  _es->init();
163  }
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
std::unique_ptr< EquationSystems > _es
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:2033
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
const DofMap & get_dof_map() const
Definition: system.h:2374

◆ LIBMESH_CPPUNIT_TEST_SUITE()

NonManifoldGhostingFunctorTest::LIBMESH_CPPUNIT_TEST_SUITE ( NonManifoldGhostingFunctorTest  )

◆ read_mesh()

void NonManifoldCouplingTestBase::read_mesh ( const std::string &  mesh_filename)
inlineprotectedinherited

Definition at line 123 of file nonmanifold_coupling_test.C.

124  {
125  // We are making assumptions in various places about the presence
126  // of the elements on the current processor so we're restricting to
127  // ReplicatedMesh for now.
128  _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
129  _mesh->read(mesh_filename);
130 
131  // Use our custom partitioner that assigns non-manifold edge
132  // neighbors to different processors.
133  _mesh->partitioner() = std::make_unique<NonManifoldTestPartitioner>();
134 
135  _mesh->prepare_for_use();
136 
137  // Debugging: print processor ids determined by partitioner
138  // for (const auto & elem : _mesh->element_ptr_range())
139  // libMesh::out << "Elem " << elem->id() << " is on processor " << elem->processor_id() << std::endl;
140  }
std::unique_ptr< MeshBase > _mesh

◆ setUp()

void NonManifoldGhostingFunctorTest::setUp ( )
inline

Definition at line 185 of file nonmanifold_coupling_test.C.

186  {
187  }

◆ tearDown()

void NonManifoldGhostingFunctorTest::tearDown ( )
inline

Definition at line 189 of file nonmanifold_coupling_test.C.

190  {
191  }

◆ verify_send_list_entries_helper()

void NonManifoldGhostingFunctorTest::verify_send_list_entries_helper ( const std::string &  mesh_filename)
inline

Definition at line 200 of file nonmanifold_coupling_test.C.

References libMesh::Utility::binary_find(), libMesh::MeshTools::SidesToElemMap::build(), distance(), libMesh::DofMap::dof_indices(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::first_dof(), libMesh::MeshTools::SidesToElemMap::get_connected_elems(), libMesh::System::get_dof_map(), libMesh::DofMap::get_send_list(), libMesh::MeshTools::Subdivision::next, and libMesh::DofObject::processor_id().

201  {
202  // Call base class implementations
203  this->read_mesh(mesh_filename);
204  this->init_es();
205 
206  // Get reference to the System, corresponding DofMap, and send_list for this processor
207  System & system = _es->get_system("SimpleSystem");
208  DofMap & dof_map = system.get_dof_map();
209  const std::vector<dof_id_type> & send_list = dof_map.get_send_list();
210 
211  MeshTools::SidesToElemMap stem = MeshTools::SidesToElemMap::build(*_mesh);
212 
213  // Use the SidesToElemMap to get a range of Elem pointers attached
214  // to the non-manifold edge that we intentionally partitioned onto
215  // different processors.
217  auto side_neighbors_found = [&]() -> bool
218  {
219  for (const auto & elem : _mesh->element_ptr_range())
220  for (auto s : elem->side_index_range())
221  {
222  auto range = stem.get_connected_elems(elem, s);
223  if (std::distance(range.first, range.second) == 5)
224  {
225  beg = range.first;
226  end = range.second;
227  return true;
228  }
229  }
230 
231  // If we made it here, then we didn't find a Side shared by
232  // 5 elements and we'll throw an error later
233  return false;
234  }();
235 
236  // Require that neighbors were found
237  CPPUNIT_ASSERT(side_neighbors_found);
238 
239  // For every pair of elements (e,f) on this edge owned by processors (proc_e, proc_f) respectively, check that:
240  // 1.) The DOFs of e are either local to, or in the send-list of, proc_f
241  // 2.) The DOFs of f are either local to, or in the send-list of, proc_e
242  for (auto it_e = beg; it_e != end; ++it_e)
243  for (auto it_f = std::next(it_e); it_f != end; ++it_f)
244  {
245  // Lambda to be used for error checking
246  auto check_dofs = [&](const Elem * elem)
247  {
248  std::vector<dof_id_type> dof_indices;
249  dof_map.dof_indices(elem, dof_indices);
250 
251  for (const auto & dof : dof_indices)
252  {
253  bool is_local = (dof >= dof_map.first_dof()) && (dof < dof_map.end_dof());
254  bool is_in_send_list = (Utility::binary_find(send_list.begin(), send_list.end(), dof) != send_list.end());
255  CPPUNIT_ASSERT(is_local || is_in_send_list);
256  }
257  };
258 
259  const Elem * elem_e = *it_e;
260  const Elem * elem_f = *it_f;
261 
262  if (_mesh->comm().rank() == elem_e->processor_id())
263  check_dofs(elem_f);
264 
265  if (_mesh->comm().rank() == elem_f->processor_id())
266  check_dofs(elem_e);
267  }
268  }
dof_id_type end_dof(const processor_id_type proc) const
Definition: dof_map_base.h:191
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
std::pair< ElemIter, ElemIter > get_connected_elems(const Elem *elem, unsigned int side) const
Return an iterator pair defining the range of Elems connected to "side" of "elem".
std::unique_ptr< EquationSystems > _es
std::unique_ptr< MeshBase > _mesh
Real distance(const Point &p)
std::vector< const Elem * >::const_iterator ElemIter
Typedef for the iterator type returned by the SidesToeElemMap::get_connected_elems() function...
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
The STL provides std::binary_search() which returns true or false depending on whether the searched-f...
Definition: utility.h:265
void read_mesh(const std::string &mesh_filename)
This class implements a generalization of the MeshTools::build_nodes_to_elem_map() function...
dof_id_type first_dof(const processor_id_type proc) const
Definition: dof_map_base.h:185
const DofMap & get_dof_map() const
Definition: system.h:2374
processor_id_type processor_id() const
Definition: dof_object.h:905
const std::vector< dof_id_type > & get_send_list() const
Definition: dof_map.h:526

◆ verifySendListEntries0()

void NonManifoldGhostingFunctorTest::verifySendListEntries0 ( )
inline

Definition at line 193 of file nonmanifold_coupling_test.C.

193 { this->verify_send_list_entries_helper("meshes/non_manifold_junction0.exo"); }
void verify_send_list_entries_helper(const std::string &mesh_filename)

◆ verifySendListEntries1()

void NonManifoldGhostingFunctorTest::verifySendListEntries1 ( )
inline

Definition at line 194 of file nonmanifold_coupling_test.C.

194 { this->verify_send_list_entries_helper("meshes/non_manifold_junction1.exo"); }
void verify_send_list_entries_helper(const std::string &mesh_filename)

◆ verifySendListEntries2()

void NonManifoldGhostingFunctorTest::verifySendListEntries2 ( )
inline

Definition at line 195 of file nonmanifold_coupling_test.C.

195 { this->verify_send_list_entries_helper("meshes/non_manifold_junction2.exo"); }
void verify_send_list_entries_helper(const std::string &mesh_filename)

◆ verifySendListEntries3()

void NonManifoldGhostingFunctorTest::verifySendListEntries3 ( )
inline

Definition at line 196 of file nonmanifold_coupling_test.C.

196 { this->verify_send_list_entries_helper("meshes/non_manifold_junction3.exo"); }
void verify_send_list_entries_helper(const std::string &mesh_filename)

Member Data Documentation

◆ _es

std::unique_ptr<EquationSystems> NonManifoldCouplingTestBase::_es
protectedinherited

Definition at line 121 of file nonmanifold_coupling_test.C.

◆ _mesh

std::unique_ptr<MeshBase> NonManifoldCouplingTestBase::_mesh
protectedinherited

Definition at line 119 of file nonmanifold_coupling_test.C.


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