10#ifndef MUELU_EMINPFACTORY_DEF_HPP
11#define MUELU_EMINPFACTORY_DEF_HPP
13#include <Xpetra_Matrix.hpp>
14#include <Xpetra_StridedMapFactory.hpp>
17#include "MueLu_ProductOperator.hpp"
18#include "MueLu_FlatOperator.hpp"
20#include "MueLu_Constraint.hpp"
23#include "MueLu_PerfUtils.hpp"
26#ifdef HAVE_MUELU_BELOS
27#include <BelosLinearProblem.hpp>
28#include <BelosSolverFactory.hpp>
29#include <BelosXpetraAdapter.hpp>
34template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
35typename Teuchos::ScalarTraits<Scalar>::magnitudeType
38 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& P,
39 Teuchos::FancyOStream& out) {
40 using MagnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
42 AP = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *P,
false, AP, out,
true,
true);
44 PtAP = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*P,
true, *AP,
false, PtAP, out,
true,
true);
45 RCP<Vector> diag = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(PtAP->getRowMap());
46 PtAP->getLocalDiagCopy(*diag);
47 MagnitudeType norm = diag->norm1();
48 norm = Teuchos::ScalarTraits<MagnitudeType>::squareroot(norm);
52template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
54 RCP<ParameterList> validParamList = rcp(
new ParameterList());
56#define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
61 validParamList->getEntry(
"emin: iterative method").setValidator(rcp(
new Teuchos::StringValidator(Teuchos::tuple<std::string>(
"cg",
"sd",
"gmres"))));
65 validParamList->set<RCP<const FactoryBase>>(
"A", Teuchos::null,
"Generating factory for the matrix A used during internal iterations");
66 validParamList->set<RCP<const FactoryBase>>(
"P", Teuchos::null,
"Generating factory for the initial guess");
67 validParamList->set<RCP<const FactoryBase>>(
"Constraint", Teuchos::null,
"Generating factory for constraints");
69 validParamList->set<RCP<Matrix>>(
"P0", Teuchos::null,
"Initial guess at P");
70 validParamList->set<
bool>(
"Keep P0",
false,
"Keep an initial P0 (for reuse)");
72 validParamList->set<RCP<Constraint>>(
"Constraint0", Teuchos::null,
"Initial Constraint");
73 validParamList->set<
bool>(
"Keep Constraint0",
false,
"Keep an initial Constraint (for reuse)");
75 return validParamList;
78template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 Input(fineLevel,
"A");
82 static bool isAvailableP0 =
false;
83 static bool isAvailableConstraint0 =
false;
98#ifdef externalSuppliedP0
101 isAvailableP0 = coarseLevel.
IsAvailable(
"P0",
this);
103 isAvailableConstraint0 = coarseLevel.
IsAvailable(
"Constraint0",
this);
106 if (isAvailableP0 ==
false)
107 Input(coarseLevel,
"P");
109 if (isAvailableConstraint0 ==
false)
110 Input(coarseLevel,
"Constraint");
113template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
115 BuildP(fineLevel, coarseLevel);
118template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
135 if (coarseLevel.
IsAvailable(
"Constraint0",
this)) {
137 X = coarseLevel.
Get<RCP<Constraint>>(
"Constraint0",
this);
151#ifdef externalSuppliedP0
157#ifdef externalSuppliedP0
158 P0 = coarseLevel.
Get<RCP<Matrix>>(
"P0");
160 P0 = coarseLevel.
Get<RCP<Matrix>>(
"P0",
this);
162 numIts = pL.get<
int>(
"emin: num reuse iterations");
169 numIts = pL.get<
int>(
"emin: num iterations");
178 std::string solverType = pL.get<std::string>(
"emin: iterative method");
179 if (solverType ==
"cg")
180 solverType =
"Pseudo Block CG";
181 else if (solverType ==
"gmres")
182 solverType =
"Pseudo Block GMRES";
185#ifdef HAVE_MUELU_BELOS
189 auto invD = MatrixFactory::Build(invDiagonal);
197 std::vector<RCP<Operator>> ops = {X, flatA};
201 auto B = MultiVectorFactory::Build(projectedFlatA->getRangeMap(), 1);
202 auto vecP = MultiVectorFactory::Build(projectedFlatA->getDomainMap(), 1);
204 X->AssignMatrixEntriesToVector(*P0, *vecP);
206 auto belosProjectedFlatA = rcp(
new Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(projectedFlatA));
207 auto belosFlatInvDiag = rcp(
new Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(flatInvD));
210 using MV = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
211 using OP = Belos::OperatorT<MV>;
213 auto problem = rcp(
new Belos::LinearProblem<Scalar, MV, OP>());
214 problem->setOperator(belosProjectedFlatA);
215 problem->setRightPrec(belosFlatInvDiag);
216 problem->setLHS(vecP);
218 problem->setLabel(
"Emin");
219 TEUCHOS_ASSERT(problem->setProblem());
221 auto belosList = rcp(
new Teuchos::ParameterList());
222 belosList->set(
"Timer Label",
"Emin");
223 belosList->set(
"Maximum Iterations", numIts);
224 belosList->set(
"Implicit Residual Scaling",
"None");
225 belosList->set(
"Verbosity", Belos::Errors + Belos::Warnings + Belos::StatusTestDetails);
226 belosList->set(
"Output Frequency", 1);
227 belosList->set(
"Output Style", Belos::Brief);
229 belosList->set(
"Output Stream", out->getOStream());
231 Belos::SolverFactory<Scalar, MV, OP> solverFactory;
232 auto solver = solverFactory.create(solverType, belosList);
233 solver->setProblem(problem);
235 if (numIts > 0) solver->solve();
238 P = X->GetMatrixWithEntriesFromVector(*vecP);
240 P = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(P0);
242 if (P0->IsView(
"stridedMaps"))
243 P->CreateView(
"stridedMaps", P0);
245 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"Energy minimization multigrid requires Belos to be enabled.");
256 if (!P->IsView(
"stridedMaps")) {
257 if (A->IsView(
"stridedMaps") ==
true) {
264 std::vector<size_t> stridingInfo(1, 1);
265 RCP<const StridedMap> dMap = StridedMapFactory::Build(X->GetPattern()->getDomainMap(), stridingInfo);
267 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), dMap);
274 Set(coarseLevel,
"P", P);
276 if (pL.get<
bool>(
"Keep P0")) {
280 coarseLevel.
Keep(
"P0",
this);
281 Set(coarseLevel,
"P0", P);
283 if (pL.get<
bool>(
"Keep Constraint0")) {
287 coarseLevel.
Keep(
"Constraint0",
this);
288 Set(coarseLevel,
"Constraint0", X);
292 RCP<ParameterList> params = rcp(
new ParameterList());
293 params->set(
"printLoadBalancingInfo",
true);
294 params->set(
"printCommInfo",
true);
307 Set(coarseLevel,
"R", R);
310 RCP<ParameterList> params = rcp(
new ParameterList());
311 params->set(
"printLoadBalancingInfo",
true);
312 params->set(
"printCommInfo",
true);
#define SET_VALID_ENTRY(name)
static bool debug()
Whether MueLu is in debug mode.
void Build(Level &fineLevel, Level &coarseLevel) const
Build method.
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
static Teuchos::ScalarTraits< Scalar >::magnitudeType ComputeProlongatorEnergyNorm(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &A, RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &P, Teuchos::FancyOStream &out)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
Exception throws to report errors in the internal logical of the program.
void Input(Level &level, const std::string &varName) const
T Get(Level &level, const std::string &varName) const
void Set(Level &level, const std::string &varName, const T &data) const
Timer to be used in factories. Similar to Monitor but with additional timers.
Interprets a matrix as an operator that acts on a vector of nonzeros via SpGEMM.
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
RequestMode GetRequestMode() const
void Keep(const std::string &ename, const FactoryBase *factory)
Request to keep variable 'ename' generated by 'factory' after the setup phase.
virtual const Teuchos::ParameterList & GetParameterList() const
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
Takes a sequence of operators and applies their product.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
static RCP< Vector > GetMatrixDiagonalInverse(const Matrix &A, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps() *100, Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero(), const bool doLumped=false)
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Transpose(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, bool optimizeTranspose=false, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
static Teuchos::RCP< Teuchos::FancyOStream > GetMueLuOStream()
bool IsPrint(MsgType type, int thisProcRankOnly=-1) const
Find out whether we need to print out information for a specific message type.
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.
@ Statistics1
Print more statistics.
@ Runtime0
One-liner description of what is happening.
@ Runtime1
Description of what is happening (more verbose).
@ Statistics0
Print statistics that do not involve significant additional computation.