MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_RfromP_Or_TransP_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_RFROMP_OR_TRANSP_DEF_HPP
11#define MUELU_RFROMP_OR_TRANSP_DEF_HPP
12
13#include <Teuchos_ParameterList.hpp>
14#include <Teuchos_Time.hpp>
15
16#include <Xpetra_Matrix.hpp>
17
19
21
23#include "MueLu_PFactory.hpp"
24#include "MueLu_PgPFactory.hpp"
25#include "MueLu_TogglePFactory.hpp"
26#include "MueLu_Monitor.hpp"
27#include "MueLu_PerfUtils.hpp"
28#include "MueLu_Utilities.hpp"
29
30namespace MueLu {
31
32template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
34 RCP<ParameterList> validParamList = rcp(new ParameterList());
35 validParamList->set<RCP<const FactoryBase>>("P", Teuchos::null, "Generating factory of the matrix P");
36 validParamList->set<RCP<const FactoryBase>>("RfromPfactory", Teuchos::null, "Generating factory of the matrix R");
37
38 // Make sure we don't recursively validate options for the matrixmatrix kernels
39 ParameterList norecurse;
40 norecurse.disableRecursiveValidation();
41 validParamList->set<ParameterList>("matrixmatrix: kernel params", norecurse, "MatrixMatrix kernel parameters");
42
43 return validParamList;
44}
45
46template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
48 Input(coarseLevel, "RfromPfactory");
49
50 // Using a PgPFactory in conjunction with a TogglePFactory is a bit problematic. Normally, PgPFactory is supposed to be
51 // invoked twice (once in standard mode and a second time in RestrictionMode). Unfortunately, TogglePFactory
52 // is not designed to produce R. A second issue is that TogglePFactory stores prolongators in an array,
53 // and there are some challenges in determining which array entry (i.e., factory) is needed when producing R.
54 // The way this is addressed is a bit clumsy. RfromP_Or_TransP invokes the prolongator factory to produce R.
55 // To do this, it must first check that this is needed (as opposed to just transposing P or using an already computed
56 // R that might be produced by SemiCoarsenPFactory). This check is needed in both DeclareInput() and in Build().
57 // The DeclareInput() check verifies that TogglePFactory was requested and that one of the prolongator factories
58 // within TogglePFactory is a PgPFactory. RfromP_Or_TransP's DeclareInput then invokes DeclareDependencies, and
59 // DeclareInput for the PgPFactory. The check within Build(), looks at "RfromPFactory" to see if it is an integer. This
60 // integer is used to find the prolongator factory that is invoked in RestrictionMode to produce R. Otherwise,
61 // "RfromPFactory" is used to get the pre-computed restriction matrix. If "RfromPFactory" is not present, then RfromP_Or_TransP
62 // just transposes P to get R.
63
64 RCP<const FactoryBase> PFact = coarseLevel.GetFactoryManager()->GetFactory("P");
65 if (PFact == Teuchos::null) {
66 PFact = GetFactory("P");
67 }
68 coarseLevel.DeclareInput("P", PFact.get(), this);
69 RCP<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>> myToggleFact = Teuchos::rcp_const_cast<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(rcp_dynamic_cast<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(PFact));
70 if (myToggleFact != Teuchos::null) {
71 for (size_t ii = 0; ii < myToggleFact->NumProlongatorFactories(); ii++) {
72 RCP<const MueLu::PgPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>> actualPFact = Teuchos::rcp_const_cast<const MueLu::PgPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(rcp_dynamic_cast<const MueLu::PgPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(myToggleFact->getProlongatorFactory(ii)));
73 if (actualPFact != Teuchos::null) {
74 RCP<PFactory> subFactory = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory(ii)));
75 ;
76 bool rmode = subFactory->isRestrictionModeSet();
77 subFactory->setRestrictionMode(true);
78 // Force request call for actualPFact
79 coarseLevel.DeclareDependencies(actualPFact.get());
80 coarseLevel.DeclareInput("R", actualPFact.get(), this);
81 subFactory->setRestrictionMode(rmode);
82 }
83 }
84 }
85}
86
87template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89 FactoryMonitor m(*this, "Transpose P", coarseLevel);
90 std::string label = "MueLu::TransP-" + Teuchos::toString(coarseLevel.GetLevelID());
91
92 const Teuchos::ParameterList& pL = GetParameterList();
93
94 // Reuse pattern if available (multiple solve)
95 RCP<ParameterList> Tparams;
96 if (pL.isSublist("matrixmatrix: kernel params"))
97 Tparams = rcp(new ParameterList(pL.sublist("matrixmatrix: kernel params")));
98 else
99 Tparams = rcp(new ParameterList);
100
101 // By default, we don't need global constants for transpose
102 Tparams->set("compute global constants: temporaries", Tparams->get("compute global constants: temporaries", false));
103 Tparams->set("compute global constants", Tparams->get("compute global constants", false));
104
105 RCP<Matrix> R;
106 RCP<const FactoryBase> PFact = coarseLevel.GetFactoryManager()->GetFactory("P");
107 if (PFact == Teuchos::null) {
108 PFact = GetFactory("P");
109 }
110
111 RCP<Matrix> P = coarseLevel.Get<RCP<Matrix>>("P", PFact.get());
112
113 if (coarseLevel.IsAvailable("RfromPfactory", PFact.get())) {
114 std::string strType = coarseLevel.GetTypeName("RfromPfactory", PFact.get());
115 // Address case where a toggle factory is used in conjunction with a PgP factory. Here,
116 // we need to invoke the PgP factory a 2nd time to produce restriction. In this
117 // situation the PgP factory puts an int RfromPfactory on the level.
118 //
119 // See comments aboove in DeclareInput() method for more detailsd
120 if (strType == "int") {
121 RCP<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>> myToggleFact = Teuchos::rcp_const_cast<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(rcp_dynamic_cast<const MueLu::TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(PFact));
122 ;
123 if (myToggleFact != Teuchos::null) {
124 MueLu::DisableMultipleCallCheck check(myToggleFact);
125 RCP<PFactory> actualPFact = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory((size_t)coarseLevel.Get<int>("RfromPfactory", PFact.get()))));
126 // toggle factory sets RfromPfactory to correct index into prolongatorFactory array
127 MueLu::DisableMultipleCallCheck check2(actualPFact);
128 bool rmode = actualPFact->isRestrictionModeSet();
129 actualPFact->setRestrictionMode(true);
130 R = coarseLevel.Get<RCP<Matrix>>("R", actualPFact.get());
131 actualPFact->setRestrictionMode(rmode);
132 } else
133 R = Utilities::Transpose(*P, true, label, Tparams);
134 } else
135 R = coarseLevel.Get<RCP<Matrix>>("RfromPfactory", PFact.get());
136 } else
137 R = Utilities::Transpose(*P, true, label, Tparams);
138
139 if (IsPrint(Statistics2)) {
140 RCP<ParameterList> params = rcp(new ParameterList());
141 params->set("printLoadBalancingInfo", true);
142 params->set("printCommInfo", true);
143 GetOStream(Statistics2) << PerfUtils::PrintMatrixInfo(*R, "R", params);
144 }
145
146 Set(coarseLevel, "R", R);
147
149 if (P->IsView("stridedMaps"))
150 R->CreateView("stridedMaps", P, true);
152}
153
154} // namespace MueLu
155
156#endif // MUELU_RFROMP_OR_TRANSP_DEF_HPP
An exception safe way to call the method TwoLevelFactoryBase::DisableMultipleCallCheck.
Timer to be used in factories. Similar to Monitor but with additional timers.
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.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
int GetLevelID() const
Return level number.
std::string GetTypeName(const std::string &ename, const FactoryBase *factory=NoFactory::get())
GetTypeName returns type string of variable stored using ename and factory.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void DeclareDependencies(const FactoryBase *factory, bool bRequestOnly=false, bool bReleaseOnly=false)
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() to declare factory depe...
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
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 > &params=Teuchos::null)
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.