//
// Class MGPoissonSolver
// This class contains methods for solving Poisson's equation for the
// space charge portion of the calculation.
//
// A smoothed aggregation based AMG preconditioned iterative solver for space charge
// \see FFTPoissonSolver
// \warning This solver is in an EXPERIMENTAL STAGE. For reliable simulations use the FFTPoissonSolver
//
// Copyright (c) 2008, Yves Ineichen, ETH Zürich,
// 2013 - 2015, Tülin Kaman, Paul Scherrer Institut, Villigen PSI, Switzerland
// 2017 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// Implemented as part of the master thesis
// "A Parallel Multigrid Solver for Beam Dynamics"
// and the paper
// "A fast parallel Poisson solver on irregular domains applied to beam dynamics simulations"
// (https://doi.org/10.1016/j.jcp.2010.02.022)
//
// In 2020, the code was ported to the second generation Trilinos packages,
// i.e., Epetra --> Tpetra, ML --> MueLu. See also issue #507.
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see .
//
#ifndef MG_POISSON_SOLVER_H_
#define MG_POISSON_SOLVER_H_
//////////////////////////////////////////////////////////////
#include "PoissonSolver.h"
#include "IrregularDomain.h"
//////////////////////////////////////////////////////////////
#include "mpi.h"
#include
#include
#include
#include
#include
#include
#include
#include "Teuchos_ParameterList.hpp"
#include "Algorithms/PartBunch.h"
typedef UniformCartesian<3, double> Mesh_t;
typedef ParticleSpatialLayout::SingleParticlePos_t Vector_t;
typedef ParticleSpatialLayout< double, 3, Mesh_t > Layout_t;
typedef Cell Center_t;
typedef CenteredFieldLayout<3, Mesh_t, Center_t> FieldLayout_t;
typedef Field Field_t;
enum {
STD_PREC,
REUSE_PREC,
REUSE_HIERARCHY
};
class BoundaryGeometry;
class MGPoissonSolver : public PoissonSolver {
public:
typedef Tpetra::Vector<> TpetraVector_t;
typedef Tpetra::MultiVector<> TpetraMultiVector_t;
typedef Tpetra::Map<> TpetraMap_t;
typedef Tpetra::Vector<>::scalar_type TpetraScalar_t;
typedef Tpetra::Vector<>::global_ordinal_type TpetraGlobalOrdinal_t;
typedef Tpetra::Operator<> TpetraOperator_t;
typedef MueLu::TpetraOperator<> MueLuTpetraOperator_t;
typedef Tpetra::CrsMatrix<> TpetraCrsMatrix_t;
typedef Teuchos::MpiComm Comm_t;
typedef Teuchos::ParameterList ParameterList_t;
typedef Belos::SolverManager SolverManager_t;
typedef Belos::LinearProblem LinearProblem_t;
MGPoissonSolver(PartBunch *beam,Mesh_t *mesh,
FieldLayout_t *fl,
std::vector geometries,
std::string itsolver, std::string interpl,
double tol, int maxiters, std::string precmode);
~MGPoissonSolver();
/// given a charge-density field rho and a set of mesh spacings hr, compute
/// the scalar potential in 'open space'
/// \param rho (inout) scalar field of the potential
/// \param hr mesh spacings in each direction
void computePotential(Field_t &rho, Vector_t hr);
void computePotential(Field_t &rho, Vector_t hr, double zshift);
/// set a geometry
void setGeometry(std::vector geometries);
double getXRangeMin(unsigned short /*level*/) { return bp_m->getXRangeMin(); }
double getXRangeMax(unsigned short /*level*/) { return bp_m->getXRangeMax(); }
double getYRangeMin(unsigned short /*level*/) { return bp_m->getYRangeMin(); }
double getYRangeMax(unsigned short /*level*/) { return bp_m->getYRangeMax(); }
double getZRangeMin(unsigned short /*level*/) { return bp_m->getZRangeMin(); }
double getZRangeMax(unsigned short /*level*/) { return bp_m->getZRangeMax(); }
void test(PartBunchBase* /*bunch*/) { }
/// useful load balance information
void printLoadBalanceStats();
void extrapolateLHS();
void resizeMesh(Vector_t& origin, Vector_t& hr, const Vector_t& rmin,
const Vector_t& rmax, double dh)
{
bp_m->resizeMesh(origin, hr, rmin, rmax, dh);
}
Inform &print(Inform &os) const;
private:
bool isMatrixfilled_m;
// true if CG and GMRES; false if BiCGStab
bool useLeftPrec_m;
//TODO: we need to update this and maybe change attached
//solver!
/// holding the currently active geometry
BoundaryGeometry *currentGeometry;
/// container for multiple geometries
std::vector geometries_m;
int repartFreq_m;
/// flag specifying if we are verbose
bool verbose_m;
/// tolerance for the iterative solver
double tol_m;
/// maximal number of iterations for the iterative solver
int maxiters_m;
/// preconditioner mode
int precmode_m;
/// maximum number of blocks in Krylov space
int numBlocks_m;
/// number of vectors in recycle space
int recycleBlocks_m;
/// structure that holds boundary points
std::unique_ptr bp_m;
/// right hand side of our problem
Teuchos::RCP RHS;
/// left hand side of the linear system of equations we solve
Teuchos::RCP LHS;
/// matrix used in the linear system of equations
Teuchos::RCP A;
/// Map holding the processor distribution of data
Teuchos::RCP map_p;
/// communicator used by Trilinos
Teuchos::RCP comm_mp;
/// last N LHS's for extrapolating the new LHS as starting vector
unsigned int nLHS_m;
Teuchos::RCP P_mp;
std::deque< TpetraVector_t > OldLHS;
Teuchos::RCP problem_mp;
Teuchos::RCP solver_mp;
/// MueLu preconditioner object
Teuchos::RCP prec_mp;
/// parameter list for the MueLu solver
Teuchos::ParameterList MueLuList_m;
/// parameter list for the iterative solver (Belos)
Teuchos::ParameterList belosList;
/// PartBunch object
PartBunch *itsBunch_m;
// mesh and layout objects for rho_m
Mesh_t *mesh_m;
FieldLayout_t *layout_m;
// domains for the various fields
NDIndex<3> domain_m;
/// mesh spacings in each direction
Vector_t hr_m;
/// current number of mesh points in each direction
Vektor nr_m;
/// global number of mesh points in each direction
Vektor orig_nr_m;
// timers
IpplTimings::TimerRef FunctionTimer1_m;
IpplTimings::TimerRef FunctionTimer2_m;
IpplTimings::TimerRef FunctionTimer3_m;
IpplTimings::TimerRef FunctionTimer4_m;
IpplTimings::TimerRef FunctionTimer5_m;
IpplTimings::TimerRef FunctionTimer6_m;
IpplTimings::TimerRef FunctionTimer7_m;
IpplTimings::TimerRef FunctionTimer8_m;
void deletePtr();
/// recomputes the map
void computeMap(NDIndex<3> localId);
/// converts IPPL grid to a 3D map
/// \param localId local IPPL grid node indices
void IPPLToMap3D(NDIndex<3> localId);
/** returns a discretized stencil that has Neumann BC in z direction and
* Dirichlet BC on the surface of a specified geometry
* \param hr gridspacings in each direction
* \param RHS right hand side might be scaled
*/
void ComputeStencil(Vector_t hr, Teuchos::RCP RHS);
protected:
/// Setup the parameters for the Belos iterative solver.
void setupBelosList();
/// Setup the parameters for the SAAMG preconditioner.
void setupMueLuList();
};
inline Inform &operator<<(Inform &os, const MGPoissonSolver &fs) {
return fs.print(os);
}
#endif