deal.II version GIT relicensing-6848-g68f52df3ff 2026-10-09 12:50:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
mg_transfer_matrix_free.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2016 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_mg_transfer_matrix_free_h
14#define dealii_mg_transfer_matrix_free_h
15
20
22
26
30
35
37
38
40
41// Forward declarations
42#ifndef DOXYGEN
43namespace internal
44{
45 class MGTwoLevelTransferImplementation;
46} // namespace internal
47
48namespace Portable
49{
50 template <int dim, typename VectorType>
52
53 namespace internal
54 {
55 class MGTwoLevelTransferImplementation;
56 } // namespace internal
57} // namespace Portable
58
59template <int dim,
60 typename Number,
63#endif
64
70namespace mg
71{
83 {
89 boost::signals2::signal<void(const bool before)> prolongation_cell_loop;
90
96 boost::signals2::signal<void(const bool before)> restriction_cell_loop;
97
105 boost::signals2::signal<void(const bool before)> prolongation;
106
114 boost::signals2::signal<void(const bool before)> restriction;
115 };
116} // namespace mg
117
118
119
123template <int dim, typename VectorType>
125{
126public:
127 static_assert(
128 std::is_same_v<
129 VectorType,
130 LinearAlgebra::distributed::Vector<typename VectorType::value_type,
132 std::is_same_v<
133 VectorType,
134 LinearAlgebra::distributed::Vector<typename VectorType::value_type,
136 "This class is currently only implemented for vectors of "
137 "type LinearAlgebra::distributed::Vector.");
138
142 std::shared_ptr<const Utilities::MPI::Partitioner> partitioner_coarse;
143
147 std::shared_ptr<const Utilities::MPI::Partitioner> partitioner_fine;
148
152 virtual void
153 prolongate_and_add(VectorType &dst, const VectorType &src) const = 0;
154
158 virtual void
159 restrict_and_add(VectorType &dst, const VectorType &src) const = 0;
160
168 virtual void
169 interpolate(VectorType &dst, const VectorType &src) const = 0;
170
176 virtual std::pair<bool, bool>
178 const std::shared_ptr<const Utilities::MPI::Partitioner>
180 const std::shared_ptr<const Utilities::MPI::Partitioner>
181 &partitioner_fine) = 0;
182
186 virtual std::size_t
188
189
193 virtual std::pair<const DoFHandler<dim> *, unsigned int>
195};
196
197
198
199namespace internal
200{
204 template <int dim, typename VectorType>
205 class MGTwoLevelTransferCore : public MGTwoLevelTransferBase<dim, VectorType>
206 {
207 public:
211 using Number = typename VectorType::value_type;
212
217
221 void
222 prolongate_and_add(VectorType &dst, const VectorType &src) const override;
223
227 void
228 restrict_and_add(VectorType &dst, const VectorType &src) const override;
229
230 protected:
234 virtual void
236 const VectorType &src) const = 0;
237
241 virtual void
242 restrict_and_add_internal(VectorType &dst, const VectorType &src) const = 0;
243
249 void
250 update_ghost_values(const VectorType &vec) const;
251
257 void
258 compress(VectorType &vec, const VectorOperation::values op) const;
259
265 void
266 zero_out_ghost_values(const VectorType &vec) const;
267
272 template <std::size_t width, typename IndexType>
273 std::pair<bool, bool>
275 const std::shared_ptr<const Utilities::MPI::Partitioner>
277 const std::shared_ptr<const Utilities::MPI::Partitioner>
281 ConstraintInfo<dim, VectorizedArray<Number, width>, IndexType>
282 &constraint_info_coarse,
283 std::vector<unsigned int> &dof_indices_fine);
284
291
292 protected:
297 mutable VectorType vec_coarse;
298
306 mutable VectorType vec_fine;
307
312
317 std::shared_ptr<const Utilities::MPI::Partitioner>
319
324 std::shared_ptr<const Utilities::MPI::Partitioner>
326
332
338 };
339} // namespace internal
340
341
342
369template <int dim, typename VectorType>
371 : public internal::MGTwoLevelTransferCore<dim, VectorType>
372{
373public:
374 static_assert(
375 std::is_same_v<
376 VectorType,
377 LinearAlgebra::distributed::Vector<typename VectorType::value_type,
379 std::is_same_v<
380 VectorType,
381 LinearAlgebra::distributed::Vector<typename VectorType::value_type,
383 "This class is currently only implemented for vectors of "
384 "type LinearAlgebra::distributed::Vector.");
385
389 using Number = typename VectorType::value_type;
390
396
405 void
408 const DoFHandler<dim> &dof_handler_coarse,
409 const AffineConstraints<Number> &constraint_fine =
411 const AffineConstraints<Number> &constraint_coarse =
413 const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
414 const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
415
425 void
428 const DoFHandler<dim> &dof_handler_coarse,
429 const AffineConstraints<Number> &constraint_fine =
431 const AffineConstraints<Number> &constraint_coarse =
433 const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
434 const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
435
449 void
451 const DoFHandler<dim> &dof_handler_coarse,
452 const AffineConstraints<Number> &constraint_fine =
454 const AffineConstraints<Number> &constraint_coarse =
456 const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
457 const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
458
468 void
469 reinit(const MatrixFree<dim, Number> &matrix_free_fine,
470 const unsigned int dof_handler_index_fine,
471 const MatrixFree<dim, Number> &matrix_free_coarse,
472 const unsigned int dof_handler_index_coarse);
473
482 static bool
483 fast_polynomial_transfer_supported(const unsigned int fe_degree_fine,
484 const unsigned int fe_degree_coarse);
485
489 void
490 interpolate(VectorType &dst, const VectorType &src) const override;
491
496 std::pair<bool, bool>
498 const std::shared_ptr<const Utilities::MPI::Partitioner>
500 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
501 override;
502
506 std::size_t
507 memory_consumption() const override;
508
512 std::pair<const DoFHandler<dim> *, unsigned int>
513 get_dof_handler_fine() const override;
514
515protected:
516 void
518 const VectorType &src) const override;
519
520 void
522 const VectorType &src) const override;
523
524private:
584
588 std::vector<MGTransferScheme> schemes;
589
594 internal::MatrixFreeFunctions::
595 ConstraintInfo<dim, VectorizedArrayType, types::global_dof_index>
597
601 internal::MatrixFreeFunctions::
602 ConstraintInfo<dim, VectorizedArrayType, types::global_dof_index>
604
637
643 std::unique_ptr<MatrixFreeRelatedData> matrix_free_data;
644
649 std::vector<unsigned int> weights_start;
650
656
661 std::vector<unsigned char> weights_are_compressed;
662
666 unsigned int n_components;
667
672
676 unsigned int mg_level_fine;
677
679
680 friend class MGTransferMatrixFree<dim, Number, MemorySpace::Host>;
681
682 friend class MGTransferMatrixFree<dim, Number, MemorySpace::Default>;
683
684 friend class Portable::MGTwoLevelTransfer<
685 dim,
686 LinearAlgebra::distributed::Vector<Number, MemorySpace::Default>>;
687
689};
690
691
697template <int dim, typename VectorType>
699 : public MGTwoLevelTransferBase<dim, VectorType>
700{
701public:
702 static_assert(
703 std::is_same_v<
704 VectorType,
705 LinearAlgebra::distributed::Vector<typename VectorType::value_type,
707 "type LinearAlgebra::distributed::Vector. This class should not be used for host vectors since it would perform redundant transfers. Use MGTwoLevelTransfer instead.");
708
709
713 using Number = typename VectorType::value_type;
714
715 /*
716 * The vector type used by vectors defined on the host.
717 */
720
725
729 void
730 reinit(const DoFHandler<dim> &dof_handler_fine,
731 const DoFHandler<dim> &dof_handler_coarse,
732 const AffineConstraints<Number> &constraint_fine =
734 const AffineConstraints<Number> &constraint_coarse =
736 const unsigned int mg_level_fine = numbers::invalid_unsigned_int,
737 const unsigned int mg_level_coarse = numbers::invalid_unsigned_int);
738
742 void
743 reinit(const MatrixFree<dim, Number> &matrix_free_fine,
744 const unsigned int dof_handler_index_fine,
745 const MatrixFree<dim, Number> &matrix_free_coarse,
746 const unsigned int dof_handler_index_coarse);
747
751 bool
752 fast_polynomial_transfer_supported(const unsigned int fe_degree_fine,
753 const unsigned int fe_degree_coarse);
754
758 void
759 prolongate_and_add(VectorType &dst, const VectorType &src) const override;
760
764 void
765 restrict_and_add(VectorType &dst, const VectorType &src) const override;
766
770 void
771 interpolate(VectorType &dst, const VectorType &src) const override;
772
776 std::pair<bool, bool>
778 const std::shared_ptr<const Utilities::MPI::Partitioner>
779 &partitioner_coarse,
780 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
781 override;
782
786 std::size_t
787 memory_consumption() const override;
788
792 std::pair<const DoFHandler<dim> *, unsigned int>
793 get_dof_handler_fine() const override;
794
795private:
800
805
810
814 void
815 copy_to_host(VectorTypeHost &dst, const VectorType &src) const;
816
820 void
821 copy_from_host(VectorType &dst, const VectorTypeHost &src) const;
822
823 friend class internal::MGTwoLevelTransferImplementation;
824
825 friend class MGTransferMatrixFree<dim,
826 Number,
827 typename VectorType::memory_space>;
828};
829
830
831
835template <int dim, typename VectorType>
837 : public internal::MGTwoLevelTransferCore<dim, VectorType>
838{
839private:
840 static_assert(
841 std::is_same_v<
842 VectorType,
844 "This class is currently only implemented for vectors of "
845 "type LinearAlgebra::distributed::Vector.");
846
847 using Number = typename VectorType::value_type;
849
851
852public:
860 {
870 AdditionalData(const double tolerance = 1e-6,
871 const unsigned int rtree_level = 0,
872 const bool enforce_all_points_found = true)
873 : tolerance(tolerance)
874 , rtree_level(rtree_level)
875 , enforce_all_points_found(enforce_all_points_found)
876 {}
877
882 double tolerance;
883
889 unsigned int rtree_level;
890
899 };
900
905
910 void
911 reinit(const DoFHandler<dim> &dof_handler_fine,
912 const DoFHandler<dim> &dof_handler_coarse,
913 const Mapping<dim> &mapping_fine,
914 const Mapping<dim> &mapping_coarse,
915 const AffineConstraints<Number> &constraint_fine =
917 const AffineConstraints<Number> &constraint_coarse =
919
926 void
927 interpolate(VectorType &dst, const VectorType &src) const override;
928
933 std::pair<bool, bool>
935 const std::shared_ptr<const Utilities::MPI::Partitioner>
936 &partitioner_coarse,
937 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
938 override;
939
943 std::size_t
944 memory_consumption() const override;
945
949 std::pair<const DoFHandler<dim> *, unsigned int>
950 get_dof_handler_fine() const override;
951
955 boost::signals2::connection
956 connect_prolongation_cell_loop(const std::function<void(const bool)> &slot);
957
961 boost::signals2::connection
962 connect_restriction_cell_loop(const std::function<void(const bool)> &slot);
963
967 boost::signals2::connection
968 connect_prolongation(const std::function<void(const bool)> &slot);
969
973 boost::signals2::connection
974 connect_restriction(const std::function<void(const bool)> &slot);
975
976protected:
981 void
983 const VectorType &src) const override;
984
988 void
990 const VectorType &src) const override;
991
992private:
996 template <int n_components>
997 void
999 const VectorType &src) const;
1000
1004 template <int n_components>
1005 void
1006 restrict_and_add_internal_comp(VectorType &dst, const VectorType &src) const;
1007
1012
1016 unsigned int mg_level_fine;
1017
1023
1027 mutable std::vector<Number> rpe_input_output;
1028
1032 mutable std::vector<Number> rpe_buffer;
1033
1037 std::shared_ptr<NonMatching::MappingInfo<dim, dim, Number>> mapping_info;
1038
1043 internal::MatrixFreeFunctions::
1044 ConstraintInfo<dim, VectorizedArrayType, unsigned int>
1046
1050 std::unique_ptr<FiniteElement<dim>> fe_coarse;
1051
1056 std::vector<unsigned int> level_dof_indices_fine;
1057
1063 std::vector<unsigned int> level_dof_indices_fine_ptrs;
1064
1065 friend class MGTransferMatrixFree<dim,
1066 Number,
1067 typename VectorType::memory_space>;
1068};
1069
1070
1071
1104template <int dim, typename Number, typename MemorySpace>
1106 : public ::MGLevelGlobalTransfer<
1107 LinearAlgebra::distributed::Vector<Number, MemorySpace>>
1108{
1109public:
1114
1121
1136 template <typename MGTwoLevelTransferObject>
1139 const std::function<void(const unsigned int, VectorType &)>
1140 &initialize_dof_vector = {});
1141
1145 template <typename MGTwoLevelTransferObject>
1146 void
1149
1158 void
1159 build(const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1160 &external_partitioners = {});
1161
1166 void
1167 build(const std::function<void(const unsigned int, VectorType &)>
1168 &initialize_dof_vector);
1169
1181 MGTransferMatrixFree(const MGConstrainedDoFs &mg_constrained_dofs);
1182
1186 void
1187 initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs);
1188
1205 void
1206 build(const DoFHandler<dim> &dof_handler,
1207 const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1208 &external_partitioners = {});
1209
1219 void
1220 build(const DoFHandler<dim> &dof_handler,
1221 const std::function<void(const unsigned int, VectorType &)>
1222 &initialize_dof_vector);
1223
1234 void
1235 prolongate(const unsigned int to_level,
1236 VectorType &dst,
1237 const VectorType &src) const override;
1238
1242 void
1243 prolongate_and_add(const unsigned int to_level,
1244 VectorType &dst,
1245 const VectorType &src) const override;
1246
1250 virtual void
1251 restrict_and_add(const unsigned int from_level,
1252 VectorType &dst,
1253 const VectorType &src) const override;
1254
1264 template <class InVector>
1265 void
1266 copy_to_mg(const DoFHandler<dim> &dof_handler,
1268 const InVector &src) const;
1269
1279 template <class OutVector>
1280 void
1281 copy_from_mg(const DoFHandler<dim> &dof_handler,
1282 OutVector &dst,
1283 const MGLevelObject<VectorType> &src) const;
1284
1303 template <class InVector>
1304 void
1307 const InVector &src) const;
1308
1317 template <class InVector>
1318 void
1319 interpolate_to_mg(MGLevelObject<VectorType> &dst, const InVector &src) const;
1320
1334 std::size_t
1336
1340 unsigned int
1341 min_level() const;
1342
1346 unsigned int
1347 max_level() const;
1348
1353 void
1355
1358private:
1362 void
1364 const DoFHandler<dim> &dof_handler,
1365 const ObserverPointer<const MGConstrainedDoFs> &mg_constrained_dofs);
1366
1370 std::pair<const DoFHandler<dim> *, unsigned int>
1372
1378 void
1380 const DoFHandler<dim> &dof_handler);
1381
1385 template <typename MGTwoLevelTransferObject>
1386 void
1389
1398 template <class InVector>
1399 void
1400 initialize_dof_vector(const unsigned int level,
1401 VectorType &vector,
1402 const InVector &vector_reference,
1403 const bool omit_zeroing_entries,
1404 const bool force_same_partitioner = false) const;
1405
1411 void
1412 assert_dof_handler(const DoFHandler<dim> &dof_handler_out) const;
1413
1418 dim,
1421
1427
1431 std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
1433};
1434
1440template <int dim, typename Number, typename TransferType>
1442 : public MGTransferBase<LinearAlgebra::distributed::BlockVector<Number>>
1443{
1444public:
1445 explicit MGTransferBlockMatrixFreeBase(const bool same_for_all)
1446 : same_for_all(same_for_all)
1447 {}
1448
1463 virtual void
1465 const unsigned int to_level,
1467 const LinearAlgebra::distributed::BlockVector<Number> &src) const override;
1468
1469 virtual void
1471 const unsigned int to_level,
1473 const LinearAlgebra::distributed::BlockVector<Number> &src) const override;
1474
1493 virtual void
1495 const unsigned int from_level,
1497 const LinearAlgebra::distributed::BlockVector<Number> &src) const override;
1498
1509 template <typename BlockVectorType2>
1510 void
1512 const DoFHandler<dim> &dof_handler,
1514 const BlockVectorType2 &src) const;
1515
1519 template <typename BlockVectorType2>
1520 void
1522 const std::vector<const DoFHandler<dim> *> &dof_handler,
1524 const BlockVectorType2 &src) const;
1525
1529 template <typename BlockVectorType2>
1530 void
1532 const DoFHandler<dim> &dof_handler,
1533 BlockVectorType2 &dst,
1535 const;
1536
1540 template <typename BlockVectorType2>
1541 void
1543 const std::vector<const DoFHandler<dim> *> &dof_handler,
1544 BlockVectorType2 &dst,
1546 const;
1547
1548protected:
1553 virtual const TransferType &
1554 get_matrix_free_transfer(const unsigned int b) const = 0;
1555
1560 const bool same_for_all;
1561};
1562
1576template <int dim, typename Number>
1579 dim,
1580 Number,
1581 MGTransferMatrixFree<dim, Number, ::MemorySpace::Host>>
1582{
1583public:
1589 &transfer_operator);
1590
1596
1602
1607 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs);
1608
1612 void
1613 initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs);
1614
1618 void
1620 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs);
1621
1625 void
1626 build(const DoFHandler<dim> &dof_handler);
1627
1631 void
1632 build(const std::vector<const DoFHandler<dim> *> &dof_handler);
1633
1634protected:
1636 get_matrix_free_transfer(const unsigned int b) const override;
1637
1638private:
1642 std::vector<MGTransferMatrixFree<dim, Number, ::MemorySpace::Host>>
1644
1648 std::vector<ObserverPointer<
1651};
1652
1653
1656#ifndef DOXYGEN
1657
1658/* ----------------------- Inline functions --------------------------------- */
1659
1660template <int dim, typename VectorType>
1661void
1663 const DoFHandler<dim> &dof_handler_fine,
1664 const DoFHandler<dim> &dof_handler_coarse,
1665 const AffineConstraints<Number> &constraint_fine,
1666 const AffineConstraints<Number> &constraint_coarse,
1667 const unsigned int mg_level_fine,
1668 const unsigned int mg_level_coarse)
1669{
1670 host_transfer.reinit(dof_handler_fine,
1671 dof_handler_coarse,
1672 constraint_fine,
1673 constraint_coarse,
1674 mg_level_fine,
1675 mg_level_coarse);
1676}
1677
1678template <int dim, typename VectorType>
1679void
1681 const MatrixFree<dim, Number> &matrix_free_fine,
1682 const unsigned int dof_handler_index_fine,
1683 const MatrixFree<dim, Number> &matrix_free_coarse,
1684 const unsigned int dof_handler_index_coarse)
1685{
1686 host_transfer.reinit(matrix_free_fine,
1687 dof_handler_index_fine,
1688 matrix_free_coarse,
1689 dof_handler_index_coarse);
1690}
1691
1692
1693template <int dim, typename VectorType>
1694bool
1696 fast_polynomial_transfer_supported(const unsigned int fe_degree_fine,
1697 const unsigned int fe_degree_coarse)
1698{
1699 return host_transfer.fast_polynomial_transfer_supported(fe_degree_fine,
1700 fe_degree_coarse);
1701}
1702
1703template <int dim, typename VectorType>
1704void
1706 VectorType &dst,
1707 const VectorType &src) const
1708{
1709 if (host_vector_coarse.size() == 0)
1710 host_vector_coarse.reinit(src.get_partitioner());
1711 if (host_vector_fine.size() == 0)
1712 host_vector_fine.reinit(dst.get_partitioner());
1713
1714 copy_to_host(host_vector_fine, dst);
1715 copy_to_host(host_vector_coarse, src);
1716
1717 host_transfer.prolongate_and_add(host_vector_fine, host_vector_coarse);
1718
1719 copy_from_host(dst, host_vector_fine);
1720}
1721
1722template <int dim, typename VectorType>
1723void
1725 VectorType &dst,
1726 const VectorType &src) const
1727{
1728 if (host_vector_coarse.size() == 0)
1729 host_vector_coarse.reinit(dst.get_partitioner());
1730 if (host_vector_fine.size() == 0)
1731 host_vector_fine.reinit(src.get_partitioner());
1732
1733 copy_to_host(host_vector_coarse, dst);
1734 copy_to_host(host_vector_fine, src);
1735
1736 host_transfer.restrict_and_add(host_vector_coarse, host_vector_fine);
1737
1738 copy_from_host(dst, host_vector_coarse);
1739}
1740
1741template <int dim, typename VectorType>
1742void
1744 VectorType &dst,
1745 const VectorType &src) const
1746{
1747 if (host_vector_coarse.size() == 0)
1748 host_vector_coarse.reinit(dst.get_partitioner());
1749 if (host_vector_fine.size() == 0)
1750 host_vector_fine.reinit(src.get_partitioner());
1751
1752 copy_to_host(host_vector_fine, src);
1753
1754 host_transfer.interpolate(host_vector_coarse, host_vector_fine);
1755
1756 copy_from_host(dst, host_vector_coarse);
1757}
1758
1759template <int dim, typename VectorType>
1760std::pair<bool, bool>
1763 const std::shared_ptr<const Utilities::MPI::Partitioner>
1764 &partitioner_coarse,
1765 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
1766{
1767 return host_transfer.enable_inplace_operations_if_possible(partitioner_coarse,
1768 partitioner_fine);
1769}
1770
1771template <int dim, typename VectorType>
1772std::size_t
1774{
1775 return host_transfer.memory_consumption();
1776}
1777
1778template <int dim, typename VectorType>
1779std::pair<const DoFHandler<dim> *, unsigned int>
1781{
1782 return host_transfer.get_dof_handler_fine();
1783}
1784
1785
1786template <int dim, typename VectorType>
1787void
1789 VectorTypeHost &dst,
1790 const VectorType &src) const
1791{
1793 src.get_partitioner()->locally_owned_range());
1794 rw_vector.import_elements(src, VectorOperation::insert);
1795
1796 dst.import_elements(rw_vector, VectorOperation::insert);
1797}
1798
1799template <int dim, typename VectorType>
1800void
1802 VectorType &dst,
1803 const VectorTypeHost &src) const
1804{
1806 src.get_partitioner()->locally_owned_range());
1807 rw_vector.import_elements(src, VectorOperation::insert);
1808
1809 dst.import_elements(rw_vector, VectorOperation::insert);
1810}
1811
1812
1813
1814template <int dim, typename Number, typename MemorySpace>
1815template <typename MGTwoLevelTransferObject>
1818 const std::function<void(const unsigned int, VectorType &)>
1819 &initialize_dof_vector)
1820{
1821 this->transfer.clear();
1822 this->internal_transfer.clear();
1823
1824 this->initialize_transfer_references(transfer);
1825 this->build(initialize_dof_vector);
1826}
1827
1828
1829
1830template <int dim, typename Number, typename MemorySpace>
1831template <typename MGTwoLevelTransferObject>
1832void
1835{
1836 this->initialize_transfer_references(transfer);
1837}
1838
1839
1840
1841template <int dim, typename Number, typename MemorySpace>
1842template <typename MGTwoLevelTransferObject>
1843void
1846{
1847 const unsigned int min_level = transfer.min_level();
1848 const unsigned int max_level = transfer.max_level();
1849
1850 this->transfer.resize(min_level, max_level);
1851
1852 // Note that transfer[min_level] is empty and never used:
1853 for (unsigned int l = min_level + 1; l <= max_level; ++l)
1854 this->transfer[l] = &const_cast<MGTwoLevelTransferBase<dim, VectorType> &>(
1855 static_cast<const MGTwoLevelTransferBase<dim, VectorType> &>(
1856 Utilities::get_underlying_value(transfer[l])));
1857}
1858
1859
1860
1861template <int dim, typename Number, typename MemorySpace>
1862template <class InVector>
1863void
1865 const unsigned int level,
1866 VectorType &vec,
1867 const InVector &vec_reference,
1868 const bool omit_zeroing_entries,
1869 const bool force_same_partitioner) const
1870{
1871 std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1872
1873 if (external_partitioners.empty())
1874 {
1875 partitioner = vec_reference.get_partitioner();
1876 }
1877 else
1878 {
1879 Assert(transfer.min_level() <= level && level <= transfer.max_level(),
1881
1882 partitioner = external_partitioners[level - transfer.min_level()];
1883 }
1884
1885 // check if vectors are already correctly initialized
1886
1887 // yes: same partitioners are used
1888 if (vec.get_partitioner().get() == partitioner.get())
1889 {
1890 if (omit_zeroing_entries == false)
1891 vec = 0;
1892 return; // nothing to do
1893 }
1894
1895 // yes: vectors are compatible
1896 if (!force_same_partitioner && vec.size() == partitioner->size() &&
1897 vec.locally_owned_size() == partitioner->locally_owned_size())
1898 {
1899 if (omit_zeroing_entries == false)
1900 vec = 0;
1901 return; // nothing to do
1902 }
1903
1904 // no
1905 vec.reinit(partitioner, omit_zeroing_entries);
1906}
1907
1908
1909
1910template <int dim, typename Number, typename MemorySpace>
1911template <class InVector>
1912void
1914 const DoFHandler<dim> &dof_handler,
1916 const InVector &src) const
1917{
1918 assert_dof_handler(dof_handler);
1919
1920 for (unsigned int level = dst.min_level(); level <= dst.max_level(); ++level)
1921 {
1922 const bool zero_out_values =
1923 (this->perform_plain_copy == false &&
1924 this->perform_renumbered_plain_copy == false) ||
1925 level != dst.max_level();
1926
1927 this->initialize_dof_vector(level,
1928 dst[level],
1929 src,
1930 !zero_out_values,
1931 /* force_same_partitioner = */ true);
1932 }
1933
1934 if (this->perform_plain_copy)
1935 {
1936 dst[dst.max_level()].copy_locally_owned_data_from(src);
1937 }
1938 else if (this->perform_renumbered_plain_copy)
1939 {
1940 auto &dst_level = dst[dst.max_level()];
1941
1942 for (unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i)
1943 dst_level.local_element(this->copy_indices.back()(1, i)) =
1944 src.local_element(i);
1945 }
1946 else
1947 {
1948 this->ghosted_global_vector = src;
1949 this->ghosted_global_vector.update_ghost_values();
1950
1951 for (unsigned int l = dst.max_level() + 1; l != dst.min_level();)
1952 {
1953 --l;
1954
1955 auto &dst_level = dst[l];
1956
1957 const auto copy_unknowns = [&](const auto &indices) {
1958 for (unsigned int i = 0; i < indices.n_cols(); ++i)
1959 dst_level.local_element(indices(1, i)) =
1960 this->ghosted_global_vector.local_element(indices(0, i));
1961 };
1962
1963 copy_unknowns(this->copy_indices[l]);
1964 copy_unknowns(this->copy_indices_level_mine[l]);
1965
1966 dst_level.compress(VectorOperation::insert);
1967 }
1968 }
1969}
1970
1971
1972
1973template <int dim, typename Number, typename MemorySpace>
1974template <class OutVector>
1975void
1977 const DoFHandler<dim> &dof_handler,
1978 OutVector &dst,
1979 const MGLevelObject<VectorType> &src) const
1980{
1981 assert_dof_handler(dof_handler);
1982
1983 if (this->perform_plain_copy)
1984 {
1985 dst.zero_out_ghost_values();
1986 dst.copy_locally_owned_data_from(src[src.max_level()]);
1987 }
1988 else if (this->perform_renumbered_plain_copy)
1989 {
1990 const auto &src_level = src[src.max_level()];
1991 dst.zero_out_ghost_values();
1992 for (unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i)
1993 dst.local_element(i) =
1994 src_level.local_element(this->copy_indices.back()(1, i));
1995 }
1996 else
1997 {
1998 dst = 0;
1999 for (unsigned int l = src.min_level(); l <= src.max_level(); ++l)
2000 {
2001 auto &ghosted_vector = this->ghosted_level_vector[l];
2002
2003 if (this->ghosted_level_vector[l].size() > 0)
2004 ghosted_vector = src[l];
2005
2006 const auto *const ghosted_vector_ptr =
2007 (this->ghosted_level_vector[l].size() > 0) ? &ghosted_vector :
2008 &src[l];
2009
2010 ghosted_vector_ptr->update_ghost_values();
2011
2012 const auto copy_unknowns = [&](const auto &indices) {
2013 for (unsigned int i = 0; i < indices.n_cols(); ++i)
2014 dst.local_element(indices(0, i)) =
2015 ghosted_vector_ptr->local_element(indices(1, i));
2016 };
2017
2018 copy_unknowns(this->copy_indices[l]);
2019 copy_unknowns(this->copy_indices_global_mine[l]);
2020 }
2021 dst.compress(VectorOperation::insert);
2022 }
2023}
2024
2025
2026
2027template <int dim, typename Number, typename MemorySpace>
2028template <class InVector>
2029void
2032 const InVector &src) const
2033{
2034 DoFHandler<dim> dof_handler_dummy;
2035
2036 this->interpolate_to_mg(dof_handler_dummy, dst, src);
2037}
2038
2039
2040
2041template <int dim, typename Number, typename MemorySpace>
2042template <class InVector>
2043void
2045 const DoFHandler<dim> &dof_handler,
2047 const InVector &src) const
2048{
2049 assert_dof_handler(dof_handler);
2050
2051 const unsigned int min_level = dst.min_level();
2052 const unsigned int max_level = transfer.max_level();
2053
2054 AssertDimension(max_level, dst.max_level());
2055
2056 for (unsigned int level = min_level; level <= max_level; ++level)
2057 {
2058 const bool zero_out_values = false;
2059 this->initialize_dof_vector(level, dst[level], src, !zero_out_values);
2060 }
2061
2062 if (this->perform_plain_copy)
2063 {
2064 dst[max_level].copy_locally_owned_data_from(src);
2065
2066 for (unsigned int l = max_level; l > min_level; --l)
2067 this->transfer[l]->interpolate(dst[l - 1], dst[l]);
2068 }
2069 else if (this->perform_renumbered_plain_copy)
2070 {
2071 auto &dst_level = dst[max_level];
2072
2073 for (unsigned int i = 0; i < this->solution_copy_indices.back().n_cols();
2074 ++i)
2075 dst_level.local_element(this->solution_copy_indices.back()(1, i)) =
2076 src.local_element(i);
2077
2078 for (unsigned int l = max_level; l > min_level; --l)
2079 this->transfer[l]->interpolate(dst[l - 1], dst[l]);
2080 }
2081 else
2082 {
2083 this->solution_ghosted_global_vector = src;
2084 this->solution_ghosted_global_vector.update_ghost_values();
2085
2086 for (unsigned int l = max_level + 1; l != min_level;)
2087 {
2088 --l;
2089
2090 auto &dst_level = dst[l];
2091
2092 const auto copy_unknowns = [&](const auto &indices) {
2093 for (unsigned int i = 0; i < indices.n_cols(); ++i)
2094 dst_level.local_element(indices(1, i)) =
2095 this->solution_ghosted_global_vector.local_element(
2096 indices(0, i));
2097 };
2098
2099 copy_unknowns(this->solution_copy_indices[l]);
2100 copy_unknowns(this->solution_copy_indices_level_mine[l]);
2101
2102 dst_level.compress(VectorOperation::insert);
2103
2104 if (l != min_level)
2105 this->transfer[l]->interpolate(dst[l - 1], dst[l]);
2106 }
2107 }
2108}
2109
2110
2111
2112template <int dim, typename Number, typename TransferType>
2113template <typename BlockVectorType2>
2114void
2116 const DoFHandler<dim> &dof_handler,
2118 const BlockVectorType2 &src) const
2119{
2120 Assert(same_for_all,
2121 ExcMessage(
2122 "This object was initialized with support for usage with one "
2123 "DoFHandler for each block, but this method assumes that "
2124 "the same DoFHandler is used for all the blocks!"));
2125 const std::vector<const DoFHandler<dim> *> mg_dofs(src.n_blocks(),
2126 &dof_handler);
2127
2128 copy_to_mg(mg_dofs, dst, src);
2129}
2130
2131
2132
2133template <int dim, typename Number, typename TransferType>
2134template <typename BlockVectorType2>
2135void
2137 const std::vector<const DoFHandler<dim> *> &dof_handler,
2139 const BlockVectorType2 &src) const
2140{
2141 const unsigned int n_blocks = src.n_blocks();
2142 AssertDimension(dof_handler.size(), n_blocks);
2143
2144 if (n_blocks == 0)
2145 return;
2146
2147 const unsigned int min_level = dst.min_level();
2148 const unsigned int max_level = dst.max_level();
2149
2150 for (unsigned int level = min_level; level <= max_level; ++level)
2151 if (dst[level].n_blocks() != n_blocks)
2152 dst[level].reinit(n_blocks);
2153
2154 // FIXME: this a quite ugly as we need a temporary object:
2156 min_level, max_level);
2157
2158 for (unsigned int b = 0; b < n_blocks; ++b)
2159 {
2160 const unsigned int data_block = same_for_all ? 0 : b;
2161 get_matrix_free_transfer(data_block)
2162 .copy_to_mg(*dof_handler[b], dst_non_block, src.block(b));
2163
2164 for (unsigned int l = min_level; l <= max_level; ++l)
2165 dst[l].block(b) = dst_non_block[l];
2166 }
2167
2168 for (unsigned int level = min_level; level <= max_level; ++level)
2169 dst[level].collect_sizes();
2170}
2171
2172template <int dim, typename Number, typename TransferType>
2173template <typename BlockVectorType2>
2174void
2176 const DoFHandler<dim> &dof_handler,
2177 BlockVectorType2 &dst,
2179 const
2180{
2181 Assert(same_for_all,
2182 ExcMessage(
2183 "This object was initialized with support for usage with one "
2184 "DoFHandler for each block, but this method assumes that "
2185 "the same DoFHandler is used for all the blocks!"));
2186 const std::vector<const DoFHandler<dim> *> mg_dofs(dst.n_blocks(),
2187 &dof_handler);
2188
2189 copy_from_mg(mg_dofs, dst, src);
2190}
2191
2192template <int dim, typename Number, typename TransferType>
2193template <typename BlockVectorType2>
2194void
2196 const std::vector<const DoFHandler<dim> *> &dof_handler,
2197 BlockVectorType2 &dst,
2199 const
2200{
2201 const unsigned int n_blocks = dst.n_blocks();
2202 AssertDimension(dof_handler.size(), n_blocks);
2203
2204 if (n_blocks == 0)
2205 return;
2206
2207 const unsigned int min_level = src.min_level();
2208 const unsigned int max_level = src.max_level();
2209
2210 for (unsigned int l = min_level; l <= max_level; ++l)
2211 AssertDimension(src[l].n_blocks(), dst.n_blocks());
2212
2213 // FIXME: this a quite ugly as we need a temporary object:
2215 min_level, max_level);
2216
2217 for (unsigned int b = 0; b < n_blocks; ++b)
2218 {
2219 for (unsigned int l = min_level; l <= max_level; ++l)
2220 {
2221 src_non_block[l].reinit(src[l].block(b));
2222 src_non_block[l] = src[l].block(b);
2223 }
2224 const unsigned int data_block = same_for_all ? 0 : b;
2225 get_matrix_free_transfer(data_block)
2226 .copy_from_mg(*dof_handler[b], dst.block(b), src_non_block);
2227 }
2228}
2229
2230#endif
2231
2233
2234#endif
virtual size_type size() const override
void reinit(const size_type size, const bool omit_zeroing_entries=false)
std::function< void(const unsigned int, LinearAlgebra::distributed::Vector< Number, MemorySpace > &)> initialize_dof_vector
void resize(const unsigned int new_minlevel, const unsigned int new_maxlevel, Args &&...args)
unsigned int max_level() const
unsigned int min_level() const
virtual void prolongate(const unsigned int to_level, LinearAlgebra::distributed::BlockVector< Number > &dst, const LinearAlgebra::distributed::BlockVector< Number > &src) const override
virtual void prolongate_and_add(const unsigned int to_level, LinearAlgebra::distributed::BlockVector< Number > &dst, const LinearAlgebra::distributed::BlockVector< Number > &src) const override
virtual const TransferType & get_matrix_free_transfer(const unsigned int b) const =0
void copy_from_mg(const std::vector< const DoFHandler< dim > * > &dof_handler, BlockVectorType2 &dst, const MGLevelObject< LinearAlgebra::distributed::BlockVector< Number > > &src) const
void copy_to_mg(const DoFHandler< dim > &dof_handler, MGLevelObject< LinearAlgebra::distributed::BlockVector< Number > > &dst, const BlockVectorType2 &src) const
virtual void restrict_and_add(const unsigned int from_level, LinearAlgebra::distributed::BlockVector< Number > &dst, const LinearAlgebra::distributed::BlockVector< Number > &src) const override
MGTransferBlockMatrixFreeBase(const bool same_for_all)
void copy_from_mg(const DoFHandler< dim > &dof_handler, BlockVectorType2 &dst, const MGLevelObject< LinearAlgebra::distributed::BlockVector< Number > > &src) const
void copy_to_mg(const std::vector< const DoFHandler< dim > * > &dof_handler, MGLevelObject< LinearAlgebra::distributed::BlockVector< Number > > &dst, const BlockVectorType2 &src) const
const MGTransferMatrixFree< dim, Number, ::MemorySpace::Host > & get_matrix_free_transfer(const unsigned int b) const override
MGTransferBlockMatrixFree(const MGTransferMatrixFree< dim, Number, ::MemorySpace::Host > &transfer_operator)
MGTransferBlockMatrixFree(const MGConstrainedDoFs &mg_constrained_dofs)
std::vector< ObserverPointer< const MGTransferMatrixFree< dim, Number, ::MemorySpace::Host > > > transfer_operators
std::vector< MGTransferMatrixFree< dim, Number, ::MemorySpace::Host > > transfer_operators_internal
MGTransferBlockMatrixFree(const std::vector< MGConstrainedDoFs > &mg_constrained_dofs)
void build(const DoFHandler< dim > &dof_handler)
MGTransferBlockMatrixFree()=default
void build(const std::vector< const DoFHandler< dim > * > &dof_handler)
void initialize_constraints(const std::vector< MGConstrainedDoFs > &mg_constrained_dofs)
void initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs)
void initialize_two_level_transfers(const MGLevelObject< MGTwoLevelTransferObject > &transfer)
void interpolate_to_mg(MGLevelObject< VectorType > &dst, const InVector &src) const
std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > external_partitioners
void interpolate_to_mg(const DoFHandler< dim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
void initialize_transfer_references(const MGLevelObject< MGTwoLevelTransferObject > &transfer)
MGLevelObject< MGTwoLevelTransfer< dim, LinearAlgebra::distributed::Vector< Number, ::MemorySpace::Host > > > internal_transfer
void build(const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners={})
unsigned int max_level() const
void prolongate(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
void initialize_dof_vector(const unsigned int level, VectorType &vector, const InVector &vector_reference, const bool omit_zeroing_entries, const bool force_same_partitioner=false) const
void copy_from_mg(const DoFHandler< dim > &dof_handler, OutVector &dst, const MGLevelObject< VectorType > &src) const
void build(const DoFHandler< dim > &dof_handler, const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners={})
MGTransferMatrixFree(const MGConstrainedDoFs &mg_constrained_dofs)
void fill_and_communicate_copy_indices_global_coarsening(const DoFHandler< dim > &dof_handler)
void build(const DoFHandler< dim > &dof_handler, const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector)
void initialize_internal_transfer(const DoFHandler< dim > &dof_handler, const ObserverPointer< const MGConstrainedDoFs > &mg_constrained_dofs)
virtual void restrict_and_add(const unsigned int from_level, VectorType &dst, const VectorType &src) const override
void prolongate_and_add(const unsigned int to_level, VectorType &dst, const VectorType &src) const override
MGLevelObject< ObserverPointer< MGTwoLevelTransferBase< dim, VectorType > > > transfer
void build(const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector)
MGTransferMatrixFree(const MGLevelObject< MGTwoLevelTransferObject > &transfer, const std::function< void(const unsigned int, VectorType &)> &initialize_dof_vector={})
void initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs)
unsigned int min_level() const
std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const
void copy_to_mg(const DoFHandler< dim > &dof_handler, MGLevelObject< VectorType > &dst, const InVector &src) const
void assert_dof_handler(const DoFHandler< dim > &dof_handler_out) const
std::size_t memory_consumption() const
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_fine
virtual std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const =0
virtual std::size_t memory_consumption() const =0
virtual void restrict_and_add(VectorType &dst, const VectorType &src) const =0
virtual std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine)=0
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_coarse
virtual void prolongate_and_add(VectorType &dst, const VectorType &src) const =0
virtual void interpolate(VectorType &dst, const VectorType &src) const =0
typename VectorType::value_type Number
std::size_t memory_consumption() const override
MGTwoLevelTransfer< dim, VectorTypeHost > host_transfer
void interpolate(VectorType &dst, const VectorType &src) const override
void reinit(const MatrixFree< dim, Number > &matrix_free_fine, const unsigned int dof_handler_index_fine, const MatrixFree< dim, Number > &matrix_free_coarse, const unsigned int dof_handler_index_coarse)
void restrict_and_add(VectorType &dst, const VectorType &src) const override
bool fast_polynomial_transfer_supported(const unsigned int fe_degree_fine, const unsigned int fe_degree_coarse)
void copy_to_host(VectorTypeHost &dst, const VectorType &src) const
std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const override
std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine) override
void copy_from_host(VectorType &dst, const VectorTypeHost &src) const
void prolongate_and_add(VectorType &dst, const VectorType &src) const override
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
std::shared_ptr< NonMatching::MappingInfo< dim, dim, Number > > mapping_info
boost::signals2::connection connect_restriction(const std::function< void(const bool)> &slot)
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const Mapping< dim > &mapping_fine, const Mapping< dim > &mapping_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >())
std::unique_ptr< FiniteElement< dim > > fe_coarse
ObserverPointer< const DoFHandler< dim > > dof_handler_fine
void restrict_and_add_internal_comp(VectorType &dst, const VectorType &src) const
boost::signals2::connection connect_prolongation_cell_loop(const std::function< void(const bool)> &slot)
std::size_t memory_consumption() const override
std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine) override
Utilities::MPI::RemotePointEvaluation< dim > rpe
void restrict_and_add_internal(VectorType &dst, const VectorType &src) const override
std::vector< unsigned int > level_dof_indices_fine_ptrs
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, unsigned int > constraint_info
boost::signals2::connection connect_prolongation(const std::function< void(const bool)> &slot)
boost::signals2::connection connect_restriction_cell_loop(const std::function< void(const bool)> &slot)
void prolongate_and_add_internal_comp(VectorType &dst, const VectorType &src) const
MGTwoLevelTransferNonNested(const AdditionalData &data=AdditionalData())
void interpolate(VectorType &dst, const VectorType &src) const override
std::vector< unsigned int > level_dof_indices_fine
typename VectorType::value_type Number
void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const override
std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const override
void reinit_geometric_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, types::global_dof_index > constraint_info_fine
void reinit(const MatrixFree< dim, Number > &matrix_free_fine, const unsigned int dof_handler_index_fine, const MatrixFree< dim, Number > &matrix_free_coarse, const unsigned int dof_handler_index_coarse)
friend class internal::MGTwoLevelTransferImplementation
std::vector< MGTransferScheme > schemes
ObserverPointer< const DoFHandler< dim > > dof_handler_fine
friend class Portable::internal::MGTwoLevelTransferImplementation
typename VectorType::value_type Number
std::vector< unsigned char > weights_are_compressed
std::pair< const DoFHandler< dim > *, unsigned int > get_dof_handler_fine() const override
void interpolate(VectorType &dst, const VectorType &src) const override
internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArrayType, types::global_dof_index > constraint_info_coarse
std::unique_ptr< MatrixFreeRelatedData > matrix_free_data
static bool fast_polynomial_transfer_supported(const unsigned int fe_degree_fine, const unsigned int fe_degree_coarse)
AlignedVector< VectorizedArrayType > weights
void reinit_polynomial_transfer(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
std::pair< bool, bool > enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine) override
void restrict_and_add_internal(VectorType &dst, const VectorType &src) const override
std::vector< unsigned int > weights_start
void reinit(const DoFHandler< dim > &dof_handler_fine, const DoFHandler< dim > &dof_handler_coarse, const AffineConstraints< Number > &constraint_fine=AffineConstraints< Number >(), const AffineConstraints< Number > &constraint_coarse=AffineConstraints< Number >(), const unsigned int mg_level_fine=numbers::invalid_unsigned_int, const unsigned int mg_level_coarse=numbers::invalid_unsigned_int)
std::size_t memory_consumption() const override
void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const override
Abstract base class for mapping classes.
Definition mapping.h:318
Communicate values between a mesh and arbitrary points.
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_fine_embedded
void restrict_and_add(VectorType &dst, const VectorType &src) const override
virtual void restrict_and_add_internal(VectorType &dst, const VectorType &src) const =0
void zero_out_ghost_values(const VectorType &vec) const
AlignedVector< Number > buffer_coarse_embedded
std::pair< bool, bool > internal_enable_inplace_operations_if_possible(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_coarse, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner_fine, bool &vec_fine_needs_ghost_update, internal::MatrixFreeFunctions::ConstraintInfo< dim, VectorizedArray< Number, width >, IndexType > &constraint_info_coarse, std::vector< unsigned int > &dof_indices_fine)
void compress(VectorType &vec, const VectorOperation::values op) const
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner_coarse_embedded
typename VectorType::value_type Number
virtual void prolongate_and_add_internal(VectorType &dst, const VectorType &src) const =0
void prolongate_and_add(VectorType &dst, const VectorType &src) const override
void update_ghost_values(const VectorType &vec) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int level
Definition grid_out.cc:4642
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
Definition mpi.cc:734
std::size_t size
Definition mpi.cc:733
void interpolate(const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, OutVector &u2)
std::enable_if_t< IsBlockVector< VectorType >::value, void > collect_sizes(VectorType &vector)
Definition operators.h:93
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
Definition operators.h:47
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
T & get_underlying_value(T &p)
Definition utilities.h:1610
Definition mg.h:79
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
STL namespace.
AdditionalData(const double tolerance=1e-6, const unsigned int rtree_level=0, const bool enforce_all_points_found=true)
internal::MatrixFreeFunctions::ShapeInfo< double > shape_info_coarse
std::vector< std::array< unsigned int, VectorizedArrayType::size()> > cell_list_fine_to_coarse
ObserverPointer< const MatrixFree< dim, Number > > matrix_free_fine
ObserverPointer< const MatrixFree< dim, Number > > matrix_free_coarse
boost::signals2::signal< void(const bool before)> prolongation_cell_loop
boost::signals2::signal< void(const bool before)> restriction
boost::signals2::signal< void(const bool before)> restriction_cell_loop
boost::signals2::signal< void(const bool before)> prolongation