1#include <libmesh/equation_systems.h>
2#include <libmesh/replicated_mesh.h>
3#include <libmesh/numeric_vector.h>
4#include <libmesh/dof_map.h>
5#include <libmesh/elem.h>
6#include <libmesh/face_quad4.h>
7#include <libmesh/ghosting_functor.h>
8#include <libmesh/coupling_matrix.h>
9#include <libmesh/quadrature_gauss.h>
10#include <libmesh/linear_implicit_system.h>
11#include <libmesh/mesh_refinement.h>
12#include <libmesh/mesh_modification.h>
13#include <libmesh/partitioner.h>
14#include <libmesh/sparse_matrix.h>
53 std::set<subdomain_id_type> ids;
55 CPPUNIT_ASSERT( ids.find(1) != ids.end() );
56 CPPUNIT_ASSERT( ids.find(2) != ids.end() );
63 virtual std::unique_ptr<GhostingFunctor>
clone ()
const override
66 std::make_unique<OverlappingCouplingFunctor>(
_system);
68 auto coupling_matrix =
70 clone_functor->set_coupling_matrix(coupling_matrix);
77 virtual void operator()
81 map_type & coupled_elements)
override
85 for(
const auto & elem :
as_range(range_begin,range_end) )
87 std::set<subdomain_id_type> allowed_subdomains;
89 if( elem->subdomain_id() == 1 )
92 allowed_subdomains.insert(2);
94 else if( elem->subdomain_id() == 2 )
97 allowed_subdomains.insert(1);
100 CPPUNIT_FAIL(
"Something bad happpend");
102 unsigned int dim = 2;
106 fe->attach_quadrature_rule (&qrule);
108 const std::vector<libMesh::Point> & qpoints = fe->get_xyz();
112 for (
const auto & qp : qpoints )
114 const Elem * overlapping_elem = (*sub_point_locator)( qp, &allowed_subdomains );
116 if( overlapping_elem && overlapping_elem->
processor_id() != p )
153 virtual std::unique_ptr<Partitioner>
clone ()
const override
155 return std::make_unique<OverlappingTestPartitioner>(*
this);
164 const unsigned int n)
override
171 libmesh_assert_greater (n, 0);
178 for (
auto & elem :
mesh.active_element_ptr_range() )
180 elem->processor_id() = e;
189 unsigned int n_sub_two_elems = std::distance(
mesh.active_subdomain_elements_begin(2),
190 mesh.active_subdomain_elements_end(2) );
192 unsigned int n_parts_sub_two = 0;
193 if( n_sub_two_elems < n/2 )
194 n_parts_sub_two = n_sub_two_elems;
196 n_parts_sub_two = n/2;
198 const unsigned int n_parts_sub_one = n - n_parts_sub_two;
200 const dof_id_type sub_two_blk_size = cast_int<dof_id_type>
201 (std::distance(
mesh.active_subdomain_elements_begin(2),
202 mesh.active_subdomain_elements_end(2) )/n_parts_sub_two );
207 const dof_id_type sub_one_blk_size = cast_int<dof_id_type>
208 (std::distance(
mesh.active_subdomain_elements_begin(1),
209 mesh.active_subdomain_elements_end(1) )/n_parts_sub_one );
219 const unsigned int n_parts,
225 if ((e/blksize) < n_parts)
226 elem->processor_id() = offset + cast_int<processor_id_type>(e/blksize);
228 elem->processor_id() = offset;
247 std::unique_ptr<EquationSystems>
_es;
256 _mesh->set_mesh_dimension(2);
267 for (
unsigned int n=0; n<4; n++)
299 _mesh->partitioner() = std::make_unique<OverlappingTestPartitioner>();
301 _mesh->prepare_for_use();
303#ifdef LIBMESH_ENABLE_AMR
304 if (n_refinements > 0)
310 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
316 _es = std::make_unique<EquationSystems>(*
_mesh);
319 std::set<subdomain_id_type> sub_one;
322 std::set<subdomain_id_type> sub_two;
342 System & system =
_es->get_system(
"SimpleSystem");
344 coupling = std::make_unique<CouplingMatrix>(system.
n_vars());
353 (*coupling)(u_var,v_var) =
true;
354 (*coupling)(l_var,v_var) =
true;
355 (*coupling)(l_var,p_var) =
true;
356 (*coupling)(v_var,u_var) =
true;
357 (*coupling)(v_var,l_var) =
true;
372#ifdef LIBMESH_HAVE_SOLVER
376# ifdef LIBMESH_ENABLE_AMR
435#if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_SOLVER)
436 if( n_refinements > 0 )
443 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
446 System & system =
_es->get_system(
"SimpleSystem");
453 coupling_functor(
_mesh->active_subdomain_elements_begin(1),
454 _mesh->active_subdomain_elements_end(1),
456 subdomain_one_couplings );
458 coupling_functor(
_mesh->active_subdomain_elements_begin(2),
459 _mesh->active_subdomain_elements_end(2),
461 subdomain_two_couplings );
463 dof_id_type n_elems_subdomain_two = std::distance(
_mesh->active_subdomain_elements_begin(2),
464 _mesh->active_subdomain_elements_end(2) );
466 CPPUNIT_ASSERT_EQUAL(n_elems_subdomain_two,
static_cast<dof_id_type>(subdomain_one_couplings.size()));
467 CPPUNIT_ASSERT_EQUAL(
static_cast<dof_id_type>(2*n_elems_subdomain_two),
static_cast<dof_id_type>(subdomain_two_couplings.size()));
472#ifdef LIBMESH_ENABLE_AMR
473 if( n_refinements > 0 )
480 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
483 System & system =
_es->get_system(
"SimpleSystem");
485 std::set<processor_id_type> sub_one_proc_ids, sub_two_proc_ids;
486 for (
auto & elem :
_mesh->active_subdomain_elements_ptr_range(1))
487 sub_one_proc_ids.insert(elem->processor_id());
489 for (
auto & elem :
_mesh->active_subdomain_elements_ptr_range(2))
490 sub_two_proc_ids.insert(elem->processor_id());
496 CPPUNIT_ASSERT_EQUAL(1,
static_cast<int>(sub_one_proc_ids.size()));
497 CPPUNIT_ASSERT_EQUAL(1,
static_cast<int>(sub_two_proc_ids.size()));
498 CPPUNIT_ASSERT( sub_one_proc_ids == sub_two_proc_ids );
504 for (
auto &
id : sub_one_proc_ids )
505 CPPUNIT_ASSERT( sub_two_proc_ids.find(
id) == sub_two_proc_ids.end() );
508 for (
auto &
id : sub_two_proc_ids )
509 CPPUNIT_ASSERT( sub_one_proc_ids.find(
id) == sub_one_proc_ids.end() );
516#ifdef LIBMESH_HAVE_PETSC
529#ifdef LIBMESH_ENABLE_AMR
558 std::unique_ptr<CouplingMatrix> coupling_matrix;
570 std::unique_ptr<CouplingMatrix> coupling_matrix;
571 if (build_coupling_matrix)
580 functor.set_coupling_matrix(coupling_matrix);
595 std::unique_ptr<PointLocatorBase> point_locator =
_mesh->sub_point_locator();
607 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(2))
610 CPPUNIT_ASSERT_EQUAL(2,
static_cast<int>(elem->subdomain_id()));
613 const std::vector<libMesh::Point> & qpoints = subdomain_two_context.
get_element_fe(u_var)->get_xyz();
619 std::set<subdomain_id_type> allowed_subdomains;
620 allowed_subdomains.insert(1);
626 for (
const auto & qp : qpoints )
628 const Elem * overlapping_elem = (*point_locator)( qp, &allowed_subdomains );
629 CPPUNIT_ASSERT(overlapping_elem);
632 subdomain_one_context.
pre_fe_reinit(system,overlapping_elem);
651#ifdef LIBMESH_ENABLE_AMR
690 std::unique_ptr<CouplingMatrix> coupling_matrix;
691 if (build_coupling_matrix)
700 coupling_functor.set_coupling_matrix(coupling_matrix);
726 std::unique_ptr<PointLocatorBase> point_locator =
_mesh->sub_point_locator();
742 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(1))
747 std::vector<dof_id_type> & rows = subdomain_one_context.
get_dof_indices();
758 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(2))
761 CPPUNIT_ASSERT_EQUAL(2,
static_cast<int>(elem->subdomain_id()));
763 const std::vector<libMesh::Point> & qpoints = subdomain_two_context.
get_element_fe(u_var)->get_xyz();
771 std::vector<dof_id_type> & rows = subdomain_two_context.
get_dof_indices();
780 std::set<subdomain_id_type> allowed_subdomains;
781 allowed_subdomains.insert(1);
787 for (
const auto & qp : qpoints )
789 const Elem * overlapping_elem = (*point_locator)( qp, &allowed_subdomains );
790 CPPUNIT_ASSERT(overlapping_elem);
793 subdomain_one_context.
pre_fe_reinit(system,overlapping_elem);
797 std::vector<dof_id_type> & v_indices = subdomain_one_context.
get_dof_indices(v_var);
798 std::vector<dof_id_type> columns(rows);
799 columns.insert( columns.end(), v_indices.begin(), v_indices.end() );
802 K21.
resize( rows.size(), columns.size() );
812 K12.
resize(v_indices.size(), rows.size());
830#ifdef LIBMESH_HAVE_PETSC
void testGhostingCouplingMatrix()
CPPUNIT_TEST(testGhostingNullCouplingMatrixUnifRef)
LIBMESH_CPPUNIT_TEST_SUITE(OverlappingAlgebraicGhostingTest)
void testGhostingNullCouplingMatrix()
void testGhostingNullCouplingMatrixUnifRef()
CPPUNIT_TEST(testGhostingCouplingMatrix)
CPPUNIT_TEST(testGhostingNullCouplingMatrix)
void run_ghosting_test(const unsigned int n_refinements, bool build_coupling_matrix)
virtual std::unique_ptr< GhostingFunctor > clone() const override
A clone() is needed because GhostingFunctor can not be shared between different meshes.
OverlappingCouplingFunctor(System &system)
std::unique_ptr< PointLocatorBase > _point_locator
std::unique_ptr< CouplingMatrix > _coupling_matrix
void set_coupling_matrix(std::unique_ptr< CouplingMatrix > &coupling_matrix)
virtual ~OverlappingCouplingFunctor()
void testSparsityNullCouplingMatrixUnifRef()
CPPUNIT_TEST(testSparsityNullCouplingMatrix)
void testSparsityNullCouplingMatrix()
void testSparsityCouplingMatrix()
CPPUNIT_TEST(testSparsityCouplingMatrix)
CPPUNIT_TEST(testSparsityNullCouplingMatrixUnifRef)
void run_sparsity_pattern_test(const unsigned int n_refinements, bool build_coupling_matrix)
LIBMESH_CPPUNIT_TEST_SUITE(OverlappingCouplingGhostingTest)
void checkCouplingFunctorQuadUnifRef()
CPPUNIT_TEST(checkCouplingFunctorTri)
void checkCouplingFunctorQuad()
void checkCouplingFunctorTri()
CPPUNIT_TEST(checkCouplingFunctorQuadUnifRef)
void run_coupling_functor_test(unsigned int n_refinements)
void checkOverlappingPartitioner()
CPPUNIT_TEST(checkCouplingFunctorTriUnifRef)
CPPUNIT_TEST(checkOverlappingPartitionerUnifRef)
void checkOverlappingPartitionerUnifRef()
CPPUNIT_TEST(checkOverlappingPartitioner)
void checkCouplingFunctorTriUnifRef()
LIBMESH_CPPUNIT_TEST_SUITE(OverlappingFunctorTest)
void run_partitioner_test(unsigned int n_refinements)
CPPUNIT_TEST(checkCouplingFunctorQuad)
std::unique_ptr< MeshBase > _mesh
std::unique_ptr< EquationSystems > _es
void setup_coupling_matrix(std::unique_ptr< CouplingMatrix > &coupling)
void build_quad_mesh(unsigned int n_refinements=0)
virtual std::unique_ptr< Partitioner > clone() const override
OverlappingTestPartitioner()=default
void assign_proc_id_subdomain(MeshBase &mesh, const subdomain_id_type sid, const dof_id_type blksize, const unsigned int n_parts, const processor_id_type offset)
virtual ~OverlappingTestPartitioner()=default
OverlappingTestPartitioner & operator=(const OverlappingTestPartitioner &)=default
OverlappingTestPartitioner(const OverlappingTestPartitioner &)=default
OverlappingTestPartitioner(OverlappingTestPartitioner &&)=default
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
Partition the MeshBase into n subdomains.
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().
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
This class handles the numbering of degrees of freedom on a mesh.
void reinit_send_list(MeshBase &mesh)
Clears the _send_list vector and then rebuilds it.
const std::vector< dof_id_type > & get_send_list() const
bool is_attached(SparseMatrix< Number > &matrix)
Matrices should not be attached more than once.
void compute_sparsity(const MeshBase &)
Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear...
void clear_sparsity()
Clears the sparsity pattern.
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors.
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
processor_id_type processor_id() const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
This is the base class from which all geometric element types are derived.
virtual Node *& set_node(const unsigned int i)
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 ...
subdomain_id_type subdomain_id() const
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
This class provides all data required for a physics package (e.g.
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
void get_element_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for interior finite element object for variable var for the largest dimension in the mesh.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Order default_quadrature_order() const
This abstract base class defines the interface by which library code and user code can report associa...
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
const MeshBase * get_mesh() const
Return the mesh associated with ghosting functor.
const SparseMatrix< Number > & get_system_matrix() const
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the MeshBase class.
void subdomain_ids(std::set< subdomain_id_type > &ids, const bool global=true) const
Constructs a list of all subdomain identifiers in the local mesh if global == false,...
unsigned int level ElemType type std::set< subdomain_id_type > ss processor_id_type pid unsigned int level std::set< subdomain_id_type > virtual ss SimpleRange< element_iterator > active_subdomain_elements_ptr_range(subdomain_id_type sid)=0
std::unique_ptr< PointLocatorBase > sub_point_locator() const
virtual dof_id_type n_active_elem() const =0
subdomain_id_type n_subdomains() const
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
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
processor_id_type n_processors() const
The Partitioner class provides a uniform interface for partitioning algorithms.
bool single_partition_range(MeshBase::element_iterator it, MeshBase::element_iterator end)
Slightly generalized version of single_partition which acts on a range of elements defined by the pai...
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class implements specific orders of Gauss quadrature.
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.
Manages consistently variables, degrees of freedom, and coefficient vectors.
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
dof_id_type n_dofs() const
const FEType & variable_type(const unsigned int i) const
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.
dof_id_type n_local_dofs() const
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
unsigned int variable_number(std::string_view var) const
unsigned int n_vars() const
const DofMap & get_dof_map() const
const MeshBase & get_mesh() const
Communicator * TestCommWorld
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
uint8_t processor_id_type
CPPUNIT_TEST_SUITE_REGISTRATION(OverlappingFunctorTest)
The definition of the const_element_iterator struct.