OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
MLPoissonSolver.cpp
Go to the documentation of this file.
1 //
2 // Class MLPoissonSolver
3 // Interface to the C++ based AMR Poisson multigrid solver of AMReX.
4 //
5 // Copyright (c) 2016 - 2020, Matthias Frey, Paul Scherrer Institute, Villigen PSI, Switzerland
6 // All rights reserved.
7 //
8 // Implemented as part of the PhD thesis
9 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 #include "MLPoissonSolver.h"
22 
24 
25 #include "Amr/AmrDefs.h"
26 
27 #include <AMReX_MultiFabUtil.H>
28 #include <AMReX_MLPoisson.H>
29 #include <AMReX_MLMG.H>
30 
32  : AmrPoissonSolver<AmrBoxLib>(itsAmrObject_p),
33  reltol_m(1.0e-10),
34  abstol_m(0.0)
35 { }
36 
40  unsigned short baseLevel,
41  unsigned short finestLevel,
42  bool /*prevAsGuess*/)
43 {
44  for (int i = 0; i <= finestLevel; ++i) {
45  phi[i]->setVal(0.0, 1);
46  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
47  efield[i][j]->setVal(0.0, 1);
48  }
49  }
50 
51  this->mlmg_m(rho, phi, efield, baseLevel, finestLevel);
52 }
53 
54 
55 double MLPoissonSolver::getXRangeMin(unsigned short level) {
56  return itsAmrObject_mp->Geom(level).ProbLo(0);
57 }
58 
59 
60 double MLPoissonSolver::getXRangeMax(unsigned short level) {
61  return itsAmrObject_mp->Geom(level).ProbHi(0);
62 }
63 
64 
65 double MLPoissonSolver::getYRangeMin(unsigned short level) {
66  return itsAmrObject_mp->Geom(level).ProbLo(1);
67 }
68 
69 
70 double MLPoissonSolver::getYRangeMax(unsigned short level) {
71  return itsAmrObject_mp->Geom(level).ProbHi(1);
72 }
73 
74 
75 double MLPoissonSolver::getZRangeMin(unsigned short level) {
76  return itsAmrObject_mp->Geom(level).ProbLo(2);
77 }
78 
79 
80 double MLPoissonSolver::getZRangeMax(unsigned short level) {
81  return itsAmrObject_mp->Geom(level).ProbHi(2);
82 }
83 
84 
86  os << "* ************* A M R e X P o i s s o n S o l v e r ************************************ " << endl
87  << "* relative tolerance " << reltol_m << '\n'
88  << "* absolute tolerance " << abstol_m << '\n' << endl
89  << "* ******************************************************************** " << endl;
90  return os;
91 }
92 
93 
97  int baseLevel,
98  int finestLevel)
99 {
100  /* According to
101  * amrex/Tutorials/LinearSolvers/ABecLaplacian_C/MyTest.H
102  */
103  amrex::LPInfo info;
104  info.setAgglomeration(true);
105  info.setConsolidation(true);
106  info.setMaxCoarseningLevel(10);
107 
108  const GeomContainer_t& geom = itsAmrObject_mp->Geom();
109 
110  int nlevels = finestLevel - baseLevel + 1;
111  GeomContainer_t geom_p(nlevels);
112  AmrGridContainer_t ba(nlevels);
113  AmrProcMapContainer_t dm(nlevels);
114  AmrFieldContainer_pt phi_p(nlevels);
115  const_AmrFieldContainer_pt rho_p(nlevels);
116 
117  for (int ilev = 0; ilev < nlevels; ++ilev) {
118  geom_p[ilev] = geom[ilev + baseLevel];
119  ba[ilev] = rho[ilev + baseLevel]->boxArray();
120  dm[ilev] = rho[ilev + baseLevel]->DistributionMap();
121  rho_p[ilev] = rho[ilev + baseLevel].get();
122  phi_p[ilev] = phi[ilev + baseLevel].get();
123  }
124 
125  amrex::MLPoisson mlpoisson(geom_p, ba, dm, info);
126 
127  mlpoisson.setMaxOrder(3);
128 
129  mlpoisson.setDomainBC({AMREX_D_DECL(amrex::LinOpBCType::Dirichlet,
130  amrex::LinOpBCType::Dirichlet,
131  amrex::LinOpBCType::Dirichlet)},
132  {AMREX_D_DECL(amrex::LinOpBCType::Dirichlet,
133  amrex::LinOpBCType::Dirichlet,
134  amrex::LinOpBCType::Dirichlet)});
135 
136  for (int ilev = 0; ilev < nlevels; ++ilev) {
137  mlpoisson.setLevelBC(ilev, phi[ilev].get());
138  }
139 
140  amrex::MLMG mlmg(mlpoisson);
141  mlmg.setMaxIter(200);
142  mlmg.setMaxFmgIter(0);
143  mlmg.setVerbose(0);
144  mlmg.setCGVerbose(0);
145 
146 
147  mlmg.solve(phi_p,
148  rho_p,
149  reltol_m, abstol_m);
150 
151  amrex::Vector<std::array<AmrField_t*, AMREX_SPACEDIM> > grad(nlevels);
152 
153  for (int i = 0; i < nlevels; ++i) {
154  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
155  grad[i][j] = efield[i][j].get();
156  }
157  }
158 
159  mlmg.getGradSolution(grad);
160 
161  for (int i = 0; i < nlevels; ++i) {
162  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
163  efield[i][j]->mult(-1.0, 0, 1, 1);
164  }
165  }
166 }
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
bool info
Info flag.
Definition: Options.cpp:28
double getYRangeMin(unsigned short level=0)
AmrBoxLib::AmrScalarFieldContainer_t AmrScalarFieldContainer_t
double getXRangeMax(unsigned short level=0)
double getZRangeMin(unsigned short level=0)
amrex::Vector< AmrBoxLib::AmrField_t * > AmrFieldContainer_pt
double abstol_m
Absolute tolerance for solver.
AmrBoxLib::AmrGridContainer_t AmrGridContainer_t
AmrBoxLib::AmrGeomContainer_t GeomContainer_t
MLPoissonSolver(AmrBoxLib *itsAmrObject_p)
Inform & print(Inform &os) const
void solve(AmrScalarFieldContainer_t &rho, AmrScalarFieldContainer_t &phi, AmrVectorFieldContainer_t &efield, unsigned short baseLevel, unsigned short finestLevel, bool prevAsGuess=true)
amrex::Vector< const AmrBoxLib::AmrField_t * > const_AmrFieldContainer_pt
void mlmg_m(AmrScalarFieldContainer_t &rho, AmrScalarFieldContainer_t &phi, AmrVectorFieldContainer_t &efield, int baseLevel, int finestLevel)
AmrBoxLib::AmrProcMapContainer_t AmrProcMapContainer_t
AmrBoxLib::AmrVectorFieldContainer_t AmrVectorFieldContainer_t
double getZRangeMax(unsigned short level=0)
double getXRangeMin(unsigned short level=0)
double getYRangeMax(unsigned short level=0)
double reltol_m
Relative tolearance for solver.
Definition: Inform.h:42