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>
91 return global_row < in.global_row;
112 template <
typename number>
125 const std::pair<size_type, number> &
pair);
128 get_size(
const size_type index)
const;
130 const std::pair<size_type, number> *
135 std::vector<std::pair<size_type, number>> data;
170 template <
typename number>
180 reinit(
const size_type n_local_rows);
190 print(std::ostream &os);
269 n_constraints()
const;
276 n_inhomogeneities()
const;
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;
394 std::vector<number> vector_values;
413 template <
class VectorType>
513template <
typename number =
double>
605 template <
typename other_number>
734 const number weight);
953 const std::vector<std::pair<size_type, number>> *
1092 template <
class VectorType>
1102 template <
class VectorType>
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,
1248 template <
typename VectorType>
1251 const std::vector<size_type> &local_dof_indices,
1274 template <
typename VectorType>
1282 bool diagonal =
false)
const;
1287 template <
class VectorType>
1385 template <
typename MatrixType>
1388 const std::vector<size_type> &local_dof_indices,
1418 template <
typename MatrixType>
1421 const std::vector<size_type> &row_indices,
1441 template <
typename MatrixType>
1444 const std::vector<size_type> &row_indices,
1446 const std::vector<size_type> &column_indices,
1469 template <
typename MatrixType,
typename VectorType>
1473 const std::vector<size_type> &local_dof_indices,
1533 const std::vector<size_type> &local_dof_indices,
1543 const std::vector<size_type> &row_indices,
1555 const std::vector<size_type> & row_indices,
1611 template <
class VectorType>
1628 using Entries = std::vector<std::pair<size_type, number>>;
1661 template <
typename Constra
intLineType>
1667 template <
typename Constra
intLineType>
1701 template <
class Archive>
1762 const bool verbose =
false)
const;
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 "
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,
1967 const std::integral_constant<bool, false>)
const;
1973 template <
typename MatrixType,
typename VectorType>
1977 const std::vector<size_type> &local_dof_indices,
1981 const std::integral_constant<bool, true>)
const;
1992 internal::AffineConstraints::GlobalRowsFromLocal<number>
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>
2048 Assert(sorted ==
false, ExcMatrixIsClosed());
2058 if (is_constrained(
line_n))
2062 if (line_index >= lines_cache.size())
2068 lines.emplace_back();
2069 lines.back().index =
line_n;
2070 lines.back().inhomogeneity = 0.;
2071 lines_cache[line_index] = lines.size() - 1;
2076template <
typename number>
2080 const number weight)
2082 Assert(sorted ==
false, ExcMatrixIsClosed());
2084 ExcMessage(
"Can't constrain a degree of freedom to itself"));
2088 Assert(line_index < lines_cache.size(),
2089 ExcMessage(
"The current AffineConstraints does not contain the line "
2090 "for the current entry. Call AffineConstraints::add_line "
2091 "before calling this function."));
2100 Assert(!local_lines.size() || local_lines.is_element(column),
2104 for (
const auto &p :
line_ptr->entries)
2105 if (p.first == column)
2108 ExcEntryAlreadyExists(
2113 line_ptr->entries.emplace_back(column, weight);
2118template <
typename number>
2125 Assert(line_index < lines_cache.size() &&
2127 ExcMessage(
"call add_line() before calling set_inhomogeneity()"));
2135template <
typename number>
2136template <
class VectorType>
2143 for (
unsigned int i = 0; i < lines.size(); ++i)
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>
2186 const size_type line_index = calculate_line_index(index);
2187 return ((line_index < lines_cache.size()) &&
2191template <
typename number>
2199 if (line_index >= lines_cache.size() ||
2205 return (lines[lines_cache[line_index]].inhomogeneity != number(0.));
2209template <
typename number>
2210inline const std::vector<std::pair<types::global_dof_index, number>> *
2219 if (line_index >= lines_cache.size() ||
2223 return &lines[lines_cache[line_index]].entries;
2226template <
typename number>
2233 if (line_index >= lines_cache.size() ||
2237 return lines[lines_cache[line_index]].inhomogeneity;
2240template <
typename number>
2245 if (local_lines.size() == 0)
2250 return local_lines.index_within_set(
line_n);
2253template <
typename number>
2257 return local_lines.size() == 0 || local_lines.is_element(
line_n);
2260template <
typename number>
2267template <
typename number>
2268template <
class VectorType>
2275 Assert(lines.empty() || sorted ==
true, ExcMatrixNotClosed());
2277 if (is_constrained(index) ==
false)
2282 lines[lines_cache[calculate_line_index(index)]];
2285 value * position.
entries[
j].second;
2289template <
typename number>
2300 Assert(lines.empty() || sorted ==
true, ExcMatrixNotClosed());
2321template <
typename number>
2322template <
class InVector,
class OutVector>
2326 const std::vector<size_type> &local_dof_indices,
2333 local_dof_indices.begin(),
2337template <
typename number>
2348 Assert(lines.empty() || sorted ==
true, ExcMatrixNotClosed());
2358 typename VectorType::value_type value = position.
inhomogeneity;
2369template <
typename MatrixType>
2371template <
typename SparsityPatternType>
2373template <
typename number>
2397 template <
typename MatrixType>
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>
2447template <
typename number>
2448template <
typename other_number>
2455 lines_cache =
other.lines_cache;
2456 local_lines =
other.local_lines;
2457 sorted =
other.sorted;
2462template <
typename number>
2463template <
typename MatrixType>
2467 const std::vector<size_type> &local_dof_indices,
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,
2500 distribute_local_to_global(
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>
2531 this->index =
other.index;
2536 this->inhomogeneity =
other.inhomogeneity;
2541template <
typename number>
2542template <
typename Constra
intLineType>
2547 this->index =
other.index;
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
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)