17#ifndef dealii_matrix_free_constraint_info_h
18#define dealii_matrix_free_constraint_info_h
36 namespace MatrixFreeFunctions
42 template <
typename Number>
54 template <
typename number2>
57 const std::vector<std::pair<types::global_dof_index, number2>>
66 std::vector<std::pair<types::global_dof_index, double>>
71 std::map<std::vector<Number>,
84 template <
int dim,
typename Number>
94 const unsigned int n_cells,
100 const unsigned int mg_level,
104 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
115 const std::vector<types::global_dof_index> &
dof_indices,
116 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
121 template <
typename T,
typename VectorType>
126 const unsigned int first_cell,
127 const unsigned int n_cells,
128 const unsigned int n_dofs_per_cell,
133 const unsigned int first_cell,
149 std::vector<std::vector<std::pair<unsigned short, unsigned short>>>
158 std::vector<std::pair<unsigned short, unsigned short>>
160 std::vector<std::pair<unsigned int, unsigned int>>
row_starts;
174 inline const typename Number::value_type *
177 inline const typename Number::value_type *
186 template <
typename Number>
194 template <
typename Number>
195 template <
typename number2>
198 const std::vector<std::pair<types::global_dof_index, number2>> &entries)
200 next_constraint.first.resize(entries.size());
201 if (entries.size() > 0)
203 constraint_indices.resize(entries.size());
206 constraint_entries.assign(entries.begin(), entries.end());
207 std::sort(constraint_entries.begin(),
208 constraint_entries.end(),
209 [](
const std::pair<types::global_dof_index, double> &
p1,
210 const std::pair<types::global_dof_index, double> &
p2) {
211 return p1.second < p2.second;
217 constraint_indices[
j] = constraint_entries[
j].first;
220 next_constraint.first[
j] = constraint_entries[
j].second;
232 const auto position = constraints.find(next_constraint.first);
233 if (position != constraints.end())
237 next_constraint.second = constraints.
size();
238 constraints.insert(next_constraint);
251 template <
int dim,
typename Number>
255 const unsigned int n_cells,
258 this->dof_indices_per_cell.resize(n_cells);
259 this->plain_dof_indices_per_cell.resize(n_cells);
260 this->constraint_indicator_per_cell.resize(n_cells);
263 const bool has_hanging_nodes =
264 dof_handler.get_triangulation().has_hanging_nodes();
268 hanging_nodes = std::make_unique<HangingNodes<dim>>(
269 dof_handler.get_triangulation());
271 hanging_node_constraint_masks.resize(n_cells);
274 const auto &
fes = dof_handler.get_fe_collection();
275 lexicographic_numbering.resize(
fes.
size());
276 shape_infos.resize(
fes.
size());
278 for (
unsigned int i = 0; i <
fes.
size(); ++i)
280 if (
fes[i].reference_cell().is_hyper_cube())
294 lexicographic_numbering[i] = shape_infos[i].lexicographic_numbering;
296 active_fe_indices.resize(n_cells);
301 template <
int dim,
typename Number>
305 this->dof_indices_per_cell.resize(n_cells);
306 this->plain_dof_indices_per_cell.resize(0);
307 this->constraint_indicator_per_cell.resize(n_cells);
312 template <
int dim,
typename Number>
316 const unsigned int mg_level,
319 const std::shared_ptr<const Utilities::MPI::Partitioner> & partitioner)
321 std::vector<types::global_dof_index> local_dof_indices(
322 cell->get_fe().n_dofs_per_cell());
324 cell->get_fe().n_dofs_per_cell());
327 cell->get_dof_indices(local_dof_indices);
329 cell->get_mg_dof_indices(local_dof_indices);
334 const auto &lexicographic_numbering =
335 shape_infos[cell->active_fe_index()].lexicographic_numbering;
338 local_dof_indices.size());
340 for (
unsigned int i = 0; i < cell->get_fe().n_dofs_per_cell(); ++i)
342 local_dof_indices[lexicographic_numbering[i]];
352 auto &constraint_indicator = this->constraint_indicator_per_cell[
cell_no];
353 auto &dof_indices = this->dof_indices_per_cell[
cell_no];
354 auto &plain_dof_indices = this->plain_dof_indices_per_cell[
cell_no];
360 const auto global_to_local =
363 return partitioner->global_to_local(global_index);
378 std::vector<ConstraintKinds>
mask(cell->get_fe().n_components());
379 hanging_nodes->setup_constraints(
383 active_fe_indices[
cell_no] = cell->active_fe_index();
398 100 * std::numeric_limits<double>::epsilon())
405 constraint_indicator.back().second =
406 constraint_values.insert_entries(entries);
413 const std::vector<types::global_dof_index>
414 &constraint_indices = constraint_values.constraint_indices;
417 dof_indices.push_back(
418 global_to_local(constraint_indices[
j]));
425 dof_indices.push_back(global_to_local(
current_dof));
430 (1 << (8 *
sizeof(
unsigned short))) - 1,
439 template <
int dim,
typename Number>
444 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
446 const auto global_to_local =
449 return partitioner->global_to_local(global_index);
456 auto &constraint_indicator = this->constraint_indicator_per_cell[
cell_no];
457 auto &dof_indices = this->dof_indices_per_cell[
cell_no];
465 std::pair<types::global_dof_index, typename Number::value_type>>
469 constraint_indicator.back().second =
470 constraint_values.insert_entries(entries);
476 dof_indices.push_back(global_to_local(
current_dof));
481 (1 << (8 *
sizeof(
unsigned short))) - 1,
490 template <
int dim,
typename Number>
494 this->dof_indices = {};
495 this->plain_dof_indices = {};
496 this->constraint_indicator = {};
498 this->row_starts = {};
499 this->row_starts.emplace_back(0, 0);
501 if (plain_dof_indices_per_cell.empty() ==
false)
503 this->row_starts_plain_indices = {};
504 this->row_starts_plain_indices.emplace_back(0);
507 for (
unsigned int i = 0; i < dof_indices_per_cell.size(); ++i)
509 this->dof_indices.insert(this->dof_indices.end(),
510 dof_indices_per_cell[i].begin(),
511 dof_indices_per_cell[i].end());
512 this->constraint_indicator.insert(
513 this->constraint_indicator.end(),
514 constraint_indicator_per_cell[i].begin(),
515 constraint_indicator_per_cell[i].end());
517 this->row_starts.emplace_back(this->dof_indices.size(),
520 if (plain_dof_indices_per_cell.empty() ==
false)
522 this->plain_dof_indices.insert(
523 this->plain_dof_indices.end(),
524 plain_dof_indices_per_cell[i].begin(),
525 plain_dof_indices_per_cell[i].end());
527 this->row_starts_plain_indices.emplace_back(
528 this->plain_dof_indices.size());
532 std::vector<const std::vector<double> *> constraints(
533 constraint_values.constraints.size());
534 unsigned int length = 0;
535 for (
const auto &
it : constraint_values.constraints)
538 constraints[
it.second] = &
it.first;
539 length +=
it.first.
size();
542 constraint_pool_data.clear();
543 constraint_pool_data.reserve(length);
544 constraint_pool_row_index.reserve(constraint_values.constraints.size() +
546 constraint_pool_row_index.resize(1, 0);
551 constraint_pool_data.insert(constraint_pool_data.end(),
554 constraint_pool_row_index.push_back(constraint_pool_data.size());
559 dof_indices_per_cell.clear();
560 constraint_indicator_per_cell.clear();
563 std::all_of(hanging_node_constraint_masks.begin(),
564 hanging_node_constraint_masks.end(),
566 return i == unconstrained_compressed_constraint_kind;
568 hanging_node_constraint_masks.clear();
573 template <
int dim,
typename Number>
574 template <
typename T,
typename VectorType>
580 const unsigned int first_cell,
581 const unsigned int n_cells,
582 const unsigned int n_dofs_per_cell,
585 if ((row_starts_plain_indices.empty() ==
false) &&
588 for (
unsigned int v = 0; v < n_cells; ++v)
590 const unsigned int cell_index = first_cell + v;
591 const unsigned int *dof_indices =
592 this->plain_dof_indices.data() +
595 for (
unsigned int i = 0; i < n_dofs_per_cell; ++dof_indices, ++i)
596 operation.process_dof(*dof_indices,
604 for (
unsigned int v = 0; v < n_cells; ++v)
606 const unsigned int cell_index = first_cell + v;
607 const unsigned int *dof_indices =
608 this->dof_indices.data() + this->row_starts[
cell_index].first;
616 const std::pair<unsigned short, unsigned short>
indicator =
621 operation.process_dof(dof_indices[
j],
630 typename Number::value_type
value;
633 const typename Number::value_type *
data_val =
634 this->constraint_pool_begin(
indicator.second);
635 const typename Number::value_type *
end_pool =
636 this->constraint_pool_end(
indicator.second);
638 operation.process_constraint(*dof_indices,
650 operation.process_dof(*dof_indices,
658 template <
int dim,
typename Number>
661 const unsigned int first_cell,
666 if (hanging_node_constraint_masks.size() == 0)
677 const auto mask = hanging_node_constraint_masks[first_cell + v];
679 constraint_mask[v] =
mask;
691 active_fe_indices[first_cell + i]);
693 const auto &shape_info = shape_infos[active_fe_indices[first_cell]];
697 typename Number::value_type,
698 Number>::apply(shape_info.n_components,
699 shape_info.data.front().fe_degree,
709 template <
int dim,
typename Number>
710 inline const typename Number::value_type *
712 const unsigned int row)
const
715 return constraint_pool_data.empty() ?
717 constraint_pool_data.
data() + constraint_pool_row_index[row];
722 template <
int dim,
typename Number>
723 inline const typename Number::value_type *
725 const unsigned int row)
const
728 return constraint_pool_data.empty() ?
730 constraint_pool_data.
data() + constraint_pool_row_index[row + 1];
735 template <
int dim,
typename Number>
739 std::size_t size = 0;
768 template <
typename Number>
772 std::size_t size = 0;
value_type * data() const noexcept
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)
std::vector< std::vector< unsigned int > > lexicographic_numbering
void read_write_operation(const T &operation, VectorType &global_vector, Number *local_vector, const unsigned int first_cell, const unsigned int n_cells, const unsigned int n_dofs_per_cell, const bool apply_constraints) const
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
void reinit(const DoFHandler< dim > &dof_handler, const unsigned int n_cells, const bool use_fast_hanging_node_algorithm=true)
std::vector< unsigned int > plain_dof_indices
std::vector< std::vector< std::pair< unsigned short, unsigned short > > > constraint_indicator_per_cell
std::vector< unsigned int > constraint_pool_row_index
std::vector< unsigned int > dof_indices
std::size_t memory_consumption() const
const Number::value_type * constraint_pool_begin(const unsigned int row) const
std::vector< unsigned int > active_fe_indices
std::vector< std::vector< unsigned int > > plain_dof_indices_per_cell
std::vector< std::vector< unsigned int > > dof_indices_per_cell
std::vector< ShapeInfo< Number > > shape_infos
ConstraintValues< double > constraint_values
std::unique_ptr< HangingNodes< dim > > hanging_nodes
std::vector< unsigned int > row_starts_plain_indices
const Number::value_type * constraint_pool_end(const unsigned int row) const
std::vector< compressed_constraint_kind > hanging_node_constraint_masks
void apply_hanging_node_constraints(const unsigned int first_cell, const unsigned int n_lanes_filled, const bool transpose, AlignedVector< Number > &evaluation_data_coarse) const
void read_dof_indices(const unsigned int cell_no, const unsigned int mg_level, const TriaIterator< DoFCellAccessor< dim, dim, false > > &cell, const ::AffineConstraints< typename Number::value_type > &constraints, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner)
std::vector< std::pair< unsigned int, unsigned int > > row_starts
std::vector< typename Number::value_type > constraint_pool_data
void reinit(const unsigned int n_cells)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
compressed_constraint_kind compress(const ConstraintKinds kind_in, const unsigned int dim)
std::uint8_t compressed_constraint_kind
constexpr compressed_constraint_kind unconstrained_compressed_constraint_kind
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
std::size_t memory_consumption() const
std::vector< types::global_dof_index > constraint_indices
std::map< std::vector< Number >, types::global_dof_index, FloatingPointComparator< Number > > constraints
unsigned short insert_entries(const std::vector< std::pair< types::global_dof_index, number2 > > &entries)
std::vector< std::pair< types::global_dof_index, double > > constraint_entries
std::pair< std::vector< Number >, types::global_dof_index > next_constraint