OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
55double MLPoissonSolver::getXRangeMin(unsigned short level) {
56 return itsAmrObject_mp->Geom(level).ProbLo(0);
57}
58
59
60double MLPoissonSolver::getXRangeMax(unsigned short level) {
61 return itsAmrObject_mp->Geom(level).ProbHi(0);
62}
63
64
65double MLPoissonSolver::getYRangeMin(unsigned short level) {
66 return itsAmrObject_mp->Geom(level).ProbLo(1);
67}
68
69
70double MLPoissonSolver::getYRangeMax(unsigned short level) {
71 return itsAmrObject_mp->Geom(level).ProbHi(1);
72}
73
74
75double MLPoissonSolver::getZRangeMin(unsigned short level) {
76 return itsAmrObject_mp->Geom(level).ProbLo(2);
77}
78
79
80double 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,
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