ThunderEgg  1.0.0
FMGCycle.h
Go to the documentation of this file.
1 /***************************************************************************
2  * ThunderEgg, a library for solvers on adaptively refined block-structured
3  * Cartesian grids.
4  *
5  * Copyright (c) 2021 Scott Aiton
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  ***************************************************************************/
20 
21 #ifndef THUNDEREGG_GMG_FMGCYCLE_H
22 #define THUNDEREGG_GMG_FMGCYCLE_H
23 
28 #include <ThunderEgg/GMG/Cycle.h>
30 namespace ThunderEgg::GMG {
34 template<int D>
35 class FMGCycle : public Cycle<D>
36 {
37 private:
38  int num_pre_sweeps = 1;
39  int num_post_sweeps = 1;
40  int num_coarse_sweeps = 1;
41  int num_mid_sweeps = 1;
42 
43  void v_visit(const Level<D>& level, const Vector<D>& f, Vector<D>& u) const
44  {
45  if (level.coarsest()) {
46  for (int i = 0; i < num_coarse_sweeps; i++) {
47  level.getSmoother().smooth(f, u);
48  }
49  } else {
50  for (int i = 0; i < num_pre_sweeps; i++) {
51  level.getSmoother().smooth(f, u);
52  }
53 
54  Vector<D> coarser_f = this->restrict(level, f, u);
55 
56  const Level<D>& coarser_level = level.getCoarser();
57  Vector<D> coarser_u = coarser_f.getZeroClone();
58 
59  this->visit(coarser_level, coarser_f, coarser_u);
60 
61  coarser_level.getInterpolator().interpolate(coarser_u, u);
62 
63  for (int i = 0; i < num_post_sweeps; i++) {
64  level.getSmoother().smooth(f, u);
65  }
66  }
67  }
68 
69 protected:
70  void visit(const Level<D>& level, const Vector<D>& f, Vector<D>& u) const override
71  {
72  if (level.coarsest()) {
73  for (int i = 0; i < num_coarse_sweeps; i++) {
74  level.getSmoother().smooth(f, u);
75  }
76  } else {
77  for (int i = 0; i < num_pre_sweeps; i++) {
78  level.getSmoother().smooth(f, u);
79  }
80 
81  Vector<D> coarser_f = this->restrict(level, f, u);
82 
83  const Level<D>& coarser_level = level.getCoarser();
84  Vector<D> coarser_u = coarser_f.getZeroClone();
85 
86  this->visit(coarser_level, coarser_f, coarser_u);
87 
88  coarser_level.getInterpolator().interpolate(coarser_u, u);
89 
90  for (int i = 0; i < num_mid_sweeps; i++) {
91  level.getSmoother().smooth(f, u);
92  }
93 
94  coarser_f = this->restrict(level, f, u);
95 
96  v_visit(coarser_level, coarser_f, coarser_u);
97 
98  coarser_level.getInterpolator().interpolate(coarser_u, u);
99 
100  for (int i = 0; i < num_post_sweeps; i++) {
101  level.getSmoother().smooth(f, u);
102  }
103  }
104  }
105 
106 public:
113  FMGCycle(const Level<D>& finest_level, const CycleOpts& opts)
114  : Cycle<D>(finest_level)
115  {
116  num_pre_sweeps = opts.pre_sweeps;
117  num_post_sweeps = opts.post_sweeps;
118  num_coarse_sweeps = opts.coarse_sweeps;
119  num_mid_sweeps = opts.mid_sweeps;
120  }
126  FMGCycle<D>* clone() const override { return new FMGCycle(*this); }
127 };
128 extern template class FMGCycle<2>;
129 extern template class FMGCycle<3>;
130 } // namespace ThunderEgg::GMG
131 #endif
ThunderEgg::GMG::Level::getSmoother
const Smoother< D > & getSmoother() const
Get smoother operator for this level.
Definition: Level.h:138
ThunderEgg::GMG::Level::getInterpolator
const Interpolator< D > & getInterpolator() const
Get the interpolation operator for this level.
Definition: Level.h:102
Cycle.h
Cycle class.
ThunderEgg::GMG::CycleOpts::mid_sweeps
int mid_sweeps
Number of sweeps inbetween up and down.
Definition: CycleOpts.h:46
ThunderEgg::GMG::FMGCycle::FMGCycle
FMGCycle(const Level< D > &finest_level, const CycleOpts &opts)
Create new FMGCycle.
Definition: FMGCycle.h:113
ThunderEgg::GMG::FMGCycle
Implementation of a full multigrid cycle.
Definition: FMGCycle.h:35
ThunderEgg::GMG::CycleOpts::post_sweeps
int post_sweeps
Number of sweeps on up cycle.
Definition: CycleOpts.h:42
ThunderEgg::GMG::FMGCycle::visit
void visit(const Level< D > &level, const Vector< D > &f, Vector< D > &u) const override
Virtual visit function that needs to be implemented in derived classes.
Definition: FMGCycle.h:70
CycleOpts.h
CycleOpts struct.
ThunderEgg::GMG::Level::getCoarser
const Level & getCoarser() const
get reference to the coarser level.
Definition: Level.h:156
ThunderEgg::GMG::FMGCycle::clone
FMGCycle< D > * clone() const override
Get a clone of this FMGCycle.
Definition: FMGCycle.h:126
ThunderEgg::GMG::Cycle
Base abstract class for cycles.
Definition: Cycle.h:40
ThunderEgg::GMG::CycleOpts::pre_sweeps
int pre_sweeps
Number of sweeps on down cycle.
Definition: CycleOpts.h:38
ThunderEgg::GMG::Level
Represents a level in geometric multi-grid.
Definition: Level.h:38
ThunderEgg::Vector
Vector class for use in thunderegg.
Definition: Vector.h:42
ThunderEgg::GMG::CycleOpts
Options for Cycle classes.
Definition: CycleOpts.h:33
ThunderEgg::Vector::getZeroClone
Vector< D > getZeroClone() const
Get a vector of the same length initialized to zero.
Definition: Vector.h:601
ThunderEgg::GMG::Cycle::restrict
Vector< D > restrict(const Level< D > &level, const Vector< D > &f, const Vector< D > &u) const
Prepare vectors for coarser level.
Definition: Cycle.h:57
ThunderEgg::GMG
Geometric-Multigrid classes.
Definition: Cycle.h:33
ThunderEgg::GMG::CycleOpts::coarse_sweeps
int coarse_sweeps
Number of sweeps on coarse level.
Definition: CycleOpts.h:50
ThunderEgg::GMG::Level::coarsest
bool coarsest() const
Check if this level is the coarsest level.
Definition: Level.h:174