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);
166 const unsigned int n)
override
173 libmesh_assert_greater (n, 0);
180 for (
auto & elem :
mesh.active_element_ptr_range() )
182 elem->processor_id() = e;
191 unsigned int n_sub_two_elems = std::distance(
mesh.active_subdomain_elements_begin(2),
192 mesh.active_subdomain_elements_end(2) );
194 unsigned int n_parts_sub_two = 0;
195 if( n_sub_two_elems < n/2 )
196 n_parts_sub_two = n_sub_two_elems;
198 n_parts_sub_two = n/2;
200 const unsigned int n_parts_sub_one = n - n_parts_sub_two;
202 const dof_id_type sub_two_blk_size = cast_int<dof_id_type>
203 (std::distance(
mesh.active_subdomain_elements_begin(2),
204 mesh.active_subdomain_elements_end(2) )/n_parts_sub_two );
209 const dof_id_type sub_one_blk_size = cast_int<dof_id_type>
210 (std::distance(
mesh.active_subdomain_elements_begin(1),
211 mesh.active_subdomain_elements_end(1) )/n_parts_sub_one );
221 const unsigned int n_parts,
227 if ((e/blksize) < n_parts)
228 elem->processor_id() = offset + cast_int<processor_id_type>(e/blksize);
230 elem->processor_id() = offset;
249 std::unique_ptr<EquationSystems>
_es;
258 _mesh->set_mesh_dimension(2);
269 for (
unsigned int n=0; n<4; n++)
301 _mesh->partitioner() = std::make_unique<OverlappingTestPartitioner>();
303 _mesh->prepare_for_use();
305#ifdef LIBMESH_ENABLE_AMR
306 if (n_refinements > 0)
312 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
318 _es = std::make_unique<EquationSystems>(*
_mesh);
321 std::set<subdomain_id_type> sub_one;
324 std::set<subdomain_id_type> sub_two;
344 System & system =
_es->get_system(
"SimpleSystem");
346 coupling = std::make_unique<CouplingMatrix>(system.
n_vars());
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;
374#ifdef LIBMESH_HAVE_SOLVER
378# ifdef LIBMESH_ENABLE_AMR
437#if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_SOLVER)
438 if( n_refinements > 0 )
445 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
448 System & system =
_es->get_system(
"SimpleSystem");
455 coupling_functor(
_mesh->active_subdomain_elements_begin(1),
456 _mesh->active_subdomain_elements_end(1),
458 subdomain_one_couplings );
460 coupling_functor(
_mesh->active_subdomain_elements_begin(2),
461 _mesh->active_subdomain_elements_end(2),
463 subdomain_two_couplings );
465 dof_id_type n_elems_subdomain_two = std::distance(
_mesh->active_subdomain_elements_begin(2),
466 _mesh->active_subdomain_elements_end(2) );
468 CPPUNIT_ASSERT_EQUAL(n_elems_subdomain_two,
static_cast<dof_id_type>(subdomain_one_couplings.size()));
469 CPPUNIT_ASSERT_EQUAL(
static_cast<dof_id_type>(2*n_elems_subdomain_two),
static_cast<dof_id_type>(subdomain_two_couplings.size()));
474#ifdef LIBMESH_ENABLE_AMR
475 if( n_refinements > 0 )
482 CPPUNIT_ASSERT_EQUAL(n_refinements, 0u);
485 System & system =
_es->get_system(
"SimpleSystem");
487 std::set<processor_id_type> sub_one_proc_ids, sub_two_proc_ids;
488 for (
auto & elem :
_mesh->active_subdomain_elements_ptr_range(1))
489 sub_one_proc_ids.insert(elem->processor_id());
491 for (
auto & elem :
_mesh->active_subdomain_elements_ptr_range(2))
492 sub_two_proc_ids.insert(elem->processor_id());
498 CPPUNIT_ASSERT_EQUAL(1,
static_cast<int>(sub_one_proc_ids.size()));
499 CPPUNIT_ASSERT_EQUAL(1,
static_cast<int>(sub_two_proc_ids.size()));
500 CPPUNIT_ASSERT( sub_one_proc_ids == sub_two_proc_ids );
506 for (
auto &
id : sub_one_proc_ids )
507 CPPUNIT_ASSERT( sub_two_proc_ids.find(
id) == sub_two_proc_ids.end() );
510 for (
auto &
id : sub_two_proc_ids )
511 CPPUNIT_ASSERT( sub_one_proc_ids.find(
id) == sub_one_proc_ids.end() );
518#ifdef LIBMESH_HAVE_PETSC
531#ifdef LIBMESH_ENABLE_AMR
560 std::unique_ptr<CouplingMatrix> coupling_matrix;
572 std::unique_ptr<CouplingMatrix> coupling_matrix;
573 if (build_coupling_matrix)
582 functor.set_coupling_matrix(coupling_matrix);
597 std::unique_ptr<PointLocatorBase> point_locator =
_mesh->sub_point_locator();
609 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(2))
612 CPPUNIT_ASSERT_EQUAL(2,
static_cast<int>(elem->subdomain_id()));
615 const std::vector<libMesh::Point> & qpoints = subdomain_two_context.
get_element_fe(u_var)->get_xyz();
621 std::set<subdomain_id_type> allowed_subdomains;
622 allowed_subdomains.insert(1);
628 for (
const auto & qp : qpoints )
630 const Elem * overlapping_elem = (*point_locator)( qp, &allowed_subdomains );
631 CPPUNIT_ASSERT(overlapping_elem);
634 subdomain_one_context.
pre_fe_reinit(system,overlapping_elem);
653#ifdef LIBMESH_ENABLE_AMR
692 std::unique_ptr<CouplingMatrix> coupling_matrix;
693 if (build_coupling_matrix)
702 coupling_functor.set_coupling_matrix(coupling_matrix);
728 std::unique_ptr<PointLocatorBase> point_locator =
_mesh->sub_point_locator();
744 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(1))
749 std::vector<dof_id_type> & rows = subdomain_one_context.
get_dof_indices();
760 for (
const auto & elem :
_mesh->active_local_subdomain_elements_ptr_range(2))
763 CPPUNIT_ASSERT_EQUAL(2,
static_cast<int>(elem->subdomain_id()));
765 const std::vector<libMesh::Point> & qpoints = subdomain_two_context.
get_element_fe(u_var)->get_xyz();
773 std::vector<dof_id_type> & rows = subdomain_two_context.
get_dof_indices();
782 std::set<subdomain_id_type> allowed_subdomains;
783 allowed_subdomains.insert(1);
789 for (
const auto & qp : qpoints )
791 const Elem * overlapping_elem = (*point_locator)( qp, &allowed_subdomains );
792 CPPUNIT_ASSERT(overlapping_elem);
795 subdomain_one_context.
pre_fe_reinit(system,overlapping_elem);
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() );
804 K21.
resize( rows.size(), columns.size() );
814 K12.
resize(v_indices.size(), rows.size());
832#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 bool partitions_from_scratch() const override
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.