15#ifndef dealii_mg_transfer_global_coarsening_h
16#define dealii_mg_transfer_global_coarsening_h
45 class MGTwoLevelTransferImplementation;
50 template <
int dim,
int spacedim>
151 const unsigned int degree,
159 std::vector<unsigned int>
161 const unsigned int max_degree,
174 template <
int dim,
int spacedim>
175 std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
195 template <
int dim,
int spacedim>
196 std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
200 const bool preserve_fine_triangulation,
201 const bool repartition_fine_triangulation);
208 template <
int dim,
int spacedim>
209 std::vector<std::shared_ptr<const Triangulation<dim, spacedim>>>
213 const bool repartition_fine_triangulation =
false);
226template <
typename VectorType>
239 "This class is currently only implemented for vectors of "
240 "type LinearAlgebra::distributed::Vector.");
245 using Number =
typename VectorType::value_type;
279 virtual std::pair<bool, bool>
281 const std::shared_ptr<const Utilities::MPI::Partitioner>
283 const std::shared_ptr<const Utilities::MPI::Partitioner>
333 template <
int dim, std::
size_t w
idth,
typename IndexType>
334 std::pair<bool, bool>
336 const std::shared_ptr<const Utilities::MPI::Partitioner>
342 &constraint_info_coarse,
343 std::vector<unsigned
int> &dof_indices_fine);
387 std::shared_ptr<const Utilities::MPI::Partitioner>
436template <
int dim,
typename VectorType>
449 "This class is currently only implemented for vectors of "
450 "type LinearAlgebra::distributed::Vector.");
455 using Number =
typename VectorType::value_type;
533 const unsigned int dof_no_fine,
535 const unsigned int dof_no_coarse);
547 const unsigned int fe_degree_coarse);
553 interpolate(VectorType &dst,
const VectorType &src)
const override;
559 std::pair<bool, bool>
561 const std::shared_ptr<const Utilities::MPI::Partitioner>
575 const VectorType &src)
const override;
579 const VectorType &src)
const override;
651 internal::MatrixFreeFunctions::
652 ConstraintInfo<dim, VectorizedArrayType, types::global_dof_index>
658 internal::MatrixFreeFunctions::
659 ConstraintInfo<dim, VectorizedArrayType, types::global_dof_index>
745template <int dim, typename VectorType>
753 "This class is currently only implemented for vectors of "
754 "type LinearAlgebra::distributed::Vector.");
756 using Number =
typename VectorType::value_type;
780 const unsigned int rtree_level = 0,
781 const bool enforce_all_points_found =
true)
782 : tolerance(tolerance)
783 , rtree_level(rtree_level)
784 , enforce_all_points_found(enforce_all_points_found)
836 interpolate(VectorType &dst,
const VectorType &src)
const override;
842 std::pair<bool, bool>
844 const std::shared_ptr<const Utilities::MPI::Partitioner>
846 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
858 boost::signals2::connection
864 boost::signals2::connection
870 boost::signals2::connection
876 boost::signals2::connection
886 const VectorType &src)
const override;
893 const VectorType &src)
const override;
899 template <
int n_components>
902 const VectorType &src)
const;
907 template <
int n_components>
940 std::shared_ptr<NonMatching::MappingInfo<dim, dim, Number>>
mapping_info;
946 internal::MatrixFreeFunctions::
947 ConstraintInfo<dim, VectorizedArrayType, unsigned int>
1001template <int dim, typename Number, typename MemorySpace>
1003 LinearAlgebra::distributed::Vector<Number, MemorySpace>>
1032 template <
typename MGTwoLevelTransferObject>
1034 const std::function<
void(
const unsigned int,
VectorType &)>
1035 &initialize_dof_vector = {});
1040 template <
typename MGTwoLevelTransferObject>
1054 build(
const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1055 &external_partitioners = {});
1063 &initialize_dof_vector);
1106 const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1107 &external_partitioners = {});
1120 const std::function<
void(
const unsigned int,
VectorType &)>
1121 &initialize_dof_vector);
1163 template <
class InVector>
1167 const InVector &src)
const;
1178 template <
class OutVector>
1202 template <
class InVector>
1206 const InVector &src)
const;
1216 template <
class InVector>
1271 std::pair<const DoFHandler<dim> *,
unsigned int>
1286 template <
typename MGTwoLevelTransferObject>
1294 template <
class InVector>
1298 const InVector &vector_reference,
1299 const bool omit_zeroing_entries)
const;
1324 std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1335template <
int dim,
typename Number>
1340 MGTransferMF<dim, Number, ::MemorySpace::Host>>
1347 &transfer_operator);
1385 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs);
1411 std::vector<MGTransferMF<dim, Number, ::MemorySpace::Host>>
1424template <
int dim,
typename VectorType>
1426 typename VectorType::value_type,
1429template <
int dim,
typename VectorType>
1442template <
int dim,
typename Number,
typename MemorySpace>
1443template <
typename MGTwoLevelTransferObject>
1446 const std::function<
void(
const unsigned int, VectorType &)>
1447 &initialize_dof_vector)
1449 this->transfer.
clear();
1450 this->internal_transfer.clear();
1452 this->initialize_transfer_references(transfer);
1453 this->build(initialize_dof_vector);
1458template <
int dim,
typename Number,
typename MemorySpace>
1459template <
typename MGTwoLevelTransferObject>
1464 this->initialize_transfer_references(transfer);
1469template <
int dim,
typename Number,
typename MemorySpace>
1470template <
typename MGTwoLevelTransferObject>
1475 const unsigned int min_level = transfer.
min_level();
1476 const unsigned int max_level = transfer.
max_level();
1478 this->transfer.
resize(min_level, max_level);
1481 for (
unsigned int l = min_level + 1;
l <= max_level; ++
l)
1489template <
int dim,
typename Number,
typename MemorySpace>
1490template <
class InVector>
1493 const unsigned int level,
1495 const InVector &vec_reference,
1496 const bool omit_zeroing_entries)
const
1498 std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1500 if (external_partitioners.empty())
1502 partitioner = vec_reference.get_partitioner();
1509 partitioner = external_partitioners[
level - transfer.
min_level()];
1515 if (vec.get_partitioner().get() == partitioner.get())
1517 if (omit_zeroing_entries ==
false)
1523 if (vec.size() == partitioner->size() &&
1524 vec.locally_owned_size() == partitioner->locally_owned_size())
1526 if (omit_zeroing_entries ==
false)
1532 vec.reinit(partitioner, omit_zeroing_entries);
1537template <
int dim,
typename Number,
typename MemorySpace>
1538template <
class InVector>
1543 const InVector &src)
const
1545 assert_dof_handler(dof_handler);
1549 const bool zero_out_values =
1550 (this->perform_plain_copy ==
false &&
1551 this->perform_renumbered_plain_copy ==
false) ||
1554 this->initialize_dof_vector(
level, dst[
level], src, !zero_out_values);
1557 if (this->perform_plain_copy)
1559 dst[dst.
max_level()].copy_locally_owned_data_from(src);
1561 else if (this->perform_renumbered_plain_copy)
1565 for (
unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i)
1566 dst_level.local_element(this->copy_indices.back()(1, i)) =
1567 src.local_element(i);
1571 this->ghosted_global_vector = src;
1572 this->ghosted_global_vector.update_ghost_values();
1578 auto &dst_level = dst[
l];
1580 const auto copy_unknowns = [&](
const auto &indices) {
1581 for (
unsigned int i = 0; i < indices.n_cols(); ++i)
1582 dst_level.local_element(indices(1, i)) =
1583 this->ghosted_global_vector.local_element(indices(0, i));
1586 copy_unknowns(this->copy_indices[l]);
1587 copy_unknowns(this->copy_indices_level_mine[l]);
1596template <
int dim,
typename Number,
typename MemorySpace>
1597template <
class OutVector>
1604 assert_dof_handler(dof_handler);
1606 if (this->perform_plain_copy)
1608 dst.zero_out_ghost_values();
1609 dst.copy_locally_owned_data_from(src[src.
max_level()]);
1611 else if (this->perform_renumbered_plain_copy)
1613 const auto &src_level = src[src.
max_level()];
1614 dst.zero_out_ghost_values();
1615 for (
unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i)
1616 dst.local_element(i) =
1617 src_level.local_element(this->copy_indices.back()(1, i));
1624 auto &ghosted_vector = this->ghosted_level_vector[
l];
1626 if (this->ghosted_level_vector[l].
size() > 0)
1627 ghosted_vector = src[l];
1629 const auto *
const ghosted_vector_ptr =
1630 (this->ghosted_level_vector[
l].size() > 0) ? &ghosted_vector :
1633 ghosted_vector_ptr->update_ghost_values();
1635 const auto copy_unknowns = [&](
const auto &indices) {
1636 for (
unsigned int i = 0; i < indices.n_cols(); ++i)
1637 dst.local_element(indices(0, i)) =
1638 ghosted_vector_ptr->local_element(indices(1, i));
1641 copy_unknowns(this->copy_indices[l]);
1642 copy_unknowns(this->copy_indices_global_mine[l]);
1650template <
int dim,
typename Number,
typename MemorySpace>
1651template <
class InVector>
1655 const InVector &src)
const
1659 this->interpolate_to_mg(dof_handler_dummy, dst, src);
1664template <
int dim,
typename Number,
typename MemorySpace>
1665template <
class InVector>
1670 const InVector &src)
const
1672 assert_dof_handler(dof_handler);
1674 const unsigned int min_level = transfer.
min_level();
1675 const unsigned int max_level = transfer.
max_level();
1682 const bool zero_out_values =
false;
1683 this->initialize_dof_vector(
level, dst[
level], src, !zero_out_values);
1686 if (this->perform_plain_copy)
1688 dst[max_level].copy_locally_owned_data_from(src);
1690 for (
unsigned int l = max_level;
l > min_level; --
l)
1691 this->transfer[l]->
interpolate(dst[l - 1], dst[l]);
1693 else if (this->perform_renumbered_plain_copy)
1695 auto &dst_level = dst[max_level];
1697 for (
unsigned int i = 0; i < this->solution_copy_indices.back().n_cols();
1699 dst_level.local_element(this->solution_copy_indices.back()(1, i)) =
1700 src.local_element(i);
1702 for (
unsigned int l = max_level;
l > min_level; --
l)
1703 this->transfer[l]->
interpolate(dst[l - 1], dst[l]);
1707 this->solution_ghosted_global_vector = src;
1708 this->solution_ghosted_global_vector.update_ghost_values();
1710 for (
unsigned int l = max_level + 1;
l != min_level;)
1714 auto &dst_level = dst[
l];
1716 const auto copy_unknowns = [&](
const auto &indices) {
1717 for (
unsigned int i = 0; i < indices.n_cols(); ++i)
1718 dst_level.local_element(indices(1, i)) =
1719 this->solution_ghosted_global_vector.local_element(
1723 copy_unknowns(this->solution_copy_indices[l]);
1724 copy_unknowns(this->solution_copy_indices_level_mine[l]);
1729 this->transfer[
l]->interpolate(dst[l - 1], dst[l]);
std::function< void(const unsigned int, LinearAlgebra::distributed::Vector< Number, MemorySpace > &)> initialize_dof_vector
void resize(const unsigned int new_minlevel, const unsigned int new_maxlevel, Args &&...args)
unsigned int max_level() const
unsigned int min_level() const
void initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs)
MGTransferBlockMF(const std::vector< MGConstrainedDoFs > &mg_constrained_dofs)
MGTransferBlockMF(const MGConstrainedDoFs &mg_constrained_dofs)
void build(const std::vector< const DoFHandler< dim > * > &dof_handler)
std::vector< MGTransferMF< dim, Number, ::MemorySpace::Host > > transfer_operators_internal
const MGTransferMF< dim, Number, ::MemorySpace::Host > & get_matrix_free_transfer(const unsigned int b) const override
MGTransferBlockMF()=default
void build(const DoFHandler< dim > &dof_handler)
MGTransferBlockMF(const MGTransferMF< dim, Number, ::MemorySpace::Host > &transfer_operator)
void initialize_constraints(const std::vector< MGConstrainedDoFs > &mg_constrained_dofs)
std::vector< ObserverPointer< const MGTransferMF< dim, Number, ::MemorySpace::Host > > > transfer_operators
void initialize_two_level_transfers(const MGLevelObject< MGTwoLevelTransferObject > &transfer)
void initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs)
void build(const DoFHandler< dim > &dof_handler, const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector)
void interpolate_to_mg(const DoFHandler< dim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
void build(const DoFHandler< dim > &dof_handler, const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners={})
std::size_t memory_consumption() const
void prolongate(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
void assert_dof_handler(const DoFHandler< dim > &dof_handler_out) const
unsigned int max_level() const
unsigned int min_level() const
void initialize_internal_transfer(const DoFHandler< dim > &dof_handler, const ObserverPointer< const MGConstrainedDoFs > &mg_constrained_dofs)
void initialize_dof_vector(const unsigned int level, VectorType &vector, const InVector &vector_reference, const bool omit_zeroing_entries) const
void initialize_transfer_references(const MGLevelObject< MGTwoLevelTransferObject > &transfer)
MGTransferMF(const MGLevelObject< MGTwoLevelTransferObject > &transfer, const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector={})
std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > external_partitioners
void interpolate_to_mg(MGLevelObject< VectorType > &dst, const InVector &src) const
MGLevelObject< MGTwoLevelTransfer< dim, VectorType > > internal_transfer
void copy_to_mg(const DoFHandler< dim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
void build(const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector)
void prolongate_and_add(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
MGTransferMF(const MGConstrainedDoFs &mg_constrained_dofs)
void copy_from_mg(const DoFHandler< dim > &dof_handler, OutVector &dst, const MGLevelObject< VectorType > &src) const
void fill_and_communicate_copy_indices_global_coarsening(const DoFHandler< dim > &dof_handler)
virtual void restrict_and_add(const unsigned int from_level, VectorType &dst, const VectorType &src) const override
void build(const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners={})
MGLevelObject< ObserverPointer< MGTwoLevelTransferBase< VectorType > > > transfer
std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const
AlignedVector< Number > buffer_coarse_embedded
void zero_out_ghost_values(const VectorType &vec) const
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_fine_embedded
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_coarse
virtual std::size_t memory_consumption() const =0
AlignedVector< Number > buffer_fine_embedded
void prolongate_and_add(VectorType &dst, const VectorType &src) const
bool fine_element_is_continuous
void update_ghost_values(const VectorType &vec) const
virtual void restrict_and_add_internal(VectorType &dst, const VectorType &src) const =0
typename VectorType::value_type Number
bool vec_fine_needs_ghost_update
virtual std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine)=0
void restrict_and_add(VectorType &dst, const VectorType &src) const
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_coarse_embedded
virtual void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const =0
std::pair< bool, bool > internal_enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine, bool &vec_fine_needs_ghost_update, internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArray< Number, width >, IndexType > &constraint_info_coarse, std::vector< unsigned int > &dof_indices_fine)
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_fine
virtual void interpolate(VectorType &dst, const VectorType &src) const =0
void compress(VectorType &vec, const VectorOperation::values op) const
std::shared_ptr< NonMatching::MappingInfo< dim, dim, Number > > mapping_info
boost::signals2::connection connect_restriction(const std::function< void(const bool)> &slot)
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const Mapping< dim > &mapping_fine, const Mapping< dim > &mapping_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >())
AdditionalData additional_data
std::unique_ptr< FiniteElement< dim > > fe_coarse
std::vector< Number > rpe_input_output
ObserverPointer< const DoFHandler< dim > > dof_handler_fine
void restrict_and_add_internal_comp(VectorType &dst, const VectorType &src) const
boost::signals2::connection connect_prolongation_cell_loop(const std::function< void(const bool)> &slot)
std::vector< Number > rpe_buffer
std::size_t memory_consumption() const override
std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine) override
Utilities::MPI::RemotePointEvaluation< dim > rpe
void restrict_and_add_internal(VectorType &dst, const VectorType &src) const override
std::vector< unsigned int > level_dof_indices_fine_ptrs
mg::SignalsNonNested signals_non_nested
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, unsigned int > constraint_info
boost::signals2::connection connect_prolongation(const std::function< void(const bool)> &slot)
boost::signals2::connection connect_restriction_cell_loop(const std::function< void(const bool)> &slot)
void prolongate_and_add_internal_comp(VectorType &dst, const VectorType &src) const
MGTwoLevelTransferNonNested(const AdditionalData &data=AdditionalData())
void interpolate(VectorType &dst, const VectorType &src) const override
std::vector< unsigned int > level_dof_indices_fine
typename VectorType::value_type Number
unsigned int mg_level_fine
void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const override
void reinit_geometric_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, types::global_dof_index > constraint_info_fine
friend class internal::MGTwoLevelTransferImplementation
std::vector< MGTransferScheme > schemes
ObserverPointer< const DoFHandler< dim > > dof_handler_fine
typename VectorType::value_type Number
std::vector< unsigned char > weights_are_compressed
void interpolate(VectorType &dst, const VectorType &src) const override
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, types::global_dof_index > constraint_info_coarse
std::unique_ptr< MatrixFreeRelatedData > matrix_free_data
static bool fast_polynomial_transfer_supported(const unsigned int fe_degree_fine, const unsigned int fe_degree_coarse)
AlignedVector< VectorizedArrayType > weights
void reinit_polynomial_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
unsigned int mg_level_fine
std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine) override
void restrict_and_add_internal(VectorType &dst, const VectorType &src) const override
unsigned int n_components
std::vector< unsigned int > weights_start
void reinit(const MatrixFree< dim, Number > &matrix_free_fine, const unsigned int dof_no_fine, const MatrixFree< dim, Number > &matrix_free_coarse, const unsigned int dof_no_coarse)
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
std::size_t memory_consumption() const override
void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const override
Abstract base class for mapping classes.
static constexpr std::size_t size()
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
std::vector< index_type > data
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T & get_underlying_value(T &p)
static const unsigned int invalid_unsigned_int
bool enforce_all_points_found
AdditionalData(const double tolerance=1e-6, const unsigned int rtree_level=0, const bool enforce_all_points_found=true)
unsigned int degree_coarse
unsigned int n_dofs_per_cell_coarse
unsigned int n_coarse_cells
AlignedVector< double > restriction_matrix
internal::MatrixFreeFunctions::ShapeInfo< double > shape_info_coarse
unsigned int n_dofs_per_cell_fine
AlignedVector< double > prolongation_matrix
boost::signals2::signal< void(const bool before)> prolongation_cell_loop
boost::signals2::signal< void(const bool before)> restriction
boost::signals2::signal< void(const bool before)> restriction_cell_loop
boost::signals2::signal< void(const bool before)> prolongation