15#ifndef dealii_affine_constraints_h
16#define dealii_affine_constraints_h
31#include <boost/range/iterator_range.hpp>
49template <
typename number>
51template <
typename number>
56 namespace AffineConstraints
82 Distributing(
const Distributing &in);
85 operator=(
const Distributing &in);
90 return global_row < in.global_row;
111 template <
typename number>
120 insert_new_index(
const std::pair<size_type, number> &pair);
123 append_index(
const size_type index,
124 const std::pair<size_type, number> &pair);
127 get_size(
const size_type index)
const;
129 const std::pair<size_type, number> *
130 get_entry(
const size_type index)
const;
134 std::vector<std::pair<size_type, number>> data;
136 std::vector<size_type> individual_size;
169 template <
typename number>
170 class GlobalRowsFromLocal
176 GlobalRowsFromLocal();
179 reinit(
const size_type n_local_rows);
182 insert_index(
const size_type global_row,
183 const size_type local_row,
184 const number constraint_value);
189 print(std::ostream &os);
202 size(
const size_type counter_index)
const;
208 global_row(
const size_type counter_index)
const;
214 global_row(
const size_type counter_index);
222 local_row(
const size_type counter_index)
const;
228 local_row(
const size_type counter_index);
236 local_row(
const size_type counter_index,
237 const size_type index_in_constraint)
const;
244 constraint_value(
const size_type counter_index,
245 const size_type index_in_constraint)
const;
254 have_indirect_rows()
const;
261 insert_constraint(
const size_type constrained_local_dof);
271 n_constraints()
const;
278 n_inhomogeneities()
const;
287 set_ith_constraint_inhomogeneous(
const size_type i);
294 constraint_origin(size_type i)
const;
301 std::vector<Distributing> total_row_indices;
307 DataCache<number> data_cache;
341 template <
typename number>
354 ScratchData(
const ScratchData &)
366 std::vector<std::pair<size_type, size_type>> new_entries;
371 std::vector<size_type> rows;
376 std::vector<size_type> columns;
381 std::vector<number>
values;
386 std::vector<size_type> block_starts;
391 std::vector<size_type> vector_indices;
396 std::vector<number> vector_values;
401 GlobalRowsFromLocal<number> global_rows;
406 GlobalRowsFromLocal<number> global_columns;
413 namespace AffineConstraintsImplementation
415 template <
typename VectorType>
417 set_zero_all(
const std::vector<types::global_dof_index> &cm,
422 set_zero_all(
const std::vector<types::global_dof_index> &cm,
427 set_zero_all(
const std::vector<types::global_dof_index> &cm,
428 ::BlockVector<T> &vec);
507template <
typename number =
double>
586 "Use the constructor with two index set arguments.")
621 const
IndexSet &locally_stored_constraints);
659 template <typename other_number>
683 "Use the reinit() function with two index set arguments.")
697 const
IndexSet &locally_stored_constraints);
817 const number inhomogeneity = 0);
909 const number weight);
999 template <typename other_number>
1004 const
bool allow_different_local_lines = false);
1319 template <typename VectorType>
1329 template <typename VectorType>
1331 condense(const VectorType &vec_ghosted, VectorType &output) const;
1345 template <typename VectorType>
1353 template <typename BlockVectorType>
1363 template <typename VectorType>
1422 template <class InVector, class OutVector>
1426 OutVector &global_vector) const;
1475 template <typename VectorType>
1479 VectorType &global_vector,
1480 const
FullMatrix<number> &local_matrix) const;
1501 template <typename VectorType>
1504 const
Vector<number> &local_vector,
1507 VectorType &global_vector,
1509 bool diagonal = false) const;
1514 template <typename VectorType>
1518 VectorType &global_vector) const;
1552 template <typename ForwardIteratorVec,
1553 typename ForwardIteratorInd,
1554 typename VectorType>
1557 ForwardIteratorVec local_vector_end,
1558 ForwardIteratorInd local_indices_begin,
1559 VectorType &global_vector) const;
1612 template <typename MatrixType>
1616 MatrixType &global_matrix) const;
1645 template <typename MatrixType>
1650 MatrixType &global_matrix) const;
1668 template <typename MatrixType>
1674 MatrixType &global_matrix) const;
1696 template <typename MatrixType, typename VectorType>
1699 const
Vector<number> &local_vector,
1701 MatrixType &global_matrix,
1702 VectorType &global_vector,
1703 bool use_inhomogeneities_for_rhs = false) const;
1762 const
bool keep_constrained_entries = true,
1763 const
Table<2,
bool> &dof_mask =
Table<2,
bool>()) const;
1773 const
bool keep_constrained_entries = true,
1774 const
Table<2,
bool> &dof_mask =
Table<2,
bool>()) const;
1786 const
bool keep_constrained_entries = true,
1787 const
Table<2,
bool> &dof_mask =
Table<2,
bool>()) const;
1808 template <typename ForwardIteratorVec,
1809 typename ForwardIteratorInd,
1810 typename VectorType>
1813 ForwardIteratorInd local_indices_begin,
1814 ForwardIteratorVec local_vector_begin,
1815 ForwardIteratorVec local_vector_end) const;
1838 template <typename VectorType>
1855 using Entries = std::vector<std::pair<size_type, number>>;
1884 const number inhomogeneity = 0.0);
1920 template <
class Archive>
1933 std::swap(l1.index, l2.index);
1934 std::swap(l1.entries, l2.entries);
1935 std::swap(l1.inhomogeneity, l2.inhomogeneity);
1990 const IndexSet &locally_active_dofs,
1992 const bool verbose =
false)
const;
2055 const IndexSet &constraints_to_make_consistent,
2065 "You are attempting an operation on an AffineConstraints object "
2066 "that requires the object to not be 'closed', i.e., for which you "
2067 "must not already have called the close() member function. But the "
2068 "object is already closed, and so the operation can not be "
2077 "You are attempting an operation on an AffineConstraints object "
2078 "that requires the object to be 'closed', i.e., for which you "
2079 "needed to call the close() member function. But the object "
2080 "is not currently closed, and so the operation can not be "
2089 <<
"The specified line " << arg1 <<
" does not exist.");
2100 <<
"The entry for the indices " << arg1 <<
" and " << arg2
2101 <<
" already exists, but the values " << arg3 <<
" (old) and "
2102 << arg4 <<
" (new) differ "
2103 <<
"by " << (arg4 - arg3) <<
'.');
2112 <<
"You tried to constrain DoF " << arg1 <<
" to DoF " << arg2
2113 <<
", but that one is also constrained. This is not allowed!");
2121 <<
"Degree of freedom " << arg1
2122 <<
" is constrained from both object in a merge operation.");
2130 <<
"In the given argument a degree of freedom is constrained "
2131 <<
"to another DoF with number " << arg1
2132 <<
", which however is constrained by this object. This is not"
2141 <<
"The index set given to this constraints object indicates "
2142 <<
"constraints for degree of freedom " << arg1
2143 <<
" should not be stored by this object, but a constraint "
2144 <<
"is being added.");
2154 <<
"The index set given to this constraints object indicates "
2155 <<
"constraints using degree of freedom " << arg2
2156 <<
" should not be stored by this object, but a constraint "
2157 <<
"for degree of freedom " << arg1 <<
" uses it.");
2167 <<
"While distributing the constraint for DoF " << arg1
2168 <<
", it turns out that one of the processors "
2169 <<
"who own the " << arg2 <<
" degrees of freedom that x_"
2170 << arg1 <<
" is constrained against does not know about "
2171 <<
"the constraint on x_" << arg1
2172 <<
". Did you not initialize the AffineConstraints container "
2173 <<
"with the appropriate locally_relevant set so "
2174 <<
"that every processor who owns a DoF that constrains "
2175 <<
"another DoF also knows about this constraint?");
2259 internal::AffineConstraints::ScratchData<number>>
2273 template <
typename MatrixType,
typename VectorType>
2277 const std::vector<size_type> &local_dof_indices,
2278 MatrixType &global_matrix,
2279 VectorType &global_vector,
2280 const bool use_inhomogeneities_for_rhs,
2281 const std::bool_constant<false>)
const;
2287 template <
typename MatrixType,
typename VectorType>
2291 const std::vector<size_type> &local_dof_indices,
2292 MatrixType &global_matrix,
2293 VectorType &global_vector,
2294 const bool use_inhomogeneities_for_rhs,
2295 const std::bool_constant<true>)
const;
2306 internal::AffineConstraints::GlobalRowsFromLocal<number>
2307 &global_rows)
const;
2318 std::vector<size_type> &active_dofs)
const;
2323 template <
typename MatrixScalar,
typename VectorScalar>
2327 const internal::AffineConstraints::GlobalRowsFromLocal<number> &global_rows,
2329 const std::vector<size_type> &local_dof_indices,
2335template <
typename number>
2342template <
typename number>
2344 const IndexSet &locally_stored_constraints)
2346 locally_stored_constraints)
2351template <
typename number>
2354 const IndexSet &locally_stored_constraints)
2361 ExcMessage(
"The set of locally stored constraints needs to be a "
2362 "superset of the locally owned DoFs."));
2372template <
typename number>
2387template <
typename number>
2411 lines.emplace_back();
2412 lines.back().index = line_n;
2413 lines.back().inhomogeneity = 0.;
2419template <
typename number>
2423 const number weight)
2426 Assert(constrained_dof_index != column,
2427 ExcMessage(
"Can't constrain a degree of freedom to itself"));
2432 ExcMessage(
"The current AffineConstraints does not contain the line "
2433 "for the current entry. Call AffineConstraints::add_line "
2434 "before calling this function."));
2447 for (
const auto &p : line_ptr->
entries)
2448 if (p.first == column)
2452 constrained_dof_index, column, p.second, weight));
2456 line_ptr->
entries.emplace_back(column, weight);
2461template <
typename number>
2470 ExcMessage(
"call add_line() before calling set_inhomogeneity()"));
2478template <
typename number>
2479template <
typename VectorType>
2485 std::vector<size_type> constrained_lines(
lines.size());
2486 for (
unsigned int i = 0; i <
lines.size(); ++i)
2487 constrained_lines[i] =
lines[i].index;
2488 internal::AffineConstraintsImplementation::set_zero_all(constrained_lines,
2492template <
typename number>
2496 return lines.size();
2499template <
typename number>
2503 return std::count_if(
lines.begin(),
2506 return (line.entries.size() == 1) &&
2507 (line.entries[0].second == number(1.));
2511template <
typename number>
2515 return std::count_if(
lines.begin(),
2518 return (line.inhomogeneity != number(0.));
2522template <
typename number>
2534template <
typename number>
2552template <
typename number>
2553inline const std::vector<std::pair<types::global_dof_index, number>> *
2569template <
typename number>
2583template <
typename number>
2598template <
typename number>
2607template <
typename number>
2616template <
typename number>
2625template <
typename number>
2626template <
typename VectorType>
2631 VectorType &global_vector)
const
2636 global_vector(index) +=
value;
2642 global_vector(position.
entries[j].first) +=
2647template <
typename number>
2648template <
typename ForwardIteratorVec,
2649 typename ForwardIteratorInd,
2650 typename VectorType>
2653 ForwardIteratorVec local_vector_begin,
2654 ForwardIteratorVec local_vector_end,
2655 ForwardIteratorInd local_indices_begin,
2656 VectorType &global_vector)
const
2659 for (; local_vector_begin != local_vector_end;
2660 ++local_vector_begin, ++local_indices_begin)
2664 *local_indices_begin,
2672 (*local_vector_begin) * position.
entries[j].second,
2679template <
typename number>
2680template <
class InVector,
class OutVector>
2683 const InVector &local_vector,
2684 const std::vector<size_type> &local_dof_indices,
2685 OutVector &global_vector)
const
2688 Assert(local_vector.size() == local_dof_indices.size(),
2692 local_dof_indices.begin(),
2696template <
typename number>
2697template <
typename ForwardIteratorVec,
2698 typename ForwardIteratorInd,
2699 typename VectorType>
2702 const VectorType &global_vector,
2703 ForwardIteratorInd local_indices_begin,
2704 ForwardIteratorVec local_vector_begin,
2705 ForwardIteratorVec local_vector_end)
const
2708 for (; local_vector_begin != local_vector_end;
2709 ++local_vector_begin, ++local_indices_begin)
2712 *local_vector_begin = global_vector(*local_indices_begin);
2721 *local_vector_begin =
value;
2728template <
typename MatrixType>
2730template <
typename SparsityPatternType>
2732template <
typename number>
2756 template <
typename MatrixType>
2757 struct IsBlockMatrix
2765 template <
typename T>
2766 static std::true_type
2773 template <
typename T>
2774 static std::true_type
2781 static std::false_type
2791 static const bool value =
2792 std::is_same_v<decltype(check(std::declval<MatrixType *>())),
2797 template <
typename MatrixType>
2798 const bool IsBlockMatrix<MatrixType>::value;
2806template <
typename number>
2807template <
typename other_number>
2815 for (
const auto &l : other.
lines)
2816 lines.emplace_back(l.index,
2830template <
typename number>
2831template <
typename other_number>
2836 const bool allow_different_local_lines)
2838 Assert(allow_different_local_lines ||
2841 "local_lines for this and the other objects are not the same "
2842 "although allow_different_local_lines is false."));
2845 const bool object_was_sorted =
sorted;
2860 for (
const std::pair<size_type, number> &entry : line.entries)
2871 this->is_constrained(entry.first)))
2872 tmp.push_back(entry);
2878 const auto *other_entries =
2882 const number weight = entry.second;
2884 for (
const auto &other_entry : *other_entries)
2885 tmp.emplace_back(other_entry.first,
2886 other_entry.second * weight);
2888 line.inhomogeneity +=
2893 line.entries.swap(tmp);
2917 for (
const auto &line : other_constraints.
lines)
2923 lines.emplace_back(line.index,
2925 line.entries.begin(), line.entries.end()),
2926 line.inhomogeneity);
2932 lines.emplace_back(line.index,
2934 line.entries.begin(), line.entries.end()),
2935 line.inhomogeneity);
2942 switch (merge_conflict_behavior)
2958 line.entries.end()),
2959 static_cast<number
>(line.inhomogeneity)};
2977 if (object_was_sorted ==
true)
2983template <
typename number>
2984template <
typename MatrixType>
2988 const std::vector<size_type> &local_dof_indices,
2989 MatrixType &global_matrix)
const
3001 std::integral_constant<
3003 internal::AffineConstraints::IsBlockMatrix<MatrixType>::value>());
3008template <
typename number>
3009template <
typename MatrixType,
typename VectorType>
3014 const std::vector<size_type> &local_dof_indices,
3015 MatrixType &global_matrix,
3016 VectorType &global_vector,
3017 bool use_inhomogeneities_for_rhs)
const
3027 use_inhomogeneities_for_rhs,
3028 std::integral_constant<
3030 internal::AffineConstraints::IsBlockMatrix<MatrixType>::value>());
3035template <
typename number>
IndexSet locally_owned_dofs
void add_entries(const size_type constrained_dof_index, const std::vector< std::pair< size_type, number > > &col_weight_pairs)
size_type n_inhomogeneities() const
types::global_dof_index size_type
bool has_inhomogeneities() const
LineRange get_lines() const
void add_line(const size_type line_n)
const IndexSet & get_locally_owned_indices() const
void add_selected_constraints(const AffineConstraints &constraints_in, const IndexSet &filter)
bool can_store_line(const size_type line_n) const
void add_constraint(const size_type constrained_dof, const ArrayView< const std::pair< size_type, number > > &dependencies, const number inhomogeneity=0)
Threads::ThreadLocalStorage< internal::AffineConstraints::ScratchData< number > > scratch_data
friend class AffineConstraints
void merge(const AffineConstraints< other_number > &other_constraints, const MergeConflictBehavior merge_conflict_behavior=no_conflicts_allowed, const bool allow_different_local_lines=false)
void add_entry(const size_type constrained_dof_index, const size_type column, const double weight)
double get_inhomogeneity(const size_type line_n) const
void make_sorted_row_list(const std::vector< size_type > &local_dof_indices, std::vector< size_type > &active_dofs) const
void get_dof_values(const VectorType &global_vector, ForwardIteratorInd local_indices_begin, ForwardIteratorVec local_vector_begin, ForwardIteratorVec local_vector_end) const
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
void make_sorted_row_list(const std::vector< size_type > &local_dof_indices, internal::AffineConstraints::GlobalRowsFromLocal< number > &global_rows) const
const IndexSet & get_local_lines() const
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
void shift(const size_type offset)
size_type n_identities() const
std::size_t memory_consumption() const
typename std::vector< ConstraintLine >::const_iterator const_iterator
void set_inhomogeneity(const size_type constrained_dof_index, const double value)
void condense(SparsityPattern &sparsity) const
size_type max_constraint_indirections() const
ProductType< VectorScalar, MatrixScalar >::type resolve_vector_entry(const size_type i, const internal::AffineConstraints::GlobalRowsFromLocal< number > &global_rows, const Vector< VectorScalar > &local_vector, const std::vector< size_type > &local_dof_indices, const FullMatrix< MatrixScalar > &local_matrix) const
void distribute(VectorType &vec) const
void resolve_indices(std::vector< types::global_dof_index > &indices) const
std::vector< ConstraintLine > lines
bool is_constrained(const size_type line_n) const
AffineConstraints get_view(const IndexSet &mask) const
IndexSet needed_elements_for_distribute
void make_consistent_in_parallel(const IndexSet &locally_owned_dofs, const IndexSet &constraints_to_make_consistent, const MPI_Comm mpi_communicator)
const std::vector< std::pair< size_type, double > > * get_constraint_entries(const size_type line_n) const
size_type calculate_line_index(const size_type line_n) const
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const Vector< number > &local_vector, const std::vector< size_type > &local_dof_indices, MatrixType &global_matrix, VectorType &global_vector, const bool use_inhomogeneities_for_rhs, const std::bool_constant< true >) const
bool is_inhomogeneously_constrained(const size_type index) const
void copy_from(const AffineConstraints< other_number > &other)
std::vector< size_type > lines_cache
void constrain_dof_to_zero(const size_type constrained_dof)
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const Vector< number > &local_vector, const std::vector< size_type > &local_dof_indices, MatrixType &global_matrix, VectorType &global_vector, const bool use_inhomogeneities_for_rhs, const std::bool_constant< false >) const
bool is_consistent_in_parallel(const std::vector< IndexSet > &locally_owned_dofs, const IndexSet &locally_active_dofs, const MPI_Comm mpi_communicator, const bool verbose=false) const
bool is_identity_constrained(const size_type line_n) const
size_type n_constraints() const
void print(std::ostream &out) const
void write_dot(std::ostream &) const
void set_zero(VectorType &vec) const
void add_lines(const std::vector< bool > &lines)
boost::iterator_range< const_iterator > LineRange
bool are_identity_constrained(const size_type line_n_1, const size_type line_n_2) const
bool is_element(const size_type index) const
A class that provides a separate storage location on each thread that accesses the object.
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcMatrixNotClosed()
static ::ExceptionBase & ExcGhostsPresent()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcDoFIsConstrainedFromBothObjects(size_type arg1)
static ::ExceptionBase & ExcDoFConstrainedToConstrainedDoF(int arg1, int arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcMatrixIsClosed()
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcDoFIsConstrainedToConstrainedDoF(size_type arg1)
static ::ExceptionBase & ExcColumnNotStoredHere(size_type arg1, size_type arg2)
static ::ExceptionBase & ExcRowNotStoredHere(size_type arg1)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIncorrectConstraint(int arg1, int arg2)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcEntryAlreadyExists(size_type arg1, size_type arg2, number arg3, number arg4)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcLineInexistent(size_type arg1)
#define AssertThrow(cond, exc)
const bool IsBlockVector< VectorType >::value
types::global_dof_index size_type
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
constexpr types::global_dof_index invalid_dof_index
constexpr types::global_dof_index invalid_size_type
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
*braid_SplitCommworld & comm
std::vector< std::pair< size_type, number > > Entries
void serialize(Archive &ar, const unsigned int)
ConstraintLine & operator=(const ConstraintLine &other)=default
ConstraintLine(const ConstraintLine &other)=default
ConstraintLine(const size_type &index=numbers::invalid_dof_index, const typename AffineConstraints< number >::ConstraintLine::Entries &entries={}, const number inhomogeneity=0.0)
ConstraintLine(ConstraintLine &&other) noexcept=default
ConstraintLine & operator=(ConstraintLine &&other) noexcept=default
std::size_t memory_consumption() const
friend void swap(ConstraintLine &l1, ConstraintLine &l2) noexcept
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
static void add(const typename VectorType::value_type value, const types::global_dof_index i, VectorType &V)
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)