OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MueLuBottomSolver.hpp
Go to the documentation of this file.
1 /* https://trilinos.org/wordpress/wp-content/uploads/2015/03/MueLu_tutorial.pdf
2  * http://prod.sandia.gov/techlib/access-control.cgi/2014/1418624r.pdf
3  */
4 
5 #include <AMReX.H>
7 #include "Utilities/Util.h"
8 
9 template <class Level>
11  const std::string& reuse)
12  : BottomSolver<Teuchos::RCP<amr::matrix_t>,
13  Teuchos::RCP<amr::multivector_t>,
14  Level>()
15  , A_mp(Teuchos::null)
16  , nSweeps_m(4)
17  , rebalance_m(rebalance)
18  , setupTimer_m(IpplTimings::getTimer("AMR MG bsolver setup"))
19 {
20  this->initMueLuList_m(reuse);
21 
22  factory_mp = Teuchos::rcp( new pListInterpreter_t(mueluList_m) );
23 
24  // empty multigrid hierarchy with a finest level only
25  hierarchy_mp = factory_mp->CreateHierarchy();
26 }
27 
28 
29 template <class Level>
30 void MueLuBottomSolver<Level>::solve(const Teuchos::RCP<mv_t>& x,
31  const Teuchos::RCP<mv_t>& b)
32 {
33  // MueLu requires Xpetra multivectors (wrap them)
34  Teuchos::RCP<xmv_t> xx = MueLu::TpetraMultiVector_To_XpetraMultiVector(x);
35  Teuchos::RCP<xmv_t> xb = MueLu::TpetraMultiVector_To_XpetraMultiVector(b);
36 
37  // InitialGuessIsZero = true
38  // startLevel = 0
39  hierarchy_mp->Iterate(*xb, *xx, nSweeps_m, true, 0);
40 
41  // put multivector back
42  x->assign(*util_t::MV2NonConstTpetraMV2(*xx));
43 }
44 
45 
46 template <class Level>
47 void MueLuBottomSolver<Level>::setOperator(const Teuchos::RCP<matrix_t>& A,
48  Level* level_p)
49 {
50  IpplTimings::startTimer(setupTimer_m);
51 
52  A_mp = MueLu::TpetraCrs_To_XpetraMatrix<scalar_t, lo_t, go_t, node_t>(A);
53  A_mp->SetFixedBlockSize(1); // only 1 DOF per node (pure Laplace problem)
54 
55  Teuchos::RCP<mv_t> coords_p = Teuchos::rcp(
56  new amr::multivector_t(A->getDomainMap(), AMREX_SPACEDIM, false)
57  );
58 
59  const scalar_t* domain = level_p->geom.ProbLo();
60  const scalar_t* dx = level_p->cellSize();
61  for (amrex::MFIter mfi(level_p->grids, level_p->dmap, true);
62  mfi.isValid(); ++mfi)
63  {
64  const AmrBox_t& tbx = mfi.tilebox();
65  const lo_t* lo = tbx.loVect();
66  const lo_t* hi = tbx.hiVect();
67 
68  for (lo_t i = lo[0]; i <= hi[0]; ++i) {
69  for (lo_t j = lo[1]; j <= hi[1]; ++j) {
70 #if AMREX_SPACEDIM == 3
71  for (lo_t k = lo[2]; k <= hi[2]; ++k) {
72 #endif
73  AmrIntVect_t iv(D_DECL(i, j, k));
74  go_t gidx = level_p->serialize(iv);
75 
76  coords_p->replaceGlobalValue(gidx, 0, domain[0] + (0.5 + i) * dx[0]);
77  coords_p->replaceGlobalValue(gidx, 1, domain[1] + (0.5 + j) * dx[1]);
78 #if AMREX_SPACEDIM == 3
79  coords_p->replaceGlobalValue(gidx, 2, domain[2] + (0.5 + k) * dx[2]);
80  }
81 #endif
82  }
83  }
84  }
85 
86  Teuchos::RCP<xmv_t> coordinates = MueLu::TpetraMultiVector_To_XpetraMultiVector(coords_p);
87 
88  Teuchos::RCP<mv_t> nullspace = Teuchos::rcp(new mv_t(A->getRowMap(), 1));
89  Teuchos::RCP<xmv_t> xnullspace = MueLu::TpetraMultiVector_To_XpetraMultiVector(nullspace);
90  xnullspace->putScalar(1.0);
91  hierarchy_mp->GetLevel(0)->Set("Nullspace", xnullspace);
92  hierarchy_mp->GetLevel(0)->Set("Coordinates", coordinates);
93  hierarchy_mp->setDefaultVerbLevel(Teuchos::VERB_HIGH);
94  hierarchy_mp->IsPreconditioner(false);
95  hierarchy_mp->GetLevel(0)->Set("A", A_mp);
96 
97 
98  Teuchos::RCP<level_t> finest_p = hierarchy_mp->GetLevel(0);
99  finest_p->Set("A", A_mp);
100 
101  factory_mp->SetupHierarchy(*hierarchy_mp);
102 
103  this->isInitialized_m = true;
104 
105  IpplTimings::stopTimer(setupTimer_m);
106 }
107 
108 
109 template <class Level>
111  return nSweeps_m;
112 }
113 
114 
115 template <class Level>
116 std::string
118 
119  std::map<std::string, std::string> map;
120  map["NONE"] = "none";
121  map["RP"] = "RP";
122  map["RAP"] = "RAP";
123  map["S"] = "S";
124  map["FULL"] = "full";
125 
126  auto muelu = map.find(Util::toUpper(reuse));
127 
128  if ( muelu == map.end() )
129  throw OpalException("MueLuBottomSolver::convertToMueLuReuseOption()",
130  "No MueLu reuse option '" + reuse + "'.");
131 
132  return muelu->second;
133 }
134 
135 
136 template <class Level>
137 void MueLuBottomSolver<Level>::initMueLuList_m(const std::string& reuse) {
138  mueluList_m.set("problem: type", "Poisson-3D");
139  mueluList_m.set("verbosity", "low");
140  mueluList_m.set("number of equations", 1);
141  mueluList_m.set("max levels", 8);
142  mueluList_m.set("cycle type", "V");
143 
144  mueluList_m.set("coarse: max size", 200);
145  mueluList_m.set("multigrid algorithm", "sa");
146  mueluList_m.set("sa: damping factor", 1.33); // default: 1.33
147  mueluList_m.set("sa: use filtered matrix", true);
148  mueluList_m.set("filtered matrix: reuse eigenvalue", false); // false: more expensive
149 
150  mueluList_m.set("repartition: enable", rebalance_m);
151  mueluList_m.set("repartition: rebalance P and R", rebalance_m);
152  mueluList_m.set("repartition: partitioner", "zoltan2");
153  mueluList_m.set("repartition: min rows per proc", 800);
154  mueluList_m.set("repartition: start level", 2);
155 
156  Teuchos::ParameterList reparms;
157  reparms.set("algorithm", "multijagged"); // rcb
158  // reparms.set("partitioning_approach", "partition");
159 
160  mueluList_m.set("repartition: params", reparms);
161 
162  mueluList_m.set("smoother: type", "CHEBYSHEV");
163  mueluList_m.set("smoother: pre or post", "both");
164  Teuchos::ParameterList smparms;
165  smparms.set("chebyshev: degree", 3);
166  smparms.set("chebyshev: assume matrix does not change", false);
167  smparms.set("chebyshev: zero starting solution", true);
168  mueluList_m.set("smoother: params", smparms);
169 
170 
171  mueluList_m.set("coarse: type", "RELAXATION");
172  Teuchos::ParameterList cparms;
173  cparms.set("relaxation: type", "Gauss-Seidel");
174  cparms.set("relaxation: sweeps", nSweeps_m);
175  cparms.set("relaxation: zero starting solution", true);
176  cparms.set("relaxation: use l1", true);
177  cparms.set("relaxation: l1 eta", 1.5);
178  mueluList_m.set("coarse: params", cparms);
179 
180 // mueluList_m.set("coarse: type", "KLU2");
181 
182  mueluList_m.set("aggregation: type", "uncoupled");
183  mueluList_m.set("aggregation: min agg size", 3);
184  mueluList_m.set("aggregation: max agg size", 27);
185 
186  mueluList_m.set("transpose: use implicit", false);
187 
188  mueluList_m.set("reuse: type", reuse);
189 }
190 
void solve(const Teuchos::RCP< mv_t > &x, const Teuchos::RCP< mv_t > &b)
void setOperator(const Teuchos::RCP< matrix_t > &A, Level *level_p=nullptr)
amr::scalar_t scalar_t
MueLuBottomSolver(const bool &rebalance, const std::string &reuse)
amr::multivector_t mv_t
The base class for all OPAL exceptions.
Definition: OpalException.h:28
amr::AmrIntVect_t AmrIntVect_t
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
amr::AmrBox_t AmrBox_t
void initMueLuList_m(const std::string &reuse)
Teuchos::RCP< hierarchy_t > hierarchy_mp
manages the multigrid hierarchy
Abstract base class for all base level solvers.
Definition: BottomSolver.h:8
static std::string convertToMueLuReuseOption(const std::string &reuse)
std::size_t getNumIters()
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
Teuchos::RCP< manager_t > factory_mp
sets up hierarchy
bool amr
Definition: Options.cpp:100
amr::matrix_t matrix_t
MueLu::ParameterListInterpreter< scalar_t, lo_t, go_t, node_t > pListInterpreter_t
Tpetra::MultiVector< scalar_t, local_ordinal_t, global_ordinal_t, node_t > multivector_t
amr::global_ordinal_t go_t
Teuchos::ParameterList mueluList_m
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
amr::local_ordinal_t lo_t