Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GMRES: Minor updates #145

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}


Loading