Reference documentation for deal.II version 9.1.0-pre
affine_constraints.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_affine_constraints_h
17 #define dealii_affine_constraints_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/index_set.h>
23 #include <deal.II/base/subscriptor.h>
24 #include <deal.II/base/table.h>
25 #include <deal.II/base/template_constraints.h>
26 
27 #include <deal.II/lac/vector.h>
28 #include <deal.II/lac/vector_element_access.h>
29 
30 #include <boost/range/iterator_range.hpp>
31 
32 #include <set>
33 #include <utility>
34 #include <vector>
35 
36 DEAL_II_NAMESPACE_OPEN
37 
38 template <typename>
39 class FullMatrix;
40 class SparsityPattern;
44 template <typename number>
45 class SparseMatrix;
46 template <typename number>
48 
49 namespace internals
50 {
51  template <typename number>
52  class GlobalRowsFromLocal;
53 }
54 
55 
56 template <typename number>
57 class AffineConstraints;
58 
65 using ConstraintMatrix DEAL_II_DEPRECATED = AffineConstraints<double>;
66 // Note: Unfortunately, we cannot move this compatibility alias into
67 // constraint_matrix.h directly. This would break a lot of user projects
68 // that include constraint_matrix.h transitively due to various deal.II
69 // headers that include the file.
70 
71 
72 // TODO[WB]: We should have a function of the kind
73 // AffineConstraints::add_constraint (const size_type constrained_dof,
74 // const std::vector<std::pair<size_type, number> > &entries,
75 // const number inhomogeneity = 0);
76 // rather than building up constraints piecemeal through add_line/add_entry
77 // etc. This would also eliminate the possibility of accidentally changing
78 // existing constraints into something pointless, see the discussion on the
79 // mailing list on "Tiny bug in interpolate_boundary_values" in Sept. 2010.
80 
155 template <typename number = double>
156 class AffineConstraints : public Subscriptor
157 {
158 public:
163 
170  {
176 
183 
189  right_object_wins
190  };
191 
209  explicit AffineConstraints(const IndexSet &local_constraints = IndexSet());
210 
214  explicit AffineConstraints(const AffineConstraints &affine_constraints);
215 
219  AffineConstraints(AffineConstraints &&affine_constraints) = default; // NOLINT
220 
231  operator=(const AffineConstraints &) = delete;
232 
237  operator=(AffineConstraints &&affine_constraints) = default; // NOLINT
238 
245  void
246  copy_from(const AffineConstraints &other);
247 
254  void
255  reinit(const IndexSet &local_constraints = IndexSet());
256 
263  bool
264  can_store_line(const size_type line_index) const;
265 
272  const IndexSet &
273  get_local_lines() const;
274 
294  void
295  add_selected_constraints(const AffineConstraints &constraints_in,
296  const IndexSet & filter);
297 
307  void
308  add_line(const size_type line);
309 
322  void
323  add_lines(const std::vector<bool> &lines);
324 
337  void
338  add_lines(const std::set<size_type> &lines);
339 
352  void
353  add_lines(const IndexSet &lines);
354 
366  void
367  add_entry(const size_type line, const size_type column, const number value);
368 
374  void
375  add_entries(const size_type line,
376  const std::vector<std::pair<size_type, number>> &col_val_pairs);
377 
384  void
385  set_inhomogeneity(const size_type line, const number value);
386 
407  void
408  close();
409 
434  void
435  merge(
436  const AffineConstraints & other_constraints,
437  const MergeConflictBehavior merge_conflict_behavior = no_conflicts_allowed,
438  const bool allow_different_local_lines = false);
439 
452  void
453  shift(const size_type offset);
454 
462  void
463  clear();
464 
477  size_type
478  n_constraints() const;
479 
489  bool
490  is_constrained(const size_type index) const;
491 
503  bool
504  is_identity_constrained(const size_type index) const;
505 
512  bool
513  are_identity_constrained(const size_type index1,
514  const size_type index2) const;
515 
526  size_type
527  max_constraint_indirections() const;
528 
533  bool
534  is_inhomogeneously_constrained(const size_type index) const;
535 
541  bool
542  has_inhomogeneities() const;
543 
548  const std::vector<std::pair<size_type, number>> *
549  get_constraint_entries(const size_type line) const;
550 
555  number
556  get_inhomogeneity(const size_type line) const;
557 
578  void
579  print(std::ostream &out) const;
580 
593  void
594  write_dot(std::ostream &) const;
595 
600  std::size_t
601  memory_consumption() const;
602 
609  void
610  resolve_indices(std::vector<types::global_dof_index> &indices) const;
611 
638  void
639  condense(SparsityPattern &sparsity) const;
640 
644  void
645  condense(BlockSparsityPattern &sparsity) const;
646 
651  void
652  condense(DynamicSparsityPattern &sparsity) const;
653 
658  void
659  condense(BlockDynamicSparsityPattern &sparsity) const;
660 
668  void
669  condense(SparseMatrix<number> &matrix) const;
670 
674  void
675  condense(BlockSparseMatrix<number> &matrix) const;
676 
688  template <class VectorType>
689  void
690  condense(VectorType &vec) const;
691 
698  template <class VectorType>
699  void
700  condense(const VectorType &vec_ghosted, VectorType &output) const;
701 
714  template <class VectorType>
715  void
716  condense(SparseMatrix<number> &matrix, VectorType &vector) const;
717 
722  template <class BlockVectorType>
723  void
724  condense(BlockSparseMatrix<number> &matrix, BlockVectorType &vector) const;
725 
732  template <class VectorType>
733  void
734  set_zero(VectorType &vec) const;
735 
787  template <class InVector, class OutVector>
788  void
789  distribute_local_to_global(const InVector & local_vector,
790  const std::vector<size_type> &local_dof_indices,
791  OutVector & global_vector) const;
792 
836  template <typename VectorType>
837  void
838  distribute_local_to_global(const Vector<number> & local_vector,
839  const std::vector<size_type> &local_dof_indices,
840  VectorType & global_vector,
841  const FullMatrix<number> & local_matrix) const;
842 
862  template <typename VectorType>
863  void
864  distribute_local_to_global(
865  const Vector<number> & local_vector,
866  const std::vector<size_type> &local_dof_indices_row,
867  const std::vector<size_type> &local_dof_indices_col,
868  VectorType & global_vector,
869  const FullMatrix<number> & local_matrix,
870  bool diagonal = false) const;
871 
875  template <class VectorType>
876  void
877  distribute_local_to_global(const size_type index,
878  const number value,
879  VectorType & global_vector) const;
880 
909  template <typename ForwardIteratorVec,
910  typename ForwardIteratorInd,
911  class VectorType>
912  void
913  distribute_local_to_global(ForwardIteratorVec local_vector_begin,
914  ForwardIteratorVec local_vector_end,
915  ForwardIteratorInd local_indices_begin,
916  VectorType & global_vector) const;
917 
965  template <typename MatrixType>
966  void
967  distribute_local_to_global(const FullMatrix<number> & local_matrix,
968  const std::vector<size_type> &local_dof_indices,
969  MatrixType & global_matrix) const;
970 
998  template <typename MatrixType>
999  void
1000  distribute_local_to_global(const FullMatrix<number> & local_matrix,
1001  const std::vector<size_type> &row_indices,
1002  const std::vector<size_type> &col_indices,
1003  MatrixType & global_matrix) const;
1004 
1021  template <typename MatrixType>
1022  void
1023  distribute_local_to_global(const FullMatrix<number> & local_matrix,
1024  const std::vector<size_type> &row_indices,
1025  const AffineConstraints &column_affine_constraints,
1026  const std::vector<size_type> &column_indices,
1027  MatrixType & global_matrix) const;
1028 
1045  template <typename MatrixType, typename VectorType>
1046  void
1047  distribute_local_to_global(const FullMatrix<number> & local_matrix,
1048  const Vector<number> & local_vector,
1049  const std::vector<size_type> &local_dof_indices,
1050  MatrixType & global_matrix,
1051  VectorType & global_vector,
1052  bool use_inhomogeneities_for_rhs = false) const;
1053 
1107  template <typename SparsityPatternType>
1108  void
1109  add_entries_local_to_global(
1110  const std::vector<size_type> &local_dof_indices,
1111  SparsityPatternType & sparsity_pattern,
1112  const bool keep_constrained_entries = true,
1113  const Table<2, bool> & dof_mask = Table<2, bool>()) const;
1114 
1118  template <typename SparsityPatternType>
1119  void
1120  add_entries_local_to_global(
1121  const std::vector<size_type> &row_indices,
1122  const std::vector<size_type> &col_indices,
1123  SparsityPatternType & sparsity_pattern,
1124  const bool keep_constrained_entries = true,
1125  const Table<2, bool> & dof_mask = Table<2, bool>()) const;
1126 
1146  template <typename ForwardIteratorVec,
1147  typename ForwardIteratorInd,
1148  class VectorType>
1149  void
1150  get_dof_values(const VectorType & global_vector,
1151  ForwardIteratorInd local_indices_begin,
1152  ForwardIteratorVec local_vector_begin,
1153  ForwardIteratorVec local_vector_end) const;
1154 
1176  template <class VectorType>
1177  void
1178  distribute(VectorType &vec) const;
1179 
1188  {
1193  using Entries = std::vector<std::pair<size_type, number>>;
1194 
1201 
1210 
1215 
1223  bool
1224  operator<(const ConstraintLine &) const;
1225 
1231  bool
1232  operator==(const ConstraintLine &) const;
1233 
1238  std::size_t
1239  memory_consumption() const;
1240 
1244  template <class Archive>
1245  void
1246  serialize(Archive &ar, const unsigned int)
1247  {
1248  ar &index &entries &inhomogeneity;
1249  }
1250  };
1251 
1255  using const_iterator = typename std::vector<ConstraintLine>::const_iterator;
1256 
1260  using LineRange = boost::iterator_range<const_iterator>;
1261 
1270  const LineRange
1271  get_lines() const;
1272 
1300  bool
1301  is_consistent_in_parallel(const std::vector<IndexSet> &locally_owned_dofs,
1302  const IndexSet & locally_active_dofs,
1303  const MPI_Comm mpi_communicator,
1304  const bool verbose = false) const;
1305 
1311  DeclException0(ExcMatrixIsClosed);
1317  DeclException0(ExcMatrixNotClosed);
1324  size_type,
1325  << "The specified line " << arg1 << " does not exist.");
1331  DeclException4(ExcEntryAlreadyExists,
1332  size_type,
1333  size_type,
1334  number,
1335  number,
1336  << "The entry for the indices " << arg1 << " and " << arg2
1337  << " already exists, but the values " << arg3 << " (old) and "
1338  << arg4 << " (new) differ "
1339  << "by " << (arg4 - arg3) << ".");
1345  DeclException2(ExcDoFConstrainedToConstrainedDoF,
1346  int,
1347  int,
1348  << "You tried to constrain DoF " << arg1 << " to DoF " << arg2
1349  << ", but that one is also constrained. This is not allowed!");
1355  DeclException1(ExcDoFIsConstrainedFromBothObjects,
1356  size_type,
1357  << "Degree of freedom " << arg1
1358  << " is constrained from both object in a merge operation.");
1364  DeclException1(ExcDoFIsConstrainedToConstrainedDoF,
1365  size_type,
1366  << "In the given argument a degree of freedom is constrained "
1367  << "to another DoF with number " << arg1
1368  << ", which however is constrained by this object. This is not"
1369  << " allowed.");
1375  DeclException1(ExcRowNotStoredHere,
1376  size_type,
1377  << "The index set given to this constraint matrix indicates "
1378  << "constraints for degree of freedom " << arg1
1379  << " should not be stored by this object, but a constraint "
1380  << "is being added.");
1381 
1387  DeclException2(ExcColumnNotStoredHere,
1388  size_type,
1389  size_type,
1390  << "The index set given to this constraint matrix indicates "
1391  << "constraints using degree of freedom " << arg2
1392  << " should not be stored by this object, but a constraint "
1393  << "for degree of freedom " << arg1 << " uses it.");
1394 
1400  DeclException2(ExcIncorrectConstraint,
1401  int,
1402  int,
1403  << "While distributing the constraint for DoF " << arg1
1404  << ", it turns out that one of the processors "
1405  << "who own the " << arg2 << " degrees of freedom that x_"
1406  << arg1 << " is constrained against does not know about "
1407  << "the constraint on x_" << arg1
1408  << ". Did you not initialize the AffineConstraints container "
1409  << "with the appropriate locally_relevant set so "
1410  << "that every processor who owns a DoF that constrains "
1411  << "another DoF also knows about this constraint?");
1412 
1413 private:
1425  std::vector<ConstraintLine> lines;
1426 
1459  std::vector<size_type> lines_cache;
1460 
1467 
1471  bool sorted;
1472 
1477  size_type
1478  calculate_line_index(const size_type line) const;
1479 
1484  static bool
1485  check_zero_weight(const std::pair<size_type, number> &p);
1486 
1491  template <typename MatrixType, typename VectorType>
1492  void
1493  distribute_local_to_global(const FullMatrix<number> & local_matrix,
1494  const Vector<number> & local_vector,
1495  const std::vector<size_type> &local_dof_indices,
1496  MatrixType & global_matrix,
1497  VectorType & global_vector,
1498  bool use_inhomogeneities_for_rhs,
1499  std::integral_constant<bool, false>) const;
1500 
1505  template <typename MatrixType, typename VectorType>
1506  void
1507  distribute_local_to_global(const FullMatrix<number> & local_matrix,
1508  const Vector<number> & local_vector,
1509  const std::vector<size_type> &local_dof_indices,
1510  MatrixType & global_matrix,
1511  VectorType & global_vector,
1512  bool use_inhomogeneities_for_rhs,
1513  std::integral_constant<bool, true>) const;
1514 
1519  template <typename SparsityPatternType>
1520  void
1521  add_entries_local_to_global(const std::vector<size_type> &local_dof_indices,
1522  SparsityPatternType & sparsity_pattern,
1523  const bool keep_constrained_entries,
1524  const Table<2, bool> &dof_mask,
1525  std::integral_constant<bool, false>) const;
1526 
1531  template <typename SparsityPatternType>
1532  void
1533  add_entries_local_to_global(const std::vector<size_type> &local_dof_indices,
1534  SparsityPatternType & sparsity_pattern,
1535  const bool keep_constrained_entries,
1536  const Table<2, bool> &dof_mask,
1537  std::integral_constant<bool, true>) const;
1538 
1546  void
1547  make_sorted_row_list(
1548  const std::vector<size_type> & local_dof_indices,
1549  internals::GlobalRowsFromLocal<number> &global_rows) const;
1550 
1558  void
1559  make_sorted_row_list(const std::vector<size_type> &local_dof_indices,
1560  std::vector<size_type> & active_dofs) const;
1561 
1565  template <typename MatrixScalar, typename VectorScalar>
1566  typename ProductType<VectorScalar, MatrixScalar>::type
1567  resolve_vector_entry(
1568  const size_type i,
1569  const internals::GlobalRowsFromLocal<number> &global_rows,
1570  const Vector<VectorScalar> & local_vector,
1571  const std::vector<size_type> & local_dof_indices,
1572  const FullMatrix<MatrixScalar> & local_matrix) const;
1573 };
1574 
1575 /* ---------------- template and inline functions ----------------- */
1576 
1577 template <typename number>
1579  const IndexSet &local_constraints)
1580  : lines()
1581  , local_lines(local_constraints)
1582  , sorted(false)
1583 {
1584  // make sure the IndexSet is compressed. Otherwise this can lead to crashes
1585  // that are hard to find (only happen in release mode).
1586  // see tests/mpi/affine_constraints_crash_01
1588 }
1589 
1590 template <typename number>
1592  const AffineConstraints &affine_constraints)
1593  : Subscriptor()
1594  , lines(affine_constraints.lines)
1595  , lines_cache(affine_constraints.lines_cache)
1596  , local_lines(affine_constraints.local_lines)
1597  , sorted(affine_constraints.sorted)
1598 {}
1599 
1600 template <typename number>
1601 inline void
1603 {
1604  Assert(sorted == false, ExcMatrixIsClosed());
1605 
1606  // the following can happen when we compute with distributed meshes and dof
1607  // handlers and we constrain a degree of freedom whose number we don't have
1608  // locally. if we don't abort here the program will try to allocate several
1609  // terabytes of memory to resize the various arrays below :-)
1611  const size_type line_index = calculate_line_index(line);
1612 
1613  // check whether line already exists; it may, in which case we can just quit
1614  if (is_constrained(line))
1615  return;
1616 
1617  // if necessary enlarge vector of existing entries for cache
1618  if (line_index >= lines_cache.size())
1619  lines_cache.resize(std::max(2 * static_cast<size_type>(lines_cache.size()),
1620  line_index + 1),
1622 
1623  // push a new line to the end of the list
1624  lines.emplace_back();
1625  lines.back().index = line;
1626  lines.back().inhomogeneity = 0.;
1627  lines_cache[line_index] = lines.size() - 1;
1628 }
1629 
1630 template <typename number>
1631 inline void
1633  const size_type column,
1634  const number value)
1635 {
1636  Assert(sorted == false, ExcMatrixIsClosed());
1637  Assert(line != column,
1638  ExcMessage("Can't constrain a degree of freedom to itself"));
1639 
1640  // Ensure that the current line is present in the cache:
1641  const size_type line_index = calculate_line_index(line);
1642  Assert(line_index < lines_cache.size(),
1643  ExcMessage("The current AffineConstraints does not contain the line "
1644  "for the current entry. Call AffineConstraints::add_line "
1645  "before calling this function."));
1646 
1647  // if in debug mode, check whether an entry for this column already exists
1648  // and if it's the same as the one entered at present
1649  //
1650  // in any case: exit the function if an entry for this column already
1651  // exists, since we don't want to enter it twice
1653  ExcInternalError());
1655  ExcColumnNotStoredHere(line, column));
1656  ConstraintLine *line_ptr = &lines[lines_cache[line_index]];
1657  Assert(line_ptr->index == line, ExcInternalError());
1658  for (const auto &p : line_ptr->entries)
1659  if (p.first == column)
1660  {
1661  Assert(std::abs(p.second - value) < 1.e-14,
1662  ExcEntryAlreadyExists(line, column, p.second, value));
1663  return;
1664  }
1665 
1666  line_ptr->entries.emplace_back(column, value);
1667 }
1668 
1669 template <typename number>
1670 inline void
1672  const number value)
1673 {
1674  const size_type line_index = calculate_line_index(line);
1675  Assert(line_index < lines_cache.size() &&
1676  lines_cache[line_index] != numbers::invalid_size_type,
1677  ExcMessage("call add_line() before calling set_inhomogeneity()"));
1678  Assert(lines_cache[line_index] < lines.size(), ExcInternalError());
1679  ConstraintLine *line_ptr = &lines[lines_cache[line_index]];
1680  line_ptr->inhomogeneity = value;
1681 }
1682 
1683 template <typename number>
1686 {
1687  return lines.size();
1688 }
1689 
1690 template <typename number>
1691 inline bool
1693 {
1694  const size_type line_index = calculate_line_index(index);
1695  return ((line_index < lines_cache.size()) &&
1696  (lines_cache[line_index] != numbers::invalid_size_type));
1697 }
1698 
1699 template <typename number>
1700 inline bool
1702  const size_type index) const
1703 {
1704  // check whether the entry is constrained. could use is_constrained, but
1705  // that means computing the line index twice
1706  const size_type line_index = calculate_line_index(index);
1707  if (line_index >= lines_cache.size() ||
1708  lines_cache[line_index] == numbers::invalid_size_type)
1709  return false;
1710  else
1711  {
1712  Assert(lines_cache[line_index] < lines.size(), ExcInternalError());
1713  return !(lines[lines_cache[line_index]].inhomogeneity == number(0.));
1714  }
1715 }
1716 
1717 template <typename number>
1718 inline const std::vector<std::pair<types::global_dof_index, number>> *
1720 {
1721  // check whether the entry is constrained. could use is_constrained, but
1722  // that means computing the line index twice
1723  const size_type line_index = calculate_line_index(line);
1724  if (line_index >= lines_cache.size() ||
1725  lines_cache[line_index] == numbers::invalid_size_type)
1726  return nullptr;
1727  else
1728  return &lines[lines_cache[line_index]].entries;
1729 }
1730 
1731 template <typename number>
1732 inline number
1734 {
1735  // check whether the entry is constrained. could use is_constrained, but
1736  // that means computing the line index twice
1737  const size_type line_index = calculate_line_index(line);
1738  if (line_index >= lines_cache.size() ||
1739  lines_cache[line_index] == numbers::invalid_size_type)
1740  return 0;
1741  else
1742  return lines[lines_cache[line_index]].inhomogeneity;
1743 }
1744 
1745 template <typename number>
1748 {
1749  // IndexSet is unused (serial case)
1750  if (!local_lines.size())
1751  return line;
1752 
1754 
1755  return local_lines.index_within_set(line);
1756 }
1757 
1758 template <typename number>
1759 inline bool
1761 {
1762  return !local_lines.size() || local_lines.is_element(line_index);
1763 }
1764 
1765 template <typename number>
1766 inline const IndexSet &
1768 {
1769  return local_lines;
1770 }
1771 
1772 template <typename number>
1773 template <class VectorType>
1774 inline void
1776  const size_type index,
1777  const number value,
1778  VectorType & global_vector) const
1779 {
1780  Assert(lines.empty() || sorted == true, ExcMatrixNotClosed());
1781 
1782  if (is_constrained(index) == false)
1783  global_vector(index) += value;
1784  else
1785  {
1786  const ConstraintLine &position =
1788  for (size_type j = 0; j < position.entries.size(); ++j)
1789  global_vector(position.entries[j].first) +=
1790  value * position.entries[j].second;
1791  }
1792 }
1793 
1794 template <typename number>
1795 template <typename ForwardIteratorVec,
1796  typename ForwardIteratorInd,
1797  class VectorType>
1798 inline void
1800  ForwardIteratorVec local_vector_begin,
1801  ForwardIteratorVec local_vector_end,
1802  ForwardIteratorInd local_indices_begin,
1803  VectorType & global_vector) const
1804 {
1805  Assert(lines.empty() || sorted == true, ExcMatrixNotClosed());
1806  for (; local_vector_begin != local_vector_end;
1807  ++local_vector_begin, ++local_indices_begin)
1808  {
1809  if (is_constrained(*local_indices_begin) == false)
1810  internal::ElementAccess<VectorType>::add(*local_vector_begin,
1811  *local_indices_begin,
1812  global_vector);
1813  else
1814  {
1815  const ConstraintLine &position =
1816  lines[lines_cache[calculate_line_index(*local_indices_begin)]];
1817  for (size_type j = 0; j < position.entries.size(); ++j)
1818  internal::ElementAccess<VectorType>::add(
1819  (*local_vector_begin) * position.entries[j].second,
1820  position.entries[j].first,
1821  global_vector);
1822  }
1823  }
1824 }
1825 
1826 template <typename number>
1827 template <class InVector, class OutVector>
1828 inline void
1830  const InVector & local_vector,
1831  const std::vector<size_type> &local_dof_indices,
1832  OutVector & global_vector) const
1833 {
1834  Assert(local_vector.size() == local_dof_indices.size(),
1835  ExcDimensionMismatch(local_vector.size(), local_dof_indices.size()));
1836  distribute_local_to_global(local_vector.begin(),
1837  local_vector.end(),
1838  local_dof_indices.begin(),
1839  global_vector);
1840 }
1841 
1842 template <typename number>
1843 template <typename ForwardIteratorVec,
1844  typename ForwardIteratorInd,
1845  class VectorType>
1846 inline void
1848  const VectorType & global_vector,
1849  ForwardIteratorInd local_indices_begin,
1850  ForwardIteratorVec local_vector_begin,
1851  ForwardIteratorVec local_vector_end) const
1852 {
1853  Assert(lines.empty() || sorted == true, ExcMatrixNotClosed());
1854  for (; local_vector_begin != local_vector_end;
1855  ++local_vector_begin, ++local_indices_begin)
1856  {
1857  if (is_constrained(*local_indices_begin) == false)
1858  *local_vector_begin = global_vector(*local_indices_begin);
1859  else
1860  {
1861  const ConstraintLine &position =
1862  lines[lines_cache[calculate_line_index(*local_indices_begin)]];
1863  typename VectorType::value_type value = position.inhomogeneity;
1864  for (size_type j = 0; j < position.entries.size(); ++j)
1865  value += (global_vector(position.entries[j].first) *
1866  position.entries[j].second);
1867  *local_vector_begin = value;
1868  }
1869  }
1870 }
1871 
1872 template <typename MatrixType>
1874 template <typename SparsityPatternType>
1876 template <typename number>
1878 
1897 template <typename MatrixType>
1899 {
1900 private:
1901  struct yes_type
1902  {
1903  char c[1];
1904  };
1905  struct no_type
1906  {
1907  char c[2];
1908  };
1909 
1915  template <typename T>
1916  static yes_type
1917  check_for_block_matrix(const BlockMatrixBase<T> *);
1918 
1923  template <typename T>
1924  static yes_type
1925  check_for_block_matrix(const BlockSparsityPatternBase<T> *);
1926 
1931  template <typename T>
1932  static yes_type
1933  check_for_block_matrix(const BlockSparseMatrixEZ<T> *);
1934 
1939  static no_type
1940  check_for_block_matrix(...);
1941 
1942 public:
1948  static const bool value =
1949  (sizeof(check_for_block_matrix((MatrixType *)nullptr)) == sizeof(yes_type));
1950 };
1951 
1952 // instantiation of the static member
1953 template <typename MatrixType>
1955 
1956 template <typename number>
1957 template <typename MatrixType>
1958 inline void
1960  const FullMatrix<number> & local_matrix,
1961  const std::vector<size_type> &local_dof_indices,
1962  MatrixType & global_matrix) const
1963 {
1964  // create a dummy and hand on to the function actually implementing this
1965  // feature in the cm.templates.h file.
1966  Vector<typename MatrixType::value_type> dummy(0);
1968  local_matrix,
1969  dummy,
1970  local_dof_indices,
1971  global_matrix,
1972  dummy,
1973  false,
1974  std::integral_constant<bool, IsBlockMatrix<MatrixType>::value>());
1975 }
1976 
1977 template <typename number>
1978 template <typename MatrixType, typename VectorType>
1979 inline void
1981  const FullMatrix<number> & local_matrix,
1982  const Vector<number> & local_vector,
1983  const std::vector<size_type> &local_dof_indices,
1984  MatrixType & global_matrix,
1985  VectorType & global_vector,
1986  bool use_inhomogeneities_for_rhs) const
1987 {
1988  // enter the internal function with the respective block information set,
1989  // the actual implementation follows in the cm.templates.h file.
1991  local_matrix,
1992  local_vector,
1993  local_dof_indices,
1994  global_matrix,
1995  global_vector,
1996  use_inhomogeneities_for_rhs,
1997  std::integral_constant<bool, IsBlockMatrix<MatrixType>::value>());
1998 }
1999 
2000 template <typename number>
2001 template <typename SparsityPatternType>
2002 inline void
2004  const std::vector<size_type> &local_dof_indices,
2005  SparsityPatternType & sparsity_pattern,
2006  const bool keep_constrained_entries,
2007  const Table<2, bool> & dof_mask) const
2008 {
2009  // enter the internal function with the respective block information set,
2010  // the actual implementation follows in the cm.templates.h file.
2012  local_dof_indices,
2013  sparsity_pattern,
2014  keep_constrained_entries,
2015  dof_mask,
2016  std::integral_constant<bool, IsBlockMatrix<SparsityPatternType>::value>());
2017 }
2018 
2019 DEAL_II_NAMESPACE_CLOSE
2020 
2021 #endif
const types::global_dof_index invalid_size_type
Definition: types.h:182
std::vector< ConstraintLine > lines
size_type calculate_line_index(const size_type line) const
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
void add_entry(const size_type line, const size_type column, const number value)
TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
static::ExceptionBase & ExcColumnNotStoredHere(size_type arg1, size_type arg2)
number get_inhomogeneity(const size_type line) const
static::ExceptionBase & ExcRowNotStoredHere(size_type arg1)
bool is_constrained(const size_type index) const
size_type size() const
Definition: index_set.h:1611
static::ExceptionBase & ExcMatrixNotClosed()
static::ExceptionBase & ExcMatrixIsClosed()
void add_line(const size_type line)
unsigned long long int global_dof_index
Definition: types.h:72
void get_dof_values(const VectorType &global_vector, ForwardIteratorInd local_indices_begin, ForwardIteratorVec local_vector_begin, ForwardIteratorVec local_vector_end) const
void serialize(Archive &ar, const unsigned int)
static::ExceptionBase & ExcMessage(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
#define Assert(cond, exc)
Definition: exceptions.h:1227
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
#define DeclException0(Exception0)
Definition: exceptions.h:385
AffineConstraints(const IndexSet &local_constraints=IndexSet())
void compress() const
Definition: index_set.h:1619
static::ExceptionBase & ExcLineInexistant(int arg1, int arg2)
bool can_store_line(const size_type line_index) const
std::vector< size_type > lines_cache
boost::iterator_range< const_iterator > LineRange
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternType &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:444
size_type index_within_set(const size_type global_index) const
Definition: index_set.h:1834
std::vector< std::pair< size_type, number >> Entries
void set_inhomogeneity(const size_type line, const number value)
bool is_element(const size_type index) const
Definition: index_set.h:1676
Definition: table.h:37
const IndexSet & get_local_lines() const
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line) const
typename std::vector< ConstraintLine >::const_iterator const_iterator
static::ExceptionBase & ExcEntryAlreadyExists(size_type arg1, size_type arg2, number arg3, number arg4)
bool is_inhomogeneously_constrained(const size_type index) const
static::ExceptionBase & ExcInternalError()
size_type n_constraints() const