MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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 
30 namespace MueLu {
31 
32 template <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 
46 template <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);
70  if (myToggleFact != Teuchos::null) {
71  for (size_t ii = 0; ii < myToggleFact->NumProlongatorFactories(); 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 
87 template <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") {
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
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level-&gt;Get&lt; RCP&lt;Matrix&gt; &gt;(&quot;A&quot;, factory) if factory == NULL =&gt; use default factory.
void DeclareDependencies(const FactoryBase *factory, bool bRequestOnly=false, bool bReleaseOnly=false)
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() to declare factory depe...
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
T & get(const std::string &name, T def_value)
Timer to be used in factories. Similar to Monitor but with additional timers.
void setRestrictionMode(bool bRestrictionMode=false)
T * get() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Print even more statistics.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
std::string GetTypeName(const std::string &ename, const FactoryBase *factory=NoFactory::get())
GetTypeName returns type string of variable stored using ename and factory.
Definition: MueLu_Level.cpp:77
Prolongator factory which allows switching between two different prolongator strategies.
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)
bool isRestrictionModeSet()
returns restrictionMode flag
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
An exception safe way to call the method TwoLevelFactoryBase::DisableMultipleCallCheck.
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
Definition: MueLu_Level.cpp:73
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:51
Factory that provides an interface for a concrete implementation of a prolongation operator...
Factory for building Petrov-Galerkin Smoothed Aggregation prolongators.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
std::string toString(const T &t)
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.