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 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_RFROMP_OR_TRANSP_DEF_HPP
47 #define MUELU_RFROMP_OR_TRANSP_DEF_HPP
48 
50 #include <Teuchos_Time.hpp>
51 
52 #include <Xpetra_Matrix.hpp>
53 
55 
57 
59 #include "MueLu_PFactory.hpp"
60 #include "MueLu_PgPFactory.hpp"
61 #include "MueLu_TogglePFactory.hpp"
62 #include "MueLu_Monitor.hpp"
63 #include "MueLu_PerfUtils.hpp"
64 #include "MueLu_Utilities.hpp"
65 
66 namespace MueLu {
67 
68 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
70  RCP<ParameterList> validParamList = rcp(new ParameterList());
71  validParamList->set<RCP<const FactoryBase>>("P", Teuchos::null, "Generating factory of the matrix P");
72  validParamList->set<RCP<const FactoryBase>>("RfromPfactory", Teuchos::null, "Generating factory of the matrix R");
73 
74  // Make sure we don't recursively validate options for the matrixmatrix kernels
75  ParameterList norecurse;
76  norecurse.disableRecursiveValidation();
77  validParamList->set<ParameterList>("matrixmatrix: kernel params", norecurse, "MatrixMatrix kernel parameters");
78 
79  return validParamList;
80 }
81 
82 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
84  Input(coarseLevel, "RfromPfactory");
85 
86  // Using a PgPFactory in conjunction with a TogglePFactory is a bit problematic. Normally, PgPFactory is supposed to be
87  // invoked twice (once in standard mode and a second time in RestrictionMode). Unfortunately, TogglePFactory
88  // is not designed to produce R. A second issue is that TogglePFactory stores prolongators in an array,
89  // and there are some challenges in determining which array entry (i.e., factory) is needed when producing R.
90  // The way this is addressed is a bit clumsy. RfromP_Or_TransP invokes the prolongator factory to produce R.
91  // To do this, it must first check that this is needed (as opposed to just transposing P or using an already computed
92  // R that might be produced by SemiCoarsenPFactory). This check is needed in both DeclareInput() and in Build().
93  // The DeclareInput() check verifies that TogglePFactory was requested and that one of the prolongator factories
94  // within TogglePFactory is a PgPFactory. RfromP_Or_TransP's DeclareInput then invokes DeclareDependencies, and
95  // DeclareInput for the PgPFactory. The check within Build(), looks at "RfromPFactory" to see if it is an integer. This
96  // integer is used to find the prolongator factory that is invoked in RestrictionMode to produce R. Otherwise,
97  // "RfromPFactory" is used to get the pre-computed restriction matrix. If "RfromPFactory" is not present, then RfromP_Or_TransP
98  // just transposes P to get R.
99 
100  RCP<const FactoryBase> PFact = coarseLevel.GetFactoryManager()->GetFactory("P");
101  if (PFact == Teuchos::null) {
102  PFact = GetFactory("P");
103  }
104  coarseLevel.DeclareInput("P", PFact.get(), this);
106  if (myToggleFact != Teuchos::null) {
107  for (size_t ii = 0; ii < myToggleFact->NumProlongatorFactories(); ii++) {
109  if (actualPFact != Teuchos::null) {
110  RCP<PFactory> subFactory = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory(ii)));
111  ;
112  bool rmode = subFactory->isRestrictionModeSet();
113  subFactory->setRestrictionMode(true);
114  // Force request call for actualPFact
115  coarseLevel.DeclareDependencies(actualPFact.get());
116  coarseLevel.DeclareInput("R", actualPFact.get(), this);
117  subFactory->setRestrictionMode(rmode);
118  }
119  }
120  }
121 }
122 
123 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
125  FactoryMonitor m(*this, "Transpose P", coarseLevel);
126  std::string label = "MueLu::TransP-" + Teuchos::toString(coarseLevel.GetLevelID());
127 
128  const Teuchos::ParameterList& pL = GetParameterList();
129 
130  // Reuse pattern if available (multiple solve)
131  RCP<ParameterList> Tparams;
132  if (pL.isSublist("matrixmatrix: kernel params"))
133  Tparams = rcp(new ParameterList(pL.sublist("matrixmatrix: kernel params")));
134  else
135  Tparams = rcp(new ParameterList);
136 
137  // By default, we don't need global constants for transpose
138  Tparams->set("compute global constants: temporaries", Tparams->get("compute global constants: temporaries", false));
139  Tparams->set("compute global constants", Tparams->get("compute global constants", false));
140 
141  RCP<Matrix> R;
142  RCP<const FactoryBase> PFact = coarseLevel.GetFactoryManager()->GetFactory("P");
143  if (PFact == Teuchos::null) {
144  PFact = GetFactory("P");
145  }
146 
147  RCP<Matrix> P = coarseLevel.Get<RCP<Matrix>>("P", PFact.get());
148 
149  if (coarseLevel.IsAvailable("RfromPfactory", PFact.get())) {
150  std::string strType = coarseLevel.GetTypeName("RfromPfactory", PFact.get());
151  // Address case where a toggle factory is used in conjunction with a PgP factory. Here,
152  // we need to invoke the PgP factory a 2nd time to produce restriction. In this
153  // situation the PgP factory puts an int RfromPfactory on the level.
154  //
155  // See comments aboove in DeclareInput() method for more detailsd
156  if (strType == "int") {
158  ;
159  if (myToggleFact != Teuchos::null) {
160  MueLu::DisableMultipleCallCheck check(myToggleFact);
161  RCP<PFactory> actualPFact = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory((size_t)coarseLevel.Get<int>("RfromPfactory", PFact.get()))));
162  // toggle factory sets RfromPfactory to correct index into prolongatorFactory array
163  MueLu::DisableMultipleCallCheck check2(actualPFact);
164  bool rmode = actualPFact->isRestrictionModeSet();
165  actualPFact->setRestrictionMode(true);
166  R = coarseLevel.Get<RCP<Matrix>>("R", actualPFact.get());
167  actualPFact->setRestrictionMode(rmode);
168  } else
169  R = Utilities::Transpose(*P, true, label, Tparams);
170  } else
171  R = coarseLevel.Get<RCP<Matrix>>("RfromPfactory", PFact.get());
172  } else
173  R = Utilities::Transpose(*P, true, label, Tparams);
174 
175  if (IsPrint(Statistics2)) {
176  RCP<ParameterList> params = rcp(new ParameterList());
177  params->set("printLoadBalancingInfo", true);
178  params->set("printCommInfo", true);
179  GetOStream(Statistics2) << PerfUtils::PrintMatrixInfo(*R, "R", params);
180  }
181 
182  Set(coarseLevel, "R", R);
183 
185  if (P->IsView("stridedMaps"))
186  R->CreateView("stridedMaps", P, true);
188 }
189 
190 } // namespace MueLu
191 
192 #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)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
void setRestrictionMode(bool bRestrictionMode=false)
T * get() const
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:99
std::string GetTypeName(const std::string &ename, const FactoryBase *factory=NoFactory::get())
GetTypeName returns type string of variable stored using ename and factory.
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:96
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
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.