22 std::vector<SpMatrixRowMajor> transferMatrices,
25 : m_nLevels(transferMatrices.size()+1), m_ops(m_nLevels), m_smoother(m_nLevels),
26 m_prolong(m_nLevels-1), m_restrict(m_nLevels-1), m_coarseSolver(coarseSolver),
27 m_numPreSmooth(1), m_numPostSmooth(1), m_symmSmooth(true), m_damping(1)
30 std::vector<SpMatrixRowMajorPtr> transferMatrixPtrs(
m_nLevels-1);
32 transferMatrixPtrs[i] = transferMatrices[i].moveToPtr();
40 std::vector<SpMatrixRowMajorPtr> transferMatrices,
43 : m_nLevels(transferMatrices.size()+1), m_ops(m_nLevels), m_smoother(m_nLevels),
44 m_prolong(m_nLevels-1), m_restrict(m_nLevels-1), m_coarseSolver(coarseSolver),
45 m_numPreSmooth(1), m_numPostSmooth(1), m_symmSmooth(true), m_damping(1)
53 const std::vector<OpPtr>& ops,
54 const std::vector<OpPtr>& prolongation,
55 const std::vector<OpPtr>& restriction,
58 : m_nLevels(ops.size()), m_ops(ops), m_smoother(m_nLevels),
59 m_prolong(prolongation), m_restrict(restriction), m_coarseSolver(coarseSolver),
60 m_numPreSmooth(1), m_numPostSmooth(1), m_symmSmooth(true), m_damping(1)
64 "gsMultiGridOp: The number of prolongation and restriction operators differ.");
66 "gsMultiGridOp: The number of prolongation and restriction operators do not fit to the number of operators.");
72 GISMO_ASSERT (fineMatrix->rows() == fineMatrix->cols(),
"gsMultiGridOp needs quadratic matrices.");
75 m_ops[m_nLevels-1] = makeMatrixOp(mat);
77 for (
index_t i = m_nLevels - 2; i >= 0; --i )
80 transferMatrices[i]->transpose() * *mat * *(transferMatrices[i])
82 m_ops[i] = makeMatrixOp(newMat);
86 for (
index_t i=0; i<m_nLevels-1; ++i )
88 m_prolong[i] = makeMatrixOp(transferMatrices[i]);
93 m_restrict[i] = makeMatrixOp(transferMatrices[i]->transpose());
108 m_coarseSolver = makeSparseLUSolver(matr);
114 if (m_ops[0]->rows() > 50)
115 gsWarn <<
"gsMultiGridOp::initCoarseSolverIfUninitialized(): The coarse grid solver is constructed "
116 "based on gsLinearOperator::toMatrix(). This might be inefficient. Consider providing matrices of "
117 "type gsSparseMatrix<T> or an exact solver for the coarset grid level to gsMultiGridOp constructor.\n";
119 m_ops[0]->toMatrix( coarse_dense );
120 m_coarseSolver = makePartialPivLUSolver( coarse_dense );
127 GISMO_ASSERT (m_smoother[level],
"gsMultiGridOp::smoothingStep: "
128 "Smoother is not defined for level "<<level<<
". Define it using setSmoother.");
131 for (
index_t i = 0; i < m_numPreSmooth; ++i)
133 m_smoother[level]->step( rhs, x );
137 for (
index_t i = 0; i < m_numPostSmooth; ++i)
140 m_smoother[level]->stepT( rhs, x );
142 m_smoother[level]->step( rhs, x );
150 GISMO_ASSERT ( 0 <= level && level < m_nLevels,
"TgsMultiGridOp: the given level is not feasible." );
161 GISMO_ASSERT (m_smoother[lf],
"gsMultiGridOp::multiGridStep: "
162 "Smoother is not defined for level "<<lf<<
". Define it using setSmoother.");
164 Matrix fineRes, fineCorr, coarseRes, coarseCorr;
167 for (
index_t i = 0; i < m_numPreSmooth; ++i)
169 m_smoother[lf]->step( rhs, x );
173 m_ops[lf]->apply( x, fineRes );
177 restrictVector( lf, fineRes, coarseRes );
180 coarseCorr.setZero( nDofs(lc), coarseRes.cols() );
181 for (
index_t i = 0; i < m_numCycles[lc]; ++i)
183 multiGridStep( lc, coarseRes, coarseCorr );
187 prolongVector( lc, coarseCorr, fineCorr );
190 x -= m_damping * fineCorr;
193 for (
index_t i = 0; i < m_numPostSmooth; ++i)
196 m_smoother[lf]->stepT( rhs, x );
198 m_smoother[lf]->step( rhs, x );
205 const std::vector<Matrix>& rhs,
206 const std::vector<Matrix>& fixedValues,
211 GISMO_ASSERT (fixedValues.size() ==
static_cast<size_t>(m_nLevels),
212 "gsMultiGridOp::fullMultiGrid: The size of fixedValues does not correspond to the number of levels.");
213 GISMO_ASSERT (rhs.size() ==
static_cast<size_t>(m_nLevels),
214 "gsMultiGridOp::fullMultiGrid: The size of rhs does not correspond to the number of levels.");
216 std::vector<Matrix> u(m_nLevels);
219 solveCoarse( rhs[0], u[0] );
221 for (
index_t i = 1; i <= finestLevel(); ++i)
224 prolongVector(i-1, u[i-1], u[i]);
225 u[i] += fixedValues[i];
228 multiGridStep(i, rhs[i], u[i]);
231 result = u[ finestLevel() ];
236 const std::vector<Matrix>& rhs,
237 const std::vector<Matrix>& fixedValues,
242 GISMO_ASSERT (fixedValues.size() ==
static_cast<size_t>(m_nLevels),
243 "gsMultiGridOp::cascadicMultiGrid: The size of fixedValue does not correspond to the number of levels.");
244 GISMO_ASSERT (rhs.size() ==
static_cast<size_t>(m_nLevels),
245 "gsMultiGridOp::cascadicMultiGrid: The size of rhs does not correspond to the number of levels.");
247 std::vector<Matrix> u(m_nLevels);
250 solveCoarse( rhs[0], u[0] );
252 for (
index_t i = 1; i <= finestLevel(); ++i)
255 prolongVector(i-1, u[i-1], u[i]);
256 u[i] += fixedValues[i];
259 smoothingStep(i, rhs[i], u[i]);
262 result = u[ finestLevel() ];
268 GISMO_ASSERT ( 0 < lf && lf < m_nLevels,
"gsMultiGrid: The given level is not feasible." );
269 GISMO_ASSERT ( fine.rows() == nDofs(lf),
"gsMultiGrid: The dimensions do not fit." );
271 m_restrict[lf-1]->apply( fine, coarse );
277 GISMO_ASSERT ( 0 <= lc && lc < m_nLevels - 1,
"gsMultiGrid: The given level is not feasible." );
278 GISMO_ASSERT ( coarse.rows() == nDofs(lc),
"gsMultiGrid: The dimensions do not fit." );
280 m_prolong[lc]->apply( coarse, fine );
286 GISMO_ASSERT ( 0 <= lvl && lvl < m_nLevels,
"gsMultiGrid: The given level is not feasible." );
287 m_smoother[lvl] = sm;
294 GISMO_ASSERT ( matrOp,
"Matrices are not available for matrix-free multigrid solvers." );
303 opt.
addInt (
"NumPreSmooth" ,
"Number of pre-smoothing steps", 1 );
304 opt.
addInt (
"NumPostSmooth" ,
"Number of post-smoothing steps", 1 );
305 opt.
addInt (
"NumCycles" ,
"Number of cycles (usually 1 for V-cycle or 2 for W-cycle)", 1 );
306 opt.
addReal (
"CoarseGridCorrectionDamping" ,
"Damping of the coarse-grid correction (usually 1)", (gsOptionList::Real)1 );
307 opt.
addSwitch(
"SymmSmooth" ,
"Iff true, stepT is called for post-smoothing",
true );
315 Base::setOptions(opt);
316 m_numPreSmooth = opt.
askInt (
"NumPreSmooth" , m_numPreSmooth );
317 m_numPostSmooth = opt.
askInt (
"NumPostSmooth" , m_numPostSmooth );
318 m_damping = opt.
askReal (
"CoarseGridCorrectionDamping" , m_damping );
319 m_symmSmooth = opt.
askSwitch(
"SymmSmooth" , m_symmSmooth );
324 m_numCycles.setConstant(m_nLevels-1, nc);
MatrixPtr matrixPtr() const
Returns a shared pinter to the matrix.
Definition: gsMatrixOp.h:88
static gsOptionList defaultOptions()
Returns a list of default options.
Definition: gsMultiGrid.hpp:300
gsMultiGridOp(SpMatrix fineMatrix, std::vector< SpMatrixRowMajor > transferMatrices, OpPtr coarseSolver=OpPtr())
Constructor.
Definition: gsMultiGrid.hpp:20
gsPreconditionerOp< T >::Ptr PrecondPtr
Shared pointer to gsPreconditionerOp.
Definition: gsMultiGrid.h:72
uPtr moveToPtr()
This function returns a smart pointer to the matrix. After calling it, the matrix object becomes empt...
Definition: gsSparseMatrix.h:249
Simple adapter class to use a matrix (or matrix-like object) as a linear operator. Needed for the iterative method classes.
Definition: gsMatrixOp.h:33
void prolongVector(index_t lc, const Matrix &coarse, Matrix &fine) const
Prolong a vector of coefficients from the level lc, given by coarse, to the next finer level...
Definition: gsMultiGrid.hpp:275
NestedMatrix matrix() const
Returns the matrix.
Definition: gsMatrixOp.h:84
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void multiGridStep(index_t level, const Matrix &rhs, Matrix &x) const
Perform one multigrid cycle, starting from the given level.
Definition: gsMultiGrid.hpp:148
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:201
#define gsWarn
Definition: gsDebug.h:50
memory::shared_ptr< SpMatrix > SpMatrixPtr
Smart pointer to sparse matrix type.
Definition: gsMultiGrid.h:87
void cascadicMultiGrid(const std::vector< Matrix > &rhs, const std::vector< Matrix > &fixedValues, Matrix &result) const
Perform one cascadic multigrid cycle and store the resulting solution vector in result.
Definition: gsMultiGrid.hpp:235
void initCoarseSolver() const
Init solver on coarsest grid level.
Definition: gsMultiGrid.hpp:102
const SpMatrix & matrix() const
Stiffness matrix for finest level.
Definition: gsMultiGrid.h:278
void setOptions(const gsOptionList &opt) override
Set the options based on a gsOptionList.
Definition: gsMultiGrid.hpp:313
void restrictVector(index_t lf, const Matrix &fine, Matrix &coarse) const
Restrict a vector of coefficients from the level lf, given by fine, to the next coarser level...
Definition: gsMultiGrid.hpp:266
void fullMultiGrid(const std::vector< Matrix > &rhs, const std::vector< Matrix > &dirichletIntp, Matrix &result) const
Perform one full multigrid cycle and store the resulting solution vector in result.
Definition: gsMultiGrid.hpp:204
Real askReal(const std::string &label, const Real &value=0) const
Reads value for option label from options.
Definition: gsOptionList.cpp:139
index_t m_nLevels
Number of levels.
Definition: gsMultiGrid.h:363
void init(SpMatrixPtr fineMatrix, std::vector< SpMatrixRowMajorPtr > transferMatrices)
Init function that is used by matrix based constructors.
Definition: gsMultiGrid.hpp:70
index_t askInt(const std::string &label, const index_t &value=0) const
Reads value for option label from options.
Definition: gsOptionList.cpp:117
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:211
gsVector< index_t > m_numCycles
Number of coarse-grid steps (1=V-cycle, 2=W-cycle)
Definition: gsMultiGrid.h:390
gsLinearOperator< T >::Ptr OpPtr
Shared pointer to gsLinearOperator.
Definition: gsMultiGrid.h:69
bool askSwitch(const std::string &label, const bool &value=false) const
Reads value for option label from options.
Definition: gsOptionList.cpp:128
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
void smoothingStep(index_t level, const Matrix &rhs, Matrix &x) const
Apply smoothing steps on the corresponding level.
Definition: gsMultiGrid.hpp:125
void addSwitch(const std::string &label, const std::string &desc, const bool &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:235
Simple adapter classes to use matrices or linear solvers as gsLinearOperators.
void setSmoother(index_t lvl, const PrecondPtr &sm)
Definition: gsMultiGrid.hpp:284