18 : cycleType(
CycleType::VCYCLE), preSmoothingSteps(1), postSmoothingSteps(1),
26 :
Solver(operators_.Last()->Height(), operators_.Last()->Width()),
27 cycleType(
CycleType::VCYCLE), preSmoothingSteps(1), postSmoothingSteps(1),
38 for (
int i = 0; i <
operators.Size(); ++i)
52void MultigridBase::InitVectors()
const
54 if (
X.NumRows() > 0 &&
X.NumCols() > 0) { EraseVectors(); }
60 for (
int i = 0; i <
X.NumRows(); ++i)
63 for (
int j = 0; j <
X.NumCols(); ++j)
65 X(i, j) =
new Vector(n);
66 Y(i, j) =
new Vector(n);
67 R(i, j) =
new Vector(n);
68 Z(i, j) =
new Vector(n);
73void MultigridBase::EraseVectors()
const
75 for (
int i = 0; i <
X.NumRows(); ++i)
77 for (
int j = 0; j <
X.NumCols(); ++j)
88 bool ownOperator,
bool ownSmoother)
99 int postSmoothingSteps_)
119 "Multigrid solver does not have operators set!");
121 "Number of columns mismatch in MultigridBase::Mult!");
124 MFEM_WARNING(
"Multigrid solver does not use iterative_mode and ignores "
125 "the initial guess!");
130 if (
X.NumCols() <
nrhs) { InitVectors(); }
134 for (
int j = 0; j <
nrhs; ++j)
136 MFEM_ASSERT(X_[j] && Y_[j],
"Missing Vector in MultigridBase::Mult!");
137 *
X(M - 1, j) = *X_[j];
141 for (
int j = 0; j <
nrhs; ++j)
143 *Y_[j] = *
Y(M - 1, j);
147void MultigridBase::SmoothingStep(
int level,
bool zero,
bool transpose)
const
157 Array<Vector *> Y_(
Y[level],
nrhs), R_(
R[level],
nrhs),
159 for (
int j = 0; j <
nrhs; ++j)
161 *R_[j] = *
X(level, j);
172 for (
int j = 0; j <
nrhs; ++j)
179void MultigridBase::Cycle(
int level)
const
184 SmoothingStep(0,
true,
false);
196 Array<Vector *> Y_(
Y[level],
nrhs), R_(
R[level],
nrhs),
197 X_(
X[level - 1],
nrhs);
198 for (
int j = 0; j <
nrhs; ++j)
200 *R_[j] = *
X(level, j);
204 for (
int j = 0; j <
nrhs; ++j)
206 *
Y(level - 1, j) = 0.0;
219 Array<Vector *> Y_(
Y[level - 1],
nrhs), Z_(
Z[level],
nrhs);
220 GetProlongationAtLevel(level - 1)->
ArrayMult(Y_, Z_);
221 for (
int j = 0; j <
nrhs; ++j)
223 *
Y(level, j) += *Z_[j];
230 SmoothingStep(level,
false,
true);
240 :
MultigridBase(operators_, smoothers_, ownedOperators_, ownedSmoothers_)
259 : fespaces(fespaces_)
266 for (
int level = 0; level < nlevels - 1; ++level)
275 : fespaces(fespaces_)
277 bool have_ess_bdr =
false;
278 for (
int i = 0; i < ess_bdr.
Size(); i++)
280 if (ess_bdr[i]) { have_ess_bdr =
true;
break; }
290 for (
int level = 0; level < nlevels; ++level)
299 for (
int level = 0; level < nlevels - 1; ++level)
318 for (
int i = 0; i <
bfs.Size(); ++i)
338 bfs.Last()->RecoverFEMSolution(
X,
b, x);
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
int GetNumLevels() const
Returns the number of levels in the hierarchy.
Operator * GetProlongationAtLevel(int level) const
Returns the prolongation operator from the finite element space at level to the finite element space ...
virtual const FiniteElementSpace & GetFESpaceAtLevel(int level) const
Returns the finite element space at the given level.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
MFEM_DEPRECATED GeometricMultigrid(const FiniteElementSpaceHierarchy &fespaces_)
Deprecated.
void RecoverFineFEMSolution(const Vector &X, const Vector &b, Vector &x)
Recover the solution of a linear system formed with FormFineLinearSystem()
Array< Array< int > * > essentialTrueDofs
Array< BilinearForm * > bfs
const FiniteElementSpaceHierarchy & fespaces
void FormFineLinearSystem(Vector &x, Vector &b, OperatorHandle &A, Vector &X, Vector &B)
virtual ~GeometricMultigrid()
Destructor.
Abstract base class for Multigrid solvers.
virtual void ArrayMult(const Array< const Vector * > &X_, Array< Vector * > &Y_) const override
Operator application on a matrix: Y=A(X).
int NumLevels() const
Returns the number of levels.
virtual ~MultigridBase()
Destructor.
Array< Operator * > operators
Array< bool > ownedSmoothers
const Operator * GetOperatorAtLevel(int level) const
Returns operator at given level.
Array< bool > ownedOperators
void AddLevel(Operator *op, Solver *smoother, bool ownOperator, bool ownSmoother)
Adds a level to the multigrid operator hierarchy.
Array< Solver * > smoothers
MultigridBase()
Constructs an empty multigrid hierarchy.
virtual void Mult(const Vector &x, Vector &y) const override
Application of the multigrid as a preconditioner.
const Solver * GetSmootherAtLevel(int level) const
Returns smoother at given level.
void SetCycleType(CycleType cycleType_, int preSmoothingSteps_, int postSmoothingSteps_)
Set cycle type and number of pre- and post-smoothing steps used by Mult.
Multigrid()=default
Constructs an empty multigrid hierarchy.
Array< bool > ownedProlongations
Array< Operator * > prolongations
virtual ~Multigrid()
Destructor.
Pointer to an Operator of a specified type.
void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, Operator *&A, Vector &X, Vector &B, int copy_interior=0)
Form a constrained linear system using a matrix-free approach.
int width
Dimension of the input / number of columns in the matrix.
virtual void ArrayMultTranspose(const Array< const Vector * > &X, Array< Vector * > &Y) const
Action of the transpose operator on a matrix: Y=A^t(X).
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
virtual void ArrayAddMult(const Array< const Vector * > &X, Array< Vector * > &Y, const real_t a=1.0) const
Operator application on a matrix: Y+=A(X) (default) or Y+=a*A(X).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual void ArrayMult(const Array< const Vector * > &X, Array< Vector * > &Y) const
Operator application on a matrix: Y=A(X).
Rectangular Operator for imposing essential boundary conditions on the input space using only the act...
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.