14#ifndef dealii_matrix_free_constraint_info_h
15#define dealii_matrix_free_constraint_info_h
39 template <
typename Number>
51 template <
typename number2>
54 const std::vector<std::pair<types::global_dof_index, number2>>
63 std::vector<std::pair<types::global_dof_index, double>>
68 std::map<std::vector<Number>,
81 template <
int dim,
typename Number,
typename IndexType =
unsigned int>
103 const unsigned int n_cells,
104 const bool use_fast_hanging_node_algorithm =
true);
108 const unsigned int cell_no,
109 const unsigned int mg_level,
111 const ::AffineConstraints<typename Number::value_type>
113 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
119 reinit(
const unsigned int n_cells);
123 const unsigned int cell_no,
124 const std::vector<types::global_dof_index> &
dof_indices,
125 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
130 std::shared_ptr<const Utilities::MPI::Partitioner>
133 template <
typename T,
typename VectorType>
136 VectorType &global_vector,
137 Number *local_vector,
138 const unsigned int first_cell,
139 const unsigned int n_cells,
140 const unsigned int n_dofs_per_cell,
141 const bool apply_constraints)
const;
145 const unsigned int first_cell,
146 const unsigned int n_lanes_filled,
161 std::vector<std::vector<std::pair<unsigned short, unsigned short>>>
169 std::vector<ConstraintKinds>
mask;
172 std::pair<types::global_dof_index, types::global_dof_index>
local_range;
177 std::vector<std::pair<unsigned short, unsigned short>>
179 std::vector<std::pair<unsigned int, unsigned int>>
row_starts;
193 inline const typename Number::value_type *
196 inline const typename Number::value_type *
205 template <
typename Number>
208 1. *
std::numeric_limits<double>::epsilon() * 1024.))
213 template <
typename Number>
214 template <
typename number2>
217 const std::vector<std::pair<types::global_dof_index, number2>> &entries)
220 if (entries.size() > 0)
228 [](
const std::pair<types::global_dof_index, double> &p1,
229 const std::pair<types::global_dof_index, double> &p2) {
230 return p1.second < p2.second;
253 insert_position = position->second;
263 Assert(insert_position < (1 << (8 *
sizeof(
unsigned short))),
265 return static_cast<unsigned short>(insert_position);
270 template <
int dim,
typename Number,
typename IndexType>
277 template <
int dim,
typename Number,
typename IndexType>
294 template <
int dim,
typename Number,
typename IndexType>
298 const unsigned int n_cells,
299 const bool use_fast_hanging_node_algorithm)
306 const bool has_hanging_nodes =
309 if (use_fast_hanging_node_algorithm && has_hanging_nodes)
321 for (
unsigned int i = 0; i < fes.size(); ++i)
323 if (fes[i].reference_cell().is_hyper_cube())
327 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
331 const auto dummy_quadrature =
332 fes[i].reference_cell().get_gauss_type_quadrature(1);
333 shape_infos[i].reinit(dummy_quadrature, fes[i], 0);
343 template <
int dim,
typename Number,
typename IndexType>
354 template <
int dim,
typename Number,
typename IndexType>
357 const unsigned int cell_no,
358 const unsigned int mg_level,
360 const ::AffineConstraints<typename Number::value_type> &constraints,
361 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
375 shape_infos[cell->active_fe_index()].lexicographic_numbering;
380 for (
unsigned int i = 0; i < cell->get_fe().n_dofs_per_cell(); ++i)
385 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
399 const auto global_to_local =
402 return partitioner->global_to_local(global_index);
424 cell->get_fe().n_components(),
435 const auto *entries_ptr =
436 constraints.get_constraint_entries(current_dof);
439 if (entries_ptr !=
nullptr)
441 const auto &entries = *entries_ptr;
443 if (n_entries == 1 &&
445 typename Number::value_type(1.)) <
446 100 * std::numeric_limits<double>::epsilon())
448 current_dof = entries[0].first;
457 constraint_iterator.first = 0;
461 const std::vector<types::global_dof_index>
463 for (
unsigned int j = 0; j < n_entries; ++j)
466 global_to_local(constraint_indices[j]));
473 dof_indices.push_back(global_to_local(current_dof));
477 Assert(constraint_iterator.first <
478 (1 << (8 *
sizeof(
unsigned short))) - 1,
480 constraint_iterator.first++;
487 template <
int dim,
typename Number,
typename IndexType>
490 const unsigned int cell_no,
492 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
494 const auto global_to_local =
497 return partitioner->global_to_local(global_index);
508 std::pair<unsigned short, unsigned short> constraint_iterator(0, 0);
519 std::pair<types::global_dof_index, typename Number::value_type>>
526 constraint_iterator.first = 0;
530 dof_indices.push_back(global_to_local(current_dof));
534 Assert(constraint_iterator.first <
535 (1 << (8 *
sizeof(
unsigned short))) - 1,
537 constraint_iterator.first++;
544 template <
int dim,
typename Number,
typename IndexType>
549 std::pair<types::global_dof_index, types::global_dof_index>{0,
568 this->dof_indices.insert(this->dof_indices.end(),
569 this->dof_indices_per_cell[i].begin(),
570 this->dof_indices_per_cell[i].end());
576 this->
row_starts.emplace_back(this->dof_indices.size(),
577 this->constraint_indicator.size());
583 this->plain_dof_indices_per_cell[i].begin(),
584 this->plain_dof_indices_per_cell[i].end());
591 std::vector<const std::vector<double> *> constraints(
593 unsigned int length = 0;
597 constraints[it.second] = &it.first;
598 length += it.first.size();
607 for (
const auto &constraint : constraints)
626 return i == unconstrained_compressed_constraint_kind;
632 template <
int dim,
typename Number,
typename IndexType>
633 inline std::shared_ptr<const Utilities::MPI::Partitioner>
652 std::vector<types::global_dof_index> ghost_dofs;
653 std::pair<unsigned int, unsigned int> counts = {0, 0};
661 ghost_dofs.push_back(j -
670 ghost_dofs.push_back(
675 std::sort(ghost_dofs.begin(), ghost_dofs.end());
676 ghost_dofs.erase(std::unique(ghost_dofs.begin(), ghost_dofs.end()),
680 locally_relevant_dofs.
add_indices(ghost_dofs.begin(), ghost_dofs.end());
682 const auto partitioner =
684 locally_relevant_dofs,
696 this->
dof_indices.push_back(partitioner->global_to_local(
705 this->constraint_indicator.size());
714 partitioner->global_to_local(
722 std::vector<const std::vector<double> *> constraints(
724 unsigned int length = 0;
728 constraints[it.second] = &it.first;
729 length += it.first.size();
738 for (
const auto &constraint : constraints)
757 return i == unconstrained_compressed_constraint_kind;
766 template <
int dim,
typename Number,
typename IndexType>
767 template <
typename T,
typename VectorType>
771 VectorType &global_vector,
772 Number *local_vector,
773 const unsigned int first_cell,
774 const unsigned int n_cells,
775 const unsigned int n_dofs_per_cell,
776 const bool apply_constraints)
const
779 (apply_constraints ==
false))
781 for (
unsigned int v = 0; v < n_cells; ++v)
783 const unsigned int cell_index = first_cell + v;
788 for (
unsigned int i = 0; i < n_dofs_per_cell; ++
dof_indices, ++i)
797 for (
unsigned int v = 0; v < n_cells; ++v)
799 const unsigned int cell_index = first_cell + v;
801 this->dof_indices.data() + this->
row_starts[cell_index].first;
802 unsigned int index_indicators = this->
row_starts[cell_index].second;
803 unsigned int next_index_indicators =
806 unsigned int ind_local = 0;
807 for (; index_indicators != next_index_indicators; ++index_indicators)
809 const std::pair<unsigned short, unsigned short> indicator =
813 for (
unsigned int j = 0; j < indicator.first; ++j)
816 local_vector[ind_local + j][v]);
818 ind_local += indicator.first;
823 typename Number::value_type
value;
824 operation.pre_constraints(local_vector[ind_local][v],
value);
826 const typename Number::value_type *data_val =
828 const typename Number::value_type *end_pool =
830 for (; data_val != end_pool; ++data_val, ++
dof_indices)
836 operation.post_constraints(
value, local_vector[ind_local][v]);
842 for (; ind_local < n_dofs_per_cell; ++
dof_indices, ++ind_local)
845 local_vector[ind_local][v]);
851 template <
int dim,
typename Number,
typename IndexType>
854 const unsigned int first_cell,
855 const unsigned int n_lanes_filled,
866 bool hn_available =
false;
868 for (
unsigned int v = 0; v < n_lanes_filled; ++v)
872 constraint_mask[v] =
mask;
877 if (hn_available ==
true)
879 std::fill(constraint_mask.begin() + n_lanes_filled,
880 constraint_mask.end(),
883 for (
unsigned int i = 1; i < n_lanes_filled; ++i)
891 typename Number::value_type,
892 Number>::apply(shape_info.n_components,
893 shape_info.data.front().fe_degree,
897 evaluation_data_coarse.
begin());
903 template <
int dim,
typename Number,
typename IndexType>
904 inline const typename Number::value_type *
906 const unsigned int row)
const
916 template <
int dim,
typename Number,
typename IndexType>
917 inline const typename Number::value_type *
919 const unsigned int row)
const
929 template <
int dim,
typename Number,
typename IndexType>
933 std::size_t size = 0;
962 template <
typename Number>
966 std::size_t size = 0;
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const Triangulation< dim, spacedim > & get_triangulation() const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
virtual bool has_hanging_nodes() const
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
std::vector< ShapeInfo< typename Number::value_type > > shape_infos
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
ConstraintValues< double > constraint_values
std::vector< typename Number::value_type > constraint_pool_data
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
const Number::value_type * constraint_pool_begin(const unsigned int row) const
std::vector< types::global_dof_index > local_dof_indices_lex
std::vector< std::vector< IndexType > > dof_indices_per_cell
IndexSet locally_owned_indices
std::vector< unsigned int > plain_dof_indices
void set_locally_owned_indices(const IndexSet &locally_owned_indices)
std::pair< types::global_dof_index, types::global_dof_index > local_range
const Number::value_type * constraint_pool_end(const unsigned int row) const
std::vector< types::global_dof_index > local_dof_indices
std::size_t memory_consumption() const
std::vector< compressed_constraint_kind > hanging_node_constraint_masks
std::vector< unsigned int > constraint_pool_row_index
std::vector< unsigned int > active_fe_indices
std::unique_ptr< HangingNodes< dim > > hanging_nodes
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::vector< std::pair< unsigned short, unsigned short > > > constraint_indicator_per_cell
std::vector< std::vector< IndexType > > plain_dof_indices_per_cell
std::vector< unsigned int > dof_indices
void reinit(const DoFHandler< dim, dim > &dof_handler, const unsigned int n_cells, const bool use_fast_hanging_node_algorithm=true)
std::vector< ConstraintKinds > mask
std::vector< unsigned int > row_starts_plain_indices
std::vector< std::pair< unsigned int, unsigned int > > row_starts
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
const bool IsBlockVector< VectorType >::value
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
std::uint8_t compressed_constraint_kind
compressed_constraint_kind compress(const ConstraintKinds kind_in, const unsigned int dim)
constexpr compressed_constraint_kind unconstrained_compressed_constraint_kind
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
*braid_SplitCommworld & comm
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