MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_MultiPhys_def.hpp
Go to the documentation of this file.
1//
2// ***********************************************************************
3//
4// MueLu: A package for multigrid based preconditioning
5// Copyright 2012 Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact
38// Jonathan Hu (jhu@sandia.gov)
39// Andrey Prokopenko (aprokop@sandia.gov)
40// Ray Tuminaro (rstumin@sandia.gov)
41//
42// ***********************************************************************
43//
44// @HEADER
45#ifndef MUELU_MULTIPHYS_DEF_HPP
46#define MUELU_MULTIPHYS_DEF_HPP
47
48#include <sstream>
49#include "MueLu_ConfigDefs.hpp"
50
51#include "Xpetra_Map.hpp"
52#include "Xpetra_CrsMatrixUtils.hpp"
53#include "Xpetra_MatrixUtils.hpp"
54
56#include "MueLu_SaPFactory.hpp"
57#include "MueLu_AggregationExportFactory.hpp"
58#include "MueLu_Utilities.hpp"
59#include "MueLu_Level.hpp"
60#include "MueLu_Hierarchy.hpp"
61#include "MueLu_RAPFactory.hpp"
62#include "MueLu_Monitor.hpp"
63#include "MueLu_PerfUtils.hpp"
64#include "MueLu_ParameterListInterpreter.hpp"
66#include <MueLu_HierarchyUtils.hpp>
67#if defined(HAVE_MUELU_KOKKOS_REFACTOR)
68# include "MueLu_Utilities_kokkos.hpp"
69#endif
73
74#ifdef HAVE_MUELU_CUDA
75#include "cuda_profiler_api.h"
76#endif
77
78namespace MueLu {
79
80
81 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
82 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::getDomainMap() const {
83 return AmatMultiphysics_->getDomainMap();
84 }
85
86
87 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
88 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::getRangeMap() const {
89 return AmatMultiphysics_->getRangeMap();
90 }
91
92
93 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
95
96 // this operator only makes sense for the Combo when using TransP for R
97
98 list.set("multigrid algorithm","combine");
99 list.set("combine: numBlks",nBlks_);
100
101 // Make sure verbosity gets passed to the sublists
102 std::string verbosity = list.get("verbosity","high");
104
106 for (int i = 0 ; i < nBlks_; i++) {
107 std::string listName = "subblockList" + Teuchos::toString(i);
108 if(list.isSublist(listName)) {
109 arrayOfParamLists_[i] = Teuchos::rcpFromRef(list.sublist(listName));
110 }
111 else
112 TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "Must provide sublist " + listName);
113
114 arrayOfParamLists_[i]->set("verbosity",arrayOfParamLists_[i]->get("verbosity",verbosity));
115 arrayOfParamLists_[i]->set("smoother: pre or post","none");
116 arrayOfParamLists_[i]->set("smoother: type", "none");
117 }
118
119 // Are we using Kokkos?
120#if !defined(HAVE_MUELU_KOKKOS_REFACTOR)
121 useKokkos_ = false;
122#else
123# ifdef HAVE_MUELU_SERIAL
124 if (typeid(Node).name() == typeid(Kokkos::Compat::KokkosSerialWrapperNode).name())
125 useKokkos_ = false;
126# endif
127# ifdef HAVE_MUELU_OPENMP
128 if (typeid(Node).name() == typeid(Kokkos::Compat::KokkosOpenMPWrapperNode).name())
129 useKokkos_ = true;
130# endif
131# ifdef HAVE_MUELU_CUDA
132 if (typeid(Node).name() == typeid(Kokkos::Compat::KokkosCudaWrapperNode).name())
133 useKokkos_ = true;
134# endif
135 useKokkos_ = list.get("use kokkos refactor",useKokkos_);
136#endif
137
138 paramListMultiphysics_ = Teuchos::rcpFromRef(list);
139 }
140
141
142 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
144 /*
145
146 Create a set of AMG hierarchies whose interpolation matrices are used to build on combined
147 AMG hierarchy for a multiphysics problem
148
149 */
150
151//#ifdef HAVE_MUELU_CUDA
152// if (paramListMultiphysics_.get<bool>("multiphysics: cuda profile setup", false)) cudaProfilerStart();
153//#endif
154
155 std::string timerLabel;
156 if (reuse)
157 timerLabel = "MueLu MultiPhys: compute (reuse)";
158 else
159 timerLabel = "MueLu MultiPhys: compute";
160 RCP<Teuchos::TimeMonitor> tmCompute = getTimer(timerLabel);
161
163 // Generate the (iii,iii) Hierarchy
164
165 for (int iii = 0; iii < nBlks_; iii++) {
166 arrayOfParamLists_[iii]->sublist("user data").set("Coordinates",arrayOfCoords_[iii]);
167
168 bool wantToRepartition = false;
169 if (paramListMultiphysics_->isParameter("repartition: enable"))
170 wantToRepartition = paramListMultiphysics_->get<bool>("repartition: enable");
171
172 arrayOfParamLists_[iii]->set("repartition: enable",wantToRepartition);
173 arrayOfParamLists_[iii]->set("repartition: rebalance P and R",true);
174 arrayOfParamLists_[iii]->set("repartition: explicit via new copy rebalance P and R",true);
175
176 if (paramListMultiphysics_->isParameter("repartition: use subcommunicators"))
177 arrayOfParamLists_[iii]->set("repartition: use subcommunicators", paramListMultiphysics_->isParameter("repartition: use subcommunicators"));
178 else
179 arrayOfParamLists_[iii]->set("repartition: use subcommunicators", true);
180 }
181 // repartitioning should only happen when createing the individual P's , not
182 // when combiing them
183
184 paramListMultiphysics_->set<bool>("repartition: enable", false);
185
186
187 LO maxLevels = 9999;
188 for (int i = 0; i < nBlks_; i++) {
189 std::string operatorLabel = "MultiPhys (" + Teuchos::toString(i) + "," + Teuchos::toString(i) + ")"; arrayOfAuxMatrices_[i]->setObjectLabel(operatorLabel);
191 LO tempNlevels = arrayOfHierarchies_[i]->GetGlobalNumLevels();
192 if (tempNlevels < maxLevels) maxLevels = tempNlevels;
193 }
194
195 hierarchyMultiphysics_ = rcp(new Hierarchy("Combo"));
196 for (LO i = 0; i < maxLevels; i++) {
197 hierarchyMultiphysics_->AddNewLevel();
198 }
199 for (int i = 0; i < nBlks_; i++) {
200 std::string subblkName = "Psubblock" + Teuchos::toString(i);
202 }
203 paramListMultiphysics_->set("coarse: max size",1);
204 paramListMultiphysics_->set("max levels",maxLevels);
205
206 AmatMultiphysics_->setObjectLabel("A: block " + Teuchos::toString(nBlks_) + " x " + Teuchos::toString(nBlks_) + "multiphysics matrix");
207
208
209 // Rip off non-serializable data before validation
210 Teuchos::ParameterList nonSerialListMultiphysics, processedListMultiphysics;
211 MueLu::ExtractNonSerializableData(*paramListMultiphysics_,processedListMultiphysics, nonSerialListMultiphysics);
212
213 // Rip off the subblock List stuff as we don't need it any more and I think it messes up validator
214
215 Teuchos::ParameterList stripped;
216 for (ParameterList::ConstIterator inListEntry = processedListMultiphysics.begin(); inListEntry != processedListMultiphysics.end(); inListEntry++) {
217 const std::string& levelName = inListEntry->first;
218 if (levelName.find("subblockList") != 0) stripped.setEntry(inListEntry->first, inListEntry->second);
219 }
220
221 RCP<HierarchyManager<SC,LO,GO,NO> > mueLuFactory = rcp(new ParameterListInterpreter<SC,LO,GO,NO>(stripped,AmatMultiphysics_->getDomainMap()->getComm()));
222 hierarchyMultiphysics_->setlib(AmatMultiphysics_->getDomainMap()->lib());
223 hierarchyMultiphysics_->SetProcRankVerbose(AmatMultiphysics_->getDomainMap()->getComm()->getRank());
224
225 // We don't need nullspace or coordinates, since we don't use them when just combining prolongators that have been already created
226 hierarchyMultiphysics_->GetLevel(0)->Set("A", AmatMultiphysics_);
227
228 // Stick the non-serializible data on the hierarchy.
229 // Not sure that we need this, since we don't use it in building the multiphysics hierarchy
231 mueLuFactory->SetupHierarchy(*hierarchyMultiphysics_);
232
234
235 }
236
237 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
238 Teuchos::RCP<Teuchos::TimeMonitor> MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::getTimer(std::string name, RCP<const Teuchos::Comm<int> > comm) const {
239 if (IsPrint(Timings)) {
240 if (!syncTimers_)
241 return Teuchos::rcp(new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(name)));
242 else {
243 if (comm.is_null())
244 return Teuchos::rcp(new Teuchos::SyncTimeMonitor(*Teuchos::TimeMonitor::getNewTimer(name), AmatMultiphysics_->getRowMap()->getComm().ptr()));
245 else
246 return Teuchos::rcp(new Teuchos::SyncTimeMonitor(*Teuchos::TimeMonitor::getNewTimer(name), comm.ptr()));
247 }
248 } else
249 return Teuchos::null;
250 }
251
252 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
253 void MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::resetMatrix(RCP<Matrix> AmatMultiphysics_new, bool ComputePrec) {
254 bool reuse = !AmatMultiphysics_.is_null();
255 AmatMultiphysics_ = AmatMultiphysics_new;
256 if (ComputePrec) compute(reuse);
257 }
258
259 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
260 void MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::applyInverse(const MultiVector& RHS, MultiVector& X) const {
261 hierarchyMultiphysics_->Iterate(RHS,X,1,true);
262 }
263
264 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
265 void MultiPhys<Scalar,LocalOrdinal,GlobalOrdinal,Node>::apply (const MultiVector& RHS, MultiVector& X,
266 Teuchos::ETransp /* mode */,
267 Scalar /* alpha */,
268 Scalar /* beta */) const {
269 RCP<Teuchos::TimeMonitor> tm = getTimer("MueLu MultiPhys: solve");
270 hierarchyMultiphysics_->Iterate(RHS,X,1,true);
271 }
272
273
274
275 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
279
280
281 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
283 initialize(const Teuchos::RCP<Matrix> & AmatMultiPhysics,
284 const Teuchos::ArrayRCP<RCP<Matrix>> arrayOfAuxMatrices,
285 const Teuchos::ArrayRCP<Teuchos::RCP<MultiVector>> arrayOfNullspaces,
286 const Teuchos::ArrayRCP<Teuchos::RCP<RealValuedMultiVector>> arrayOfCoords,
287 const int nBlks,
288 Teuchos::ParameterList& List)
289 {
291 for (int i = 0; i < nBlks_; i++) arrayOfHierarchies_[i] = Teuchos::null;
292
293
294 // Default settings
295 useKokkos_=false;
296 enable_reuse_=false;
297 syncTimers_=false;
298
299
300 // set parameters
301 setParameters(List);
302
303 } // initialize
304
305
306
307 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
309 describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel /* verbLevel */) const {
310
311 std::ostringstream oss;
312
313 RCP<const Teuchos::Comm<int> > comm = AmatMultiphysics_->getDomainMap()->getComm();
314
315
316 oss << "\n--------------------------------------------------------------------------------\n" <<
317 "--- MultiPhysics Summary ---\n"
318 "--------------------------------------------------------------------------------" << std::endl;
319 oss << std::endl;
320
321 GlobalOrdinal numRows;
322 GlobalOrdinal nnz;
323
324 AmatMultiphysics_->getRowMap()->getComm()->barrier();
325
326 for (int i = 0; i < nBlks_; i++) {
327 numRows = arrayOfAuxMatrices_[i]->getGlobalNumRows();
328 nnz = arrayOfAuxMatrices_[i]->getGlobalNumEntries();
329 Xpetra::global_size_t tt = numRows;
330 int rowspacer = 3; while (tt != 0) { tt /= 10; rowspacer++; }
331 tt = nnz;
332 int nnzspacer = 2; while (tt != 0) { tt /= 10; nnzspacer++; }
333
334 oss << "block " << std::setw(rowspacer) << " rows " << std::setw(nnzspacer) << " nnz " << std::setw(9) << " nnz/row" << std::endl;
335 oss << "(" << Teuchos::toString(i) << ", " << Teuchos::toString(i) << ")" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
336 }
337 oss << std::endl;
338
339
340 for (int i = 0; i < nBlks_; i++) {
341 arrayOfHierarchies_[i]->describe(out, GetVerbLevel());
342 }
343
344
345
346 } // describe
347
348
349
350} // namespace
351
352#define MUELU_MULTIPHYS_SHORT
353#endif //ifdef MUELU_MULTIPHYS_DEF_HPP
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
MueLu::DefaultNode Node
Exception throws to report errors in the internal logical of the program.
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
Add non-serializable data to Hierarchy.
static void CopyBetweenHierarchies(Hierarchy &fromHierarchy, Hierarchy &toHierarchy, const std::string fromLabel, const std::string toLabel, const std::string dataType)
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
Teuchos::RCP< Hierarchy > hierarchyMultiphysics_
Teuchos::RCP< Teuchos::TimeMonitor > getTimer(std::string name, RCP< const Teuchos::Comm< int > > comm=Teuchos::null) const
get a (synced) timer
Teuchos::ArrayRCP< Teuchos::RCP< Matrix > > arrayOfAuxMatrices_
void compute(bool reuse=false)
Setup the preconditioner.
void applyInverse(const MultiVector &RHS, MultiVector &X) const
apply standard MultiPhys cycle
Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.
void setParameters(Teuchos::ParameterList &list)
Set parameters.
void resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new, bool ComputePrec=true)
Reset system matrix.
Teuchos::RCP< Matrix > AmatMultiphysics_
Hierarchies: used to define P for (0,0)-block, .... (nBlks_-1,nBlks_-1) block.
Teuchos::ArrayRCP< Teuchos::RCP< Hierarchy > > arrayOfHierarchies_
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
Teuchos::RCP< Teuchos::ParameterList > paramListMultiphysics_
Teuchos::ArrayRCP< Teuchos::RCP< RealValuedMultiVector > > arrayOfCoords_
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_HIGH) const
void initialize(const Teuchos::RCP< Matrix > &AmatMultiPhysics, const Teuchos::ArrayRCP< RCP< Matrix > > arrayOfAuxMatrices, const Teuchos::ArrayRCP< Teuchos::RCP< MultiVector > > arrayOfNullspaces, const Teuchos::ArrayRCP< Teuchos::RCP< RealValuedMultiVector > > arrayOfCoords, const int nBlks, Teuchos::ParameterList &List)
void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
Teuchos::ArrayRCP< Teuchos::RCP< Teuchos::ParameterList > > arrayOfParamLists_
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
VerbLevel GetVerbLevel() const
Get the verbosity level.
bool IsPrint(MsgType type, int thisProcRankOnly=-1) const
Find out whether we need to print out information for a specific message type.
static void SetDefaultVerbLevel(const VerbLevel defaultVerbLevel)
Set the default (global) verbosity level.
Namespace for MueLu classes and methods.
long ExtractNonSerializableData(const Teuchos::ParameterList &inList, Teuchos::ParameterList &serialList, Teuchos::ParameterList &nonSerialList)
Extract non-serializable data from level-specific sublists and move it to a separate parameter list.
@ Runtime0
One-liner description of what is happening.
@ Timings
Print all timing information.
MsgType toVerbLevel(const std::string &verbLevelStr)
Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateXpetraPreconditioner(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > op, const Teuchos::ParameterList &inParamList)
Helper function to create a MueLu preconditioner that can be used by Xpetra.Given an Xpetra::Matrix,...