MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
53 #include "Xpetra_MatrixUtils.hpp"
54 
55 #include "MueLu_MultiPhys_decl.hpp"
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
70 #include "MueLu_VerbosityLevel.hpp"
73 
74 #ifdef HAVE_MUELU_CUDA
75 #include "cuda_profiler_api.h"
76 #endif
77 
78 namespace MueLu {
79 
80 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
82  return AmatMultiphysics_->getDomainMap();
83 }
84 
85 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
87  return AmatMultiphysics_->getRangeMap();
88 }
89 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  // this operator only makes sense for the Combo when using TransP for R
93 
94  list.set("multigrid algorithm", "combine");
95  list.set("combine: numBlks", nBlks_);
96 
97  // Make sure verbosity gets passed to the sublists
98  std::string verbosity = list.get("verbosity", "high");
100 
101  arrayOfParamLists_.resize(nBlks_);
102  for (int i = 0; i < nBlks_; i++) {
103  std::string listName = "subblockList" + Teuchos::toString(i);
104  if (list.isSublist(listName)) {
105  arrayOfParamLists_[i] = Teuchos::rcpFromRef(list.sublist(listName));
106  } else
107  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "Must provide sublist " + listName);
108 
109  arrayOfParamLists_[i]->set("verbosity", arrayOfParamLists_[i]->get("verbosity", verbosity));
110  arrayOfParamLists_[i]->set("smoother: pre or post", "none");
111  arrayOfParamLists_[i]->set("smoother: type", "none");
112  }
113 
114  // Are we using Kokkos?
115  useKokkos_ = !Node::is_serial;
116  useKokkos_ = list.get("use kokkos refactor", useKokkos_);
117 
118  paramListMultiphysics_ = Teuchos::rcpFromRef(list);
119 }
120 
121 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
123  /*
124 
125  Create a set of AMG hierarchies whose interpolation matrices are used to build on combined
126  AMG hierarchy for a multiphysics problem
127 
128  */
129 
130  //#ifdef HAVE_MUELU_CUDA
131  // if (paramListMultiphysics_.get<bool>("multiphysics: cuda profile setup", false)) cudaProfilerStart();
132  //#endif
133 
134  std::string timerLabel;
135  if (reuse)
136  timerLabel = "MueLu MultiPhys: compute (reuse)";
137  else
138  timerLabel = "MueLu MultiPhys: compute";
139  RCP<Teuchos::TimeMonitor> tmCompute = getTimer(timerLabel);
140 
142  // Generate the (iii,iii) Hierarchy
143 
144  for (int iii = 0; iii < nBlks_; iii++) {
145  arrayOfParamLists_[iii]->sublist("user data").set("Coordinates", arrayOfCoords_[iii]);
146 
147  bool wantToRepartition = false;
148  if (paramListMultiphysics_->isParameter("repartition: enable"))
149  wantToRepartition = paramListMultiphysics_->get<bool>("repartition: enable");
150 
151  arrayOfParamLists_[iii]->set("repartition: enable", wantToRepartition);
152  arrayOfParamLists_[iii]->set("repartition: rebalance P and R", true);
153  arrayOfParamLists_[iii]->set("repartition: explicit via new copy rebalance P and R", true);
154 
155  if (paramListMultiphysics_->isParameter("repartition: use subcommunicators"))
156  arrayOfParamLists_[iii]->set("repartition: use subcommunicators", paramListMultiphysics_->isParameter("repartition: use subcommunicators"));
157  else
158  arrayOfParamLists_[iii]->set("repartition: use subcommunicators", true);
159  }
160  // repartitioning should only happen when createing the individual P's , not
161  // when combiing them
162 
163  paramListMultiphysics_->set<bool>("repartition: enable", false);
164 
165  LO maxLevels = 9999;
166  for (int i = 0; i < nBlks_; i++) {
167  std::string operatorLabel = "MultiPhys (" + Teuchos::toString(i) + "," + Teuchos::toString(i) + ")";
168  arrayOfAuxMatrices_[i]->setObjectLabel(operatorLabel);
169  arrayOfHierarchies_[i] = MueLu::CreateXpetraPreconditioner(arrayOfAuxMatrices_[i], *arrayOfParamLists_[i]);
170  LO tempNlevels = arrayOfHierarchies_[i]->GetGlobalNumLevels();
171  if (tempNlevels < maxLevels) maxLevels = tempNlevels;
172  }
173 
174  hierarchyMultiphysics_ = rcp(new Hierarchy("Combo"));
175  for (LO i = 0; i < maxLevels; i++) {
176  hierarchyMultiphysics_->AddNewLevel();
177  }
178  for (int i = 0; i < nBlks_; i++) {
179  std::string subblkName = "Psubblock" + Teuchos::toString(i);
180  MueLu::HierarchyUtils<SC, LO, GO, NO>::CopyBetweenHierarchies(*(arrayOfHierarchies_[i]), *(hierarchyMultiphysics_), "P", subblkName, "RCP<Matrix>");
181  }
182  paramListMultiphysics_->set("coarse: max size", 1);
183  paramListMultiphysics_->set("max levels", maxLevels);
184 
185  AmatMultiphysics_->setObjectLabel("A: block " + Teuchos::toString(nBlks_) + " x " + Teuchos::toString(nBlks_) + "multiphysics matrix");
186 
187  // Rip off non-serializable data before validation
188  Teuchos::ParameterList nonSerialListMultiphysics, processedListMultiphysics;
189  MueLu::ExtractNonSerializableData(*paramListMultiphysics_, processedListMultiphysics, nonSerialListMultiphysics);
190 
191  // Rip off the subblock List stuff as we don't need it any more and I think it messes up validator
192 
193  Teuchos::ParameterList stripped;
194  for (ParameterList::ConstIterator inListEntry = processedListMultiphysics.begin(); inListEntry != processedListMultiphysics.end(); inListEntry++) {
195  const std::string& levelName = inListEntry->first;
196  if (levelName.find("subblockList") != 0) stripped.setEntry(inListEntry->first, inListEntry->second);
197  }
198 
199  RCP<HierarchyManager<SC, LO, GO, NO>> mueLuFactory = rcp(new ParameterListInterpreter<SC, LO, GO, NO>(stripped, AmatMultiphysics_->getDomainMap()->getComm()));
200  hierarchyMultiphysics_->setlib(AmatMultiphysics_->getDomainMap()->lib());
201  hierarchyMultiphysics_->SetProcRankVerbose(AmatMultiphysics_->getDomainMap()->getComm()->getRank());
202 
203  // We don't need nullspace or coordinates, since we don't use them when just combining prolongators that have been already created
204  hierarchyMultiphysics_->GetLevel(0)->Set("A", AmatMultiphysics_);
205 
206  // Stick the non-serializible data on the hierarchy.
207  // Not sure that we need this, since we don't use it in building the multiphysics hierarchy
208  HierarchyUtils<SC, LO, GO, NO>::AddNonSerializableDataToHierarchy(*mueLuFactory, *hierarchyMultiphysics_, nonSerialListMultiphysics);
209  mueLuFactory->SetupHierarchy(*hierarchyMultiphysics_);
210 
211  describe(GetOStream(Runtime0));
212 }
213 
214 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
216  if (IsPrint(Timings)) {
217  if (!syncTimers_)
219  else {
220  if (comm.is_null())
221  return Teuchos::rcp(new Teuchos::SyncTimeMonitor(*Teuchos::TimeMonitor::getNewTimer(name), AmatMultiphysics_->getRowMap()->getComm().ptr()));
222  else
224  }
225  } else
226  return Teuchos::null;
227 }
228 
229 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
231  bool reuse = !AmatMultiphysics_.is_null();
232  AmatMultiphysics_ = AmatMultiphysics_new;
233  if (ComputePrec) compute(reuse);
234 }
235 
236 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
238  hierarchyMultiphysics_->Iterate(RHS, X, 1, true);
239 }
240 
241 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
243  Teuchos::ETransp /* mode */,
244  Scalar /* alpha */,
245  Scalar /* beta */) const {
246  RCP<Teuchos::TimeMonitor> tm = getTimer("MueLu MultiPhys: solve");
247  hierarchyMultiphysics_->Iterate(RHS, X, 1, true);
248 }
249 
250 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
252  return false;
253 }
254 
255 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
257  initialize(const Teuchos::RCP<Matrix>& AmatMultiPhysics,
258  const Teuchos::ArrayRCP<RCP<Matrix>> arrayOfAuxMatrices,
259  const Teuchos::ArrayRCP<Teuchos::RCP<MultiVector>> arrayOfNullspaces,
261  const int nBlks,
262  Teuchos::ParameterList& List) {
263  arrayOfHierarchies_.resize(nBlks_);
264  for (int i = 0; i < nBlks_; i++) arrayOfHierarchies_[i] = Teuchos::null;
265 
266  // Default settings
267  useKokkos_ = false;
268  enable_reuse_ = false;
269  syncTimers_ = false;
270 
271  // set parameters
272  setParameters(List);
273 
274 } // initialize
275 
276 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
278  describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel /* verbLevel */) const {
279  std::ostringstream oss;
280 
281  RCP<const Teuchos::Comm<int>> comm = AmatMultiphysics_->getDomainMap()->getComm();
282 
283  oss << "\n--------------------------------------------------------------------------------\n"
284  << "--- MultiPhysics Summary ---\n"
285  "--------------------------------------------------------------------------------"
286  << std::endl;
287  oss << std::endl;
288 
289  GlobalOrdinal numRows;
290  GlobalOrdinal nnz;
291 
292  AmatMultiphysics_->getRowMap()->getComm()->barrier();
293 
294  for (int i = 0; i < nBlks_; i++) {
295  numRows = arrayOfAuxMatrices_[i]->getGlobalNumRows();
296  nnz = arrayOfAuxMatrices_[i]->getGlobalNumEntries();
297  Xpetra::global_size_t tt = numRows;
298  int rowspacer = 3;
299  while (tt != 0) {
300  tt /= 10;
301  rowspacer++;
302  }
303  tt = nnz;
304  int nnzspacer = 2;
305  while (tt != 0) {
306  tt /= 10;
307  nnzspacer++;
308  }
309 
310  oss << "block " << std::setw(rowspacer) << " rows " << std::setw(nnzspacer) << " nnz " << std::setw(9) << " nnz/row" << std::endl;
311  oss << "(" << Teuchos::toString(i) << ", " << Teuchos::toString(i) << ")" << std::setw(rowspacer) << numRows << std::setw(nnzspacer) << nnz << std::setw(9) << as<double>(nnz) / numRows << std::endl;
312  }
313  oss << std::endl;
314 
315  for (int i = 0; i < nBlks_; i++) {
316  arrayOfHierarchies_[i]->describe(out, GetVerbLevel());
317  }
318 
319 } // describe
320 
321 } // namespace MueLu
322 
323 #define MUELU_MULTIPHYS_SHORT
324 #endif // ifdef MUELU_MULTIPHYS_DEF_HPP
ParameterList & setEntry(const std::string &name, U &&entry)
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
ConstIterator end() const
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
Add non-serializable data to Hierarchy.
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)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
LocalOrdinal LO
One-liner description of what is happening.
void setParameters(Teuchos::ParameterList &list)
Set parameters.
MsgType toVerbLevel(const std::string &verbLevelStr)
static RCP< Time > getNewTimer(const std::string &name)
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...
static void SetDefaultVerbLevel(const VerbLevel defaultVerbLevel)
Set the default (global) verbosity level.
void applyInverse(const MultiVector &RHS, MultiVector &X) const
apply standard MultiPhys cycle
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
const Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
const Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
bool isSublist(const std::string &name) const
params_t::ConstIterator ConstIterator
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_HIGH) const
ConstIterator begin() const
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
Teuchos::RCP< Teuchos::TimeMonitor > getTimer(std::string name, RCP< const Teuchos::Comm< int >> comm=Teuchos::null) const
get a (synced) timer
size_t global_size_t
Print all timing information.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
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
Exception throws to report errors in the internal logical of the program.
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 resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new, bool ComputePrec=true)
Reset system matrix.
void compute(bool reuse=false)
Setup the preconditioner.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
std::string toString(const T &t)
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...
static void CopyBetweenHierarchies(Hierarchy &fromHierarchy, Hierarchy &toHierarchy, const std::string fromLabel, const std::string toLabel, const std::string dataType)