53 #ifndef MUELU_BLOCKEDPFACTORY_DEF_HPP_ 54 #define MUELU_BLOCKEDPFACTORY_DEF_HPP_ 56 #include <Xpetra_VectorFactory.hpp> 57 #include <Xpetra_ImportFactory.hpp> 58 #include <Xpetra_ExportFactory.hpp> 59 #include <Xpetra_CrsMatrixWrap.hpp> 61 #include <Xpetra_BlockedCrsMatrix.hpp> 62 #include <Xpetra_Map.hpp> 63 #include <Xpetra_MapFactory.hpp> 64 #include <Xpetra_MapExtractor.hpp> 65 #include <Xpetra_MapExtractorFactory.hpp> 68 #include "MueLu_TentativePFactory.hpp" 70 #include "MueLu_SmootherFactory.hpp" 71 #include "MueLu_FactoryManager.hpp" 72 #include "MueLu_Utilities.hpp" 74 #include "MueLu_HierarchyHelpers.hpp" 78 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 RCP<ParameterList> validParamList = rcp(
new ParameterList());
82 validParamList->set< RCP<const FactoryBase> >(
"A", null,
"Generating factory of the matrix A (block matrix)");
83 validParamList->set<
bool > (
"backwards",
false,
"Forward/backward order");
85 return validParamList;
88 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
90 Input(fineLevel,
"A");
92 const ParameterList& pL = GetParameterList();
93 const bool backwards = pL.get<
bool>(
"backwards");
95 const int numFactManagers = FactManager_.size();
96 for (
int k = 0; k < numFactManagers; k++) {
97 int i = (backwards ? numFactManagers-1 - k : k);
98 const RCP<const FactoryManagerBase>& factManager = FactManager_[i];
103 if (!restrictionMode_)
104 coarseLevel.
DeclareInput(
"P", factManager->GetFactory(
"P").get(),
this);
106 coarseLevel.
DeclareInput(
"R", factManager->GetFactory(
"R").get(),
this);
111 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
115 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
117 RCP<Matrix> Ain = Get< RCP<Matrix> >(fineLevel,
"A");
119 RCP<BlockedCrsMatrix> A = rcp_dynamic_cast<BlockedCrsMatrix>(Ain);
120 TEUCHOS_TEST_FOR_EXCEPTION(A.is_null(),
Exceptions::BadCast,
"Input matrix A is not a BlockedCrsMatrix.");
122 const int numFactManagers = FactManager_.size();
126 "Number of block rows [" << A->Rows() <<
"] does not match the number of SubFactorManagers [" << numFactManagers <<
"]");
128 "Number of block cols [" << A->Cols() <<
"] does not match the number of SubFactorManagers [" << numFactManagers <<
"]");
132 std::vector<RCP<Matrix> > subBlockP (numFactManagers);
133 std::vector<RCP<const Map> > subBlockPRangeMaps (numFactManagers);
134 std::vector<RCP<const Map> > subBlockPDomainMaps(numFactManagers);
136 std::vector<GO> fullRangeMapVector;
137 std::vector<GO> fullDomainMapVector;
139 const ParameterList& pL = GetParameterList();
140 const bool backwards = pL.get<
bool>(
"backwards");
145 for (
int k = 0; k < numFactManagers; k++) {
146 int i = (backwards ? numFactManagers-1 - k : k);
147 const RCP<const FactoryManagerBase>& factManager = FactManager_[i];
152 if (!restrictionMode_) subBlockP[i] = coarseLevel.
Get<RCP<Matrix> >(
"P", factManager->GetFactory(
"P").get());
153 else subBlockP[i] = coarseLevel.
Get<RCP<Matrix> >(
"R", factManager->GetFactory(
"R").get());
156 TEUCHOS_TEST_FOR_EXCEPTION(subBlockP[i]->IsView(
"stridedMaps") ==
false,
Exceptions::BadCast,
157 "subBlock P operator [" << i <<
"] has no strided map information.");
160 subBlockPRangeMaps[i] = subBlockP[i]->getRowMap(
"stridedMaps");
163 ArrayView<const GO> nodeRangeMap = subBlockPRangeMaps[i]->getNodeElementList();
164 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMap.begin(), nodeRangeMap.end());
165 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
168 subBlockPDomainMaps[i] = subBlockP[i]->getColMap(
"stridedMaps");
171 ArrayView<const GO> nodeDomainMap = subBlockPDomainMaps[i]->getNodeElementList();
172 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMap.begin(), nodeDomainMap.end());
173 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
177 GO rangeIndexBase = 0;
178 GO domainIndexBase = 0;
179 if (!restrictionMode_) {
181 rangeIndexBase = A->getRangeMap() ->getIndexBase();
182 domainIndexBase = A->getDomainMap()->getIndexBase();
186 rangeIndexBase = A->getDomainMap()->getIndexBase();
187 domainIndexBase = A->getRangeMap()->getIndexBase();
193 RCP<const MapExtractor> rangeAMapExtractor = A->getRangeMapExtractor();
194 RCP<const StridedMap> stridedRgFullMap = rcp_dynamic_cast<
const StridedMap>(rangeAMapExtractor->getFullMap());
195 RCP<const Map > fullRangeMap = Teuchos::null;
197 ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0, fullRangeMapVector.size());
198 if (stridedRgFullMap != Teuchos::null) {
199 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
200 fullRangeMap = StridedMapFactory::Build(
201 A->getRangeMap()->lib(),
202 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
206 A->getRangeMap()->getComm(),
209 stridedRgFullMap->getOffset());
211 fullRangeMap = MapFactory::Build(
212 A->getRangeMap()->lib(),
213 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
216 A->getRangeMap()->getComm());
219 RCP<const MapExtractor> domainAMapExtractor = A->getDomainMapExtractor();
220 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0,fullDomainMapVector.size());
221 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<
const StridedMap>(domainAMapExtractor->getFullMap());
222 Teuchos::RCP<const Map > fullDomainMap = Teuchos::null;
223 if (stridedDoFullMap != Teuchos::null) {
224 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap==Teuchos::null,
Exceptions::BadCast,
"MueLu::BlockedPFactory::Build: full map in domain map extractor has no striding information! error.");
225 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
226 fullDomainMap = StridedMapFactory::Build(
227 A->getDomainMap()->lib(),
228 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
232 A->getDomainMap()->getComm(),
235 stridedDoFullMap->getOffset());
237 fullDomainMap = MapFactory::Build(
238 A->getDomainMap()->lib(),
239 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
242 A->getDomainMap()->getComm());
247 RCP<const MapExtractor> rangeMapExtractor = MapExtractorFactory::Build(fullRangeMap, subBlockPRangeMaps);
248 RCP<const MapExtractor> domainMapExtractor = MapExtractorFactory::Build(fullDomainMap, subBlockPDomainMaps);
250 RCP<BlockedCrsMatrix> P = rcp(
new BlockedCrsMatrix(rangeMapExtractor, domainMapExtractor, 10));
251 for (
size_t i = 0; i < subBlockPRangeMaps.size(); i++)
252 for (
size_t j = 0; j < subBlockPRangeMaps.size(); j++)
254 RCP<CrsMatrixWrap> crsOpii = rcp_dynamic_cast<CrsMatrixWrap>(subBlockP[i]);
255 RCP<CrsMatrix> crsMatii = crsOpii->getCrsMatrix();
256 P->setMatrix(i, i, crsMatii);
258 P->setMatrix(i, j, Teuchos::null);
264 if (!restrictionMode_) {
266 coarseLevel.
Set(
"P", rcp_dynamic_cast<Matrix>(P),
this);
272 coarseLevel.
Set(
"R", Teuchos::rcp_dynamic_cast<Matrix>(P),
this);
Exception indicating invalid cast attempted.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
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->Get< RCP<Matrix> >("A", factory) if factory == NULL => use default factory.
Namespace for MueLu classes and methods.
Class that holds all level-specific information.
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
Exception throws to report errors in the internal logical of the program.
An exception safe way to call the method 'Level::SetFactoryManager()'.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
void Build(Level &fineLevel, Level &coarseLevel) const
Build method.