46 #ifndef MUELU_BLOCKEDRAPFACTORY_DEF_HPP
47 #define MUELU_BLOCKEDRAPFACTORY_DEF_HPP
49 #include <Xpetra_BlockedCrsMatrix.hpp>
50 #include <Xpetra_MatrixFactory.hpp>
51 #include <Xpetra_Matrix.hpp>
52 #include <Xpetra_MatrixMatrix.hpp>
53 #include <Xpetra_VectorFactory.hpp>
54 #include <Xpetra_Vector.hpp>
60 #include "MueLu_PerfUtils.hpp"
62 #include "MueLu_Utilities.hpp"
66 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
68 : checkAc_(false), repairZeroDiagonals_(false)
71 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
73 RCP<ParameterList> validParamList = rcp(
new ParameterList());
75 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
77 #undef SET_VALID_ENTRY
78 validParamList->set< RCP<const FactoryBase> >(
"A",
null,
"Generating factory of the matrix A used during the prolongator smoothing process");
79 validParamList->set< RCP<const FactoryBase> >(
"P",
null,
"Prolongator factory");
80 validParamList->set< RCP<const FactoryBase> >(
"R",
null,
"Restrictor factory");
82 return validParamList;
85 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 const Teuchos::ParameterList& pL = GetParameterList();
88 if (pL.get<
bool>(
"transpose: use implicit") ==
false)
89 Input(coarseLevel,
"R");
91 Input(fineLevel,
"A");
92 Input(coarseLevel,
"P");
95 for (std::vector<RCP<const FactoryBase> >::const_iterator it = transferFacts_.begin(); it != transferFacts_.end(); ++it)
96 (*it)->CallDeclareInput(coarseLevel);
99 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
103 const ParameterList& pL = GetParameterList();
105 RCP<Matrix> A = Get< RCP<Matrix> >(fineLevel,
"A");
106 RCP<Matrix> P = Get< RCP<Matrix> >(coarseLevel,
"P");
109 RCP<BlockedCrsMatrix> bA = rcp_dynamic_cast<BlockedCrsMatrix>(A);
110 RCP<BlockedCrsMatrix> bP = rcp_dynamic_cast<BlockedCrsMatrix>(P);
111 TEUCHOS_TEST_FOR_EXCEPTION(bA.is_null() || bP.is_null(),
Exceptions::BadCast,
"Matrices A and P must be of type BlockedCrsMatrix.");
114 RCP<BlockedCrsMatrix> bAP;
115 RCP<BlockedCrsMatrix> bAc;
121 "Block matrix dimensions do not match: "
122 "A is " << bA->Rows() <<
"x" << bA->Cols() <<
123 "P is " << bP->Rows() <<
"x" << bP->Cols());
125 bAP = MatrixMatrix::TwoMatrixMultiplyBlock(*bA,
false, *bP,
false, GetOStream(
Statistics2),
true,
true);
131 bool doOptimizeStorage = !checkAc_;
133 const bool doTranspose =
true;
134 const bool doFillComplete =
true;
135 if (pL.get<
bool>(
"transpose: use implicit") ==
true) {
137 bAc = MatrixMatrix::TwoMatrixMultiplyBlock(*bP, doTranspose, *bAP, !doTranspose, GetOStream(
Statistics2), doFillComplete, doOptimizeStorage);
140 RCP<Matrix> R = Get< RCP<Matrix> >(coarseLevel,
"R");
141 RCP<BlockedCrsMatrix> bR = rcp_dynamic_cast<BlockedCrsMatrix>(R);
142 TEUCHOS_TEST_FOR_EXCEPTION(bR.is_null(),
Exceptions::BadCast,
"Matrix R must be of type BlockedCrsMatrix.");
145 "Block matrix dimensions do not match: "
146 "R is " << bR->Rows() <<
"x" << bR->Cols() <<
147 "A is " << bA->Rows() <<
"x" << bA->Cols());
150 bAc = MatrixMatrix::TwoMatrixMultiplyBlock(*bR, !doTranspose, *bAP, !doTranspose, GetOStream(
Statistics2), doFillComplete, doOptimizeStorage);
155 CheckMainDiagonal(bAc);
170 Set<RCP <Matrix> >(coarseLevel,
"A", bAc);
172 if (transferFacts_.begin() != transferFacts_.end()) {
176 for (std::vector<RCP<const FactoryBase> >::const_iterator it = transferFacts_.begin(); it != transferFacts_.end(); ++it) {
177 RCP<const FactoryBase> fac = *it;
179 GetOStream(
Runtime0) <<
"BlockRAPFactory: call transfer factory: " << fac->description() << std::endl;
181 fac->CallBuild(coarseLevel);
191 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
193 RCP<Matrix> c00 = bAc->getMatrix(0, 0);
194 RCP<Matrix> Aout = MatrixFactory::Build(c00->getRowMap(), c00->getGlobalMaxNumRowEntries(), Xpetra::StaticProfile);
196 RCP<Vector> diagVec = VectorFactory::Build(c00->getRowMap());
197 c00->getLocalDiagCopy(*diagVec);
198 ArrayRCP<SC> diagVal = diagVec->getDataNonConst(0);
201 for (
size_t row = 0; row < c00->getNodeNumRows(); row++) {
203 GO grid = c00->getRowMap()->getGlobalElement(row);
205 ArrayView<const LO> indices;
206 ArrayView<const SC> vals;
207 c00->getLocalRowView(row, indices, vals);
210 ArrayRCP<GO> indout(indices.size(), Teuchos::OrdinalTraits<GO>::zero());
211 ArrayRCP<SC> valout(indices.size(), Teuchos::ScalarTraits<SC>::zero());
214 for (
size_t i = 0; i < as<size_t>(indices.size()); i++) {
215 GO gcid = c00->getColMap()->getGlobalElement(indices[i]);
217 valout [i] = vals[i];
220 Aout->insertGlobalValues(grid, indout.view(0, indout.size()), valout.view(0, valout.size()));
221 if (diagVal[row] == Teuchos::ScalarTraits<SC>::zero() && repairZeroDiagonals) {
223 Aout->insertGlobalValues(grid, Teuchos::tuple<GO>(grid), Teuchos::tuple<SC>(1.0));
227 Aout->fillComplete(c00->getDomainMap(), c00->getRangeMap());
229 bAc->setMatrix(0, 0, Aout);
232 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
235 TEUCHOS_TEST_FOR_EXCEPTION(rcp_dynamic_cast<const TwoLevelFactoryBase>(factory) == Teuchos::null,
Exceptions::BadCast,
236 "Transfer factory is not derived from TwoLevelFactoryBase. This is very strange. "
237 "(Note: you can remove this exception if there's a good reason for)");
238 transferFacts_.push_back(factory);
243 #define MUELU_BLOCKEDRAPFACTORY_SHORT
#define SET_VALID_ENTRY(name)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
static void CheckMainDiagonal(RCP< BlockedCrsMatrix > &bAc, bool repairZeroDiagonals=false)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
void AddTransferFactory(const RCP< const FactoryBase > &factory)
Add transfer factory in the end of list of transfer factories in RepartitionAcFactory.
Exception indicating invalid cast attempted.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
void Release(const FactoryBase &factory)
Decrement the storage counter for all the inputs of a factory.
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
Namespace for MueLu classes and methods.
@ Statistics2
Print even more statistics.
@ Statistics1
Print more statistics.
@ Runtime0
One-liner description of what is happening.