MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_ReplicatePFactory_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_REPLICATEPFACTORY_DEF_HPP
11 #define MUELU_REPLICATEPFACTORY_DEF_HPP
12 
13 #include <stdlib.h>
14 #include <iomanip>
15 
16 // #include <Teuchos_LAPACK.hpp>
20 
21 #include <Xpetra_CrsMatrixWrap.hpp>
22 #include <Xpetra_ImportFactory.hpp>
23 #include <Xpetra_Matrix.hpp>
24 #include <Xpetra_MapFactory.hpp>
25 #include <Xpetra_MultiVectorFactory.hpp>
26 #include <Xpetra_VectorFactory.hpp>
27 
28 #include <Xpetra_IO.hpp>
29 
31 
32 #include "MueLu_Monitor.hpp"
33 
34 namespace MueLu {
35 
36 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
38  RCP<ParameterList> validParamList = rcp(new ParameterList());
39  validParamList->setEntry("replicate: npdes", ParameterEntry(1));
40 
41  return validParamList;
42 }
43 
44 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
46  DeclareInput(Level& fineLevel, Level& /* coarseLevel */) const {
47  // Input(fineLevel, "Psubblock");
48 }
49 
50 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
52  Level& coarseLevel) const {
53  return BuildP(fineLevel, coarseLevel);
54 }
55 
56 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
58  Level& coarseLevel) const {
59  FactoryMonitor m(*this, "Build", coarseLevel);
60 
61  RCP<Matrix> Psubblock = coarseLevel.Get<RCP<Matrix> >("Psubblock", NoFactory::get());
62  const ParameterList& pL = GetParameterList();
63  const LO dofPerNode = as<LO>(pL.get<int>("replicate: npdes"));
64 
65  Teuchos::ArrayRCP<const size_t> amalgRowPtr(Psubblock->getLocalNumRows());
66  Teuchos::ArrayRCP<const LocalOrdinal> amalgCols(Psubblock->getLocalNumEntries());
67  Teuchos::ArrayRCP<const Scalar> amalgVals(Psubblock->getLocalNumEntries());
68  Teuchos::RCP<CrsMatrixWrap> Psubblockwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(Psubblock);
69  Teuchos::RCP<CrsMatrix> Psubblockcrs = Psubblockwrap->getCrsMatrix();
70  Psubblockcrs->getAllValues(amalgRowPtr, amalgCols, amalgVals);
71 
72  size_t paddedNrows = Psubblock->getRowMap()->getLocalNumElements() * Teuchos::as<size_t>(dofPerNode);
73  Teuchos::ArrayRCP<size_t> newPRowPtr(paddedNrows + 1);
74  Teuchos::ArrayRCP<LocalOrdinal> newPCols(Psubblock->getLocalNumEntries() * dofPerNode);
75  Teuchos::ArrayRCP<Scalar> newPVals(Psubblock->getLocalNumEntries() * dofPerNode);
76  size_t cnt = 0; // local id counter
77  for (decltype(amalgRowPtr.size()) i = 0; i < amalgRowPtr.size() - 1; i++) {
78  size_t rowLength = amalgRowPtr[i + 1] - amalgRowPtr[i];
79  for (int j = 0; j < dofPerNode; j++) {
80  newPRowPtr[i * dofPerNode + j] = cnt;
81  for (size_t k = 0; k < rowLength; k++) {
82  newPCols[cnt] = amalgCols[k + amalgRowPtr[i]] * dofPerNode + j;
83  newPVals[cnt++] = amalgVals[k + amalgRowPtr[i]];
84  }
85  }
86  }
87 
88  newPRowPtr[paddedNrows] = cnt; // close row CSR array
89  std::vector<size_t> stridingInfo(1, dofPerNode);
90 
91  GlobalOrdinal nCoarseDofs = Psubblock->getDomainMap()->getLocalNumElements() * dofPerNode;
92  GlobalOrdinal indexBase = Psubblock->getDomainMap()->getIndexBase();
93  RCP<const Map> coarseDomainMap = StridedMapFactory::Build(Psubblock->getDomainMap()->lib(),
95  nCoarseDofs,
96  indexBase,
97  stridingInfo,
98  Psubblock->getDomainMap()->getComm(),
99  -1 /* stridedBlockId */,
100  0 /*domainGidOffset */);
101 
102  size_t nColCoarseDofs = Teuchos::as<size_t>(Psubblock->getColMap()->getLocalNumElements() * dofPerNode);
103  Teuchos::Array<GlobalOrdinal> unsmooshColMapGIDs(nColCoarseDofs);
104  for (size_t c = 0; c < Psubblock->getColMap()->getLocalNumElements(); ++c) {
105  GlobalOrdinal gid = (Psubblock->getColMap()->getGlobalElement(c) - indexBase) * dofPerNode + indexBase;
106 
107  for (int i = 0; i < dofPerNode; ++i) {
108  unsmooshColMapGIDs[c * dofPerNode + i] = gid + i;
109  }
110  }
111  Teuchos::RCP<Map> coarseColMap = MapFactory::Build(Psubblock->getDomainMap()->lib(),
113  unsmooshColMapGIDs(), // View,
114  indexBase,
115  Psubblock->getDomainMap()->getComm());
116 
117  Teuchos::Array<GlobalOrdinal> unsmooshRowMapGIDs(paddedNrows);
118  for (size_t c = 0; c < Psubblock->getRowMap()->getLocalNumElements(); ++c) {
119  GlobalOrdinal gid = (Psubblock->getRowMap()->getGlobalElement(c) - indexBase) * dofPerNode + indexBase;
120 
121  for (int i = 0; i < dofPerNode; ++i) {
122  unsmooshRowMapGIDs[c * dofPerNode + i] = gid + i;
123  }
124  }
125  Teuchos::RCP<Map> fineRowMap = MapFactory::Build(Psubblock->getDomainMap()->lib(),
127  unsmooshRowMapGIDs(), // View,
128  indexBase,
129  Psubblock->getDomainMap()->getComm());
130 
131  Teuchos::RCP<CrsMatrix> bigPCrs = CrsMatrixFactory::Build(fineRowMap, coarseColMap,
132  dofPerNode * Psubblock->getLocalMaxNumRowEntries());
133  for (size_t i = 0; i < paddedNrows; i++) {
134  bigPCrs->insertLocalValues(i,
135  newPCols.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]),
136  newPVals.view(newPRowPtr[i], newPRowPtr[i + 1] - newPRowPtr[i]));
137  }
138  bigPCrs->fillComplete(coarseDomainMap, fineRowMap);
139 
140  Teuchos::RCP<Matrix> bigP = Teuchos::rcp(new CrsMatrixWrap(bigPCrs));
141 
142  Set(coarseLevel, "P", bigP);
143 }
144 
145 } // namespace MueLu
146 
147 #define MUELU_REPLICATEPFACTORY_SHORT
148 #endif // MUELU_REPLICATEPFACTORY_DEF_HPP
ParameterList & setEntry(const std::string &name, U &&entry)
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 BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
Timer to be used in factories. Similar to Monitor but with additional timers.
LocalOrdinal LO
T * get() const
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
static const NoFactory * get()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.