53#include <Tpetra_Import.hpp>
54#include <BelosTpetraAdapter.hpp>
57 #include "TpetraExt_MatrixMatrix.hpp"
60#include "Teuchos_CommandLineProcessor.hpp"
62#include "BelosLinearProblem.hpp"
63#include "BelosRCGSolMgr.hpp"
64#include "BelosBlockCGSolMgr.hpp"
65#include "BelosBiCGStabSolMgr.hpp"
66#include "BelosBlockGmresSolMgr.hpp"
67#include "BelosGCRODRSolMgr.hpp"
69#include <MueLu_CreateTpetraPreconditioner.hpp>
80 std::vector<BoundaryGeometry *> geometries,
99 for (
int i = 0; i < 3; i++) {
117 if (currentGeometry->getTopology() == Topology::ELLIPTIC){
118 bp_m = std::unique_ptr<IrregularDomain>(
119 new EllipticDomain(currentGeometry, orig_nr_m, hr_m, interpl));
122 bp_m = std::unique_ptr<IrregularDomain>(
123 new BoxCornerDomain(currentGeometry->getA(),
124 currentGeometry->getB(),
125 currentGeometry->getC(),
126 currentGeometry->getL1(),
127 currentGeometry->getL2(),
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>(
132 new RectangularDomain(currentGeometry->getA(),
133 currentGeometry->getB(),
137 NDIndex<3> localId = layout_m->getLocalNDIndex();
138 if (localId[0].length() != domain_m[0].length() ||
139 localId[1].length() != domain_m[1].length()) {
141 "The class ArbitraryDomain only works with parallelization\n"
143 "Please set PARFFTX=FALSE, PARFFTY=FALSE, PARFFTT=TRUE in \n"
144 "the definition of the field solver in the input file.\n");
146 Vector_t hr = (currentGeometry->getmaxcoords() -
147 currentGeometry->getmincoords()) / orig_nr_m;
148 bp_m = std::unique_ptr<IrregularDomain>(
152 map_p = Teuchos::null;
156 prec_mp = Teuchos::null;
163 problem_mp = rcp(
new Belos::LinearProblem<TpetraScalar_t,
167 if (itsolver ==
"CG") {
168 if (numBlocks_m == 0 || recycleBlocks_m == 0) {
169 solver_mp = rcp(
new Belos::BlockCGSolMgr<TpetraScalar_t,
171 TpetraOperator_t>());
173 solver_mp = rcp(
new Belos::RCGSolMgr<TpetraScalar_t,
175 TpetraOperator_t>());
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>());
188 solver_mp = rcp(
new Belos::GCRODRSolMgr<TpetraScalar_t,
190 TpetraOperator_t>());
194 solver_mp->setParameters(rcp(&belosList,
false));
209 map_p = Teuchos::null;
224 throw OpalException(
"MGPoissonSolver",
"not implemented yet");
243 if (Teuchos::is_null(
LHS)){
248 Tpetra::Import<> importer(
map_p,
LHS->getMap());
249 tmplhs->doImport(*
LHS, importer, Tpetra::CombineMode::ADD);
254 std::deque< TpetraVector_t >::iterator it =
OldLHS.begin();
257 for (
int i = 0; i < n; ++i) {
259 Tpetra::Import<> importer(
map_p, it->getMap());
260 tmplhs.doImport(*it, importer, Tpetra::CombineMode::ADD);
270 else if (
OldLHS.size() == 1)
272 else if (
OldLHS.size() == 2)
273 LHS->update(2.0, *it++, -1.0, *it, 0.0);
274 else if (
OldLHS.size() > 2) {
277 for (
int i = 0; i < n; ++i) {
278 *(
P_mp->getVectorNonConst(i)) = *it++;
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);
288 "Invalid number of old LHS: " + std::to_string(
OldLHS.size()));
310 bp_m->compute(hr, localId);
321 if (Teuchos::is_null(
RHS))
337 msg <<
"* Node:" <<
Ippl::myNode() <<
", Rho for final element: "
338 << rho[localId[0].last()][localId[1].last()][localId[2].last()].get()
342 msg <<
"* Node:" <<
Ippl::myNode() <<
", Local nx*ny*nz = "
343 << localId[2].last() * localId[0].last() * localId[1].last()
346 <<
", Number of reserved local elements in RHS: "
347 <<
RHS->getLocalLength() <<
endl;
349 <<
", Number of reserved global elements in RHS: "
350 <<
RHS->getGlobalLength() <<
endl;
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++) {
357 if (
bp_m->isInside(idx, idy, idz))
358 RHS->replaceGlobalValue(
bp_m->getIdx(idx, idy, idz),
368 <<
", Number of Local Inside Points " <<
id <<
endl;
375#if defined(__clang__)
376# pragma clang diagnostic push
377# pragma clang diagnostic warning "-Wdeprecated-declarations"
379 if (Teuchos::is_null(
A))
381#if defined(__clang__)
382# pragma clang diagnostic pop
389 Tpetra::MatrixMarket::Writer<TpetraCrsMatrix_t>::writeSparseFile(
390 "DiscrStencil.dat",
A);
395 if (Teuchos::is_null(
prec_mp)) {
396 Teuchos::RCP<TpetraOperator_t> At = Teuchos::rcp_dynamic_cast<TpetraOperator_t>(
A);
403 MueLu::ReuseTpetraPreconditioner(
A, *
prec_mp);
408 Teuchos::RCP<TpetraOperator_t> At = Teuchos::rcp_dynamic_cast<TpetraOperator_t>(
A);
432 ERRORMSG(
"Belos::LinearProblem failed to set up correctly!" <<
endl);
438 double time = MPI_Wtime();
447 std::ofstream timings;
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>());
457 snprintf(filename,
sizeof(filename),
458 "timing_MX%d_MY%d_MZ%d_nProc%d_recB%d_numB%d_nLHS%d",
462 timings.open(filename, std::ios::app);
463 timings <<
solver_mp->getNumIters() <<
"\t"
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++) {
490 if (
bp_m->isInside(idx, idy, idz))
508 int NumMyElements = 0;
509 std::vector<TpetraGlobalOrdinal_t> MyGlobalElements;
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));
523 map_p = Teuchos::rcp(
new TpetraMap_t(Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(),
524 &MyGlobalElements[0], NumMyElements, indexbase,
comm_mp));
530 A->setAllToScalar(0.0);
532#if defined(__clang__)
533# pragma clang diagnostic push
534# pragma clang diagnostic warning "-Wdeprecated-declarations"
536 int NumMyElements =
map_p->getLocalNumElements();
537#if defined(__clang__)
538# pragma clang diagnostic pop
541 auto MyGlobalElements =
map_p->getMyGlobalIndices();
543 std::vector<TpetraScalar_t> Values(6);
544 std::vector<TpetraGlobalOrdinal_t> Indices(6);
549 for (
int i = 0 ; i < NumMyElements ; i++) {
553 double scaleFactor=1.0;
555 bp_m->getBoundaryStencil(MyGlobalElements[i], value, scaleFactor);
556 RHS->scale(scaleFactor);
558 bp_m->getNeighbours(MyGlobalElements[i], index);
559 if (index.
east != -1) {
560 Indices[NumEntries] = index.
east;
561 Values[NumEntries++] = value.
east;
563 if (index.
west != -1) {
564 Indices[NumEntries] = index.
west;
565 Values[NumEntries++] = value.
west;
567 if (index.
south != -1) {
568 Indices[NumEntries] = index.
south;
569 Values[NumEntries++] = value.
south;
571 if (index.
north != -1) {
572 Indices[NumEntries] = index.
north;
573 Values[NumEntries++] = value.
north;
575 if (index.
front != -1) {
576 Indices[NumEntries] = index.
front;
577 Values[NumEntries++] = value.
front;
579 if (index.
back != -1) {
580 Indices[NumEntries] = index.
back;
581 Values[NumEntries++] = value.
back;
589 A->replaceGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
591 A->replaceGlobalValues(MyGlobalElements[i], 1, &value.
center, &MyGlobalElements[i]);
594 A->insertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
596 A->insertGlobalValues(MyGlobalElements[i], 1, &value.
center, &MyGlobalElements[i]);
600 RCP<ParameterList_t> params = Teuchos::parameterList();
601 params->set (
"Optimize Storage",
true);
602 A->fillComplete(params);
610#if defined(__clang__)
611# pragma clang diagnostic push
612# pragma clang diagnostic warning "-Wdeprecated-declarations"
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
619 double imbalance = 1.0;
620 if (myNumPart >= NumPart)
621 imbalance += (myNumPart - NumPart) / NumPart;
623 imbalance += (NumPart - myNumPart) / NumPart;
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>());
634 *
gmsg <<
"LBAL min = " <<
min <<
", max = " <<
max <<
", avg = " << avg <<
endl;
635 *
gmsg <<
"min nr gridpoints = " << minn <<
", max nr gridpoints = " << maxn <<
endl;
647 belosList.set(
"Verbosity", Belos::Errors + Belos::Warnings +
648 Belos::TimingDetails + Belos::FinalSummary +
649 Belos::StatusTestDetails);
652 belosList.set(
"Verbosity", Belos::Errors + Belos::Warnings);
664 int coarsest_size = std::max(
comm_mp->getSize() * 10, 1024);
665 MueLuList_m.set(
"coarse: max size", coarsest_size);
670 MueLuList_m.set(
"filtered matrix: reuse eigenvalue",
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);
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);
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;
UniformCartesian< 3, double > Mesh_t
ParticleSpatialLayout< double, 3 >::SingleParticlePos_t Vector_t
Field< double, 3, Mesh_t, Center_t > Field_t
CenteredFieldLayout< 3, Mesh_t, Center_t > FieldLayout_t
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Inform & endl(Inform &inf)
Inform & level3(Inform &inf)
constexpr double c
The velocity of light in m/s.
int numBlocks
RCG: cycle length.
int nLHS
number of old left hand sides used to extrapolate a new start vector
int recycleBlocks
RCG: number of recycle blocks.
Stencil< int > StencilIndex_t
Stencil< double > StencilValue_t
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
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)
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
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
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
static Track * block
The block of track data.
The base class for all OPAL exceptions.
T & localElement(const NDIndex< Dim > &) const
static Communicate * Comm
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t