16#ifndef dealii_affine_constraints_h
17#define dealii_affine_constraints_h
32#include <boost/range/iterator_range.hpp>
50template <
typename number>
52template <
typename number>
83 Distributing(
const Distributing &in);
86 operator=(
const Distributing &in);
91 return global_row < in.global_row;
112 template <
typename number>
121 insert_new_index(
const std::pair<size_type, number> &pair);
124 append_index(
const size_type index,
125 const std::pair<size_type, number> &pair);
128 get_size(
const size_type index)
const;
130 const std::pair<size_type, number> *
131 get_entry(
const size_type index)
const;
135 std::vector<std::pair<size_type, number>> data;
137 std::vector<size_type> individual_size;
170 template <
typename number>
171 class GlobalRowsFromLocal
177 GlobalRowsFromLocal();
180 reinit(
const size_type n_local_rows);
183 insert_index(
const size_type global_row,
184 const size_type local_row,
185 const number constraint_value);
190 print(std::ostream &os);
203 size(
const size_type counter_index)
const;
209 global_row(
const size_type counter_index)
const;
215 global_row(
const size_type counter_index);
223 local_row(
const size_type counter_index)
const;
229 local_row(
const size_type counter_index);
237 local_row(
const size_type counter_index,
238 const size_type index_in_constraint)
const;
245 constraint_value(
const size_type counter_index,
246 const size_type index_in_constraint)
const;
254 have_indirect_rows()
const;
261 insert_constraint(
const size_type constrained_local_dof);
269 n_constraints()
const;
276 n_inhomogeneities()
const;
285 set_ith_constraint_inhomogeneous(
const size_type i);
292 constraint_origin(size_type i)
const;
299 std::vector<Distributing> total_row_indices;
305 DataCache<number> data_cache;
339 template <
typename number>
352 ScratchData(
const ScratchData &)
364 std::vector<std::pair<size_type, size_type>> new_entries;
369 std::vector<size_type> rows;
374 std::vector<size_type> columns;
379 std::vector<number>
values;
384 std::vector<size_type> block_starts;
389 std::vector<size_type> vector_indices;
394 std::vector<number> vector_values;
399 GlobalRowsFromLocal<number> global_rows;
404 GlobalRowsFromLocal<number> global_columns;
411 namespace AffineConstraintsImplementation
413 template <
class VectorType>
415 set_zero_all(
const std::vector<types::global_dof_index> &cm,
420 set_zero_all(
const std::vector<types::global_dof_index> &cm,
425 set_zero_all(
const std::vector<types::global_dof_index> &cm,
513template <
typename number =
double>
605 template <
typename other_number>
734 const number weight);
744 const std::vector<std::pair<size_type, number>> &col_weight_pairs);
828 const bool allow_different_local_lines =
false);
953 const std::vector<std::pair<size_type, number>> *
1092 template <
class VectorType>
1102 template <
class VectorType>
1104 condense(
const VectorType &vec_ghosted, VectorType &output)
const;
1118 template <
class VectorType>
1126 template <
class BlockVectorType>
1136 template <
class VectorType>
1195 template <
class InVector,
class OutVector>
1198 const std::vector<size_type> &local_dof_indices,
1199 OutVector & global_vector)
const;
1248 template <
typename VectorType>
1251 const std::vector<size_type> &local_dof_indices,
1252 VectorType & global_vector,
1274 template <
typename VectorType>
1278 const std::vector<size_type> &local_dof_indices_row,
1279 const std::vector<size_type> &local_dof_indices_col,
1280 VectorType & global_vector,
1282 bool diagonal =
false)
const;
1287 template <
class VectorType>
1291 VectorType & global_vector)
const;
1325 template <
typename ForwardIteratorVec,
1326 typename ForwardIteratorInd,
1330 ForwardIteratorVec local_vector_end,
1331 ForwardIteratorInd local_indices_begin,
1332 VectorType & global_vector)
const;
1385 template <
typename MatrixType>
1388 const std::vector<size_type> &local_dof_indices,
1389 MatrixType & global_matrix)
const;
1418 template <
typename MatrixType>
1421 const std::vector<size_type> &row_indices,
1422 const std::vector<size_type> &col_indices,
1423 MatrixType & global_matrix)
const;
1441 template <
typename MatrixType>
1444 const std::vector<size_type> &row_indices,
1446 const std::vector<size_type> &column_indices,
1447 MatrixType & global_matrix)
const;
1469 template <
typename MatrixType,
typename VectorType>
1473 const std::vector<size_type> &local_dof_indices,
1474 MatrixType & global_matrix,
1475 VectorType & global_vector,
1476 bool use_inhomogeneities_for_rhs =
false)
const;
1533 const std::vector<size_type> &local_dof_indices,
1535 const bool keep_constrained_entries =
true,
1543 const std::vector<size_type> &row_indices,
1544 const std::vector<size_type> &col_indices,
1546 const bool keep_constrained_entries =
true,
1555 const std::vector<size_type> & row_indices,
1557 const std::vector<size_type> & col_indices,
1559 const bool keep_constrained_entries =
true,
1581 template <
typename ForwardIteratorVec,
1582 typename ForwardIteratorInd,
1586 ForwardIteratorInd local_indices_begin,
1587 ForwardIteratorVec local_vector_begin,
1588 ForwardIteratorVec local_vector_end)
const;
1611 template <
class VectorType>
1628 using Entries = std::vector<std::pair<size_type, number>>;
1661 template <
typename Constra
intLineType>
1662 ConstraintLine(
const ConstraintLineType &other);
1667 template <
typename Constra
intLineType>
1701 template <
class Archive>
1760 const IndexSet & locally_active_dofs,
1762 const bool verbose =
false)
const;
1771 const IndexSet &locally_relevant_dofs,
1793 <<
"The specified line " << arg1 <<
" does not exist.");
1804 <<
"The entry for the indices " << arg1 <<
" and " << arg2
1805 <<
" already exists, but the values " << arg3 <<
" (old) and "
1806 << arg4 <<
" (new) differ "
1807 <<
"by " << (arg4 - arg3) <<
'.');
1816 <<
"You tried to constrain DoF " << arg1 <<
" to DoF " << arg2
1817 <<
", but that one is also constrained. This is not allowed!");
1825 <<
"Degree of freedom " << arg1
1826 <<
" is constrained from both object in a merge operation.");
1834 <<
"In the given argument a degree of freedom is constrained "
1835 <<
"to another DoF with number " << arg1
1836 <<
", which however is constrained by this object. This is not"
1845 <<
"The index set given to this constraints object indicates "
1846 <<
"constraints for degree of freedom " << arg1
1847 <<
" should not be stored by this object, but a constraint "
1848 <<
"is being added.");
1858 <<
"The index set given to this constraints object indicates "
1859 <<
"constraints using degree of freedom " << arg2
1860 <<
" should not be stored by this object, but a constraint "
1861 <<
"for degree of freedom " << arg1 <<
" uses it.");
1871 <<
"While distributing the constraint for DoF " << arg1
1872 <<
", it turns out that one of the processors "
1873 <<
"who own the " << arg2 <<
" degrees of freedom that x_"
1874 << arg1 <<
" is constrained against does not know about "
1875 <<
"the constraint on x_" << arg1
1876 <<
". Did you not initialize the AffineConstraints container "
1877 <<
"with the appropriate locally_relevant set so "
1878 <<
"that every processor who owns a DoF that constrains "
1879 <<
"another DoF also knows about this constraint?");
1945 internal::AffineConstraints::ScratchData<number>>
1959 template <
typename MatrixType,
typename VectorType>
1963 const std::vector<size_type> &local_dof_indices,
1964 MatrixType & global_matrix,
1965 VectorType & global_vector,
1966 const bool use_inhomogeneities_for_rhs,
1967 const std::integral_constant<bool, false>)
const;
1973 template <
typename MatrixType,
typename VectorType>
1977 const std::vector<size_type> &local_dof_indices,
1978 MatrixType & global_matrix,
1979 VectorType & global_vector,
1980 const bool use_inhomogeneities_for_rhs,
1981 const std::integral_constant<bool, true>)
const;
1992 internal::AffineConstraints::GlobalRowsFromLocal<number>
1993 &global_rows)
const;
2004 std::vector<size_type> & active_dofs)
const;
2009 template <
typename MatrixScalar,
typename VectorScalar>
2013 const internal::AffineConstraints::GlobalRowsFromLocal<number> &global_rows,
2015 const std::vector<size_type> & local_dof_indices,
2021template <
typename number>
2034template <
typename number>
2044template <
typename number>
2068 lines.emplace_back();
2069 lines.back().index = line_n;
2070 lines.back().inhomogeneity = 0.;
2076template <
typename number>
2080 const number weight)
2083 Assert(constrained_dof_index != column,
2084 ExcMessage(
"Can't constrain a degree of freedom to itself"));
2089 ExcMessage(
"The current AffineConstraints does not contain the line "
2090 "for the current entry. Call AffineConstraints::add_line "
2091 "before calling this function."));
2104 for (
const auto &p : line_ptr->
entries)
2105 if (p.first == column)
2109 constrained_dof_index, column, p.second, weight));
2113 line_ptr->
entries.emplace_back(column, weight);
2118template <
typename number>
2127 ExcMessage(
"call add_line() before calling set_inhomogeneity()"));
2135template <
typename number>
2136template <
class VectorType>
2142 std::vector<size_type> constrained_lines(
lines.size());
2143 for (
unsigned int i = 0; i <
lines.size(); ++i)
2144 constrained_lines[i] =
lines[i].index;
2145 internal::AffineConstraintsImplementation::set_zero_all(constrained_lines,
2149template <
typename number>
2153 return lines.size();
2156template <
typename number>
2160 return std::count_if(
lines.begin(),
2163 return (line.entries.size() == 1) &&
2164 (line.entries[0].second == number(1.));
2168template <
typename number>
2172 return std::count_if(
lines.begin(),
2175 return (line.inhomogeneity != number(0.));
2179template <
typename number>
2191template <
typename number>
2209template <
typename number>
2210inline const std::vector<std::pair<types::global_dof_index, number>> *
2226template <
typename number>
2240template <
typename number>
2253template <
typename number>
2260template <
typename number>
2267template <
typename number>
2268template <
class VectorType>
2273 VectorType & global_vector)
const
2278 global_vector(index) += value;
2284 global_vector(position.
entries[j].first) +=
2285 value * position.
entries[j].second;
2289template <
typename number>
2290template <
typename ForwardIteratorVec,
2291 typename ForwardIteratorInd,
2295 ForwardIteratorVec local_vector_begin,
2296 ForwardIteratorVec local_vector_end,
2297 ForwardIteratorInd local_indices_begin,
2298 VectorType & global_vector)
const
2301 for (; local_vector_begin != local_vector_end;
2302 ++local_vector_begin, ++local_indices_begin)
2306 *local_indices_begin,
2314 (*local_vector_begin) * position.
entries[j].second,
2321template <
typename number>
2322template <
class InVector,
class OutVector>
2325 const InVector & local_vector,
2326 const std::vector<size_type> &local_dof_indices,
2327 OutVector & global_vector)
const
2329 Assert(local_vector.size() == local_dof_indices.size(),
2333 local_dof_indices.begin(),
2337template <
typename number>
2338template <
typename ForwardIteratorVec,
2339 typename ForwardIteratorInd,
2343 const VectorType & global_vector,
2344 ForwardIteratorInd local_indices_begin,
2345 ForwardIteratorVec local_vector_begin,
2346 ForwardIteratorVec local_vector_end)
const
2349 for (; local_vector_begin != local_vector_end;
2350 ++local_vector_begin, ++local_indices_begin)
2353 *local_vector_begin = global_vector(*local_indices_begin);
2358 typename VectorType::value_type value = position.
inhomogeneity;
2360 value += (global_vector(position.
entries[j].first) *
2362 *local_vector_begin = value;
2369template <
typename MatrixType>
2371template <
typename SparsityPatternType>
2373template <
typename number>
2397 template <
typename MatrixType>
2398 struct IsBlockMatrix
2406 template <
typename T>
2407 static std::true_type
2414 template <
typename T>
2415 static std::true_type
2422 static std::false_type
2432 static const bool value =
2433 std::is_same<decltype(check(std::declval<MatrixType *>())),
2434 std::true_type>::value;
2438 template <
typename MatrixType>
2439 const bool IsBlockMatrix<MatrixType>::value;
2447template <
typename number>
2448template <
typename other_number>
2454 lines.insert(lines.begin(), other.
lines.begin(), other.
lines.end());
2462template <
typename number>
2463template <
typename MatrixType>
2467 const std::vector<size_type> &local_dof_indices,
2468 MatrixType & global_matrix)
const
2473 distribute_local_to_global(
2480 std::integral_constant<
2482 internal::AffineConstraints::IsBlockMatrix<MatrixType>::value>());
2487template <
typename number>
2488template <
typename MatrixType,
typename VectorType>
2493 const std::vector<size_type> &local_dof_indices,
2494 MatrixType & global_matrix,
2495 VectorType & global_vector,
2496 bool use_inhomogeneities_for_rhs)
const
2500 distribute_local_to_global(
2506 use_inhomogeneities_for_rhs,
2507 std::integral_constant<
2509 internal::AffineConstraints::IsBlockMatrix<MatrixType>::value>());
2514template <
typename number>
2518 const number &inhomogeneity)
2521 , inhomogeneity(inhomogeneity)
2526template <
typename number>
2527template <
typename Constra
intLineType>
2529 const ConstraintLineType &other)
2531 this->index = other.index;
2534 entries.insert(entries.begin(), other.entries.begin(), other.entries.end());
2536 this->inhomogeneity = other.inhomogeneity;
2541template <
typename number>
2542template <
typename Constra
intLineType>
2545 const ConstraintLineType &other)
2547 this->index = other.index;
2550 entries.insert(entries.begin(), other.entries.begin(), other.entries.end());
2552 this->inhomogeneity = other.inhomogeneity;
const LineRange get_lines() const
void add_entries(const size_type constrained_dof_index, const std::vector< std::pair< size_type, number > > &col_weight_pairs)
void condense(DynamicSparsityPattern &sparsity) const
void distribute_local_to_global(ForwardIteratorVec local_vector_begin, ForwardIteratorVec local_vector_end, ForwardIteratorInd local_indices_begin, VectorType &global_vector) const
void merge(const AffineConstraints &other_constraints, const MergeConflictBehavior merge_conflict_behavior=no_conflicts_allowed, const bool allow_different_local_lines=false)
size_type n_inhomogeneities() const
bool has_inhomogeneities() const
void add_line(const size_type line_n)
void add_entries_local_to_global(const std::vector< size_type > &row_indices, const AffineConstraints< number > &col_constraints, const std::vector< size_type > &col_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) 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::integral_constant< bool, true >) const
void add_selected_constraints(const AffineConstraints &constraints_in, const IndexSet &filter)
void condense(VectorType &vec) const
bool can_store_line(const size_type line_n) const
AffineConstraints(AffineConstraints &&affine_constraints) noexcept=default
Threads::ThreadLocalStorage< internal::AffineConstraints::ScratchData< number > > scratch_data
friend class AffineConstraints
void add_entry(const size_type constrained_dof_index, const size_type column, const number weight)
void reinit(const IndexSet &local_constraints=IndexSet())
void make_consistent_in_parallel(const IndexSet &locally_owned_dofs, const IndexSet &locally_relevant_dofs, const MPI_Comm mpi_communicator)
number 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
void distribute_local_to_global(const Vector< number > &local_vector, const std::vector< size_type > &local_dof_indices_row, const std::vector< size_type > &local_dof_indices_col, VectorType &global_vector, const FullMatrix< number > &local_matrix, bool diagonal=false) const
typename std::vector< ConstraintLine >::const_iterator const_iterator
void condense(SparseMatrix< number > &matrix, VectorType &vector) const
void set_inhomogeneity(const size_type constrained_dof_index, const number value)
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, MatrixType &global_matrix) const
bool is_closed(const MPI_Comm comm) const
void condense(BlockSparsityPattern &sparsity) 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::integral_constant< bool, false >) const
void condense(SparsityPattern &sparsity) const
void distribute_local_to_global(const size_type index, const number value, VectorType &global_vector) 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 add_lines(const std::set< size_type > &lines)
AffineConstraints(const AffineConstraints &affine_constraints)
void distribute(VectorType &vec) const
void add_lines(const IndexSet &lines)
void condense(BlockSparseMatrix< number > &matrix) const
void add_entries_local_to_global(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) 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
void condense(BlockDynamicSparsityPattern &sparsity) const
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const std::vector< size_type > &local_dof_indices, MatrixType &global_matrix) const
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line_n) const
size_type calculate_line_index(const size_type line_n) const
AffineConstraints & operator=(AffineConstraints &&affine_constraints) noexcept=default
void condense(SparseMatrix< number > &matrix) const
bool is_inhomogeneously_constrained(const size_type index) 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, bool use_inhomogeneities_for_rhs=false) const
void condense(const VectorType &vec_ghosted, VectorType &output) const
void copy_from(const AffineConstraints< other_number > &other)
std::vector< size_type > lines_cache
AffineConstraints(const IndexSet &local_constraints=IndexSet())
void condense(BlockSparseMatrix< number > &matrix, BlockVectorType &vector) 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 distribute_local_to_global(const Vector< number > &local_vector, const std::vector< size_type > &local_dof_indices, VectorType &global_vector, const FullMatrix< number > &local_matrix) const
void set_zero(VectorType &vec) const
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const std::vector< size_type > &row_indices, const AffineConstraints &column_affine_constraints, const std::vector< size_type > &column_indices, MatrixType &global_matrix) 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
AffineConstraints & operator=(const AffineConstraints &)=delete
size_type index_within_set(const size_type global_index) 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_NAMESPACE_CLOSE
#define DeclException0(Exception0)
static ::ExceptionBase & ExcMatrixNotClosed()
static ::ExceptionBase & ExcLineInexistant(size_type arg1)
#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)
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)
types::global_dof_index size_type
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
const types::global_dof_index invalid_dof_index
const 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
bool operator<(const ConstraintLine &) const
void serialize(Archive &ar, const unsigned int)
ConstraintLine & operator=(const ConstraintLineType &other)
ConstraintLine(const size_type &index=numbers::invalid_dof_index, const Entries &entries={}, const number &inhomogeneity=0.0)
std::vector< std::pair< size_type, number > > Entries
std::size_t memory_consumption() const
bool operator==(const ConstraintLine &) const
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::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)