// DO NOT EDIT ! // This file is generated using the MantaFlow preprocessor (prep generate). /****************************************************************************** * * MantaFlow fluid solver framework * Copyright 2011 Tobias Pfaff, Nils Thuerey * * This program is free software, distributed under the terms of the * Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Multigrid solver by Florian Ferstl (florian.ferstl.ff@gmail.com) * * This is an implementation of the solver developed by Dick et al. [1] * without topology awareness (= vertex duplication on coarser levels). This * simplification allows us to use regular grids for all levels of the multigrid * hierarchy and works well for moderately complex domains. * * [1] Solving the Fluid Pressure Poisson Equation Using Multigrid-Evaluation * and Improvements, C. Dick, M. Rogowsky, R. Westermann, IEEE TVCG 2015 * ******************************************************************************/ #ifndef _MULTIGRID_H #define _MULTIGRID_H #include "vectorbase.h" #include "grid.h" namespace Manta { //! Multigrid solver class GridMg { public: //! constructor: preallocates most of required memory for multigrid hierarchy GridMg(const Vec3i &gridSize); ~GridMg(){}; //! update system matrix A from symmetric 7-point stencil void setA(const Grid *pA0, const Grid *pAi, const Grid *pAj, const Grid *pAk); //! set right-hand side after setting A void setRhs(const Grid &rhs); bool isASet() const { return mIsASet; } bool isRhsSet() const { return mIsRhsSet; } //! perform VCycle iteration // - if src is null, then a zero vector is used instead // - returns norm of residual after VCylcle Real doVCycle(Grid &dst, const Grid *src = nullptr); // access void setCoarsestLevelAccuracy(Real accuracy) { mCoarsestLevelAccuracy = accuracy; } Real getCoarsestLevelAccuracy() const { return mCoarsestLevelAccuracy; } void setSmoothing(int numPreSmooth, int numPostSmooth) { mNumPreSmooth = numPreSmooth; mNumPostSmooth = numPostSmooth; } int getNumPreSmooth() const { return mNumPreSmooth; } int getNumPostSmooth() const { return mNumPostSmooth; } //! Set factor for automated downscaling of trivial equations: // 1*x_i = b_i ---> trivialEquationScale*x_i = trivialEquationScale*b_i // Factor should be significantly smaller than the scale of the entries in A. // Info: Trivial equations of the form x_i = b_i can have a negative // effect on the coarse grid operators of the multigrid hierarchy (due // to scaling mismatches), which can lead to slow multigrid convergence. // To avoid this, the solver checks for such equations when updating A // (and rhs) and scales these equations by a fixed factor < 1. void setTrivialEquationScale(Real scale) { mTrivialEquationScale = scale; } private: 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)); } int linIdx(Vec3i V, int l) const { return V.x + V.y * mPitch[l].y + V.z * mPitch[l].z; } 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; } void analyzeStencil(int v, bool is3D, bool &isStencilSumNonZero, bool &isEquationTrivial) const; void genCoarseGrid(int l); void genCoraseGridOperator(int l); void smoothGS(int l, bool reversedOrder); void calcResidual(int l); Real calcResidualNorm(int l); void solveCG(int l); void restrict(int l_dst, const std::vector &src, std::vector &dst) const; void interpolate(int l_dst, const std::vector &src, std::vector &dst) const; private: enum VertexType : char { vtInactive = 0, vtActive = 1, vtActiveTrivial = 2, // only on finest level 0 vtRemoved = 3, //-+ vtZero = 4, // +-- only during coarse grid generation vtFree = 5 //-+ }; struct CoarseningPath { Vec3i U, W, N; int sc, sf; Real rw, iw; bool inUStencil; }; int mNumPreSmooth; int mNumPostSmooth; Real mCoarsestLevelAccuracy; Real mTrivialEquationScale; std::vector> mA; std::vector> mx; std::vector> mb; std::vector> mr; std::vector> mType; std::vector> mCGtmp1, mCGtmp2, mCGtmp3, mCGtmp4; std::vector mSize, mPitch; std::vector mCoarseningPaths0; bool mIs3D; int mDim; int mStencilSize; int mStencilSize0; Vec3i mStencilMin; Vec3i mStencilMax; bool mIsASet; bool mIsRhsSet; // provide kernels with access friend struct knActivateVertices; friend struct knActivateCoarseVertices; friend struct knSetRhs; friend struct knGenCoarseGridOperator; friend struct knSmoothColor; friend struct knCalcResidual; friend struct knResidualNormSumSqr; friend struct knRestrict; friend struct knInterpolate; }; // GridMg } // namespace Manta #endif