libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
OverlappingCouplingGhostingTest Class Reference
Inheritance diagram for OverlappingCouplingGhostingTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (OverlappingCouplingGhostingTest)
 
 CPPUNIT_TEST (testSparsityCouplingMatrix)
 
 CPPUNIT_TEST (testSparsityNullCouplingMatrix)
 
 CPPUNIT_TEST (testSparsityNullCouplingMatrixUnifRef)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testSparsityCouplingMatrix ()
 
void testSparsityNullCouplingMatrix ()
 
void testSparsityNullCouplingMatrixUnifRef ()
 

Protected Member Functions

void build_quad_mesh (unsigned int n_refinements=0)
 
void init ()
 
void clear ()
 
void setup_coupling_matrix (std::unique_ptr< CouplingMatrix > &coupling)
 

Protected Attributes

std::unique_ptr< MeshBase > _mesh
 
std::unique_ptr< EquationSystems > _es
 

Private Member Functions

void run_sparsity_pattern_test (const unsigned int n_refinements, bool build_coupling_matrix)
 

Detailed Description

Definition at line 645 of file overlapping_coupling_test.C.

Member Function Documentation

◆ build_quad_mesh()

void OverlappingTestBase::build_quad_mesh ( unsigned int  n_refinements = 0)
inlineprotectedinherited

Definition at line 251 of file overlapping_coupling_test.C.

252 {
253 // We are making assumptions in various places about the presence
254 // of the elements on the current processor so we're restricting to
255 // ReplicatedMesh for now.
256 _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
257
258 _mesh->set_mesh_dimension(2);
259
260 _mesh->add_point( Point(0.0,0.0),0 );
261 _mesh->add_point( Point(1.0,0.0),1 );
262 _mesh->add_point( Point(1.0,1.0),2 );
263 _mesh->add_point( Point(0.0,1.0),3 );
264
265 {
266 Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 0));
267 elem->subdomain_id() = 1;
268
269 for (unsigned int n=0; n<4; n++)
270 elem->set_node(n, _mesh->node_ptr(n));
271 }
272
273 _mesh->add_point( Point(1.0,2.0),4 );
274 _mesh->add_point( Point(0.0,2.0),5 );
275
276 {
277 Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 1));
278 elem->subdomain_id() = 1;
279
280 elem->set_node(0, _mesh->node_ptr(3));
281 elem->set_node(1, _mesh->node_ptr(2));
282 elem->set_node(2, _mesh->node_ptr(4));
283 elem->set_node(3, _mesh->node_ptr(5));
284 }
285
286 _mesh->add_point( Point(0.0,0.0),6 );
287 _mesh->add_point( Point(1.0,0.0),7 );
288 _mesh->add_point( Point(1.0,2.0),8 );
289 _mesh->add_point( Point(0.0,2.0),9 );
290
291 {
292 Elem* elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 2));
293 elem->subdomain_id() = 2;
294
295 elem->set_node(0, _mesh->node_ptr(6));
296 elem->set_node(1, _mesh->node_ptr(7));
297 elem->set_node(2, _mesh->node_ptr(8));
298 elem->set_node(3, _mesh->node_ptr(9));
299 }
300
301 _mesh->partitioner() = std::make_unique<OverlappingTestPartitioner>();
302
303 _mesh->prepare_for_use();
304
305#ifdef LIBMESH_ENABLE_AMR
306 if (n_refinements > 0)
307 {
308 MeshRefinement refine(*_mesh);
309 refine.uniformly_refine(n_refinements);
310 }
311#else
312 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
313#endif // LIBMESH_ENABLE_AMR
314 }
std::unique_ptr< MeshBase > _mesh
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2688
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem's ...
Definition elem.C:496
subdomain_id_type subdomain_id() const
Definition elem.h:2712
Implements (adaptive) mesh refinement algorithms for a MeshBase.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:41

References OverlappingTestBase::_mesh, libMesh::Elem::build_with_id(), libMesh::QUAD4, libMesh::Elem::set_node(), libMesh::Elem::subdomain_id(), TestCommWorld, and libMesh::MeshRefinement::uniformly_refine().

Referenced by OverlappingAlgebraicGhostingTest::run_ghosting_test(), run_sparsity_pattern_test(), and OverlappingFunctorTest::setUp().

◆ clear()

void OverlappingTestBase::clear ( )
inlineprotectedinherited

Definition at line 336 of file overlapping_coupling_test.C.

337 {
338 _es.reset();
339 _mesh.reset();
340 }
std::unique_ptr< EquationSystems > _es

References OverlappingTestBase::_es, and OverlappingTestBase::_mesh.

Referenced by OverlappingFunctorTest::tearDown(), OverlappingAlgebraicGhostingTest::tearDown(), and tearDown().

◆ CPPUNIT_TEST() [1/3]

OverlappingCouplingGhostingTest::CPPUNIT_TEST ( testSparsityCouplingMatrix  )

◆ CPPUNIT_TEST() [2/3]

OverlappingCouplingGhostingTest::CPPUNIT_TEST ( testSparsityNullCouplingMatrix  )

◆ CPPUNIT_TEST() [3/3]

OverlappingCouplingGhostingTest::CPPUNIT_TEST ( testSparsityNullCouplingMatrixUnifRef  )

◆ CPPUNIT_TEST_SUITE_END()

OverlappingCouplingGhostingTest::CPPUNIT_TEST_SUITE_END ( )

◆ init()

void OverlappingTestBase::init ( )
inlineprotectedinherited

Definition at line 316 of file overlapping_coupling_test.C.

317 {
318 _es = std::make_unique<EquationSystems>(*_mesh);
319 LinearImplicitSystem & sys = _es->add_system<LinearImplicitSystem> ("SimpleSystem");
320
321 std::set<subdomain_id_type> sub_one;
322 sub_one.insert(1);
323
324 std::set<subdomain_id_type> sub_two;
325 sub_two.insert(2);
326
327 sys.add_variable("U", FIRST, LAGRANGE, &sub_two);
328 sys.add_variable("L", FIRST, LAGRANGE, &sub_two);
329
330 sys.add_variable("V", FIRST, LAGRANGE, &sub_one);
331 sys.add_variable("p", FIRST, LAGRANGE, &sub_one);
332
333 _es->init();
334 }
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
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:1344

References OverlappingTestBase::_es, OverlappingTestBase::_mesh, libMesh::System::add_variable(), libMesh::FIRST, and libMesh::LAGRANGE.

Referenced by OverlappingAlgebraicGhostingTest::run_ghosting_test(), run_sparsity_pattern_test(), and OverlappingFunctorTest::setUp().

◆ LIBMESH_CPPUNIT_TEST_SUITE()

OverlappingCouplingGhostingTest::LIBMESH_CPPUNIT_TEST_SUITE ( OverlappingCouplingGhostingTest  )

◆ run_sparsity_pattern_test()

void OverlappingCouplingGhostingTest::run_sparsity_pattern_test ( const unsigned int  n_refinements,
bool  build_coupling_matrix 
)
inlineprivate

Definition at line 687 of file overlapping_coupling_test.C.

688 {
689 this->build_quad_mesh(n_refinements);
690 this->init();
691
692 std::unique_ptr<CouplingMatrix> coupling_matrix;
693 if (build_coupling_matrix)
694 this->setup_coupling_matrix(coupling_matrix);
695
696 LinearImplicitSystem & system = _es->get_system<LinearImplicitSystem>("SimpleSystem");
697
698 // If we don't add this coupling functor and properly recompute the
699 // sparsity pattern, then PETSc will throw a malloc error when we
700 // try to assemble into the global matrix
701 OverlappingCouplingFunctor coupling_functor(system);
702 coupling_functor.set_coupling_matrix(coupling_matrix);
703
704 DofMap & dof_map = system.get_dof_map();
705 dof_map.add_coupling_functor(coupling_functor);
706 dof_map.reinit_send_list(system.get_mesh());
707
708 // Update current local solution
710
711 system.current_local_solution->init(system.n_dofs(), system.n_local_dofs(),
712 dof_map.get_send_list(), false,
714
715 system.solution->localize(*(system.current_local_solution),dof_map.get_send_list());
716
717 // Now that we've added the coupling functor, we need
718 // to recompute the sparsity
719 dof_map.clear_sparsity();
720 dof_map.compute_sparsity(system.get_mesh());
721
722 // Now that we've recomputed the sparsity pattern, we need
723 // to reinitialize the system matrix.
724 SparseMatrix<Number> & matrix = system.get_system_matrix();
725 libmesh_assert(dof_map.is_attached(matrix));
726 matrix.init();
727
728 std::unique_ptr<PointLocatorBase> point_locator = _mesh->sub_point_locator();
729
730 const unsigned int u_var = system.variable_number("U");
731 const unsigned int v_var = system.variable_number("V");
732
733 DenseMatrix<Number> K12, K21;
734
735 FEMContext subdomain_one_context(system);
736 subdomain_one_context.get_element_fe(u_var)->get_nothing();
737 subdomain_one_context.get_element_fe(v_var)->get_nothing();
738
739 FEMContext subdomain_two_context(system);
740 subdomain_two_context.get_element_fe(u_var)->get_xyz();
741 subdomain_two_context.get_element_fe(v_var)->get_nothing();
742
743 // Add normally coupled parts of the matrix
744 for (const auto & elem : _mesh->active_local_subdomain_elements_ptr_range(1))
745 {
746 subdomain_one_context.pre_fe_reinit(system,elem);
747 subdomain_one_context.elem_fe_reinit();
748
749 std::vector<dof_id_type> & rows = subdomain_one_context.get_dof_indices();
750
751 // Fill with ones in case PETSc ignores the zeros at some point
752 std::fill( subdomain_one_context.get_elem_jacobian().get_values().begin(),
753 subdomain_one_context.get_elem_jacobian().get_values().end(),
754 1);
755
756 // Insert the Jacobian for the dofs for this element
757 matrix.add_matrix( subdomain_one_context.get_elem_jacobian(), rows );
758 }
759
760 for (const auto & elem : _mesh->active_local_subdomain_elements_ptr_range(2))
761 {
762 // A little extra unit testing on the range iterator
763 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(elem->subdomain_id()));
764
765 const std::vector<libMesh::Point> & qpoints = subdomain_two_context.get_element_fe(u_var)->get_xyz();
766
767 // Setup the context for the current element
768 subdomain_two_context.pre_fe_reinit(system,elem);
769 subdomain_two_context.elem_fe_reinit();
770
771 // We're only assembling rows for the dofs on subdomain 2 (U,L), so
772 // the current element will have all those dof_indices.
773 std::vector<dof_id_type> & rows = subdomain_two_context.get_dof_indices();
774
775 std::fill( subdomain_two_context.get_elem_jacobian().get_values().begin(),
776 subdomain_two_context.get_elem_jacobian().get_values().end(),
777 1);
778
779 // Insert the Jacobian for the normally coupled dofs for this element
780 matrix.add_matrix( subdomain_two_context.get_elem_jacobian(), rows );
781
782 std::set<subdomain_id_type> allowed_subdomains;
783 allowed_subdomains.insert(1);
784
785 // Now loop over the quadrature points and find the subdomain-one element that overlaps
786 // with the current subdomain-two element and then add a local element matrix with
787 // the coupling to the global matrix to try and trip any issues with sparsity pattern
788 // construction
789 for ( const auto & qp : qpoints )
790 {
791 const Elem * overlapping_elem = (*point_locator)( qp, &allowed_subdomains );
792 CPPUNIT_ASSERT(overlapping_elem);
793
794 // Setup the context for the overlapping element
795 subdomain_one_context.pre_fe_reinit(system,overlapping_elem);
796 subdomain_one_context.elem_fe_reinit();
797
798 // We're only coupling to the "V" variable so only need those dof indices
799 std::vector<dof_id_type> & v_indices = subdomain_one_context.get_dof_indices(v_var);
800 std::vector<dof_id_type> columns(rows);
801 columns.insert( columns.end(), v_indices.begin(), v_indices.end() );
802
803 // This will also zero the matrix so we can just insert zeros for this test
804 K21.resize( rows.size(), columns.size() );
805
806 std::fill(K21.get_values().begin(), K21.get_values().end(), 1);
807
808 // Now adding this local matrix to the global would trip a PETSc
809 // malloc error if the sparsity pattern hasn't been correctly
810 // built to include the overlapping coupling.
811 matrix.add_matrix (K21, rows, columns);
812
813 // Now add the other part of the overlapping coupling
814 K12.resize(v_indices.size(), rows.size());
815 std::fill(K12.get_values().begin(), K12.get_values().end(), 1);
816 matrix.add_matrix(K12,v_indices,rows);
817 }
818 } // end element loop
819
820 // We need to make sure to close the matrix for this test. There could still
821 // be PETSc malloc errors tripped here if we didn't allocate the off-processor
822 // part of the sparsity pattern correctly.
823 matrix.close();
824 }
void setup_coupling_matrix(std::unique_ptr< CouplingMatrix > &coupling)
void build_quad_mesh(unsigned int n_refinements=0)
Defines a dense matrix for use in Finite Element-type computations.
std::vector< T > & get_values()
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
void reinit_send_list(MeshBase &mesh)
Clears the _send_list vector and then rebuilds it.
Definition dof_map.C:1879
const std::vector< dof_id_type > & get_send_list() const
Definition dof_map.h:540
bool is_attached(SparseMatrix< Number > &matrix)
Matrices should not be attached more than once.
Definition dof_map.C:296
void compute_sparsity(const MeshBase &)
Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear...
Definition dof_map.C:1962
void clear_sparsity()
Clears the sparsity pattern.
Definition dof_map.C:1983
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:2007
This class provides all data required for a physics package (e.g.
Definition fem_context.h:64
const SparseMatrix< Number > & get_system_matrix() const
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
const Parallel::Communicator & comm() const
Generic sparse matrix.
virtual void init(const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz=30, const numeric_index_type noz=10, const numeric_index_type blocksize=1)=0
Initialize SparseMatrix with the specified sizes.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition system.h:1667
dof_id_type n_dofs() const
Definition system.C:118
dof_id_type n_local_dofs() const
Definition system.C:155
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
unsigned int variable_number(std::string_view var) const
Definition system.C:1398
const DofMap & get_dof_map() const
Definition system.h:2417
const MeshBase & get_mesh() const
Definition system.h:2401
libmesh_assert(ctx)

References OverlappingTestBase::_es, OverlappingTestBase::_mesh, libMesh::DofMap::add_coupling_functor(), libMesh::SparseMatrix< T >::add_matrix(), libMesh::NumericVector< T >::build(), OverlappingTestBase::build_quad_mesh(), libMesh::DofMap::clear_sparsity(), libMesh::SparseMatrix< T >::close(), libMesh::ParallelObject::comm(), libMesh::DofMap::compute_sparsity(), libMesh::System::current_local_solution, libMesh::FEMContext::elem_fe_reinit(), libMesh::DiffContext::get_dof_indices(), libMesh::System::get_dof_map(), libMesh::DiffContext::get_elem_jacobian(), libMesh::FEMContext::get_element_fe(), libMesh::System::get_mesh(), libMesh::DofMap::get_send_list(), libMesh::ImplicitSystem::get_system_matrix(), libMesh::DenseMatrix< T >::get_values(), libMesh::GHOSTED, OverlappingTestBase::init(), libMesh::SparseMatrix< T >::init(), libMesh::DofMap::is_attached(), libMesh::libmesh_assert(), libMesh::System::n_dofs(), libMesh::System::n_local_dofs(), libMesh::FEMContext::pre_fe_reinit(), libMesh::DofMap::reinit_send_list(), libMesh::DenseMatrix< T >::resize(), OverlappingTestBase::setup_coupling_matrix(), libMesh::System::solution, and libMesh::System::variable_number().

Referenced by testSparsityCouplingMatrix(), testSparsityNullCouplingMatrix(), and testSparsityNullCouplingMatrixUnifRef().

◆ setUp()

void OverlappingCouplingGhostingTest::setUp ( )
inline

Definition at line 661 of file overlapping_coupling_test.C.

662 {}

◆ setup_coupling_matrix()

void OverlappingTestBase::setup_coupling_matrix ( std::unique_ptr< CouplingMatrix > &  coupling)
inlineprotectedinherited

Definition at line 342 of file overlapping_coupling_test.C.

343 {
344 System & system = _es->get_system("SimpleSystem");
345
346 coupling = std::make_unique<CouplingMatrix>(system.n_vars());
347
348 const unsigned int u_var = system.variable_number("U");
349 const unsigned int l_var = system.variable_number("L");
350 const unsigned int v_var = system.variable_number("V");
351 const unsigned int p_var = system.variable_number("p");
352
353 // Only adding the overlapping couplings since the primary ones should
354 // be there by default.
355 (*coupling)(u_var,v_var) = true;
356 (*coupling)(l_var,v_var) = true;
357 (*coupling)(l_var,p_var) = true;
358 (*coupling)(v_var,u_var) = true;
359 (*coupling)(v_var,l_var) = true;
360 }
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
unsigned int n_vars() const
Definition system.C:2674

References OverlappingTestBase::_es, libMesh::System::n_vars(), and libMesh::System::variable_number().

Referenced by OverlappingAlgebraicGhostingTest::run_ghosting_test(), and run_sparsity_pattern_test().

◆ tearDown()

void OverlappingCouplingGhostingTest::tearDown ( )
inline

Definition at line 664 of file overlapping_coupling_test.C.

665 { this->clear(); }

References OverlappingTestBase::clear().

◆ testSparsityCouplingMatrix()

void OverlappingCouplingGhostingTest::testSparsityCouplingMatrix ( )
inline

Definition at line 667 of file overlapping_coupling_test.C.

668 {
669 LOG_UNIT_TEST;
670 this->run_sparsity_pattern_test(0, true);
671 }
void run_sparsity_pattern_test(const unsigned int n_refinements, bool build_coupling_matrix)

References run_sparsity_pattern_test().

◆ testSparsityNullCouplingMatrix()

void OverlappingCouplingGhostingTest::testSparsityNullCouplingMatrix ( )
inline

Definition at line 673 of file overlapping_coupling_test.C.

674 {
675 LOG_UNIT_TEST;
676 this->run_sparsity_pattern_test(0, false);
677 }

References run_sparsity_pattern_test().

◆ testSparsityNullCouplingMatrixUnifRef()

void OverlappingCouplingGhostingTest::testSparsityNullCouplingMatrixUnifRef ( )
inline

Definition at line 679 of file overlapping_coupling_test.C.

680 {
681 LOG_UNIT_TEST;
682 this->run_sparsity_pattern_test(1, false);
683 }

References run_sparsity_pattern_test().

Member Data Documentation

◆ _es

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

◆ _mesh

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

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