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// ***********************************************************************
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
49#include <Teuchos_ParameterList.hpp>
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
66namespace 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) { PFact = GetFactory("P"); }
102 coarseLevel.DeclareInput("P", PFact.get(), this);
103 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));
104 if (myToggleFact != Teuchos::null) {
105 for (size_t ii = 0; ii < myToggleFact->NumProlongatorFactories(); ii++) {
106 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)));
107 if (actualPFact != Teuchos::null) {
108 RCP<PFactory> subFactory = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory(ii)));;
109 bool rmode = subFactory->isRestrictionModeSet();
110 subFactory->setRestrictionMode(true);
111 // Force request call for actualPFact
112 coarseLevel.DeclareDependencies(actualPFact.get());
113 coarseLevel.DeclareInput("R", actualPFact.get(), this);
114 subFactory->setRestrictionMode(rmode);
115 }
116 }
117 }
118 }
119
120 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
122 FactoryMonitor m(*this, "Transpose P", coarseLevel);
123 std::string label = "MueLu::TransP-" + Teuchos::toString(coarseLevel.GetLevelID());
124
125 const Teuchos::ParameterList& pL = GetParameterList();
126
127 // Reuse pattern if available (multiple solve)
128 RCP<ParameterList> Tparams;
129 if(pL.isSublist("matrixmatrix: kernel params"))
130 Tparams=rcp(new ParameterList(pL.sublist("matrixmatrix: kernel params")));
131 else
132 Tparams= rcp(new ParameterList);
133
134 // By default, we don't need global constants for transpose
135 Tparams->set("compute global constants: temporaries",Tparams->get("compute global constants: temporaries",false));
136 Tparams->set("compute global constants",Tparams->get("compute global constants",false));
137
138 RCP<Matrix> R;
139 RCP<const FactoryBase> PFact = coarseLevel.GetFactoryManager()->GetFactory("P");
140 if (PFact == Teuchos::null) { PFact = GetFactory("P"); }
141
142 RCP<Matrix> P = coarseLevel.Get< RCP<Matrix> >("P", PFact.get());
143
144 if (coarseLevel.IsAvailable("RfromPfactory", PFact.get()))
145 {
146 std::string strType = coarseLevel.GetTypeName("RfromPfactory", PFact.get());
147 // Address case where a toggle factory is used in conjunction with a PgP factory. Here,
148 // we need to invoke the PgP factory a 2nd time to produce restriction. In this
149 // situation the PgP factory puts an int RfromPfactory on the level.
150 //
151 // See comments aboove in DeclareInput() method for more detailsd
152 if (strType == "int") {
153 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));;
154 if (myToggleFact != Teuchos::null) {
155 MueLu::DisableMultipleCallCheck check(myToggleFact);
156 RCP<PFactory> actualPFact = Teuchos::rcp_const_cast<PFactory>(rcp_dynamic_cast<const PFactory>(myToggleFact->getProlongatorFactory((size_t) coarseLevel.Get<int>("RfromPfactory", PFact.get()))));
157 // toggle factory sets RfromPfactory to correct index into prolongatorFactory array
158 MueLu::DisableMultipleCallCheck check2(actualPFact);
159 bool rmode = actualPFact->isRestrictionModeSet();
160 actualPFact->setRestrictionMode(true);
161 R = coarseLevel.Get<RCP<Matrix> >("R",actualPFact.get());
162 actualPFact->setRestrictionMode(rmode);
163 }
164 else R = Utilities::Transpose(*P, true,label,Tparams);
165 }
166 else R = coarseLevel.Get< RCP<Matrix> >("RfromPfactory", PFact.get());
167 }
168 else
169 R = Utilities::Transpose(*P, true,label,Tparams);
170
171 if (IsPrint(Statistics2)) {
172 RCP<ParameterList> params = rcp(new ParameterList());
173 params->set("printLoadBalancingInfo", true);
174 params->set("printCommInfo", true);
175 GetOStream(Statistics2) << PerfUtils::PrintMatrixInfo(*R, "R", params);
176 }
177
178 Set(coarseLevel, "R", R);
179
181 if (P->IsView("stridedMaps"))
182 R->CreateView("stridedMaps", P, true);
184
185 }
186
187} //namespace MueLu
188
189#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.
Definition: MueLu_Level.hpp:99
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
Definition: MueLu_Level.cpp:96
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
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.