OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
MGPoissonSolver.cpp
Go to the documentation of this file.
1 //
2 // Class MGPoissonSolver
3 // This class contains methods for solving Poisson's equation for the
4 // space charge portion of the calculation.
5 //
6 // A smoothed aggregation based AMG preconditioned iterative solver for space charge
7 // \see FFTPoissonSolver
8 // \warning This solver is in an EXPERIMENTAL STAGE. For reliable simulations use the FFTPoissonSolver
9 //
10 // Copyright (c) 2008, Yves Ineichen, ETH Zürich,
11 // 2013 - 2015, Tülin Kaman, Paul Scherrer Institut, Villigen PSI, Switzerland
12 // 2017 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
13 // All rights reserved
14 //
15 // Implemented as part of the master thesis
16 // "A Parallel Multigrid Solver for Beam Dynamics"
17 // and the paper
18 // "A fast parallel Poisson solver on irregular domains applied to beam dynamics simulations"
19 // (https://doi.org/10.1016/j.jcp.2010.02.022)
20 //
21 // In 2020, the code was ported to the second generation Trilinos packages,
22 // i.e., Epetra --> Tpetra, ML --> MueLu. See also issue #507.
23 //
24 // This file is part of OPAL.
25 //
26 // OPAL is free software: you can redistribute it and/or modify
27 // it under the terms of the GNU General Public License as published by
28 // the Free Software Foundation, either version 3 of the License, or
29 // (at your option) any later version.
30 //
31 // You should have received a copy of the GNU General Public License
32 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
33 //
34 
35 //#define DBG_STENCIL
36 
38 
40 #include "ArbitraryDomain.h"
41 #include "EllipticDomain.h"
42 #include "BoxCornerDomain.h"
43 #include "RectangularDomain.h"
44 
45 #include "Track/Track.h"
46 #include "Physics/Physics.h"
48 #include "Attributes/Attributes.h"
51 #include "Utilities/Options.h"
52 
53 #include <Tpetra_Import.hpp>
54 #include <BelosTpetraAdapter.hpp>
55 
56 #ifdef DBG_STENCIL
57  #include "TpetraExt_MatrixMatrix.hpp"
58 #endif
59 
60 #include "Teuchos_CommandLineProcessor.hpp"
61 
62 #include "BelosLinearProblem.hpp"
63 #include "BelosRCGSolMgr.hpp"
64 #include "BelosBlockCGSolMgr.hpp"
65 #include "BelosBiCGStabSolMgr.hpp"
66 #include "BelosBlockGmresSolMgr.hpp"
67 #include "BelosGCRODRSolMgr.hpp"
68 
69 #include <MueLu_CreateTpetraPreconditioner.hpp>
70 
71 #include <algorithm>
72 
73 using Teuchos::RCP;
74 using Teuchos::rcp;
75 using Physics::c;
76 
78  Mesh_t *mesh,
79  FieldLayout_t *fl,
80  std::vector<BoundaryGeometry *> geometries,
81  std::string itsolver,
82  std::string interpl,
83  double tol,
84  int maxiters,
85  std::string precmode)
86  : isMatrixfilled_m(false)
87  , useLeftPrec_m(true)
88  , geometries_m(geometries)
89  , tol_m(tol)
90  , maxiters_m(maxiters)
91  , comm_mp(new Comm_t(Ippl::getComm()))
92  , itsBunch_m(beam)
93  , mesh_m(mesh)
94  , layout_m(fl)
95 {
96 
98 
99  for (int i = 0; i < 3; i++) {
100  hr_m[i] = mesh_m->get_meshSpacing(i);
101  orig_nr_m[i] = domain_m[i].length();
102  }
103 
105  if (precmode == "HIERARCHY") precmode_m = REUSE_HIERARCHY;
106  else if (precmode == "REUSE") precmode_m = REUSE_PREC;
107 
108  repartFreq_m = 1000;
109  if (Ippl::Info->getOutputLevel() > 3) {
110  verbose_m = true;
111  } else {
112  verbose_m = false;
113  }
114  // Find CURRENT geometry
116  if ( (currentGeometry->getFilename()).empty() ) {
118  bp_m = std::unique_ptr<IrregularDomain>(
119  new EllipticDomain(currentGeometry, orig_nr_m, hr_m, interpl));
120 
122  bp_m = std::unique_ptr<IrregularDomain>(
128  orig_nr_m, hr_m, interpl));
129  bp_m->compute(itsBunch_m->get_hr(), layout_m->getLocalNDIndex());
131  bp_m = std::unique_ptr<IrregularDomain>(
134  orig_nr_m, hr_m));
135  }
136  } else {
137  NDIndex<3> localId = layout_m->getLocalNDIndex();
138  if (localId[0].length() != domain_m[0].length() ||
139  localId[1].length() != domain_m[1].length()) {
140  throw OpalException("MGPoissonSolver::MGPoissonSolver",
141  "The class ArbitraryDomain only works with parallelization\n"
142  "in z-direction.\n"
143  "Please set PARFFTX=FALSE, PARFFTY=FALSE, PARFFTT=TRUE in \n"
144  "the definition of the field solver in the input file.\n");
145  }
148  bp_m = std::unique_ptr<IrregularDomain>(
149  new ArbitraryDomain(currentGeometry, orig_nr_m, hr, interpl));
150  }
151 
152  map_p = Teuchos::null;
153  A = Teuchos::null;
154  LHS = Teuchos::null;
155  RHS = Teuchos::null;
156  prec_mp = Teuchos::null;
157 
161  setupMueLuList();
162  setupBelosList();
163  problem_mp = rcp(new Belos::LinearProblem<TpetraScalar_t,
166  // setup Belos solver
167  if (itsolver == "CG") {
168  if (numBlocks_m == 0 || recycleBlocks_m == 0) {
169  solver_mp = rcp(new Belos::BlockCGSolMgr<TpetraScalar_t,
171  TpetraOperator_t>());
172  } else {
173  solver_mp = rcp(new Belos::RCGSolMgr<TpetraScalar_t,
175  TpetraOperator_t>());
176  }
177  } else if (itsolver == "BICGSTAB") {
178  useLeftPrec_m = false;
179  solver_mp = rcp(new Belos::BiCGStabSolMgr<TpetraScalar_t,
181  TpetraOperator_t>());
182  } else if (itsolver == "GMRES") {
183  if (numBlocks_m == 0 || recycleBlocks_m == 0) {
184  solver_mp = rcp(new Belos::BlockGmresSolMgr<TpetraScalar_t,
186  TpetraOperator_t>());
187  } else {
188  solver_mp = rcp(new Belos::GCRODRSolMgr<TpetraScalar_t,
190  TpetraOperator_t>());
191  }
192  }
193 
194  solver_mp->setParameters(rcp(&belosList, false));
195 
196 
197  //all timers used here
198  FunctionTimer1_m = IpplTimings::getTimer("BGF-IndexCoordMap");
199  FunctionTimer2_m = IpplTimings::getTimer("computeMap");
200  FunctionTimer3_m = IpplTimings::getTimer("IPPL to RHS");
201  FunctionTimer4_m = IpplTimings::getTimer("ComputeStencil");
205  FunctionTimer8_m = IpplTimings::getTimer("LHS to IPPL");
206 }
207 
209  map_p = Teuchos::null;
210  A = Teuchos::null;
211  LHS = Teuchos::null;
212  RHS = Teuchos::null;
213  prec_mp = Teuchos::null;
214  isMatrixfilled_m = false;
215 }
216 
218  deletePtr ();
219  solver_mp = Teuchos::null;
220  problem_mp = Teuchos::null;
221 }
222 
223 void MGPoissonSolver::computePotential(Field_t& /*rho*/, Vector_t /*hr*/, double /*zshift*/) {
224  throw OpalException("MGPoissonSolver", "not implemented yet");
225 }
226 
229  deletePtr();
230  IPPLToMap3D(localId);
231 
232  extrapolateLHS();
233  }
234 }
235 
237 // Aitken-Neville
238 // Pi0 (x) := yi , i = 0 : n
239 // Pik (x) := (x − xi ) Pi+1,k−1(x) − (x − xi+k ) Pi,k−1(x) /(xi+k − xi )
240 // k = 1, . . . , n, i = 0, . . . , n − k.
241  //we also have to redistribute LHS
242 
243  if (Teuchos::is_null(LHS)){
244  LHS = rcp(new TpetraVector_t(map_p));
245  LHS->putScalar(1.0);
246  } else {
247  RCP<TpetraVector_t> tmplhs = rcp(new TpetraVector_t(map_p));
248  Tpetra::Import<> importer(map_p, LHS->getMap());
249  tmplhs->doImport(*LHS, importer, Tpetra::CombineMode::ADD);
250  LHS = tmplhs;
251  }
252 
253  //...and all previously saved LHS
255  if (!OldLHS.empty()) {
256  int n = OldLHS.size();
257  for (int i = 0; i < n; ++i) {
259  Tpetra::Import<> importer(map_p, it->getMap());
260  tmplhs.doImport(*it, importer, Tpetra::CombineMode::ADD);
261  *it = tmplhs;
262  ++it;
263  }
264  }
265 
266  // extrapolate last OldLHS.size LHS to get a new start vector
267  it = OldLHS.begin();
268  if (nLHS_m == 0 || OldLHS.size()==0)
269  LHS->putScalar(1.0);
270  else if (OldLHS.size() == 1)
271  *LHS = *it;
272  else if (OldLHS.size() == 2)
273  LHS->update(2.0, *it++, -1.0, *it, 0.0);
274  else if (OldLHS.size() > 2) {
275  int n = OldLHS.size();
276  P_mp = rcp(new TpetraMultiVector_t(map_p, nLHS_m, false));
277  for (int i = 0; i < n; ++i) {
278  *(P_mp->getVectorNonConst(i)) = *it++;
279  }
280  for (int k = 1; k < n; ++k) {
281  for (int i = 0; i < n - k; ++i) {
282  P_mp->getVectorNonConst(i)->update(-(i + 1) / (float)k, *(P_mp->getVector(i + 1)), (i + k + 1) / (float)k);
283  }
284  }
285  *LHS = *(P_mp->getVector(0));
286  } else
287  throw OpalException("MGPoissonSolver",
288  "Invalid number of old LHS: " + std::to_string(OldLHS.size()));
289 }
290 
291 
292 // given a charge-density field rho and a set of mesh spacings hr,
293 // compute the electric field and put in eg by solving the Poisson's equation
294 // XXX: use matrix stencil in computation directly (no Tpetra, define operators
295 // on IPPL GRID)
297 
298  Inform msg("OPAL ", INFORM_ALL_NODES);
299  nr_m[0] = orig_nr_m[0];
300  nr_m[1] = orig_nr_m[1];
301  nr_m[2] = orig_nr_m[2];
302 
303  bp_m->setNr(nr_m);
304 
305  NDIndex<3> localId = layout_m->getLocalNDIndex();
306 
308  // Compute boundary intersections (only do on the first step)
310  bp_m->compute(hr, localId);
312 
313  // Define the Map
314  INFOMSG(level3 << "* Computing Map..." << endl);
316  computeMap(localId);
318  INFOMSG(level3 << "* Done." << endl);
319 
320  // Allocate the RHS with the new Tpetra Map
321  if (Teuchos::is_null(RHS))
322  RHS = rcp(new TpetraVector_t(map_p));
323  RHS->putScalar(0.0);
324 
325  // get charge densities from IPPL field and store in Tpetra vector (RHS)
326  if (verbose_m) {
327  Ippl::Comm->barrier();
328  msg << "* Node:" << Ippl::myNode() << ", Filling RHS..." << endl;
329  Ippl::Comm->barrier();
330  }
332  int id = 0;
333  float scaleFactor = itsBunch_m->getdT();
334 
335 
336  if (verbose_m) {
337  msg << "* Node:" << Ippl::myNode() << ", Rho for final element: "
338  << rho[localId[0].last()][localId[1].last()][localId[2].last()].get()
339  << endl;
340 
341  Ippl::Comm->barrier();
342  msg << "* Node:" << Ippl::myNode() << ", Local nx*ny*nz = "
343  << localId[2].last() * localId[0].last() * localId[1].last()
344  << endl;
345  msg << "* Node:" << Ippl::myNode()
346  << ", Number of reserved local elements in RHS: "
347  << RHS->getLocalLength() << endl;
348  msg << "* Node:" << Ippl::myNode()
349  << ", Number of reserved global elements in RHS: "
350  << RHS->getGlobalLength() << endl;
351  Ippl::Comm->barrier();
352  }
353  for (int idz = localId[2].first(); idz <= localId[2].last(); idz++) {
354  for (int idy = localId[1].first(); idy <= localId[1].last(); idy++) {
355  for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) {
356  NDIndex<3> l(Index(idx, idx), Index(idy, idy), Index(idz, idz));
357  if (bp_m->isInside(idx, idy, idz))
358  RHS->replaceGlobalValue(bp_m->getIdx(idx, idy, idz),
359  4.0 * M_PI * rho.localElement(l) / scaleFactor);
360  }
361  }
362  }
363 
365  if (verbose_m) {
366  Ippl::Comm->barrier();
367  msg << "* Node:" << Ippl::myNode()
368  << ", Number of Local Inside Points " << id << endl;
369  msg << "* Node:" << Ippl::myNode() << ", Done." << endl;
370  Ippl::Comm->barrier();
371  }
372  // build discretization matrix
373  INFOMSG(level3 << "* Building Discretization Matrix..." << endl);
375 #if defined(__clang__)
376 # pragma clang diagnostic push
377 # pragma clang diagnostic warning "-Wdeprecated-declarations"
378 #endif
379  if (Teuchos::is_null(A))
380  A = rcp(new TpetraCrsMatrix_t(map_p, 7));
381 #if defined(__clang__)
382 # pragma clang diagnostic pop
383 #endif
384  ComputeStencil(hr, RHS);
386  INFOMSG(level3 << "* Done." << endl);
387 
388 #ifdef DBG_STENCIL
389  Tpetra::MatrixMarket::Writer<TpetraCrsMatrix_t>::writeSparseFile(
390  "DiscrStencil.dat", A);
391 #endif
392 
393  INFOMSG(level3 << "* Computing Preconditioner..." << endl);
395  if (Teuchos::is_null(prec_mp)) {
396  Teuchos::RCP<TpetraOperator_t> At = Teuchos::rcp_dynamic_cast<TpetraOperator_t>(A);
397  prec_mp = MueLu::CreateTpetraPreconditioner(At, MueLuList_m);
398  }
399 
400  switch (precmode_m) {
401  case REUSE_PREC:
402  case REUSE_HIERARCHY: {
403  MueLu::ReuseTpetraPreconditioner(A, *prec_mp);
404  break;
405  }
406  case STD_PREC:
407  default: {
408  Teuchos::RCP<TpetraOperator_t> At = Teuchos::rcp_dynamic_cast<TpetraOperator_t>(A);
409  prec_mp = MueLu::CreateTpetraPreconditioner(At, MueLuList_m);
410  break;
411  }
412  }
414  INFOMSG(level3 << "* Done." << endl);
415 
416  // setup preconditioned iterative solver
417  // use old LHS solution as initial guess
418  INFOMSG(level3 << "* Final Setup of Solver..." << endl);
420  problem_mp->setOperator(A);
421  problem_mp->setLHS(LHS);
422  problem_mp->setRHS(RHS);
423 
424  if (useLeftPrec_m)
425  problem_mp->setLeftPrec(prec_mp);
426  else
427  problem_mp->setRightPrec(prec_mp);
428 
429  solver_mp->setProblem( problem_mp);
430  if (!problem_mp->isProblemSet()) {
431  if (problem_mp->setProblem() == false) {
432  ERRORMSG("Belos::LinearProblem failed to set up correctly!" << endl);
433  }
434  }
436  INFOMSG(level3 << "* Done." << endl);
437 
438  double time = MPI_Wtime();
439 
440  INFOMSG(level3 << "* Solving for Space Charge..." << endl);
442  solver_mp->solve();
443 
445  INFOMSG(level3 << "* Done." << endl);
446 
447  std::ofstream timings;
448  if (true || verbose_m) {
449  time = MPI_Wtime() - time;
450  double minTime = 0, maxTime = 0, avgTime = 0;
451  reduce(time, minTime, 1, std::less<double>());
452  reduce(time, maxTime, 1, std::greater<double>());
453  reduce(time, avgTime, 1, std::plus<double>());
454  avgTime /= comm_mp->getSize();
455  if (comm_mp->getRank() == 0) {
456  char filename[256]; // common size supported by most file-systems
457  snprintf(filename, sizeof(filename),
458  "timing_MX%d_MY%d_MZ%d_nProc%d_recB%d_numB%d_nLHS%d",
459  orig_nr_m[0], orig_nr_m[1], orig_nr_m[2],
460  comm_mp->getSize(), recycleBlocks_m, numBlocks_m, nLHS_m);
461 
462  timings.open(filename, std::ios::app);
463  timings << solver_mp->getNumIters() << "\t"
464  //<< time <<" "<<
465  << minTime << "\t"
466  << maxTime << "\t"
467  << avgTime << "\t"
468  << numBlocks_m << "\t"
469  << recycleBlocks_m << "\t"
470  << nLHS_m << "\t"
471  //<< OldLHS.size() <<"\t"<<
472  << std::endl;
473 
474  timings.close();
475  }
476 
477  }
478  // Store new LHS in OldLHS
479  if (nLHS_m > 1) OldLHS.push_front(*(LHS.get()));
480  if (OldLHS.size() > nLHS_m) OldLHS.pop_back();
481 
482  //now transfer solution back to IPPL grid
484  id = 0;
485  rho = 0.0;
486  for (int idz = localId[2].first(); idz <= localId[2].last(); idz++) {
487  for (int idy = localId[1].first(); idy <= localId[1].last(); idy++) {
488  for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) {
489  NDIndex<3> l(Index(idx, idx), Index(idy, idy), Index(idz, idz));
490  if (bp_m->isInside(idx, idy, idz))
491  rho.localElement(l) = LHS->getData()[id++] * scaleFactor;
492  }
493  }
494  }
496 
497  if (itsBunch_m->getLocalTrackStep()+1 == (long long)Track::block->localTimeSteps.front()) {
498  A = Teuchos::null;
499  LHS = Teuchos::null;
500  RHS = Teuchos::null;
501  prec_mp = Teuchos::null;
502  }
503 }
504 
505 
507 
508  int NumMyElements = 0;
509  std::vector<TpetraGlobalOrdinal_t> MyGlobalElements;
510 
511  for (int idz = localId[2].first(); idz <= localId[2].last(); idz++) {
512  for (int idy = localId[1].first(); idy <= localId[1].last(); idy++) {
513  for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) {
514  if (bp_m->isInside(idx, idy, idz)) {
515  MyGlobalElements.push_back(bp_m->getIdx(idx, idy, idz));
516  NumMyElements++;
517  }
518  }
519  }
520  }
521 
522  int indexbase = 0;
523  map_p = Teuchos::rcp(new TpetraMap_t(Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(),
524  &MyGlobalElements[0], NumMyElements, indexbase, comm_mp));
525 }
526 
527 void MGPoissonSolver::ComputeStencil(Vector_t /*hr*/, Teuchos::RCP<TpetraVector_t> RHS) {
528 
529  A->resumeFill();
530  A->setAllToScalar(0.0);
531 
532 #if defined(__clang__)
533 # pragma clang diagnostic push
534 # pragma clang diagnostic warning "-Wdeprecated-declarations"
535 #endif
536  int NumMyElements = map_p->getLocalNumElements();
537 #if defined(__clang__)
538 # pragma clang diagnostic pop
539 #endif
540 
541  auto MyGlobalElements = map_p->getMyGlobalIndices();
542 
543  std::vector<TpetraScalar_t> Values(6);
544  std::vector<TpetraGlobalOrdinal_t> Indices(6);
545 
548 
549  for (int i = 0 ; i < NumMyElements ; i++) {
550 
551  int NumEntries = 0;
552 
553  double scaleFactor=1.0;
554 
555  bp_m->getBoundaryStencil(MyGlobalElements[i], value, scaleFactor);
556  RHS->scale(scaleFactor);
557 
558  bp_m->getNeighbours(MyGlobalElements[i], index);
559  if (index.east != -1) {
560  Indices[NumEntries] = index.east;
561  Values[NumEntries++] = value.east;
562  }
563  if (index.west != -1) {
564  Indices[NumEntries] = index.west;
565  Values[NumEntries++] = value.west;
566  }
567  if (index.south != -1) {
568  Indices[NumEntries] = index.south;
569  Values[NumEntries++] = value.south;
570  }
571  if (index.north != -1) {
572  Indices[NumEntries] = index.north;
573  Values[NumEntries++] = value.north;
574  }
575  if (index.front != -1) {
576  Indices[NumEntries] = index.front;
577  Values[NumEntries++] = value.front;
578  }
579  if (index.back != -1) {
580  Indices[NumEntries] = index.back;
581  Values[NumEntries++] = value.back;
582  }
583 
584  // if matrix has already been filled (fillComplete()) we can only
585  // replace entries
586 
587  if (isMatrixfilled_m) {
588  // off-diagonal entries
589  A->replaceGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
590  // diagonal entry
591  A->replaceGlobalValues(MyGlobalElements[i], 1, &value.center, &MyGlobalElements[i]);
592  } else {
593  // off-diagonal entries
594  A->insertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
595  // diagonal entry
596  A->insertGlobalValues(MyGlobalElements[i], 1, &value.center, &MyGlobalElements[i]);
597  }
598  }
599 
600  RCP<ParameterList_t> params = Teuchos::parameterList();
601  params->set ("Optimize Storage", true);
602  A->fillComplete(params);
603  isMatrixfilled_m = true;
604 }
605 
607 
608  //compute some load balance statistics
609 
610 #if defined(__clang__)
611 # pragma clang diagnostic push
612 # pragma clang diagnostic warning "-Wdeprecated-declarations"
613 #endif
614  size_t myNumPart = map_p->getLocalNumElements();
615  size_t NumPart = map_p->getGlobalNumElements() * 1.0 / comm_mp->getSize();
616 #if defined(__clang__)
617 # pragma clang diagnostic pop
618 #endif
619  double imbalance = 1.0;
620  if (myNumPart >= NumPart)
621  imbalance += (myNumPart - NumPart) / NumPart;
622  else
623  imbalance += (NumPart - myNumPart) / NumPart;
624 
625  double max = 0.0, min = 0.0, avg = 0.0;
626  size_t minn = 0, maxn = 0;
627  reduce(imbalance, min, 1, std::less<double>());
628  reduce(imbalance, max, 1, std::greater<double>());
629  reduce(imbalance, avg, 1, std::plus<double>());
630  reduce(myNumPart, minn, 1, std::less<size_t>());
631  reduce(myNumPart, maxn, 1, std::greater<size_t>());
632 
633  avg /= comm_mp->getSize();
634  *gmsg << "LBAL min = " << min << ", max = " << max << ", avg = " << avg << endl;
635  *gmsg << "min nr gridpoints = " << minn << ", max nr gridpoints = " << maxn << endl;
636 }
637 
639  belosList.set("Maximum Iterations", maxiters_m);
640  belosList.set("Convergence Tolerance", tol_m);
641 
642  if (numBlocks_m != 0 && recycleBlocks_m != 0){//only set if solver==RCGSolMgr
643  belosList.set("Num Blocks", numBlocks_m); // Maximum number of blocks in Krylov space
644  belosList.set("Num Recycled Blocks", recycleBlocks_m); // Number of vectors in recycle space
645  }
646  if (verbose_m) {
647  belosList.set("Verbosity", Belos::Errors + Belos::Warnings +
648  Belos::TimingDetails + Belos::FinalSummary +
649  Belos::StatusTestDetails);
650  belosList.set("Output Frequency", 1);
651  } else
652  belosList.set("Verbosity", Belos::Errors + Belos::Warnings);
653 }
654 
655 
657  MueLuList_m.set("problem: type", "Poisson-3D");
658  MueLuList_m.set("verbosity", "none");
659  MueLuList_m.set("number of equations", 1);
660  MueLuList_m.set("max levels", 8);
661  MueLuList_m.set("cycle type", "V");
662 
663  // heuristic for max coarse size depending on number of processors
664  int coarsest_size = std::max(comm_mp->getSize() * 10, 1024);
665  MueLuList_m.set("coarse: max size", coarsest_size);
666 
667  MueLuList_m.set("multigrid algorithm", "sa");
668  MueLuList_m.set("sa: damping factor", 1.33);
669  MueLuList_m.set("sa: use filtered matrix", true);
670  MueLuList_m.set("filtered matrix: reuse eigenvalue", false);
671 
672  MueLuList_m.set("repartition: enable", false);
673  MueLuList_m.set("repartition: rebalance P and R", false);
674  MueLuList_m.set("repartition: partitioner", "zoltan2");
675  MueLuList_m.set("repartition: min rows per proc", 800);
676  MueLuList_m.set("repartition: start level", 2);
677 
678  MueLuList_m.set("smoother: type", "CHEBYSHEV");
679  MueLuList_m.set("smoother: pre or post", "both");
680  Teuchos::ParameterList smparms;
681  smparms.set("chebyshev: degree", 3);
682  smparms.set("chebyshev: assume matrix does not change", false);
683  smparms.set("chebyshev: zero starting solution", true);
684  smparms.set("relaxation: sweeps", 3);
685  MueLuList_m.set("smoother: params", smparms);
686 
687  MueLuList_m.set("smoother: type", "CHEBYSHEV");
688  MueLuList_m.set("smoother: pre or post", "both");
689 
690  MueLuList_m.set("coarse: type", "KLU2");
691 
692  MueLuList_m.set("aggregation: type", "uncoupled");
693  MueLuList_m.set("aggregation: min agg size", 3);
694  MueLuList_m.set("aggregation: max agg size", 27);
695 
696  MueLuList_m.set("transpose: use implicit", false);
697 
698  switch (precmode_m) {
699  case REUSE_PREC:
700  MueLuList_m.set("reuse: type", "full");
701  break;
702  case REUSE_HIERARCHY:
703  MueLuList_m.set("sa: use filtered matrix", false);
704  MueLuList_m.set("reuse: type", "tP");
705  break;
706  case STD_PREC:
707  default:
708  MueLuList_m.set("reuse: type", "none");
709  break;
710  }
711 }
712 
714  os << "* *************** M G P o i s s o n S o l v e r ************************************ " << endl;
715  os << "* h " << hr_m << '\n';
716  os << "* ********************************************************************************** " << endl;
717  return os;
718 }
Vector_t hr_m
mesh spacings in each direction
Tpetra::CrsMatrix TpetraCrsMatrix_t
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
Teuchos::RCP< TpetraVector_t > LHS
left hand side of the linear system of equations we solve
int numBlocks_m
maximum number of blocks in Krylov space
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
IpplTimings::TimerRef FunctionTimer6_m
void barrier(void)
std::unique_ptr< IrregularDomain > bp_m
structure that holds boundary points
Teuchos::RCP< TpetraMap_t > map_p
Map holding the processor distribution of data.
T & localElement(const NDIndex< Dim > &) const
Definition: BareField.hpp:1154
IpplTimings::TimerRef FunctionTimer2_m
IpplTimings::TimerRef FunctionTimer4_m
void printLoadBalanceStats()
useful load balance information
IpplTimings::TimerRef FunctionTimer7_m
static int myNode()
Definition: IpplInfo.cpp:691
double tol_m
tolerance for the iterative solver
IpplTimings::TimerRef FunctionTimer8_m
void setupMueLuList()
Setup the parameters for the SAAMG preconditioner.
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
MGPoissonSolver(PartBunch *beam, Mesh_t *mesh, FieldLayout_t *fl, std::vector< BoundaryGeometry * > geometries, std::string itsolver, std::string interpl, double tol, int maxiters, std::string precmode)
long long getLocalTrackStep() const
Teuchos::RCP< LinearProblem_t > problem_mp
void computeMap(NDIndex< 3 > localId)
recomputes the map
IpplTimings::TimerRef FunctionTimer3_m
Vektor< int, 3 > orig_nr_m
global number of mesh points in each direction
virtual Vector_t get_hr() const
Definition: Index.h:236
Tpetra::Vector TpetraVector_t
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
double getdT() const
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
Teuchos::ParameterList MueLuList_m
parameter list for the MueLu solver
Vector_t getmaxcoords()
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
static Inform * Info
Definition: IpplInfo.h:78
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
std::string::iterator iterator
Definition: MSLang.h:15
std::string getFilename() const
Teuchos::RCP< TpetraMultiVector_t > P_mp
Teuchos::RCP< SolverManager_t > solver_mp
int numBlocks
RCG: cycle length.
Definition: Options.cpp:71
static Communicate * Comm
Definition: IpplInfo.h:84
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Tpetra::Map TpetraMap_t
NDIndex< Dim > getLocalNDIndex()
IpplTimings::TimerRef FunctionTimer5_m
Definition: Inform.h:42
IpplTimings::TimerRef FunctionTimer1_m
Teuchos::RCP< MueLuTpetraOperator_t > prec_mp
MueLu preconditioner object.
void IPPLToMap3D(NDIndex< 3 > localId)
bool verbose_m
flag specifying if we are verbose
#define INFORM_ALL_NODES
Definition: Inform.h:39
static Track * block
The block of track data.
Definition: Track.h:59
void setupBelosList()
Setup the parameters for the Belos iterative solver.
Teuchos::RCP< TpetraVector_t > RHS
right hand side of our problem
int nLHS
number of old left hand sides used to extrapolate a new start vector
Definition: Options.cpp:75
int recycleBlocks_m
number of vectors in recycle space
Tpetra::Vector::scalar_type TpetraScalar_t
Topology getTopology() const
Teuchos::RCP< const Comm_t > comm_mp
communicator used by Trilinos
Teuchos::MpiComm< int > Comm_t
int recycleBlocks
RCG: number of recycle blocks.
Definition: Options.cpp:73
MFLOAT get_meshSpacing(unsigned d) const
std::vector< BoundaryGeometry * > geometries_m
container for multiple geometries
std::deque< TpetraVector_t > OldLHS
int maxiters_m
maximal number of iterations for the iterative solver
Vektor< int, 3 > nr_m
current number of mesh points in each direction
Teuchos::ParameterList belosList
parameter list for the iterative solver (Belos)
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
FieldLayout_t * layout_m
Tpetra::Operator TpetraOperator_t
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
NDIndex< 3 > domain_m
void computePotential(Field_t &rho, Vector_t hr)
Inform & print(Inform &os) const
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
Teuchos::RCP< TpetraCrsMatrix_t > A
matrix used in the linear system of equations
Vector_t getmincoords()
Inform * gmsg
Definition: Main.cpp:70
void ComputeStencil(Vector_t hr, Teuchos::RCP< TpetraVector_t > RHS)
int precmode_m
preconditioner mode
Tpetra::MultiVector TpetraMultiVector_t
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
unsigned int nLHS_m
last N LHS&#39;s for extrapolating the new LHS as starting vector
BoundaryGeometry * currentGeometry
holding the currently active geometry
PartBunch * itsBunch_m
PartBunch object.