* user code. It combines constraint related functionalities from
* MatrixFree and FEEvaluation.
*/
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType = unsigned int>
class ConstraintInfo
{
public:
* Version 1: indices are extracted from DoFCellAccessor and
* constraints are resolved with the help of AffineConstraints.
*/
- template <typename T = unsigned int>
void
reinit(const DoFHandler<dim> &dof_handler,
const unsigned int n_cells,
const bool use_fast_hanging_node_algorithm = true);
- template <typename T = unsigned int>
void
read_dof_indices(
const unsigned int cell_no,
/**
* Version 2: no constraints, indices are user-provided.
*/
- template <typename T = unsigned int>
void
reinit(const unsigned int n_cells);
- template <typename T = unsigned int>
void
read_dof_indices(
const unsigned int cell_no,
const std::vector<types::global_dof_index> &dof_indices,
const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
- template <typename T = unsigned int>
void
finalize();
- template <typename T = unsigned int>
std::shared_ptr<const Utilities::MPI::Partitioner>
finalize(const MPI_Comm comm);
ConstraintValues<double> constraint_values;
std::vector<std::vector<unsigned int>> dof_indices_per_cell;
std::vector<std::vector<unsigned int>> plain_dof_indices_per_cell;
- std::vector<std::vector<types::global_dof_index>>
- dof_indices_per_cell_long;
- std::vector<std::vector<types::global_dof_index>>
- plain_dof_indices_per_cell_long;
std::vector<std::vector<std::pair<unsigned short, unsigned short>>>
constraint_indicator_per_cell;
std::unique_ptr<HangingNodes<dim>> hanging_nodes;
std::vector<std::vector<unsigned int>> lexicographic_numbering;
+ std::vector<types::global_dof_index> local_dof_indices;
+ std::vector<types::global_dof_index> local_dof_indices_lex;
+ std::vector<ConstraintKinds> mask;
+
IndexSet locally_owned_indices;
std::pair<types::global_dof_index, types::global_dof_index> local_range;
inline const typename Number::value_type *
constraint_pool_end(const unsigned int row) const;
-
- // TODO
- std::vector<types::global_dof_index> local_dof_indices;
- std::vector<types::global_dof_index> local_dof_indices_lex;
- std::vector<ConstraintKinds> mask;
-
- template <typename T>
- std::vector<std::vector<T>> &
- get_dof_indices_per_cell()
- {
- if constexpr (std::is_same_v<T, unsigned int>)
- return dof_indices_per_cell;
- else if constexpr (std::is_same_v<T, types::global_dof_index>)
- return dof_indices_per_cell_long;
- else
- return {};
- }
-
- template <typename T>
- std::vector<std::vector<T>> &
- get_plain_dof_indices_per_cell()
- {
- if constexpr (std::is_same_v<T, unsigned int>)
- return plain_dof_indices_per_cell;
- else if constexpr (std::is_same_v<T, types::global_dof_index>)
- return plain_dof_indices_per_cell_long;
- else
- return {};
- }
};
- template <int dim, typename Number>
- ConstraintInfo<dim, Number>::ConstraintInfo()
+ template <int dim, typename Number, typename IndexType>
+ ConstraintInfo<dim, Number, IndexType>::ConstraintInfo()
: local_range({0, 0})
{}
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
void
- ConstraintInfo<dim, Number>::set_locally_owned_indices(
+ ConstraintInfo<dim, Number, IndexType>::set_locally_owned_indices(
const IndexSet &locally_owned_indices)
{
this->locally_owned_indices = locally_owned_indices;
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::reinit(
+ ConstraintInfo<dim, Number, IndexType>::reinit(
const DoFHandler<dim> &dof_handler,
const unsigned int n_cells,
const bool use_fast_hanging_node_algorithm)
{
- this->template get_dof_indices_per_cell<T>().resize(n_cells);
- this->template get_plain_dof_indices_per_cell<T>().resize(n_cells);
+ this->dof_indices_per_cell.resize(n_cells);
+ this->plain_dof_indices_per_cell.resize(n_cells);
this->constraint_indicator_per_cell.resize(n_cells);
// note: has_hanging_nodes() is a global operatrion
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::reinit(const unsigned int n_cells)
+ ConstraintInfo<dim, Number, IndexType>::reinit(const unsigned int n_cells)
{
- this->template get_dof_indices_per_cell<T>().resize(n_cells);
- this->template get_plain_dof_indices_per_cell<T>().resize(0);
+ this->dof_indices_per_cell.resize(n_cells);
+ this->plain_dof_indices_per_cell.resize(0);
this->constraint_indicator_per_cell.resize(n_cells);
}
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::read_dof_indices(
+ ConstraintInfo<dim, Number, IndexType>::read_dof_indices(
const unsigned int cell_no,
const unsigned int mg_level,
const TriaIterator<DoFCellAccessor<dim, dim, false>> &cell,
std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
AssertIndexRange(cell_no, this->constraint_indicator_per_cell.size());
- AssertIndexRange(cell_no,
- this->template get_dof_indices_per_cell<T>().size());
- AssertIndexRange(
- cell_no, this->template get_plain_dof_indices_per_cell<T>().size());
+ AssertIndexRange(cell_no, this->dof_indices_per_cell.size());
+ AssertIndexRange(cell_no, this->plain_dof_indices_per_cell.size());
auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
- auto &dof_indices = this->template get_dof_indices_per_cell<T>()[cell_no];
- auto &plain_dof_indices =
- this->template get_plain_dof_indices_per_cell<T>()[cell_no];
+ auto &dof_indices = this->dof_indices_per_cell[cell_no];
+ auto &plain_dof_indices = this->plain_dof_indices_per_cell[cell_no];
AssertDimension(constraint_indicator_per_cell[cell_no].size(), 0);
- AssertDimension(
- this->template get_dof_indices_per_cell<T>()[cell_no].size(), 0);
- AssertDimension(
- this->template get_plain_dof_indices_per_cell<T>()[cell_no].size(), 0);
+ AssertDimension(this->dof_indices_per_cell[cell_no].size(), 0);
+ AssertDimension(this->plain_dof_indices_per_cell[cell_no].size(), 0);
const auto global_to_local =
- [&](const types::global_dof_index global_index) -> T {
+ [&](const types::global_dof_index global_index) -> IndexType {
if (partitioner)
return partitioner->global_to_local(global_index);
else
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::read_dof_indices(
+ ConstraintInfo<dim, Number, IndexType>::read_dof_indices(
const unsigned int cell_no,
const std::vector<types::global_dof_index> &local_dof_indices_lex,
const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
{
const auto global_to_local =
- [&](const types::global_dof_index global_index) -> T {
+ [&](const types::global_dof_index global_index) -> IndexType {
if (partitioner)
return partitioner->global_to_local(global_index);
else
std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
auto &constraint_indicator = this->constraint_indicator_per_cell[cell_no];
- auto &dof_indices = this->template get_dof_indices_per_cell<T>()[cell_no];
+ auto &dof_indices = this->dof_indices_per_cell[cell_no];
for (const auto current_dof : local_dof_indices_lex)
{
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::finalize()
+ ConstraintInfo<dim, Number, IndexType>::finalize()
{
Assert((local_range ==
std::pair<types::global_dof_index, types::global_dof_index>{0,
this->row_starts = {};
this->row_starts.emplace_back(0, 0);
- if (this->template get_plain_dof_indices_per_cell<T>().empty() == false)
+ if (this->plain_dof_indices_per_cell.empty() == false)
{
this->row_starts_plain_indices = {};
this->row_starts_plain_indices.emplace_back(0);
}
- for (unsigned int i = 0;
- i < this->template get_dof_indices_per_cell<T>().size();
- ++i)
+ for (unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
{
- this->dof_indices.insert(
- this->dof_indices.end(),
- this->template get_dof_indices_per_cell<T>()[i].begin(),
- this->template get_dof_indices_per_cell<T>()[i].end());
+ this->dof_indices.insert(this->dof_indices.end(),
+ this->dof_indices_per_cell[i].begin(),
+ this->dof_indices_per_cell[i].end());
this->constraint_indicator.insert(
this->constraint_indicator.end(),
constraint_indicator_per_cell[i].begin(),
this->row_starts.emplace_back(this->dof_indices.size(),
this->constraint_indicator.size());
- if (this->template get_plain_dof_indices_per_cell<T>().empty() ==
- false)
+ if (this->plain_dof_indices_per_cell.empty() == false)
{
this->plain_dof_indices.insert(
this->plain_dof_indices.end(),
- this->template get_plain_dof_indices_per_cell<T>()[i].begin(),
- this->template get_plain_dof_indices_per_cell<T>()[i].end());
+ this->plain_dof_indices_per_cell[i].begin(),
+ this->plain_dof_indices_per_cell[i].end());
this->row_starts_plain_indices.emplace_back(
this->plain_dof_indices.size());
AssertDimension(constraint_pool_data.size(), length);
- this->template get_dof_indices_per_cell<T>().clear();
+ this->dof_indices_per_cell.clear();
constraint_indicator_per_cell.clear();
if (hanging_nodes &&
}
- template <int dim, typename Number>
- template <typename T>
+ template <int dim, typename Number, typename IndexType>
inline std::shared_ptr<const Utilities::MPI::Partitioner>
- ConstraintInfo<dim, Number>::finalize(const MPI_Comm comm)
+ ConstraintInfo<dim, Number, IndexType>::finalize(const MPI_Comm comm)
{
this->dof_indices.clear();
this->plain_dof_indices.clear();
this->constraint_indicator.clear();
this->row_starts.clear();
- this->row_starts.reserve(
- this->template get_dof_indices_per_cell<T>().size());
+ this->row_starts.reserve(this->dof_indices_per_cell.size());
this->row_starts.emplace_back(0, 0);
- if (this->template get_plain_dof_indices_per_cell<T>().empty() == false)
+ if (this->plain_dof_indices_per_cell.empty() == false)
{
this->row_starts_plain_indices.clear();
this->row_starts_plain_indices.reserve(
- this->template get_dof_indices_per_cell<T>().size());
+ this->dof_indices_per_cell.size());
this->row_starts_plain_indices.emplace_back(0);
}
std::vector<types::global_dof_index> ghost_dofs;
std::pair<unsigned int, unsigned int> counts = {0, 0};
- for (unsigned int i = 0;
- i < this->template get_dof_indices_per_cell<T>().size();
- ++i)
+ for (unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
{
- counts.first +=
- this->template get_dof_indices_per_cell<T>()[i].size();
+ counts.first += this->dof_indices_per_cell[i].size();
- for (const auto &j : this->template get_dof_indices_per_cell<T>()[i])
+ for (const auto &j : this->dof_indices_per_cell[i])
if (j >= (local_range.second - local_range.first))
ghost_dofs.push_back(j -
(local_range.second - local_range.first));
- if (this->template get_plain_dof_indices_per_cell<T>().empty() ==
- false)
+ if (this->plain_dof_indices_per_cell.empty() == false)
{
- counts.second +=
- this->template get_plain_dof_indices_per_cell<T>()[i].size();
+ counts.second += this->plain_dof_indices_per_cell[i].size();
- for (const auto &j :
- this->template get_plain_dof_indices_per_cell<T>()[i])
+ for (const auto &j : this->plain_dof_indices_per_cell[i])
if (j >= (local_range.second - local_range.first))
ghost_dofs.push_back(
j - (local_range.second - local_range.first));
this->dof_indices.reserve(counts.first);
this->plain_dof_indices.reserve(counts.second);
- for (unsigned int i = 0;
- i < this->template get_dof_indices_per_cell<T>().size();
- ++i)
+ for (unsigned int i = 0; i < this->dof_indices_per_cell.size(); ++i)
{
- for (const auto &j : this->template get_dof_indices_per_cell<T>()[i])
+ for (const auto &j : this->dof_indices_per_cell[i])
if (j < (local_range.second - local_range.first))
this->dof_indices.push_back(j);
else
this->row_starts.emplace_back(this->dof_indices.size(),
this->constraint_indicator.size());
- if (this->template get_plain_dof_indices_per_cell<T>().empty() ==
- false)
+ if (this->plain_dof_indices_per_cell.empty() == false)
{
- for (const auto &j :
- this->template get_plain_dof_indices_per_cell<T>()[i])
+ for (const auto &j : this->plain_dof_indices_per_cell[i])
if (j < (local_range.second - local_range.first))
this->plain_dof_indices.push_back(j);
else
AssertDimension(constraint_pool_data.size(), length);
- this->template get_dof_indices_per_cell<T>().clear();
+ this->dof_indices_per_cell.clear();
constraint_indicator_per_cell.clear();
if (hanging_nodes &&
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
template <typename T, typename VectorType>
inline void
- ConstraintInfo<dim, Number>::read_write_operation(
+ ConstraintInfo<dim, Number, IndexType>::read_write_operation(
const T &operation,
VectorType &global_vector,
Number *local_vector,
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
inline void
- ConstraintInfo<dim, Number>::apply_hanging_node_constraints(
+ ConstraintInfo<dim, Number, IndexType>::apply_hanging_node_constraints(
const unsigned int first_cell,
const unsigned int n_lanes_filled,
const bool transpose,
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
inline const typename Number::value_type *
- ConstraintInfo<dim, Number>::constraint_pool_begin(
+ ConstraintInfo<dim, Number, IndexType>::constraint_pool_begin(
const unsigned int row) const
{
AssertIndexRange(row, constraint_pool_row_index.size() - 1);
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
inline const typename Number::value_type *
- ConstraintInfo<dim, Number>::constraint_pool_end(
+ ConstraintInfo<dim, Number, IndexType>::constraint_pool_end(
const unsigned int row) const
{
AssertIndexRange(row, constraint_pool_row_index.size() - 1);
- template <int dim, typename Number>
+ template <int dim, typename Number, typename IndexType>
inline std::size_t
- ConstraintInfo<dim, Number>::memory_consumption() const
+ ConstraintInfo<dim, Number, IndexType>::memory_consumption() const
{
std::size_t size = 0;
size += MemoryConsumption::memory_consumption(constraint_values);
size += MemoryConsumption::memory_consumption(dof_indices_per_cell);
size += MemoryConsumption::memory_consumption(plain_dof_indices_per_cell);
- size += MemoryConsumption::memory_consumption(dof_indices_per_cell_long);
- size +=
- MemoryConsumption::memory_consumption(plain_dof_indices_per_cell_long);
size +=
MemoryConsumption::memory_consumption(constraint_indicator_per_cell);
unsigned int cell_no_0 = 0;
unsigned int cell_no_1 = transfer.schemes[0].n_coarse_cells;
- transfer.constraint_info_coarse
- .template reinit<types::global_dof_index>(
- dof_handler_coarse,
- transfer.schemes[0].n_coarse_cells +
- transfer.schemes[1].n_coarse_cells,
- constraints_coarse.n_constraints() > 0 &&
- use_fast_hanging_node_algorithm(dof_handler_coarse,
- mg_level_coarse));
+ transfer.constraint_info_coarse.reinit(
+ dof_handler_coarse,
+ transfer.schemes[0].n_coarse_cells +
+ transfer.schemes[1].n_coarse_cells,
+ constraints_coarse.n_constraints() > 0 &&
+ use_fast_hanging_node_algorithm(dof_handler_coarse,
+ mg_level_coarse));
transfer.constraint_info_coarse.set_locally_owned_indices(
(mg_level_coarse == numbers::invalid_unsigned_int) ?
dof_handler_coarse.locally_owned_dofs() :
dof_handler_coarse.locally_owned_mg_dofs(mg_level_coarse));
- transfer.constraint_info_fine.template reinit<types::global_dof_index>(
+ transfer.constraint_info_fine.reinit(
transfer.schemes[0].n_coarse_cells +
transfer.schemes[1].n_coarse_cells);
transfer.constraint_info_fine.set_locally_owned_indices(
[&](const auto &cell_coarse, const auto &cell_fine) {
// parent
{
- transfer.constraint_info_coarse
- .template read_dof_indices<types::global_dof_index>(
- cell_no_0,
- mg_level_coarse,
- cell_coarse,
- constraints_coarse,
- {});
+ transfer.constraint_info_coarse.read_dof_indices(
+ cell_no_0,
+ mg_level_coarse,
+ cell_coarse,
+ constraints_coarse,
+ {});
}
// child
level_dof_indices_fine_0[i] =
local_dof_indices[lexicographic_numbering_fine[i]];
- transfer.constraint_info_fine
- .template read_dof_indices<types::global_dof_index>(
- cell_no_0, level_dof_indices_fine_0, {});
+ transfer.constraint_info_fine.read_dof_indices(
+ cell_no_0, level_dof_indices_fine_0, {});
}
// move pointers
// parent (only once at the beginning)
if (c == 0)
{
- transfer.constraint_info_coarse
- .template read_dof_indices<types::global_dof_index>(
- cell_no_1,
- mg_level_coarse,
- cell_coarse,
- constraints_coarse,
- {});
+ transfer.constraint_info_coarse.read_dof_indices(
+ cell_no_1,
+ mg_level_coarse,
+ cell_coarse,
+ constraints_coarse,
+ {});
level_dof_indices_fine_1.assign(level_dof_indices_fine_1.size(),
numbers::invalid_dof_index);
// move pointers (only once at the end)
if (c + 1 == GeometryInfo<dim>::max_children_per_cell)
{
- transfer.constraint_info_fine
- .template read_dof_indices<types::global_dof_index>(
- cell_no_1, level_dof_indices_fine_1, {});
+ transfer.constraint_info_fine.read_dof_indices(
+ cell_no_1, level_dof_indices_fine_1, {});
cell_no_1++;
}
}
{
- transfer.partitioner_coarse =
- transfer.constraint_info_coarse
- .template finalize<types::global_dof_index>(
- dof_handler_coarse.get_communicator());
+ transfer.partitioner_coarse = transfer.constraint_info_coarse.finalize(
+ dof_handler_coarse.get_communicator());
transfer.vec_coarse.reinit(transfer.partitioner_coarse);
- transfer.partitioner_fine =
- transfer.constraint_info_fine
- .template finalize<types::global_dof_index>(
- dof_handler_fine.get_communicator());
+ transfer.partitioner_fine = transfer.constraint_info_fine.finalize(
+ dof_handler_fine.get_communicator());
transfer.vec_fine.reinit(transfer.partitioner_fine);
}
// parent
{
- transfer.constraint_info_coarse
- .template read_dof_indices<types::global_dof_index>(
- cell_no[fe_pair_no],
- mg_level_coarse,
- cell_coarse,
- constraints_coarse,
- {});
+ transfer.constraint_info_coarse.read_dof_indices(
+ cell_no[fe_pair_no],
+ mg_level_coarse,
+ cell_coarse,
+ constraints_coarse,
+ {});
}
// child
local_dof_indices_fine_lex[fe_pair_no][i] = local_dof_indices_fine
[fe_pair_no][lexicographic_numbering_fine[fe_pair_no][i]];
- transfer.constraint_info_fine
- .template read_dof_indices<types::global_dof_index>(
- cell_no[fe_pair_no],
- local_dof_indices_fine_lex[fe_pair_no],
- {});
+ transfer.constraint_info_fine.read_dof_indices(
+ cell_no[fe_pair_no], local_dof_indices_fine_lex[fe_pair_no], {});
}
// move pointers
}
{
- transfer.partitioner_coarse =
- transfer.constraint_info_coarse
- .template finalize<types::global_dof_index>(
- dof_handler_coarse.get_communicator());
+ transfer.partitioner_coarse = transfer.constraint_info_coarse.finalize(
+ dof_handler_coarse.get_communicator());
transfer.vec_coarse.reinit(transfer.partitioner_coarse);
- transfer.partitioner_fine =
- transfer.constraint_info_fine
- .template finalize<types::global_dof_index>(
- dof_handler_fine.get_communicator());
+ transfer.partitioner_fine = transfer.constraint_info_fine.finalize(
+ dof_handler_fine.get_communicator());
transfer.vec_fine.reinit(transfer.partitioner_fine);
}
} // namespace internal
template <typename Number>
-template <int dim, std::size_t width>
+template <int dim, std::size_t width, typename IndexType>
void
MGTwoLevelTransferBase<LinearAlgebra::distributed::Vector<Number>>::
internal_enable_inplace_operations_if_possible(
const std::shared_ptr<const Utilities::MPI::Partitioner>
&external_partitioner_fine,
bool &vec_fine_needs_ghost_update,
- internal::MatrixFreeFunctions::ConstraintInfo<
- dim,
- VectorizedArray<Number, width>> &constraint_info_coarse,
- std::vector<unsigned int> &dof_indices_fine)
+ internal::MatrixFreeFunctions::
+ ConstraintInfo<dim, VectorizedArray<Number, width>, IndexType>
+ &constraint_info_coarse,
+ std::vector<unsigned int> &dof_indices_fine)
{
if (this->partitioner_coarse->is_globally_compatible(
*external_partitioner_coarse))