OPAL (Object Oriented Parallel Accelerator Library) 2022.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"
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
73using Teuchos::RCP;
74using Teuchos::rcp;
75using 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>(
120
122 bp_m = std::unique_ptr<IrregularDomain>(
128 orig_nr_m, hr_m, interpl));
131 bp_m = std::unique_ptr<IrregularDomain>(
134 orig_nr_m, hr_m));
135 }
136 } else {
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
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,
172 } else {
173 solver_mp = rcp(new Belos::RCGSolMgr<TpetraScalar_t,
176 }
177 } else if (itsolver == "BICGSTAB") {
178 useLeftPrec_m = false;
179 solver_mp = rcp(new Belos::BiCGStabSolMgr<TpetraScalar_t,
182 } else if (itsolver == "GMRES") {
183 if (numBlocks_m == 0 || recycleBlocks_m == 0) {
184 solver_mp = rcp(new Belos::BlockGmresSolMgr<TpetraScalar_t,
187 } else {
188 solver_mp = rcp(new Belos::GCRODRSolMgr<TpetraScalar_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");
201 FunctionTimer4_m = IpplTimings::getTimer("ComputeStencil");
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
223void 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
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
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) {
328 msg << "* Node:" << Ippl::myNode() << ", Filling RHS..." << endl;
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
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;
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) {
367 msg << "* Node:" << Ippl::myNode()
368 << ", Number of Local Inside Points " << id << endl;
369 msg << "* Node:" << Ippl::myNode() << ", Done." << endl;
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, Tpetra::StaticProfile));
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[50];
457 sprintf(filename, "timing_MX%d_MY%d_MZ%d_nProc%d_recB%d_numB%d_nLHS%d",
458 orig_nr_m[0], orig_nr_m[1], orig_nr_m[2],
460
461 timings.open(filename, std::ios::app);
462 timings << solver_mp->getNumIters() << "\t"
463 //<< time <<" "<<
464 << minTime << "\t"
465 << maxTime << "\t"
466 << avgTime << "\t"
467 << numBlocks_m << "\t"
468 << recycleBlocks_m << "\t"
469 << nLHS_m << "\t"
470 //<< OldLHS.size() <<"\t"<<
471 << std::endl;
472
473 timings.close();
474 }
475
476 }
477 // Store new LHS in OldLHS
478 if (nLHS_m > 1) OldLHS.push_front(*(LHS.get()));
479 if (OldLHS.size() > nLHS_m) OldLHS.pop_back();
480
481 //now transfer solution back to IPPL grid
483 id = 0;
484 rho = 0.0;
485 for (int idz = localId[2].first(); idz <= localId[2].last(); idz++) {
486 for (int idy = localId[1].first(); idy <= localId[1].last(); idy++) {
487 for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) {
488 NDIndex<3> l(Index(idx, idx), Index(idy, idy), Index(idz, idz));
489 if (bp_m->isInside(idx, idy, idz))
490 rho.localElement(l) = LHS->getData()[id++] * scaleFactor;
491 }
492 }
493 }
495
496 if (itsBunch_m->getLocalTrackStep()+1 == (long long)Track::block->localTimeSteps.front()) {
497 A = Teuchos::null;
498 LHS = Teuchos::null;
499 RHS = Teuchos::null;
500 prec_mp = Teuchos::null;
501 }
502}
503
504
506
507 int NumMyElements = 0;
508 std::vector<TpetraGlobalOrdinal_t> MyGlobalElements;
509
510 for (int idz = localId[2].first(); idz <= localId[2].last(); idz++) {
511 for (int idy = localId[1].first(); idy <= localId[1].last(); idy++) {
512 for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) {
513 if (bp_m->isInside(idx, idy, idz)) {
514 MyGlobalElements.push_back(bp_m->getIdx(idx, idy, idz));
515 NumMyElements++;
516 }
517 }
518 }
519 }
520
521 int indexbase = 0;
522 map_p = Teuchos::rcp(new TpetraMap_t(Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(),
523 &MyGlobalElements[0], NumMyElements, indexbase, comm_mp));
524}
525
526void MGPoissonSolver::ComputeStencil(Vector_t /*hr*/, Teuchos::RCP<TpetraVector_t> RHS) {
527
528 A->resumeFill();
529 A->setAllToScalar(0.0);
530
531#if defined(__clang__)
532# pragma clang diagnostic push
533# pragma clang diagnostic warning "-Wdeprecated-declarations"
534#endif
535 int NumMyElements = map_p->getNodeNumElements();
536#if defined(__clang__)
537# pragma clang diagnostic pop
538#endif
539
540 auto MyGlobalElements = map_p->getMyGlobalIndices();
541
542 std::vector<TpetraScalar_t> Values(6);
543 std::vector<TpetraGlobalOrdinal_t> Indices(6);
544
547
548 for (int i = 0 ; i < NumMyElements ; i++) {
549
550 int NumEntries = 0;
551
552 double scaleFactor=1.0;
553
554 bp_m->getBoundaryStencil(MyGlobalElements[i], value, scaleFactor);
555 RHS->scale(scaleFactor);
556
557 bp_m->getNeighbours(MyGlobalElements[i], index);
558 if (index.east != -1) {
559 Indices[NumEntries] = index.east;
560 Values[NumEntries++] = value.east;
561 }
562 if (index.west != -1) {
563 Indices[NumEntries] = index.west;
564 Values[NumEntries++] = value.west;
565 }
566 if (index.south != -1) {
567 Indices[NumEntries] = index.south;
568 Values[NumEntries++] = value.south;
569 }
570 if (index.north != -1) {
571 Indices[NumEntries] = index.north;
572 Values[NumEntries++] = value.north;
573 }
574 if (index.front != -1) {
575 Indices[NumEntries] = index.front;
576 Values[NumEntries++] = value.front;
577 }
578 if (index.back != -1) {
579 Indices[NumEntries] = index.back;
580 Values[NumEntries++] = value.back;
581 }
582
583 // if matrix has already been filled (fillComplete()) we can only
584 // replace entries
585
586 if (isMatrixfilled_m) {
587 // off-diagonal entries
588 A->replaceGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
589 // diagonal entry
590 A->replaceGlobalValues(MyGlobalElements[i], 1, &value.center, &MyGlobalElements[i]);
591 } else {
592 // off-diagonal entries
593 A->insertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
594 // diagonal entry
595 A->insertGlobalValues(MyGlobalElements[i], 1, &value.center, &MyGlobalElements[i]);
596 }
597 }
598
599 RCP<ParameterList_t> params = Teuchos::parameterList();
600 params->set ("Optimize Storage", true);
601 A->fillComplete(params);
602 isMatrixfilled_m = true;
603}
604
606
607 //compute some load balance statistics
608
609#if defined(__clang__)
610# pragma clang diagnostic push
611# pragma clang diagnostic warning "-Wdeprecated-declarations"
612#endif
613 size_t myNumPart = map_p->getNodeNumElements();
614 size_t NumPart = map_p->getGlobalNumElements() * 1.0 / comm_mp->getSize();
615#if defined(__clang__)
616# pragma clang diagnostic pop
617#endif
618 double imbalance = 1.0;
619 if (myNumPart >= NumPart)
620 imbalance += (myNumPart - NumPart) / NumPart;
621 else
622 imbalance += (NumPart - myNumPart) / NumPart;
623
624 double max = 0.0, min = 0.0, avg = 0.0;
625 size_t minn = 0, maxn = 0;
626 reduce(imbalance, min, 1, std::less<double>());
627 reduce(imbalance, max, 1, std::greater<double>());
628 reduce(imbalance, avg, 1, std::plus<double>());
629 reduce(myNumPart, minn, 1, std::less<size_t>());
630 reduce(myNumPart, maxn, 1, std::greater<size_t>());
631
632 avg /= comm_mp->getSize();
633 *gmsg << "LBAL min = " << min << ", max = " << max << ", avg = " << avg << endl;
634 *gmsg << "min nr gridpoints = " << minn << ", max nr gridpoints = " << maxn << endl;
635}
636
638 belosList.set("Maximum Iterations", maxiters_m);
639 belosList.set("Convergence Tolerance", tol_m);
640
641 if (numBlocks_m != 0 && recycleBlocks_m != 0){//only set if solver==RCGSolMgr
642 belosList.set("Num Blocks", numBlocks_m); // Maximum number of blocks in Krylov space
643 belosList.set("Num Recycled Blocks", recycleBlocks_m); // Number of vectors in recycle space
644 }
645 if (verbose_m) {
646 belosList.set("Verbosity", Belos::Errors + Belos::Warnings +
647 Belos::TimingDetails + Belos::FinalSummary +
648 Belos::StatusTestDetails);
649 belosList.set("Output Frequency", 1);
650 } else
651 belosList.set("Verbosity", Belos::Errors + Belos::Warnings);
652}
653
654
656 MueLuList_m.set("problem: type", "Poisson-3D");
657 MueLuList_m.set("verbosity", "none");
658 MueLuList_m.set("number of equations", 1);
659 MueLuList_m.set("max levels", 8);
660 MueLuList_m.set("cycle type", "V");
661
662 // heuristic for max coarse size depending on number of processors
663 int coarsest_size = std::max(comm_mp->getSize() * 10, 1024);
664 MueLuList_m.set("coarse: max size", coarsest_size);
665
666 MueLuList_m.set("multigrid algorithm", "sa");
667 MueLuList_m.set("sa: damping factor", 1.33);
668 MueLuList_m.set("sa: use filtered matrix", true);
669 MueLuList_m.set("filtered matrix: reuse eigenvalue", false);
670
671 MueLuList_m.set("repartition: enable", false);
672 MueLuList_m.set("repartition: rebalance P and R", false);
673 MueLuList_m.set("repartition: partitioner", "zoltan2");
674 MueLuList_m.set("repartition: min rows per proc", 800);
675 MueLuList_m.set("repartition: start level", 2);
676
677 MueLuList_m.set("smoother: type", "CHEBYSHEV");
678 MueLuList_m.set("smoother: pre or post", "both");
679 Teuchos::ParameterList smparms;
680 smparms.set("chebyshev: degree", 3);
681 smparms.set("chebyshev: assume matrix does not change", false);
682 smparms.set("chebyshev: zero starting solution", true);
683 smparms.set("relaxation: sweeps", 3);
684 MueLuList_m.set("smoother: params", smparms);
685
686 MueLuList_m.set("smoother: type", "CHEBYSHEV");
687 MueLuList_m.set("smoother: pre or post", "both");
688
689 MueLuList_m.set("coarse: type", "KLU2");
690
691 MueLuList_m.set("aggregation: type", "uncoupled");
692 MueLuList_m.set("aggregation: min agg size", 3);
693 MueLuList_m.set("aggregation: max agg size", 27);
694
695 MueLuList_m.set("transpose: use implicit", false);
696
697 switch (precmode_m) {
698 case REUSE_PREC:
699 MueLuList_m.set("reuse: type", "full");
700 break;
701 case REUSE_HIERARCHY:
702 MueLuList_m.set("sa: use filtered matrix", false);
703 MueLuList_m.set("reuse: type", "tP");
704 break;
705 case STD_PREC:
706 default:
707 MueLuList_m.set("reuse: type", "none");
708 break;
709 }
710}
711
713 os << "* *************** M G P o i s s o n S o l v e r ************************************ " << endl;
714 os << "* h " << hr_m << '\n';
715 os << "* ********************************************************************************** " << endl;
716 return os;
717}
@ REUSE_HIERARCHY
@ STD_PREC
@ REUSE_PREC
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#define INFORM_ALL_NODES
Definition: Inform.h:39
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
#define INFOMSG(msg)
Definition: IpplInfo.h:348
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
std::string::iterator iterator
Definition: MSLang.h:16
int numBlocks
RCG: cycle length.
Definition: Options.cpp:71
int nLHS
number of old left hand sides used to extrapolate a new start vector
Definition: Options.cpp:75
int recycleBlocks
RCG: number of recycle blocks.
Definition: Options.cpp:73
double getdT() const
long long getLocalTrackStep() const
virtual Vector_t get_hr() const
int precmode_m
preconditioner mode
Teuchos::RCP< TpetraVector_t > LHS
left hand side of the linear system of equations we solve
void computeMap(NDIndex< 3 > localId)
recomputes the map
Teuchos::MpiComm< int > Comm_t
void setupMueLuList()
Setup the parameters for the SAAMG preconditioner.
IpplTimings::TimerRef FunctionTimer2_m
IpplTimings::TimerRef FunctionTimer4_m
Teuchos::RCP< LinearProblem_t > problem_mp
Tpetra::CrsMatrix TpetraCrsMatrix_t
Inform & print(Inform &os) const
NDIndex< 3 > domain_m
Tpetra::Vector ::scalar_type TpetraScalar_t
void printLoadBalanceStats()
useful load balance information
Tpetra::Vector TpetraVector_t
Vector_t hr_m
mesh spacings in each direction
Teuchos::ParameterList belosList
parameter list for the iterative solver (Belos)
PartBunch * itsBunch_m
PartBunch object.
int recycleBlocks_m
number of vectors in recycle space
int numBlocks_m
maximum number of blocks in Krylov space
IpplTimings::TimerRef FunctionTimer5_m
Tpetra::MultiVector TpetraMultiVector_t
Vektor< int, 3 > nr_m
current number of mesh points in each direction
IpplTimings::TimerRef FunctionTimer3_m
double tol_m
tolerance for the iterative solver
std::deque< TpetraVector_t > OldLHS
void setupBelosList()
Setup the parameters for the Belos iterative solver.
void computePotential(Field_t &rho, Vector_t hr)
FieldLayout_t * layout_m
IpplTimings::TimerRef FunctionTimer7_m
int maxiters_m
maximal number of iterations for the iterative solver
Teuchos::RCP< MueLuTpetraOperator_t > prec_mp
MueLu preconditioner object.
void IPPLToMap3D(NDIndex< 3 > localId)
void ComputeStencil(Vector_t hr, Teuchos::RCP< TpetraVector_t > RHS)
unsigned int nLHS_m
last N LHS's for extrapolating the new LHS as starting vector
Teuchos::RCP< const Comm_t > comm_mp
communicator used by Trilinos
bool verbose_m
flag specifying if we are verbose
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)
BoundaryGeometry * currentGeometry
holding the currently active geometry
Tpetra::Operator TpetraOperator_t
Vektor< int, 3 > orig_nr_m
global number of mesh points in each direction
Teuchos::RCP< TpetraMap_t > map_p
Map holding the processor distribution of data.
Teuchos::RCP< SolverManager_t > solver_mp
Tpetra::Map TpetraMap_t
IpplTimings::TimerRef FunctionTimer6_m
Teuchos::RCP< TpetraMultiVector_t > P_mp
IpplTimings::TimerRef FunctionTimer8_m
Teuchos::RCP< TpetraVector_t > RHS
right hand side of our problem
IpplTimings::TimerRef FunctionTimer1_m
Teuchos::ParameterList MueLuList_m
parameter list for the MueLu solver
std::vector< BoundaryGeometry * > geometries_m
container for multiple geometries
Teuchos::RCP< TpetraCrsMatrix_t > A
matrix used in the linear system of equations
std::unique_ptr< IrregularDomain > bp_m
structure that holds boundary points
Vector_t getmincoords()
Vector_t getmaxcoords()
Topology getTopology() const
std::string getFilename() const
std::vector< unsigned long long > localTimeSteps
Maximal number of timesteps.
Definition: Track.h:75
static Track * block
The block of track data.
Definition: Track.h:59
The base class for all OPAL exceptions.
Definition: OpalException.h:28
T & localElement(const NDIndex< Dim > &) const
Definition: BareField.hpp:1154
NDIndex< Dim > getLocalNDIndex()
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
MFLOAT get_meshSpacing(unsigned d) const
Definition: Index.h:237
void barrier(void)
Definition: Inform.h:42
static Inform * Info
Definition: IpplInfo.h:78
static int myNode()
Definition: IpplInfo.cpp:691
static Communicate * Comm
Definition: IpplInfo.h:84
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
Inform * gmsg
Definition: Main.cpp:61