Skip to content

Commit

Permalink
Merge pull request #145 from WeiqunZhang/gmres_tweak
Browse files Browse the repository at this point in the history
GMRES: Minor updates
  • Loading branch information
ajnonaka authored Dec 4, 2024
2 parents 29f211e + 8a50f87 commit 65cdc73
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 91 deletions.
78 changes: 78 additions & 0 deletions ExampleCodes/LinearSolvers/GMRES/Poisson/GMRES_Poisson.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef GMRES_POISSON_H_
#define GMRES_POISSON_H_

#include <AMReX_GMRES.H>
#include <AMReX_Geometry.H>
#include <AMReX_MultiFab.H>

/**
* \brief Solve Poisson's equation using amrex GMRES class
*
* Refer to comments in amrex/Src/LinearSolvers/AMReX_GMRES.H
* for details on function implementation requirements
*/
class GMRESPOISSON
{
public:
using RT = amrex::Real; // double or float
using GM = amrex::GMRES<amrex::MultiFab,GMRESPOISSON>;

GMRESPOISSON (const amrex::BoxArray& ba, const amrex::DistributionMapping& dm, const amrex::Geometry& geom);

/**
* \brief Solve the linear system
*
* \param a_sol unknowns, i.e., x in A x = b.
* \param a_rhs RHS, i.e., b in A x = b.
* \param a_tol_rel relative tolerance.
* \param a_tol_abs absolute tolerance.
*/
void solve (amrex::MultiFab& a_sol, amrex::MultiFab const& a_rhs, RT a_tol_rel, RT a_tol_abs);

//! Sets verbosity.
void setVerbose (int v) { m_gmres.setVerbose(v); }

//! Get the GMRES object.
GM& getGMRES () { return m_gmres; }

//! Make MultiFab without ghost cells
amrex::MultiFab makeVecRHS () const;

//! Make MultiFab with ghost cells and set ghost cells to zero
amrex::MultiFab makeVecLHS () const;

RT norm2 (amrex::MultiFab const& mf) const;

static void scale (amrex::MultiFab& mf, RT scale_factor);

RT dotProduct (amrex::MultiFab const& mf1, amrex::MultiFab const& mf2) const;

//! lhs = 0
static void setToZero (amrex::MultiFab& lhs);

//! lhs = rhs
static void assign (amrex::MultiFab& lhs, amrex::MultiFab const& rhs);

//! lhs += a*rhs
static void increment (amrex::MultiFab& lhs, amrex::MultiFab const& rhs, RT a);

//! lhs = a*rhs_a + b*rhs_b
static void linComb (amrex::MultiFab& lhs, RT a, amrex::MultiFab const& rhs_a, RT b, amrex::MultiFab const& rhs_b);

//! lhs = L(rhs)
void apply (amrex::MultiFab& lhs, amrex::MultiFab& rhs) const;

void precond (amrex::MultiFab& lhs, amrex::MultiFab const& rhs) const;

//! Control whether or not to use MLMG as preconditioner.
bool usePrecond (bool new_flag) { return std::exchange(m_use_precond, new_flag); }

private:
GM m_gmres;
amrex::BoxArray m_ba;
amrex::DistributionMapping m_dm;
amrex::Geometry m_geom;
bool m_use_precond;
};

#endif
Original file line number Diff line number Diff line change
@@ -1,99 +1,24 @@
#ifndef AMREX_GMRES_POISSON_H_
#define AMREX_GMRES_POISSON_H_
#include <AMReX_Config.H>

#include <AMReX_GMRES.H>
#include <utility>

namespace amrex {

/**
* \brief Solve Poisson's equation using amrex GMRES class
*
* Refer to comments in amrex/Src/LinearSolvers/AMReX_GMRES.H
* for details on function implementation requirements
*/
class GMRESPOISSON
{
public:
using RT = amrex::Real; // double or float
using GM = GMRES<MultiFab,GMRESPOISSON>;

explicit GMRESPOISSON (const BoxArray& ba, const DistributionMapping& dm, const Geometry& geom);

/**
* \brief Solve the linear system
*
* \param a_sol unknowns, i.e., x in A x = b.
* \param a_rhs RHS, i.e., b in A x = b.
* \param a_tol_rel relative tolerance.
* \param a_tol_abs absolute tolerance.
*/
void solve (MultiFab& a_sol, MultiFab const& a_rhs, RT a_tol_rel, RT a_tol_abs);

//! Sets verbosity.
void setVerbose (int v) { m_gmres.setVerbose(v); }

//! Get the GMRES object.
GM& getGMRES () { return m_gmres; }

//! Make MultiFab without ghost cells
MultiFab makeVecRHS () const;

//! Make MultiFab with ghost cells and set ghost cells to zero
MultiFab makeVecLHS () const;

RT norm2 (MultiFab const& mf) const;

static void scale (MultiFab& mf, RT scale_factor);

RT dotProduct (MultiFab const& mf1, MultiFab const& mf2) const;

//! lhs = 0
static void setToZero (MultiFab& lhs);
#include "GMRES_Poisson.H"

//! lhs = rhs
static void assign (MultiFab& lhs, MultiFab const& rhs);

//! lhs += a*rhs
static void increment (MultiFab& lhs, MultiFab const& rhs, RT a);

//! lhs = a*rhs_a + b*rhs_b
static void linComb (MultiFab& lhs, RT a, MultiFab const& rhs_a, RT b, MultiFab const& rhs_b);

//! lhs = L(rhs)
void apply (MultiFab& lhs, MultiFab& rhs) const;

void precond (MultiFab& lhs, MultiFab const& rhs) const;

//! Control whether or not to use MLMG as preconditioner.
bool usePrecond (bool new_flag) { return std::exchange(m_use_precond, new_flag); }

private:
GM m_gmres;
BoxArray m_ba;
DistributionMapping m_dm;
Geometry m_geom;
bool m_use_precond;
};
using namespace amrex;

GMRESPOISSON::GMRESPOISSON (const BoxArray& ba, const DistributionMapping& dm, const Geometry& geom)
: m_ba(ba), m_dm(dm), m_geom(geom)
{
m_gmres.define(*this);
}

auto GMRESPOISSON::makeVecRHS () const -> MultiFab
MultiFab GMRESPOISSON::makeVecRHS () const
{
return MultiFab(m_ba, m_dm, 1, 0);
}

auto GMRESPOISSON::makeVecLHS () const -> MultiFab
MultiFab GMRESPOISSON::makeVecLHS () const
{
return MultiFab(m_ba, m_dm, 1, 1);
}

auto GMRESPOISSON::norm2 (MultiFab const& mf) const -> RT
Real GMRESPOISSON::norm2 (MultiFab const& mf) const
{
return mf.norm2();
}
Expand All @@ -103,7 +28,7 @@ void GMRESPOISSON::scale (MultiFab& mf, RT scale_factor)
mf.mult(scale_factor);
}

auto GMRESPOISSON::dotProduct (MultiFab const& mf1, MultiFab const& mf2) const -> RT
Real GMRESPOISSON::dotProduct (MultiFab const& mf1, MultiFab const& mf2) const
{
return MultiFab::Dot(mf1,0,mf2,0,1,0);
}
Expand Down Expand Up @@ -209,7 +134,3 @@ void GMRESPOISSON::solve (MultiFab& a_sol, MultiFab const& a_rhs, RT a_tol_rel,
{
m_gmres.solve(a_sol, a_rhs, a_tol_rel, a_tol_abs);
}

}

#endif
4 changes: 2 additions & 2 deletions ExampleCodes/LinearSolvers/GMRES/Poisson/Make.package
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
CEXE_sources += main.cpp
CEXE_headers += AMReX_GMRES_Poisson.H
CEXE_sources += main.cpp GMRES_Poisson.cpp
CEXE_headers += GMRES_Poisson.H
7 changes: 3 additions & 4 deletions ExampleCodes/LinearSolvers/GMRES/Poisson/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
* A simplified usage of the AMReX GMRES class
*/

#include "GMRES_Poisson.H"

#include <AMReX.H>
#include <AMReX_PlotFileUtil.H>
#include <AMReX_ParmParse.H>
#include <AMReX_GMRES_Poisson.H>

int main (int argc, char* argv[])
{
Expand Down Expand Up @@ -112,7 +113,7 @@ int main (int argc, char* argv[])

WriteSingleLevelPlotfile("rhs", rhs, {"rhs"}, geom, 0., 0);

amrex::GMRESPOISSON gmres_poisson(ba,dm,geom);
GMRESPOISSON gmres_poisson(ba,dm,geom);

// initial guess
phi.setVal(0.);
Expand All @@ -127,5 +128,3 @@ int main (int argc, char* argv[])
amrex::Finalize();
return 0;
}


0 comments on commit 65cdc73

Please sign in to comment.