OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FieldSolver.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: FieldSolver.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.3.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: FieldSolver
10 // The class for the OPAL FIELDSOLVER command.
11 //
12 // ------------------------------------------------------------------------
13 //
14 // $Date: 2003/08/11 22:09:00 $
15 // $Author: ADA $
16 //
17 // ------------------------------------------------------------------------
18 
19 #include "Structure/FieldSolver.h"
23 #ifdef HAVE_SAAMG_SOLVER
25 #endif
28 #include "Attributes/Attributes.h"
29 #include "Expressions/SAutomatic.h"
30 #include "Expressions/SRefExpr.h"
31 #include "Physics/Physics.h"
33 #include "Utilities/Util.h"
34 #include "BoundaryGeometry.h"
37 
38 #ifdef ENABLE_AMR
39  #include "Amr/AmrBoxLib.h"
40 #ifdef AMREX_ENABLE_FBASELIB
42 #endif
44  #include "Amr/AmrDefs.h"
45  #include "Algorithms/AmrPartBunch.h"
46 
47  #include <algorithm>
48  #include <cctype>
49  #include <functional>
50 #endif
51 
52 #ifdef HAVE_AMR_MG_SOLVER
54 #endif
55 
56 using namespace Expressions;
57 using namespace Physics;
58 
59 //TODO: o add a FIELD for DISCRETIZATION, MAXITERS, TOL...
60 
61 // Class FieldSolver
62 // ------------------------------------------------------------------------
63 
64 // The attributes of class FieldSolver.
65 namespace {
66  namespace deprecated {
67  enum {
68  BCFFTT,
69  SIZE
70  };
71  }
72  enum {
73  FSTYPE = deprecated::SIZE, // The field solver name
74  // FOR FFT BASED SOLVER
75  MX, // mesh sixe in x
76  MY, // mesh sixe in y
77  MT, // mesh sixe in z
78  PARFFTX, // parallelized grind in x
79  PARFFTY, // parallelized grind in y
80  PARFFTT, // parallelized grind in z
81  BCFFTX, // boundary condition in x [FFT + AMR_MG only]
82  BCFFTY, // boundary condition in y [FFT + AMR_MG only]
83  BCFFTZ, // boundary condition in z [FFT + AMR_MG only]
84  GREENSF, // holds greensfunction to be used [FFT only]
85  BBOXINCR, // how much the boundingbox is increased
86  GEOMETRY, // geometry of boundary [SAAMG only]
87  ITSOLVER, // iterative solver [SAAMG + AMR_MG]
88  INTERPL, // interpolation used for boundary points [SAAMG only]
89  TOL, // tolerance of the SAAMG preconditioned solver [SAAMG only]
90  MAXITERS, // max number of iterations [SAAMG only]
91  PRECMODE, // preconditioner mode [SAAMG only]
92  RC, // cutoff radius for PP interactions
93  ALPHA, // Green’s function splitting parameter
94  EPSILON, // regularization for PP interaction
95 #ifdef ENABLE_AMR
96  AMR_MAXLEVEL, // AMR, maximum refinement level
97  AMR_REFX, // AMR, refinement ratio in x
98  AMR_REFY, // AMR, refinement ratio in y
99  AMR_REFZ, // AMR, refinement ration in z
100  AMR_MAXGRIDX, // AMR, maximum grid size in x (default: 16)
101  AMR_MAXGRIDY, // AMR, maximum grid size in y (default: 16)
102  AMR_MAXGRIDZ, // AMR, maximum grid size in z (default: 16)
103  AMR_BFX, // AMR, blocking factor in x (maxgrid needs to be a multiple, default: 8)
104  AMR_BFY, // AMR, blocking factor in y (maxgrid needs to be a multiple, default: 8)
105  AMR_BFZ, // AMR, blocking factor in z (maxgrid needs to be a multiple, default: 8)
106  AMR_TAGGING,
107  AMR_DENSITY,
108  AMR_MAX_NUM_PART,
109  AMR_MIN_NUM_PART,
110  AMR_SCALING,
111  AMR_DOMAIN_RATIO,
112 #endif
113 #ifdef HAVE_AMR_MG_SOLVER
114  // AMR_MG = Adaptive-Mesh-Refinement Multi-Grid
115  AMR_MG_SMOOTHER, // AMR, smoother for level solution
116  AMR_MG_NSWEEPS, // AMR, number of smoothing sweeps
117  AMR_MG_PREC, // AMR, preconditioner for bottom solver
118  AMR_MG_INTERP, // AMR, interpolater for solution from level l to l+1
119  AMR_MG_NORM, // AMR, norm convergence criteria
120  AMR_MG_VERBOSE, // AMR, enable solver info writing (SDDS file)
121  AMR_MG_REBALANCE, // AMR, rebalance smoothed aggregation (SA) preconditioner
122  AMR_MG_REUSE, // AMR, reuse type of SA (none, RP, RAP, S or full)
123 #endif
124  // FOR XXX BASED SOLVER
125  SIZE
126  };
127 }
128 
129 
131  Definition(SIZE, "FIELDSOLVER",
132  "The \"FIELDSOLVER\" statement defines data for a the field solver ") {
133 
134  itsAttr[FSTYPE] = Attributes::makeString("FSTYPE",
135  "Name of the attached field solver: FFT, FFTPERIODIC, SAAMG, AMR, and NONE ");
136 
137  itsAttr[MX] = Attributes::makeReal("MX", "Meshsize in x");
138  itsAttr[MY] = Attributes::makeReal("MY", "Meshsize in y");
139  itsAttr[MT] = Attributes::makeReal("MT", "Meshsize in z(t)");
140 
141  itsAttr[PARFFTX] = Attributes::makeBool("PARFFTX",
142  "True, dimension 0 i.e x is parallelized",
143  false);
144 
145  itsAttr[PARFFTY] = Attributes::makeBool("PARFFTY",
146  "True, dimension 1 i.e y is parallelized",
147  false);
148 
149  itsAttr[PARFFTT] = Attributes::makeBool("PARFFTT",
150  "True, dimension 2 i.e z(t) is parallelized",
151  true);
152 
153  //FFT ONLY:
154  itsAttr[BCFFTX] = Attributes::makeString("BCFFTX",
155  "Boundary conditions in x: open, dirichlet (box), periodic", "OPEN");
156 
157  itsAttr[BCFFTY] = Attributes::makeString("BCFFTY",
158  "Boundary conditions in y: open, dirichlet (box), periodic", "OPEN");
159 
160  itsAttr[BCFFTZ] = Attributes::makeString("BCFFTZ",
161  "Boundary conditions in z(t): open, periodic", "OPEN");
162 
163  itsAttr[deprecated::BCFFTT] = Attributes::makeString("BCFFTT",
164  "Boundary conditions in z(t): open, periodic", "OPEN");
165 
166  itsAttr[GREENSF] = Attributes::makeString("GREENSF",
167  "Which Greensfunction to be used [STANDARD | INTEGRATED]",
168  "INTEGRATED");
169 
170  itsAttr[BBOXINCR] = Attributes::makeReal("BBOXINCR",
171  "Increase of bounding box in % ",
172  2.0);
173 
174  // P3M only:
175  itsAttr[RC] = Attributes::makeReal("RC",
176  "cutoff radius for PP interactions",
177  0.0);
178 
179  itsAttr[ALPHA] = Attributes::makeReal("ALPHA",
180  "Green’s function splitting parameter",
181  0.0);
182 
183  itsAttr[EPSILON] = Attributes::makeReal("EPSILON",
184  "regularization for PP interaction",
185  0.0);
186 
187  //SAAMG and in case of FFT with dirichlet BC in x and y
188  itsAttr[GEOMETRY] = Attributes::makeString("GEOMETRY",
189  "GEOMETRY to be used as domain boundary",
190  "");
191 
192  itsAttr[ITSOLVER] = Attributes::makeString("ITSOLVER",
193  "Type of iterative solver [CG | BiCGSTAB | GMRES]",
194  "CG");
195 
196  itsAttr[INTERPL] = Attributes::makeString("INTERPL",
197  "interpolation used for boundary points [CONSTANT | LINEAR | QUADRATIC]",
198  "LINEAR");
199 
201  "Tolerance for iterative solver",
202  1e-8);
203 
204  itsAttr[MAXITERS] = Attributes::makeReal("MAXITERS",
205  "Maximum number of iterations of iterative solver",
206  100);
207 
208  itsAttr[PRECMODE] = Attributes::makeString("PRECMODE",
209  "Preconditioner Mode [STD | HIERARCHY | REUSE]",
210  "HIERARCHY");
211 
212  // AMR
213 #ifdef ENABLE_AMR
214  itsAttr[AMR_MAXLEVEL] = Attributes::makeReal("AMR_MAXLEVEL",
215  "Maximum number of levels in AMR",
216  0);
217 
218  itsAttr[AMR_REFX] = Attributes::makeReal("AMR_REFX",
219  "Refinement ration in x-direction in AMR",
220  2);
221 
222  itsAttr[AMR_REFY] = Attributes::makeReal("AMR_REFY",
223  "Refinement ration in y-direction in AMR",
224  2);
225 
226  itsAttr[AMR_REFZ] = Attributes::makeReal("AMR_REFZ",
227  "Refinement ration in z-direction in AMR",
228  2);
229 
230  itsAttr[AMR_MAXGRIDX] = Attributes::makeReal("AMR_MAXGRIDX",
231  "Maximum grid size in x for AMR",
232  16);
233 
234  itsAttr[AMR_MAXGRIDY] = Attributes::makeReal("AMR_MAXGRIDY",
235  "Maximum grid size in y for AMR",
236  16);
237 
238  itsAttr[AMR_MAXGRIDZ] = Attributes::makeReal("AMR_MAXGRIDZ",
239  "Maximum grid size in z for AMR",
240  16);
241 
242  itsAttr[AMR_BFX] = Attributes::makeReal("AMR_BFX",
243  "Blocking factor in x for AMR (AMR_MAXGRIDX needs to be a multiple",
244  8);
245 
246  itsAttr[AMR_BFY] = Attributes::makeReal("AMR_BFY",
247  "Blocking factor in y for AMR (AMR_MAXGRIDY needs to be a multiple",
248  8);
249 
250  itsAttr[AMR_BFZ] = Attributes::makeReal("AMR_BFZ",
251  "Blocking factor in y for AMR (AMR_MAXGRIDZ needs to be a multiple",
252  8);
253 
254  itsAttr[AMR_TAGGING] = Attributes::makeString("AMR_TAGGING",
255  "Refinement criteria [CHARGE_DENSITY | POTENTIAL | EFIELD]",
256  "CHARGE_DENSITY");
257 
258  itsAttr[AMR_DENSITY] = Attributes::makeReal("AMR_DENSITY",
259  "Tagging value for charge density refinement [C / cell volume]",
260  1.0e-14);
261 
262  itsAttr[AMR_MAX_NUM_PART] = Attributes::makeReal("AMR_MAX_NUM_PART",
263  "Tagging value for max. #particles",
264  1);
265 
266  itsAttr[AMR_MIN_NUM_PART] = Attributes::makeReal("AMR_MIN_NUM_PART",
267  "Tagging value for min. #particles",
268  1);
269 
270  itsAttr[AMR_SCALING] = Attributes::makeReal("AMR_SCALING",
271  "Scaling value for maximum value tagging "
272  "(only POTENTIAL / CHARGE_DENSITY / "
273  "MOMENTA", 0.75);
274 
275  itsAttr[AMR_DOMAIN_RATIO] = Attributes::makeRealArray("AMR_DOMAIN_RATIO",
276  "Box ratio of AMR computation domain. Default: [-1, 1]^3");
277 
278  // default
279  Attributes::setRealArray(itsAttr[AMR_DOMAIN_RATIO], {1.0, 1.0, 1.0});
280 #endif
281 
282 #ifdef HAVE_AMR_MG_SOLVER
283  itsAttr[AMR_MG_SMOOTHER] = Attributes::makeString("AMR_MG_SMOOTHER",
284  "Smoothing of level solution", "GS");
285 
286  itsAttr[AMR_MG_NSWEEPS] = Attributes::makeReal("AMR_MG_NSWEEPS",
287  "Number of relaxation steps",
288  8);
289 
290  itsAttr[AMR_MG_PREC] = Attributes::makeString("AMR_MG_PREC",
291  "Preconditioner of bottom solver",
292  "NONE");
293 
294  itsAttr[AMR_MG_INTERP] = Attributes::makeString("AMR_MG_INTERP",
295  "Interpolater between levels",
296  "PC");
297 
298  itsAttr[AMR_MG_NORM] = Attributes::makeString("AMR_MG_NORM",
299  "Norm for convergence criteria",
300  "LINF");
301 
302  itsAttr[AMR_MG_VERBOSE] = Attributes::makeBool("AMR_MG_VERBOSE",
303  "Write solver info in SDDS format (*.solver)",
304  false);
305 
306  itsAttr[AMR_MG_REBALANCE] = Attributes::makeBool("AMR_MG_REBALANCE",
307  "Rebalancing of Smoothed Aggregation "
308  "Preconditioner",
309  false);
310 
311  itsAttr[AMR_MG_REUSE] = Attributes::makeString("AMR_MG_REUSE",
312  "Reuse type of Smoothed Aggregation",
313  "RAP");
314 #endif
315 
316  mesh_m = 0;
317  FL_m = 0;
318  PL_m.reset(nullptr);
319 
320  solver_m = 0;
321 
323 }
324 
325 
326 FieldSolver::FieldSolver(const std::string &name, FieldSolver *parent):
327  Definition(name, parent)
328 {
329  mesh_m = 0;
330  FL_m = 0;
331  PL_m.reset(nullptr);
332  solver_m = 0;
333 }
334 
335 
337  if (mesh_m) {
338  delete mesh_m;
339  mesh_m = 0;
340  }
341  if (FL_m) {
342  delete FL_m;
343  FL_m = 0;
344  }
345  if (solver_m) {
346  delete solver_m;
347  solver_m = 0;
348  }
349 }
350 
351 FieldSolver *FieldSolver::clone(const std::string &name) {
352  return new FieldSolver(name, this);
353 }
354 
356  update();
357 }
358 
359 FieldSolver *FieldSolver::find(const std::string &name) {
360  FieldSolver *fs = dynamic_cast<FieldSolver *>(OpalData::getInstance()->find(name));
361 
362  if(fs == 0) {
363  throw OpalException("FieldSolver::find()", "FieldSolver \"" + name + "\" not found.");
364  }
365  return fs;
366 }
367 
368 std::string FieldSolver::getType() {
370 }
371 
372 double FieldSolver::getMX() const {
373  return Attributes::getReal(itsAttr[MX]);
374 }
375 
376 double FieldSolver::getMY() const {
377  return Attributes::getReal(itsAttr[MY]);
378 }
379 
380 double FieldSolver::getMT() const {
381  return Attributes::getReal(itsAttr[MT]);
382 }
383 
384 void FieldSolver::setMX(double value) {
385  Attributes::setReal(itsAttr[MX], value);
386 }
387 
388 void FieldSolver::setMY(double value) {
389  Attributes::setReal(itsAttr[MY], value);
390 }
391 
392 void FieldSolver::setMT(double value) {
393  Attributes::setReal(itsAttr[MT], value);
394 }
395 
397 
398 }
399 
401 
402  e_dim_tag decomp[3] = {SERIAL, SERIAL, SERIAL};
403 
404  NDIndex<3> domain;
405  domain[0] = Index((int)getMX() + 1);
406  domain[1] = Index((int)getMY() + 1);
407  domain[2] = Index((int)getMT() + 1);
408 
409  if(Attributes::getBool(itsAttr[PARFFTX]))
410  decomp[0] = PARALLEL;
411  if(Attributes::getBool(itsAttr[PARFFTY]))
412  decomp[1] = PARALLEL;
413  if(Attributes::getBool(itsAttr[PARFFTT]))
414  decomp[2] = PARALLEL;
415 
416  if(Util::toUpper(Attributes::getString(itsAttr[FSTYPE])) == "FFTPERIODIC") {
417  decomp[0] = decomp[1] = SERIAL;
418  decomp[2] = PARALLEL;
419  }
420  // create prototype mesh and layout objects for this problem domain
421 
422 #ifdef ENABLE_AMR
423  if ( !isAmrSolverType() ) {
424 #endif
425  mesh_m = new Mesh_t(domain);
426  FL_m = new FieldLayout_t(*mesh_m, decomp);
427  PL_m.reset(new Layout_t(*FL_m, *mesh_m));
428  // OpalData::getInstance()->setMesh(mesh_m);
429  // OpalData::getInstance()->setFieldLayout(FL_m);
430  // OpalData::getInstance()->setLayout(PL_m);
431 #ifdef ENABLE_AMR
432  }
433 #endif
434 }
435 
437  if (itsAttr[deprecated::BCFFTT])
438  return (Util::toUpper(Attributes::getString(itsAttr[deprecated::BCFFTT])) == "PERIODIC");
439 
440  return (Util::toUpper(Attributes::getString(itsAttr[BCFFTZ])) == "PERIODIC");
441 }
442 
443 #ifdef ENABLE_AMR
444 inline bool FieldSolver::isAmrSolverType() const {
445  return Options::amr;
446 }
447 #endif
448 
450  itsBunch_m = b;
452  std::string greens = Util::toUpper(Attributes::getString(itsAttr[GREENSF]));
453  std::string bcx = Util::toUpper(Attributes::getString(itsAttr[BCFFTX]));
454  std::string bcy = Util::toUpper(Attributes::getString(itsAttr[BCFFTY]));
455  std::string bcz = Util::toUpper(Attributes::getString(itsAttr[deprecated::BCFFTT]));
456  if (bcz == "") {
458  }
459 
460 #ifdef ENABLE_AMR
461  if ( isAmrSolverType() ) {
462  Inform m("FieldSolver::initAmrSolver");
463  fsType_m = "AMR";
464 
465  initAmrObject_m();
466 
467  initAmrSolver_m();
468 
469  } else if(fsType_m == "FFT") {
470 #else
471  if(fsType_m == "FFT") {
472 #endif
473  bool sinTrafo = ((bcx == "DIRICHLET") && (bcy == "DIRICHLET") && (bcz == "DIRICHLET"));
474  if(sinTrafo) {
475  std::cout << "FFTBOX ACTIVE" << std::endl;
476  //we go over all geometries and add the Geometry Elements to the geometry list
477  std::string geoms = Util::toUpper(Attributes::getString(itsAttr[GEOMETRY]));
478  std::string tmp = "";
479  //split and add all to list
480  std::vector<BoundaryGeometry *> geometries;
481  for(unsigned int i = 0; i <= geoms.length(); i++) {
482  if(i == geoms.length() || geoms[i] == ',') {
484  if(geom != 0)
485  geometries.push_back(geom);
486  tmp.clear();
487  } else
488  tmp += geoms[i];
489  }
490  BoundaryGeometry *ttmp = geometries[0];
491  solver_m = new FFTBoxPoissonSolver(mesh_m, FL_m, greens, ttmp->getA());
493  fsType_m = "FFTBOX";
494  } else {
495  solver_m = new FFTPoissonSolver(mesh_m, FL_m, greens, bcz);
497  }
498  } else if (fsType_m == "P3M") {
500  FL_m,
503  Attributes::getReal(itsAttr[EPSILON]));
504 
505  PL_m->setAllCacheDimensions(Attributes::getReal(itsAttr[RC]));
506  PL_m->enableCaching();
507 
508  } else if(fsType_m == "SAAMG") {
509 #ifdef HAVE_SAAMG_SOLVER
510  //we go over all geometries and add the Geometry Elements to the geometry list
511  std::string geoms = Util::toUpper(Attributes::getString(itsAttr[GEOMETRY]));
512  std::string tmp = "";
513  //split and add all to list
514  std::vector<BoundaryGeometry *> geometries;
515  for(unsigned int i = 0; i <= geoms.length(); i++) {
516  if(i == geoms.length() || geoms[i] == ',') {
518  if(geom != 0) {
519  geometries.push_back(geom);
520  }
521  tmp.clear();
522  } else
523  tmp += geoms[i];
524  }
525  solver_m = new MGPoissonSolver(dynamic_cast<PartBunch*>(itsBunch_m), mesh_m, FL_m,
526  geometries,
530  Attributes::getReal(itsAttr[MAXITERS]),
533 #else
534  throw OpalException("FieldSolver::initSolver",
535  "SAAMG Solver not enabled! Please build OPAL with -DENABLE_SAAMG_SOLVER=1");
536 #endif
537  } else {
538  solver_m = 0;
539  INFOMSG("no solver attached" << endl);
540  }
541 }
542 
544  return (solver_m != 0);
545 }
546 
548  std::string fsType = Util::toUpper(Attributes::getString(itsAttr[FSTYPE]));
549 
550  os << "* ************* F I E L D S O L V E R ********************************************** " << endl;
551  os << "* FIELDSOLVER " << getOpalName() << '\n'
552  << "* TYPE " << fsType << '\n'
553  << "* N-PROCESSORS " << Ippl::getNodes() << '\n'
554  << "* MX " << Attributes::getReal(itsAttr[MX]) << '\n'
555  << "* MY " << Attributes::getReal(itsAttr[MY]) << '\n'
556  << "* MT " << Attributes::getReal(itsAttr[MT]) << '\n'
557  << "* BBOXINCR " << Attributes::getReal(itsAttr[BBOXINCR]) << endl;
558 
559  if(fsType == "P3M")
560  os << "* RC " << Attributes::getReal(itsAttr[RC]) << '\n'
561  << "* ALPHA " << Attributes::getReal(itsAttr[ALPHA]) << '\n'
562  << "* EPSILON " << Attributes::getReal(itsAttr[EPSILON]) << endl;
563 
564 
565  if(fsType == "FFT") {
566  os << "* GRRENSF " << Util::toUpper(Attributes::getString(itsAttr[GREENSF])) << endl;
567  } else if (fsType == "SAAMG") {
568  os << "* GEOMETRY " << Attributes::getString(itsAttr[GEOMETRY]) << '\n'
569  << "* ITSOLVER " << Util::toUpper(Attributes::getString(itsAttr[ITSOLVER])) << '\n'
570  << "* INTERPL " << Util::toUpper(Attributes::getString(itsAttr[INTERPL])) << '\n'
571  << "* TOL " << Attributes::getReal(itsAttr[TOL]) << '\n'
572  << "* MAXITERS " << Attributes::getReal(itsAttr[MAXITERS]) << '\n'
573  << "* PRECMODE " << Util::toUpper(Attributes::getString(itsAttr[PRECMODE])) << endl;
574  }
575 #ifdef ENABLE_AMR
576  else if (fsType == "AMR" || Options::amr) {
577  os << "* AMR_MAXLEVEL " << Attributes::getReal(itsAttr[AMR_MAXLEVEL]) << '\n'
578  << "* AMR_REFX " << Attributes::getReal(itsAttr[AMR_REFX]) << '\n'
579  << "* AMR_REFY " << Attributes::getReal(itsAttr[AMR_REFY]) << '\n'
580  << "* AMR_REFZ " << Attributes::getReal(itsAttr[AMR_REFZ]) << '\n'
581  << "* AMR_MAXGRIDX " << Attributes::getReal(itsAttr[AMR_MAXGRIDX]) << '\n'
582  << "* AMR_MAXGRIDY " << Attributes::getReal(itsAttr[AMR_MAXGRIDY]) << '\n'
583  << "* AMR_MAXGRIDZ " << Attributes::getReal(itsAttr[AMR_MAXGRIDZ]) << '\n'
584  << "* AMR_BFX " << Attributes::getReal(itsAttr[AMR_BFX]) << '\n'
585  << "* AMR_BFY " << Attributes::getReal(itsAttr[AMR_BFY]) << '\n'
586  << "* AMR_BFZ " << Attributes::getReal(itsAttr[AMR_BFZ]) << '\n'
587  << "* AMR_TAGGING " << this->getTagging_m() <<'\n'
588  << "* AMR_DENSITY " << Attributes::getReal(itsAttr[AMR_DENSITY]) << '\n'
589  << "* AMR_MAX_NUM_PART " << Attributes::getReal(itsAttr[AMR_MAX_NUM_PART]) << '\n'
590  << "* AMR_MIN_NUM_PART " << Attributes::getReal(itsAttr[AMR_MIN_NUM_PART]) << '\n'
591  << "* AMR_DENSITY " << Attributes::getReal(itsAttr[AMR_DENSITY]) << '\n'
592  << "* AMR_SCALING " << Attributes::getReal(itsAttr[AMR_SCALING]) << endl;
593  auto length = Attributes::getRealArray(itsAttr[AMR_DOMAIN_RATIO]);
594  os << "* AMR_DOMAIN_RATIO ( ";
595  for (auto& l : length) {
596  os << l << " ";
597  }
598  os << ")" << endl;
599  }
600 #endif
601 
602 #ifdef HAVE_AMR_MG_SOLVER
603  if (fsType == "AMR_MG") {
604  os << "* ITSOLVER (AMR_MG) "
605  << Util::toUpper(Attributes::getString(itsAttr[ITSOLVER])) << '\n'
606  << "* AMR_MG_PREC "
607  << Util::toUpper(Attributes::getString(itsAttr[AMR_MG_PREC])) << '\n'
608  << "* AMR_MG_REBALANCE "
609  << Attributes::getBool(itsAttr[AMR_MG_REBALANCE]) << '\n'
610  << "* AMR_MG_REUSE "
611  << Util::toUpper(Attributes::getString(itsAttr[AMR_MG_REUSE])) << '\n'
612  << "* AMR_MG_SMOOTHER "
613  << Util::toUpper(Attributes::getString(itsAttr[AMR_MG_SMOOTHER])) << '\n'
614  << "* AMR_MG_NSWEEPS "
615  << Attributes::getReal(itsAttr[AMR_MG_NSWEEPS]) << '\n'
616  << "* AMR_MG_INTERP "
617  << Util::toUpper(Attributes::getString(itsAttr[AMR_MG_INTERP])) << '\n'
618  << "* AMR_MG_NORM "
619  << Util::toUpper(Attributes::getString(itsAttr[AMR_MG_NORM])) << '\n'
620  << "* AMR_MG_VERBOSE "
621  << Attributes::getBool(itsAttr[AMR_MG_VERBOSE]) << '\n'
622  << "* BCFFTX "
623  << Util::toUpper(Attributes::getString(itsAttr[BCFFTX])) << '\n'
624  << "* BCFFTY "
625  << Util::toUpper(Attributes::getString(itsAttr[BCFFTY])) << '\n';
626  if (itsAttr[deprecated::BCFFTT]) {
627  os << "* BCFFTT (deprec.) "
628  << Util::toUpper(Attributes::getString(itsAttr[deprecated::BCFFTT])) << endl;
629  } else {
630  os << "* BCFFTZ "
632  }
633  }
634 #endif
635 
636  if(Attributes::getBool(itsAttr[PARFFTX]))
637  os << "* XDIM parallel " << endl;
638  else
639  os << "* XDIM serial " << endl;
640 
641  if(Attributes::getBool(itsAttr[PARFFTY]))
642  os << "* YDIM parallel " << endl;
643  else
644  os << "* YDIM serial " << endl;
645 
646  if(Attributes::getBool(itsAttr[PARFFTT]))
647  os << "* Z(T)DIM parallel " << endl;
648  else
649  os << "* Z(T)DIM serial " << endl;
650 
651 #ifdef ENABLE_AMR
652  if ( !isAmrSolverType() ) {
653 #endif
654  INFOMSG(level3 << *mesh_m << endl);
655  INFOMSG(level3 << *PL_m << endl);
656 #ifdef ENABLE_AMR
657  }
658 #endif
659 
660  if(solver_m)
661  os << *solver_m << endl;
662  os << "* ********************************************************************************** " << endl;
663  return os;
664 }
665 
666 #ifdef ENABLE_AMR
667 std::string FieldSolver::getTagging_m() const {
668  std::string tagging = Attributes::getString(itsAttr[AMR_TAGGING]);
669 
670  std::function<bool(const std::string&)> all_digits = [](const std::string& s) {
671  // 15. Feb. 2019
672  // https://stackoverflow.com/questions/19678572/how-to-validate-that-there-are-only-digits-in-a-string
673  return std::all_of(s.begin(), s.end(),
674  [](char c) { return std::isdigit(c); });
675  };
676 
677  if ( all_digits(tagging) )
678  tagging = AmrObject::enum2string(std::stoi(tagging));
679  return tagging;
680 }
681 
682 
684 
685  auto domain = Attributes::getRealArray(itsAttr[AMR_DOMAIN_RATIO]);
686  dynamic_cast<AmrPartBunch*>(itsBunch_m)->setAmrDomainRatio(
687  Attributes::getRealArray(itsAttr[AMR_DOMAIN_RATIO])
688  );
690 
691  // setup initial info for creating the object
693  info.grid[0] = (int)this->getMX();
694  info.grid[1] = (int)this->getMY();
695  info.grid[2] = (int)this->getMT();
696  info.maxgrid[0] = Attributes::getReal(itsAttr[AMR_MAXGRIDX]);
697  info.maxgrid[1] = Attributes::getReal(itsAttr[AMR_MAXGRIDY]);
698  info.maxgrid[2] = Attributes::getReal(itsAttr[AMR_MAXGRIDZ]);
699  info.bf[0] = Attributes::getReal(itsAttr[AMR_BFX]);
700  info.bf[1] = Attributes::getReal(itsAttr[AMR_BFY]);
701  info.bf[2] = Attributes::getReal(itsAttr[AMR_BFZ]);
702  info.maxlevel = Attributes::getReal(itsAttr[AMR_MAXLEVEL]);
703  info.refratio[0] = Attributes::getReal(itsAttr[AMR_REFX]);
704  info.refratio[1] = Attributes::getReal(itsAttr[AMR_REFY]);
705  info.refratio[2] = Attributes::getReal(itsAttr[AMR_REFZ]);
706 
707  itsAmrObject_mp = AmrBoxLib::create(info, dynamic_cast<AmrPartBunch*>(itsBunch_m));
708 
709  itsAmrObject_mp->setTagging( this->getTagging_m() );
710 
711  itsAmrObject_mp->setScalingFactor( Attributes::getReal(itsAttr[AMR_SCALING]) );
712 
713  itsAmrObject_mp->setChargeDensity( Attributes::getReal(itsAttr[AMR_DENSITY]) );
714 
715  itsAmrObject_mp->setMaxNumParticles(
716  Attributes::getReal(itsAttr[AMR_MAX_NUM_PART])
717  );
718 
719  itsAmrObject_mp->setMinNumParticles(
720  Attributes::getReal(itsAttr[AMR_MIN_NUM_PART])
721  );
722 }
723 
724 
726  std::string fsType = Util::toUpper(Attributes::getString(itsAttr[FSTYPE]));
727 
728  if ( fsType == "ML" ) {
729  if ( dynamic_cast<AmrBoxLib*>( itsAmrObject_mp.get() ) == 0 )
730  throw OpalException("FieldSolver::initAmrSolver_m()",
731  "ML solver requires AMReX.");
732  solver_m = new MLPoissonSolver(static_cast<AmrBoxLib*>(itsAmrObject_mp.get()));
733 #ifdef AMREX_ENABLE_FBASELIB
734  } else if (fsType == "FMG") {
735 
736  if ( dynamic_cast<AmrBoxLib*>( itsAmrObject_mp.get() ) == 0 )
737  throw OpalException("FieldSolver::initAmrSolver_m()",
738  "FMultiGrid solver requires AMReX.");
739 
740  solver_m = new FMGPoissonSolver(static_cast<AmrBoxLib*>(itsAmrObject_mp.get()));
741 #endif
742  } else if (fsType == "HYPRE") {
743  throw OpalException("FieldSolver::initAmrSolver_m()",
744  "HYPRE solver not yet implemented.");
745  } else if (fsType == "HPGMG") {
746  throw OpalException("FieldSolver::initAmrSolver_m()",
747  "HPGMG solver not yet implemented.");
748  } else if (fsType == "AMR_MG") {
749 #ifdef HAVE_AMR_MG_SOLVER
750  if ( dynamic_cast<AmrBoxLib*>( itsAmrObject_mp.get() ) == 0 )
751  throw OpalException("FieldSolver::initAmrSolver_m()",
752  "FMultiGrid solver requires AMReX.");
753 
754  std::string bcz = Attributes::getString(itsAttr[deprecated::BCFFTT]);
755  if (bcz == "") {
756  bcz = Attributes::getString(itsAttr[BCFFTZ]);
757  }
758  solver_m = new AmrMultiGrid(static_cast<AmrBoxLib*>(itsAmrObject_mp.get()),
759  Attributes::getString(itsAttr[ITSOLVER]),
760  Attributes::getString(itsAttr[AMR_MG_PREC]),
761  Attributes::getBool(itsAttr[AMR_MG_REBALANCE]),
762  Attributes::getString(itsAttr[AMR_MG_REUSE]),
765  bcz,
766  Attributes::getString(itsAttr[AMR_MG_SMOOTHER]),
767  Attributes::getReal(itsAttr[AMR_MG_NSWEEPS]),
768  Attributes::getString(itsAttr[AMR_MG_INTERP]),
769  Attributes::getString(itsAttr[AMR_MG_NORM]));
770 
771  dynamic_cast<AmrMultiGrid*>(solver_m)->setVerbose(
772  Attributes::getBool(itsAttr[AMR_MG_VERBOSE]));
773 #else
774  throw OpalException("FieldSolver::initAmrSolver_m()",
775  "Multigrid solver not enabled! "
776  "Please build OPAL with -DENABLE_AMR_MG_SOLVER=1");
777 #endif
778  } else
779  throw OpalException("FieldSolver::initAmrSolver_m()",
780  "Unknown solver " + fsType + ".");
781 }
782 #endif
void setReal(Attribute &attr, double val)
Set real value.
Definition: Attributes.cpp:236
static int getNodes()
Definition: IpplInfo.cpp:773
static FieldSolver * find(const std::string &name)
Find named FieldSolver.
void initAmrSolver_m()
static std::unique_ptr< AmrBoxLib > create(const AmrInfo &info, AmrPartBunch *bunch_p)
Definition: AmrBoxLib.cpp:46
constexpr double e
The value of .
Definition: Physics.h:40
The base class for all OPAL definitions.
Definition: Definition.h:30
double getMT() const
Return meshsize.
The FieldSolver definition.
Definition: FieldSolver.h:43
virtual void set_meshEnlargement(double dh)
static std::string enum2string(int number)
Definition: AmrObject.cpp:79
The base class for all OPAL exceptions.
Definition: OpalException.h:28
CenteredFieldLayout< 3, Mesh_t, Center_t > FieldLayout_t
Definition: PBunchDefs.h:48
virtual void execute()
Execute (init) the field solver data.
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
FRONT * fs
Definition: hypervolume.cpp:59
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
bool info
Info flag.
Definition: Options.cpp:8
void initSolver(PartBunchBase< double, 3 > *b)
double getMY() const
Return meshsize.
int refratio[3]
Mesh refinement ratio in x-, y- and z-direction.
Definition: AmrObject.h:47
bool getBool(const Attribute &attr)
Return logical value.
Definition: Attributes.cpp:66
int grid[3]
Number of grid points in x-, y- and z-direction.
Definition: AmrObject.h:43
static OpalData * getInstance()
Definition: OpalData.cpp:209
void setMX(double)
Store emittance for mode 1.
virtual ~FieldSolver()
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:284
bool hasValidSolver()
Definition: Index.h:236
PoissonSolver * solver_m
the actual solver, should be a base object
Definition: FieldSolver.h:114
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void initAmrObject_m()
std::unique_ptr< Layout_t > PL_m
The particle layout.
Definition: FieldSolver.h:142
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:194
static BoundaryGeometry * find(const std::string &name)
#define INFOMSG(msg)
Definition: IpplInfo.h:397
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:258
void setRealArray(Attribute &attr, const std::vector< double > &value)
Set array value.
Definition: Attributes.cpp:273
virtual void update()
Update the field solver data.
virtual FieldSolver * clone(const std::string &name)
Make clone.
std::string fsType_m
Definition: FieldSolver.h:147
void setMT(double)
Store emittance for mode 3.
FieldSolver()
Exemplar constructor.
Mesh_t * mesh_m
The cartesian mesh.
Definition: FieldSolver.h:136
bool amr
Definition: Options.cpp:100
std::string getTagging_m() const
std::unique_ptr< AmrObject > itsAmrObject_mp
Definition: FieldSolver.h:125
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
PartBunchBase< double, 3 > * itsBunch_m
all the particles are here ...
Definition: FieldSolver.h:145
#define TOL
Definition: svdfit.cpp:328
void clear()
Clear the occurrence counter.
Definition: Object.cpp:315
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
Definition: Attributes.cpp:56
const std::string name
void initCartesianFields()
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Definition: Attributes.cpp:253
std::string getType()
e_dim_tag
Definition: FieldLayout.h:55
double getMX() const
Return meshsize.
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
void setMY(double)
Store emittance for mode 2.
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
ParticleSpatialLayout< double, 3, Mesh_t > Layout_t
Definition: PBunchDefs.h:43
bool hasPeriodicZ()
Inform & printInfo(Inform &os) const
int maxlevel
Maximum level for AMR (0: single-level)
Definition: AmrObject.h:46
Definition: Inform.h:41
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:296
UniformCartesian< 3, double > Mesh_t
Definition: PBunchDefs.h:41
bool isAmrSolverType() const
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
FieldLayout_t * FL_m
The field layout f.
Definition: FieldSolver.h:139
int bf[3]
Grid blocking factor in x-, y- and z-direction.
Definition: AmrObject.h:45
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
BoundaryGeometry * getGlobalGeometry()
Definition: OpalData.cpp:506
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:307
int maxgrid[3]
Maximum grid size in x-, y- and z-direction.
Definition: AmrObject.h:44