deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20: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
multigrid.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) 1999 - 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_multigrid_h
14#define dealii_multigrid_h
15
16
17#include <deal.II/base/config.h>
18
22
24
26
28#include <deal.II/lac/vector.h>
29
31
32#include <boost/signals2.hpp>
33
34#include <vector>
35
36
38
39#ifdef signals
40# error \
41 "The name 'signals' is already defined. You are most likely using the QT library \
42and using the 'signals' keyword. You can either #include the Qt headers (or any conflicting headers) \
43*after* the deal.II headers or you can define the 'QT_NO_KEYWORDS' macro and use the 'Q_SIGNALS' macro."
44#endif
45
51namespace mg
52{
62 struct Signals
63 {
69 boost::signals2::signal<void(const bool before)> transfer_to_mg;
70
76 boost::signals2::signal<void(const bool before)> transfer_to_global;
77
87 boost::signals2::signal<void(const bool before, const unsigned int level)>
89
98 boost::signals2::signal<void(const bool before, const unsigned int level)>
100
106 boost::signals2::signal<void(const bool before, const unsigned int level)>
108
117 boost::signals2::signal<void(const bool before, const unsigned int level)>
119
125 boost::signals2::signal<void(const bool before, const unsigned int level)>
127
133 boost::signals2::signal<void(const bool before, const unsigned int level)>
135
140 boost::signals2::signal<void(const bool before, const unsigned int level)>
142 };
143} // namespace mg
144
162template <typename VectorType>
164{
165public:
178
179 using vector_type = VectorType;
180 using const_vector_type = const VectorType;
181
196 const unsigned int minlevel = 0,
197 const unsigned int maxlevel = numbers::invalid_unsigned_int,
199
203 void
204 reinit(const unsigned int minlevel, const unsigned int maxlevel);
205
210 void
212
223 void
225
238 void
241
248 void
250
263 void
266
270 unsigned int
272
276 unsigned int
278
284 void
285 set_maxlevel(const unsigned int);
286
302 void
303 set_minlevel(const unsigned int level, bool relative = false);
304
309
313 boost::signals2::connection
315 const std::function<void(const bool, const unsigned int)> &slot);
316
320 boost::signals2::connection
322 const std::function<void(const bool, const unsigned int)> &slot);
323
327 boost::signals2::connection
329 const std::function<void(const bool, const unsigned int)> &slot);
330
334 boost::signals2::connection
336 const std::function<void(const bool, const unsigned int)> &slot);
337
341 boost::signals2::connection
343 const std::function<void(const bool, const unsigned int)> &slot);
344
348 boost::signals2::connection
350 const std::function<void(const bool, const unsigned int)> &slot);
351
355 boost::signals2::connection
357 const std::function<void(const bool, const unsigned int)> &slot);
358
359private:
364
371 void
372 level_v_step(const unsigned int level);
373
381 void
382 level_step(const unsigned int level,
383 const Cycle cycle,
384 const unsigned int iteration);
385
390
394 unsigned int minlevel;
395
399 unsigned int maxlevel;
400
401public:
407
412
413private:
418
423
424
429
435
441
447
453
460
468
476
484
485 template <int dim, typename OtherVectorType, typename TransferType>
486 friend class PreconditionMG;
487};
488
489
504template <int dim, typename VectorType, typename TransferType>
506{
507public:
512 PreconditionMG(const DoFHandler<dim> &dof_handler,
514 const TransferType &transfer);
515
520 PreconditionMG(const std::vector<const DoFHandler<dim> *> &dof_handler,
522 const TransferType &transfer);
523
527 bool
528 empty() const;
529
536 template <typename OtherVectorType>
537 void
538 vmult(OtherVectorType &dst, const OtherVectorType &src) const;
539
544 template <typename OtherVectorType>
545 void
546 vmult_add(OtherVectorType &dst, const OtherVectorType &src) const;
547
553 template <typename OtherVectorType>
554 void
555 Tvmult(OtherVectorType &dst, const OtherVectorType &src) const;
556
562 template <typename OtherVectorType>
563 void
564 Tvmult_add(OtherVectorType &dst, const OtherVectorType &src) const;
565
573 locally_owned_range_indices(const unsigned int block = 0) const;
574
582 locally_owned_domain_indices(const unsigned int block = 0) const;
583
589
593 boost::signals2::connection
594 connect_transfer_to_mg(const std::function<void(bool)> &slot);
595
599 boost::signals2::connection
600 connect_transfer_to_global(const std::function<void(bool)> &slot);
601
607
613
614private:
618 std::vector<ObserverPointer<const DoFHandler<dim>,
621
626 std::vector<const DoFHandler<dim> *> dof_handler_vector_raw;
627
634
638 ObserverPointer<const TransferType,
641
647
652};
653
656#ifndef DOXYGEN
657/* --------------------------- inline functions --------------------- */
658
659
660template <typename VectorType>
662 const MGCoarseGridBase<VectorType> &coarse,
663 const MGTransferBase<VectorType> &transfer,
664 const MGSmootherBase<VectorType> &pre_smooth,
665 const MGSmootherBase<VectorType> &post_smooth,
666 const unsigned int min_level,
667 const unsigned int max_level,
668 Cycle cycle)
669 : cycle_type(cycle)
670 , matrix(&matrix, typeid(*this).name())
671 , coarse(&coarse, typeid(*this).name())
672 , transfer(&transfer, typeid(*this).name())
673 , pre_smooth(&pre_smooth, typeid(*this).name())
674 , post_smooth(&post_smooth, typeid(*this).name())
675 , edge_out(nullptr, typeid(*this).name())
676 , edge_in(nullptr, typeid(*this).name())
677 , edge_down(nullptr, typeid(*this).name())
678 , edge_up(nullptr, typeid(*this).name())
679{
680 if (max_level == numbers::invalid_unsigned_int)
681 maxlevel = matrix.get_maxlevel();
682 else
683 maxlevel = max_level;
684 reinit(min_level, maxlevel);
685}
686
687
688
689template <typename VectorType>
690inline unsigned int
692{
693 return maxlevel;
694}
695
696
697
698template <typename VectorType>
699inline unsigned int
701{
702 return minlevel;
703}
704
705
706/* --------------------------- inline functions --------------------- */
707
708
709namespace internal
710{
711 namespace PreconditionMGImplementation
712 {
713 template <typename DoFHandlerType,
714 typename VectorType,
715 typename TransferType,
716 typename OtherVectorType>
717 using get_dof_handler_vector_support =
718 decltype(std::declval<TransferType>().copy_from_mg(
719 std::vector<const DoFHandlerType *>{},
720 std::declval<OtherVectorType &>(),
721 std::declval<MGLevelObject<VectorType>>()));
722
723 template <typename DoFHandlerType,
724 typename VectorType,
725 typename TransferType,
726 typename OtherVectorType>
727 constexpr bool supports_dof_handler_vector =
728 ::internal::is_supported_operation<get_dof_handler_vector_support,
729 DoFHandlerType,
731 TransferType,
732 OtherVectorType>;
733
734 template <int dim,
735 typename VectorType,
736 typename TransferType,
737 typename OtherVectorType>
738 void
739 vmult(const std::vector<const DoFHandler<dim> *> &dof_handler_vector,
740 Multigrid<VectorType> &multigrid,
741 const TransferType &transfer,
742 OtherVectorType &dst,
743 const OtherVectorType &src,
744 const bool uses_dof_handler_vector,
745 const typename ::mg::Signals &signals)
746 {
747 if constexpr (supports_dof_handler_vector<DoFHandler<dim>,
749 TransferType,
750 OtherVectorType>)
751 {
752 signals.transfer_to_mg(true);
753 if (uses_dof_handler_vector)
754 transfer.copy_to_mg(dof_handler_vector, multigrid.defect, src);
755 else
756 transfer.copy_to_mg(*dof_handler_vector[0], multigrid.defect, src);
757 signals.transfer_to_mg(false);
758
759 multigrid.cycle();
760
761 signals.transfer_to_global(true);
762 if (uses_dof_handler_vector)
763 transfer.copy_from_mg(dof_handler_vector, dst, multigrid.solution);
764 else
765 transfer.copy_from_mg(*dof_handler_vector[0],
766 dst,
767 multigrid.solution);
768 signals.transfer_to_global(false);
769 }
770 else
771 {
772 (void)uses_dof_handler_vector;
773 Assert(!uses_dof_handler_vector, ExcInternalError());
774
775 signals.transfer_to_mg(true);
776 transfer.copy_to_mg(*dof_handler_vector[0], multigrid.defect, src);
777 signals.transfer_to_mg(false);
778
779 multigrid.cycle();
780
781 signals.transfer_to_global(true);
782 transfer.copy_from_mg(*dof_handler_vector[0],
783 dst,
784 multigrid.solution);
785 signals.transfer_to_global(false);
786 }
787 }
788
789 template <int dim,
790 typename VectorType,
791 typename TransferType,
792 typename OtherVectorType>
793 void
794 vmult_add(const std::vector<const DoFHandler<dim> *> &dof_handler_vector,
795 Multigrid<VectorType> &multigrid,
796 const TransferType &transfer,
797 OtherVectorType &dst,
798 const OtherVectorType &src,
799 const bool uses_dof_handler_vector,
800 const typename ::mg::Signals &signals)
801 {
802 if constexpr (supports_dof_handler_vector<DoFHandler<dim>,
804 TransferType,
805 OtherVectorType>)
806 {
807 signals.transfer_to_mg(true);
808 if (uses_dof_handler_vector)
809 transfer.copy_to_mg(dof_handler_vector, multigrid.defect, src);
810 else
811 transfer.copy_to_mg(*dof_handler_vector[0], multigrid.defect, src);
812 signals.transfer_to_mg(false);
813
814 multigrid.cycle();
815
816 signals.transfer_to_global(true);
817 if (uses_dof_handler_vector)
818 transfer.copy_from_mg_add(dof_handler_vector,
819 dst,
820 multigrid.solution);
821 else
822 transfer.copy_from_mg_add(*dof_handler_vector[0],
823 dst,
824 multigrid.solution);
825 signals.transfer_to_global(false);
826 }
827 else
828 {
829 (void)uses_dof_handler_vector;
830 Assert(!uses_dof_handler_vector, ExcInternalError());
831
832 signals.transfer_to_mg(true);
833 transfer.copy_to_mg(*dof_handler_vector[0], multigrid.defect, src);
834 signals.transfer_to_mg(false);
835
836 multigrid.cycle();
837
838 signals.transfer_to_global(true);
839 transfer.copy_from_mg_add(*dof_handler_vector[0],
840 dst,
841 multigrid.solution);
842 signals.transfer_to_global(false);
843 }
844 }
845 } // namespace PreconditionMGImplementation
846} // namespace internal
847
848template <int dim, typename VectorType, typename TransferType>
850 const DoFHandler<dim> &dof_handler,
852 const TransferType &transfer)
853 : dof_handler_vector(1, &dof_handler)
854 , dof_handler_vector_raw(1, &dof_handler)
855 , multigrid(&mg)
856 , transfer(&transfer)
857 , uses_dof_handler_vector(false)
858{}
859
860template <int dim, typename VectorType, typename TransferType>
862 const std::vector<const DoFHandler<dim> *> &dof_handler,
864 const TransferType &transfer)
865 : dof_handler_vector(dof_handler.size())
866 , dof_handler_vector_raw(dof_handler.size())
867 , multigrid(&mg)
868 , transfer(&transfer)
869 , uses_dof_handler_vector(true)
870{
871 for (unsigned int i = 0; i < dof_handler.size(); ++i)
872 {
873 dof_handler_vector[i] = dof_handler[i];
874 dof_handler_vector_raw[i] = dof_handler[i];
875 }
876}
877
878template <int dim, typename VectorType, typename TransferType>
879inline bool
881{
882 return false;
883}
884
885template <int dim, typename VectorType, typename TransferType>
886template <typename OtherVectorType>
887void
889 OtherVectorType &dst,
890 const OtherVectorType &src) const
891{
892 internal::PreconditionMGImplementation::vmult(dof_handler_vector_raw,
893 *multigrid,
894 *transfer,
895 dst,
896 src,
897 uses_dof_handler_vector,
898 this->signals);
899}
900
901
902template <int dim, typename VectorType, typename TransferType>
905 const unsigned int block) const
906{
907 AssertIndexRange(block, dof_handler_vector.size());
908 return dof_handler_vector[block]->locally_owned_dofs();
909}
910
911
912template <int dim, typename VectorType, typename TransferType>
915 const unsigned int block) const
916{
917 AssertIndexRange(block, dof_handler_vector.size());
918 return dof_handler_vector[block]->locally_owned_dofs();
919}
920
921
922
923template <int dim, typename VectorType, typename TransferType>
926{
927 // currently parallel GMG works with parallel triangulations only,
928 // so it should be a safe bet to use it to query MPI communicator:
929 const Triangulation<dim> &tria = dof_handler_vector[0]->get_triangulation();
931 dynamic_cast<const parallel::TriangulationBase<dim> *>(&tria);
932 Assert(ptria != nullptr, ExcInternalError());
933 return ptria->get_mpi_communicator();
934}
935
936
937
938template <int dim, typename VectorType, typename TransferType>
939boost::signals2::connection
941 const std::function<void(bool)> &slot)
942{
943 return this->signals.transfer_to_mg.connect(slot);
944}
945
946
947
948template <int dim, typename VectorType, typename TransferType>
949boost::signals2::connection
951 const std::function<void(bool)> &slot)
952{
953 return this->signals.transfer_to_global.connect(slot);
954}
955
956
957
958template <int dim, typename VectorType, typename TransferType>
959template <typename OtherVectorType>
960void
962 OtherVectorType &dst,
963 const OtherVectorType &src) const
964{
965 internal::PreconditionMGImplementation::vmult_add(dof_handler_vector_raw,
966 *multigrid,
967 *transfer,
968 dst,
969 src,
970 uses_dof_handler_vector,
971 this->signals);
972}
973
974
975template <int dim, typename VectorType, typename TransferType>
976template <typename OtherVectorType>
977void
979 OtherVectorType &,
980 const OtherVectorType &) const
981{
983}
984
985
986template <int dim, typename VectorType, typename TransferType>
987template <typename OtherVectorType>
988void
990 OtherVectorType &,
991 const OtherVectorType &) const
992{
994}
995
996
997template <int dim, typename VectorType, typename TransferType>
1000{
1001 return *this->multigrid;
1002}
1003
1004
1005template <int dim, typename VectorType, typename TransferType>
1008{
1009 return *this->multigrid;
1010}
1011
1012#endif // DOXYGEN
1013
1015
1016#endif
@ v_cycle
The V-cycle.
Definition multigrid.h:172
@ w_cycle
The W-cycle.
Definition multigrid.h:174
@ f_cycle
The F-cycle.
Definition multigrid.h:176
ObserverPointer< const MGMatrixBase< VectorType > > edge_out
Definition multigrid.h:459
MGLevelObject< VectorType > defect2
Definition multigrid.h:422
void cycle()
void set_edge_flux_matrices(const MGMatrixBase< VectorType > &edge_down, const MGMatrixBase< VectorType > &edge_up)
unsigned int minlevel
Definition multigrid.h:394
mg::Signals signals
Definition multigrid.h:363
MGLevelObject< VectorType > solution
Definition multigrid.h:411
ObserverPointer< const MGSmootherBase< VectorType >, Multigrid< VectorType > > post_smooth
Definition multigrid.h:452
boost::signals2::connection connect_edge_prolongation(const std::function< void(const bool, const unsigned int)> &slot)
void level_step(const unsigned int level, const Cycle cycle, const unsigned int iteration)
ObserverPointer< const MGMatrixBase< VectorType > > edge_in
Definition multigrid.h:467
unsigned int maxlevel
Definition multigrid.h:399
VectorType vector_type
Definition multigrid.h:179
void set_maxlevel(const unsigned int)
unsigned int get_minlevel() const
void set_edge_matrices(const MGMatrixBase< VectorType > &edge_out, const MGMatrixBase< VectorType > &edge_in)
boost::signals2::connection connect_residual_step(const std::function< void(const bool, const unsigned int)> &slot)
void set_cycle(Cycle)
unsigned int get_maxlevel() const
ObserverPointer< const MGCoarseGridBase< VectorType >, Multigrid< VectorType > > coarse
Definition multigrid.h:434
ObserverPointer< const MGSmootherBase< VectorType >, Multigrid< VectorType > > pre_smooth
Definition multigrid.h:446
const VectorType const_vector_type
Definition multigrid.h:180
boost::signals2::connection connect_post_smoother_step(const std::function< void(const bool, const unsigned int)> &slot)
boost::signals2::connection connect_coarse_solve(const std::function< void(const bool, const unsigned int)> &slot)
ObserverPointer< const MGMatrixBase< VectorType >, Multigrid< VectorType > > matrix
Definition multigrid.h:428
Cycle cycle_type
Definition multigrid.h:389
boost::signals2::connection connect_prolongation(const std::function< void(const bool, const unsigned int)> &slot)
void set_edge_in_matrix(const MGMatrixBase< VectorType > &edge_in)
MGLevelObject< VectorType > t
Definition multigrid.h:417
void set_minlevel(const unsigned int level, bool relative=false)
void level_v_step(const unsigned int level)
Multigrid(const MGMatrixBase< VectorType > &matrix, const MGCoarseGridBase< VectorType > &coarse, const MGTransferBase< VectorType > &transfer, const MGSmootherBase< VectorType > &pre_smooth, const MGSmootherBase< VectorType > &post_smooth, const unsigned int minlevel=0, const unsigned int maxlevel=numbers::invalid_unsigned_int, Cycle cycle=v_cycle)
MGLevelObject< VectorType > defect
Definition multigrid.h:406
void vcycle()
ObserverPointer< const MGMatrixBase< VectorType >, Multigrid< VectorType > > edge_down
Definition multigrid.h:475
boost::signals2::connection connect_restriction(const std::function< void(const bool, const unsigned int)> &slot)
void reinit(const unsigned int minlevel, const unsigned int maxlevel)
ObserverPointer< const MGMatrixBase< VectorType >, Multigrid< VectorType > > edge_up
Definition multigrid.h:483
boost::signals2::connection connect_pre_smoother_step(const std::function< void(const bool, const unsigned int)> &slot)
ObserverPointer< const MGTransferBase< VectorType >, Multigrid< VectorType > > transfer
Definition multigrid.h:440
std::vector< const DoFHandler< dim > * > dof_handler_vector_raw
Definition multigrid.h:626
void Tvmult(OtherVectorType &dst, const OtherVectorType &src) const
IndexSet locally_owned_domain_indices(const unsigned int block=0) const
ObserverPointer< Multigrid< VectorType >, PreconditionMG< dim, VectorType, TransferType > > multigrid
Definition multigrid.h:633
const Multigrid< VectorType > & get_multigrid() const
boost::signals2::connection connect_transfer_to_global(const std::function< void(bool)> &slot)
mg::Signals signals
Definition multigrid.h:651
boost::signals2::connection connect_transfer_to_mg(const std::function< void(bool)> &slot)
PreconditionMG(const DoFHandler< dim > &dof_handler, Multigrid< VectorType > &mg, const TransferType &transfer)
ObserverPointer< const TransferType, PreconditionMG< dim, VectorType, TransferType > > transfer
Definition multigrid.h:640
MPI_Comm get_mpi_communicator() const
const bool uses_dof_handler_vector
Definition multigrid.h:646
void vmult_add(OtherVectorType &dst, const OtherVectorType &src) const
bool empty() const
IndexSet locally_owned_range_indices(const unsigned int block=0) const
std::vector< ObserverPointer< const DoFHandler< dim >, PreconditionMG< dim, VectorType, TransferType > > > dof_handler_vector
Definition multigrid.h:620
PreconditionMG(const std::vector< const DoFHandler< dim > * > &dof_handler, Multigrid< VectorType > &mg, const TransferType &transfer)
Multigrid< VectorType > & get_multigrid()
void Tvmult_add(OtherVectorType &dst, const OtherVectorType &src) const
void vmult(OtherVectorType &dst, const OtherVectorType &src) const
Triangulation< dim, spacedim > & get_triangulation()
virtual MPI_Comm get_mpi_communicator() const override
Definition tria_base.cc:158
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4642
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
std::size_t size
Definition mpi.cc:733
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
constexpr bool is_supported_operation
Definition mg.h:79
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
boost::signals2::signal< void(const bool before, const unsigned int level)> prolongation
Definition multigrid.h:107
boost::signals2::signal< void(const bool before, const unsigned int level)> pre_smoother_step
Definition multigrid.h:118
boost::signals2::signal< void(const bool before, const unsigned int level)> coarse_solve
Definition multigrid.h:88
boost::signals2::signal< void(const bool before, const unsigned int level)> edge_prolongation
Definition multigrid.h:141
boost::signals2::signal< void(const bool before, const unsigned int level)> post_smoother_step
Definition multigrid.h:126
boost::signals2::signal< void(const bool before)> transfer_to_global
Definition multigrid.h:76
boost::signals2::signal< void(const bool before, const unsigned int level)> residual_step
Definition multigrid.h:134
boost::signals2::signal< void(const bool before, const unsigned int level)> restriction
Definition multigrid.h:99
boost::signals2::signal< void(const bool before)> transfer_to_mg
Definition multigrid.h:69