mantaflow  0.10
A framework for fluid simulation
multigrid.h
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * MantaFlow fluid solver framework
5  * Copyright 2011 Tobias Pfaff, Nils Thuerey
6  *
7  * This program is free software, distributed under the terms of the
8  * GNU General Public License (GPL)
9  * http://www.gnu.org/licenses
10  *
11  * Multigrid solver by Florian Ferstl (florian.ferstl.ff@gmail.com)
12  *
13  * This is an implementation of the solver developed by Dick et al. [1]
14  * without topology awareness (= vertex duplication on coarser levels). This
15  * simplification allows us to use regular grids for all levels of the multigrid
16  * hierarchy and works well for moderately complex domains.
17  *
18  * [1] Solving the Fluid Pressure Poisson Equation Using Multigrid-Evaluation
19  * and Improvements, C. Dick, M. Rogowsky, R. Westermann, IEEE TVCG 2015
20  *
21  ******************************************************************************/
22 
23 #ifndef _MULTIGRID_H
24 #define _MULTIGRID_H
25 
26 #include "vectorbase.h"
27 #include "grid.h"
28 
29 namespace Manta {
30 
32 class GridMg {
33  public:
35  GridMg(const Vec3i& gridSize);
36  ~GridMg() {};
37 
39  void setA(const Grid<Real>* pA0, const Grid<Real>* pAi, const Grid<Real>* pAj, const Grid<Real>* pAk);
40 
42  void setRhs(const Grid<Real>& rhs);
43 
44  bool isASet() const { return mIsASet; }
45  bool isRhsSet() const { return mIsRhsSet; }
46 
48  // - if src is null, then a zero vector is used instead
49  // - returns norm of residual after VCylcle
50  Real doVCycle(Grid<Real>& dst, const Grid<Real>* src = nullptr);
51 
52  // access
53  void setCoarsestLevelAccuracy(Real accuracy) { mCoarsestLevelAccuracy = accuracy; }
54  Real getCoarsestLevelAccuracy() const { return mCoarsestLevelAccuracy; }
55  void setSmoothing(int numPreSmooth, int numPostSmooth) { mNumPreSmooth = numPreSmooth; mNumPostSmooth = numPostSmooth; }
56  int getNumPreSmooth() const { return mNumPreSmooth; }
57  int getNumPostSmooth() const { return mNumPostSmooth; }
58 
60  // 1*x_i = b_i ---> trivialEquationScale*x_i = trivialEquationScale*b_i
61  // Factor should be significantly smaller than the scale of the entries in A.
62  // Info: Trivial equations of the form x_i = b_i can have a negative
63  // effect on the coarse grid operators of the multigrid hierarchy (due
64  // to scaling mismatches), which can lead to slow multigrid convergence.
65  // To avoid this, the solver checks for such equations when updating A
66  // (and rhs) and scales these equations by a fixed factor < 1.
67  void setTrivialEquationScale(Real scale) { mTrivialEquationScale = scale; }
68 
69  private:
70  Vec3i vecIdx(int v, int l) const { return Vec3i(v%mSize[l].x, (v%(mSize[l].x*mSize[l].y))/mSize[l].x, v/(mSize[l].x*mSize[l].y)); }
71  int linIdx(Vec3i V, int l) const { return V.x + V.y*mPitch[l].y + V.z*mPitch[l].z; }
72  bool inGrid(Vec3i V, int l) const { return V.x>=0 && V.y>=0 && V.z>=0 && V.x<mSize[l].x && V.y<mSize[l].y && V.z<mSize[l].z; }
73 
74  void analyzeStencil(int v, bool is3D, bool& isStencilSumNonZero, bool& isEquationTrivial) const;
75 
76  void genCoarseGrid(int l);
77  void genCoraseGridOperator(int l);
78 
79  void smoothGS(int l, bool reversedOrder);
80  void calcResidual(int l);
81  Real calcResidualNorm(int l);
82  void solveCG(int l);
83 
84  void restrict(int l_dst, const std::vector<Real>& src, std::vector<Real>& dst) const;
85  void interpolate(int l_dst, const std::vector<Real>& src, std::vector<Real>& dst) const;
86 
87  private:
88  enum VertexType : char {
89  vtInactive = 0,
90  vtActive = 1,
91  vtActiveTrivial = 2, // only on finest level 0
92  vtRemoved = 3, //-+
93  vtZero = 4, // +-- only during coarse grid generation
94  vtFree = 5 //-+
95  };
96 
97  struct CoarseningPath {
98  Vec3i U, W, N;
99  int sc, sf;
100  Real rw, iw;
101  bool inUStencil;
102  };
103 
104  int mNumPreSmooth;
105  int mNumPostSmooth;
106  Real mCoarsestLevelAccuracy;
107  Real mTrivialEquationScale;
108 
109  std::vector<std::vector<Real>> mA;
110  std::vector<std::vector<Real>> mx;
111  std::vector<std::vector<Real>> mb;
112  std::vector<std::vector<Real>> mr;
113  std::vector<std::vector<VertexType>> mType;
114  std::vector<std::vector<double>> mCGtmp1, mCGtmp2, mCGtmp3, mCGtmp4;
115  std::vector<Vec3i> mSize, mPitch;
116  std::vector<CoarseningPath> mCoarseningPaths0;
117 
118  bool mIs3D;
119  int mDim;
120  int mStencilSize;
121  int mStencilSize0;
122  Vec3i mStencilMin;
123  Vec3i mStencilMax;
124 
125  bool mIsASet;
126  bool mIsRhsSet;
127 
128  // provide kernels with access
129  friend struct knActivateVertices;
130  friend struct knActivateCoarseVertices;
131  friend struct knSetRhs;
132  friend struct knGenCoarseGridOperator;
133  friend struct knSmoothColor;
134  friend struct knCalcResidual;
135  friend struct knResidualNormSumSqr;
136  friend struct knRestrict;
137  friend struct knInterpolate;
138 }; // GridMg
139 
140 } // namespace
141 
142 #endif
143 
144 
Definition: commonkernels.h:22
Real doVCycle(Grid< Real > &dst, const Grid< Real > *src=nullptr)
perform VCycle iteration
Definition: multigrid.cpp:420
void setTrivialEquationScale(Real scale)
Set factor for automated downscaling of trivial equations:
Definition: multigrid.h:67
Basic inlined vector class.
Definition: vectorbase.h:71
Multigrid solver.
Definition: multigrid.h:32
GridMg(const Vec3i &gridSize)
constructor: preallocates most of required memory for multigrid hierarchy
Definition: multigrid.cpp:221
void setRhs(const Grid< Real > &rhs)
set right-hand side after setting A
Definition: multigrid.cpp:394
void setA(const Grid< Real > *pA0, const Grid< Real > *pAi, const Grid< Real > *pAj, const Grid< Real > *pAk)
update system matrix A from symmetric 7-point stencil
Definition: multigrid.cpp:359