Files
mfem/fem/multigrid.hpp
T

120 lines
3.4 KiB
C++

// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#ifndef MFEM_MULTIGRID
#define MFEM_MULTIGRID
#include "fespacehierarchy.hpp"
#include "bilinearform.hpp"
#include "../linalg/operator.hpp"
#include "../linalg/handle.hpp"
namespace mfem
{
/// Multigrid solver class
class Multigrid : public Solver
{
public:
enum class CycleType
{
VCYCLE,
WCYCLE
};
protected:
const FiniteElementSpaceHierarchy& fespaces;
Array<Array<int>*> essentialTrueDofs;
Array<BilinearForm*> bfs;
private:
Array<Operator*> operators;
Array<Solver*> smoothers;
Array<bool> ownedOperators;
Array<bool> ownedSmoothers;
CycleType cycleType;
int preSmoothingSteps;
int postSmoothingSteps;
mutable Array<Vector*> X;
mutable Array<Vector*> Y;
mutable Array<Vector*> R;
mutable Array<Vector*> Z;
public:
/// Constructs an empty multigrid for the given FiniteElementSpaceHierarchy
Multigrid(const FiniteElementSpaceHierarchy& fespaces_);
/// Destructor
virtual ~Multigrid();
/// Adds a level to the multigrid operator hierarchy.
/** The ownership of the operators and solvers/smoothers may be transferred
to the Multigrid by setting the according boolean variables. */
void AddLevel(Operator* opr, Solver* smoother, bool ownOperator,
bool ownSmoother);
/// Returns the number of levels
int NumLevels() const;
/// Returns the index of the finest level
int GetFinestLevelIndex() const;
/// Returns operator at given level
const Operator* GetOperatorAtLevel(int level) const;
/// Returns operator at given level
Operator* GetOperatorAtLevel(int level);
/// Returns operator at finest level
const Operator* GetOperatorAtFinestLevel() const;
/// Returns operator at finest level
Operator* GetOperatorAtFinestLevel();
/// Returns smoother at given level
Solver* GetSmootherAtLevel(int level) const;
/// Returns smoother at given level
Solver* GetSmootherAtLevel(int level);
/// Set the cycle type and number of pre- and post-smoothing steps used by Mult
void SetCycleType(CycleType cycleType_, int preSmoothingSteps_,
int postSmoothingSteps_);
/// Application of the multigrid as a preconditioner
virtual void Mult(const Vector& x, Vector& y) const override;
/// Not supported for multigrid
virtual void SetOperator(const Operator& op) override;
/// Form the linear system A X = B, corresponding to the operator on the finest level
void FormFineLinearSystem(Vector& x, Vector& b, OperatorHandle& A, Vector& X,
Vector& B);
/// Recover the solution of a linear system formed with FormFineLinearSystem()
void RecoverFineFEMSolution(const Vector& X, const Vector& b, Vector& x);
private:
/// Application of a smoothing step at particular level
void SmoothingStep(int level) const;
/// Application of a cycle at particular level
void Cycle(int level) const;
};
} // namespace mfem
#endif