MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_RebalanceBlockInterpolationFactory_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_REBALANCEBLOCKINTERPOLATIONFACTORY_DEF_HPP_
11#define MUELU_REBALANCEBLOCKINTERPOLATIONFACTORY_DEF_HPP_
12
13#include <Teuchos_Tuple.hpp>
14
15#include "Xpetra_MultiVector.hpp"
16#include "Xpetra_MultiVectorFactory.hpp"
17#include "Xpetra_Vector.hpp"
18#include "Xpetra_VectorFactory.hpp"
19#include <Xpetra_Matrix.hpp>
20#include <Xpetra_BlockedCrsMatrix.hpp>
21#include <Xpetra_MapFactory.hpp>
22#include <Xpetra_MapExtractor.hpp>
23#include <Xpetra_MapExtractorFactory.hpp>
24#include <Xpetra_MatrixFactory.hpp>
25#include <Xpetra_Import.hpp>
26#include <Xpetra_ImportFactory.hpp>
27
29
31#include "MueLu_HierarchyUtils.hpp"
32#include "MueLu_Level.hpp"
33#include "MueLu_Monitor.hpp"
34#include "MueLu_PerfUtils.hpp"
35
36namespace MueLu {
37
38template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
40 RCP<ParameterList> validParamList = rcp(new ParameterList());
41
42 validParamList->set<RCP<const FactoryBase> >("P", Teuchos::null, "Factory of the prolongation operator that need to be rebalanced (only used if type=Interpolation)");
43 validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Factory for generating the non-rebalanced coarse level A. We need this to make sure the non-rebalanced coarse A is calculated first before rebalancing takes place.");
44
45 validParamList->set<RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Factory for generating the non-rebalanced Coordinates.");
46 validParamList->set<RCP<const FactoryBase> >("Importer", Teuchos::null, "Generating factory of the matrix Importer for rebalancing");
47 validParamList->set<RCP<const FactoryBase> >("SubImporters", Teuchos::null, "Generating factory of the matrix sub-Importers for rebalancing");
48
49#define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
50 // SET_VALID_ENTRY("repartition: use subcommunicators");
51#undef SET_VALID_ENTRY
52
53 // TODO validation: "P" parameter valid only for type="Interpolation" and "R" valid only for type="Restriction". Like so:
54 // if (paramList.isEntry("type") && paramList.get("type) == "Interpolation) {
55 // validParamList->set< RCP<const FactoryBase> >("P", Teuchos::null, "Factory of the prolongation operator that need to be rebalanced (only used if type=Interpolation)");
56
57 return validParamList;
58}
59
60template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
62 FactManager_.push_back(FactManager);
63}
64
65template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
67 Input(coarseLevel, "P");
68 Input(coarseLevel, "A"); // we request the non-rebalanced coarse level A since we have to make sure it is calculated before rebalancing starts!
69
70 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
71 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
72 SetFactoryManager fineSFM(rcpFromRef(fineLevel), *it);
73 SetFactoryManager coarseSFM(rcpFromRef(coarseLevel), *it);
74
75 // Request Importer and Coordinates (if defined in xml file)
76 // Note, that we have to use the Level::DeclareInput routine in order to use the FactoryManager *it (rather than the main factory manager)
77 coarseLevel.DeclareInput("Importer", (*it)->GetFactory("Importer").get(), this);
78 if ((*it)->hasFactory("Coordinates") == true)
79 coarseLevel.DeclareInput("Coordinates", (*it)->GetFactory("Coordinates").get(), this);
80 }
81
82 // Use the non-manager path if the maps / importers are generated in one place
83 if (FactManager_.size() == 0) {
84 Input(coarseLevel, "Importer");
85 Input(coarseLevel, "SubImporters");
86 Input(coarseLevel, "Coordinates");
87 }
88}
89
90template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92 FactoryMonitor m(*this, "Build", coarseLevel);
93 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> xdMV;
94 typedef Xpetra::BlockedMultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> xdBV;
95
96 bool UseSingleSource = FactManager_.size() == 0;
97 // RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
98
99 Teuchos::RCP<Matrix> nonrebCoarseA = Get<RCP<Matrix> >(coarseLevel, "A");
100
101 Teuchos::RCP<Matrix> originalTransferOp = Teuchos::null;
102 originalTransferOp = Get<RCP<Matrix> >(coarseLevel, "P");
103
104 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bOriginalTransferOp =
105 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalTransferOp);
106 TEUCHOS_TEST_FOR_EXCEPTION(bOriginalTransferOp == Teuchos::null, Exceptions::BadCast, "MueLu::RebalanceBlockTransferFactory::Build: input matrix P or R is not of type BlockedCrsMatrix! error.");
107
108 RCP<const MapExtractor> rangeMapExtractor = bOriginalTransferOp->getRangeMapExtractor();
109 RCP<const MapExtractor> domainMapExtractor = bOriginalTransferOp->getDomainMapExtractor();
110
111 // check if GIDs for full maps have to be sorted:
112 // For the Thyra mode ordering they do not have to be sorted since the GIDs are
113 // numbered as 0...n1,0...,n2 (starting with zero for each subblock). The MapExtractor
114 // generates unique GIDs during the construction.
115 // For Xpetra style, the GIDs have to be reordered. Such that one obtains a ordered
116 // list of GIDs in an increasing ordering. In Xpetra, the GIDs are all unique through
117 // out all submaps.
118 bool bThyraRangeGIDs = rangeMapExtractor->getThyraMode();
119 bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
120
121 // declare variables for maps of blocked rebalanced prolongation operator
122 std::vector<GO> fullRangeMapVector; // contains all range GIDs on current processor
123 std::vector<GO> fullDomainMapVector; // contains all domain GIDs on current processor
124 std::vector<RCP<const Map> > subBlockPRangeMaps;
125 std::vector<RCP<const Map> > subBlockPDomainMaps;
126 subBlockPRangeMaps.reserve(bOriginalTransferOp->Rows()); // reserve size for block P operators
127 subBlockPDomainMaps.reserve(bOriginalTransferOp->Cols()); // reserve size for block P operators
128
129 std::vector<Teuchos::RCP<Matrix> > subBlockRebP;
130 subBlockRebP.reserve(bOriginalTransferOp->Rows());
131
132 // For use in single-source mode only
133 std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bOriginalTransferOp->Rows(), Teuchos::null);
134 std::vector<RCP<xdMV> > newCoordinates(bOriginalTransferOp->Rows());
135 RCP<xdBV> oldCoordinates;
136 if (UseSingleSource) {
137 importers = Get<std::vector<RCP<const Import> > >(coarseLevel, "SubImporters");
138 oldCoordinates = Get<RCP<xdBV> >(coarseLevel, "Coordinates");
139 }
140
141 int curBlockId = 0;
142 Teuchos::RCP<const Import> rebalanceImporter = Teuchos::null;
143 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
144 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
145 // begin SubFactoryManager environment
146 SetFactoryManager fineSFM(rcpFromRef(fineLevel), *it);
147 SetFactoryManager coarseSFM(rcpFromRef(coarseLevel), *it);
148
149 // TAW: use the Level::Get routine in order to access the data declared in (*it) factory manager (rather than the main factory manager)
150 if (UseSingleSource)
151 rebalanceImporter = importers[curBlockId];
152 else
153 rebalanceImporter = coarseLevel.Get<Teuchos::RCP<const Import> >("Importer", (*it)->GetFactory("Importer").get());
154
155 // extract diagonal matrix block
156 Teuchos::RCP<Matrix> Pii = bOriginalTransferOp->getMatrix(curBlockId, curBlockId);
157 Teuchos::RCP<CrsMatrixWrap> Pwii = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(Pii);
158 TEUCHOS_TEST_FOR_EXCEPTION(Pwii == Teuchos::null, Xpetra::Exceptions::BadCast, "MueLu::RebalanceBlockTransferFactory::Build: block " << curBlockId << " is not of type CrsMatrixWrap. We need an underlying CsrMatrix to replace domain map and importer!");
159
160 MUELU_TEST_FOR_EXCEPTION(bThyraRangeGIDs == true && Pii->getRowMap()->getMinAllGlobalIndex() != 0,
162 "MueLu::RebalanceBlockInterpolationFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block range " << curBlockId << " start with " << Pii->getRowMap()->getMinAllGlobalIndex() << " but should start with 0");
163 MUELU_TEST_FOR_EXCEPTION(bThyraDomainGIDs == true && Pii->getColMap()->getMinAllGlobalIndex() != 0,
165 "MueLu::RebalanceBlockInterpolationFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block domain " << curBlockId << " start with " << Pii->getColMap()->getMinAllGlobalIndex() << " but should start with 0");
166
167 // rebalance P11
168 if (rebalanceImporter != Teuchos::null) {
169 std::stringstream ss;
170 ss << "Rebalancing prolongator block P(" << curBlockId << "," << curBlockId << ")";
171 SubFactoryMonitor m1(*this, ss.str(), coarseLevel);
172
173 // P is the transfer operator from the coarse grid to the fine grid.
174 // P must transfer the data from the newly reordered coarse A to the (unchanged) fine A.
175 // This means that the domain map (coarse) of P must be changed according to the new partition. The range map (fine) is kept unchanged.
176 //
177 // The domain map of P must match the range map of R.
178 // See also note below about domain/range map of R and its implications for P.
179 //
180 // To change the domain map of P, P needs to be fillCompleted again with the new domain map.
181 // To achieve this, P is copied into a new matrix that is not fill-completed.
182 // The doImport() operation is just used here to make a copy of P: the importer is trivial and there is no data movement involved.
183 // The reordering actually happens during the fillComplete() with domainMap == rebalanceImporter->getTargetMap().
184 RCP<const Import> newImporter;
185 {
186 SubFactoryMonitor subM(*this, "Rebalancing prolongator -- fast map replacement", coarseLevel);
187 newImporter = ImportFactory::Build(rebalanceImporter->getTargetMap(), Pii->getColMap());
188 Pwii->getCrsMatrix()->replaceDomainMapAndImporter(rebalanceImporter->getTargetMap(), newImporter);
189 }
190
191 RCP<ParameterList> params = rcp(new ParameterList());
192 params->set("printLoadBalancingInfo", true);
193 std::stringstream ss2;
194 ss2 << "P(" << curBlockId << "," << curBlockId << ") rebalanced:";
195 GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*Pii, ss2.str(), params);
196
197 // store rebalanced P block
198 subBlockRebP.push_back(Pii);
199
200 // rebalance coordinates
201 // TAW: Note, that each sub-block manager overwrites the Coordinates. So far we only support one set of Coordinates
202 // for a multiphysics problem (i.e., we only support volume coupled problems with the same mesh)
203 if (UseSingleSource) {
204 RCP<xdMV> localCoords = oldCoordinates->getMultiVector(curBlockId);
205
206 // FIXME: This should be extended to work with blocking
207 RCP<const Import> coordImporter = rebalanceImporter;
208
209 RCP<xdMV> permutedLocalCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), localCoords->getNumVectors());
210 permutedLocalCoords->doImport(*localCoords, *coordImporter, Xpetra::INSERT);
211
212 newCoordinates[curBlockId] = permutedLocalCoords;
213 } else if ((*it)->hasFactory("Coordinates") == true && coarseLevel.IsAvailable("Coordinates", (*it)->GetFactory("Coordinates").get()) == true) {
214 RCP<xdMV> coords = coarseLevel.Get<RCP<xdMV> >("Coordinates", (*it)->GetFactory("Coordinates").get());
215
216 // This line must be after the Get call
217 SubFactoryMonitor subM(*this, "Rebalancing coordinates", coarseLevel);
218
219 LO nodeNumElts = coords->getMap()->getLocalNumElements();
220
221 // If a process has no matrix rows, then we can't calculate blocksize using the formula below.
222 LO myBlkSize = 0, blkSize = 0;
223
224 if (nodeNumElts > 0) {
225 MUELU_TEST_FOR_EXCEPTION(rebalanceImporter->getSourceMap()->getLocalNumElements() % nodeNumElts != 0,
227 "MueLu::RebalanceBlockInterpolationFactory::Build: block size. " << rebalanceImporter->getSourceMap()->getLocalNumElements() << " not divisable by " << nodeNumElts);
228 myBlkSize = rebalanceImporter->getSourceMap()->getLocalNumElements() / nodeNumElts;
229 }
230
231 MueLu_maxAll(coords->getMap()->getComm(), myBlkSize, blkSize);
232
233 RCP<const Import> coordImporter = Teuchos::null;
234 if (blkSize == 1) {
235 coordImporter = rebalanceImporter;
236 } else {
237 // NOTE: there is an implicit assumption here: we assume that dof any node are enumerated consequently
238 // Proper fix would require using decomposition similar to how we construct importer in the
239 // RepartitionFactory
240 RCP<const Map> origMap = coords->getMap();
241 GO indexBase = origMap->getIndexBase();
242
243 ArrayView<const GO> OEntries = rebalanceImporter->getTargetMap()->getLocalElementList();
244 LO numEntries = OEntries.size() / blkSize;
245 ArrayRCP<GO> Entries(numEntries);
246 for (LO i = 0; i < numEntries; i++)
247 Entries[i] = (OEntries[i * blkSize] - indexBase) / blkSize + indexBase;
248
249 RCP<const Map> targetMap = MapFactory::Build(origMap->lib(), origMap->getGlobalNumElements(), Entries(), indexBase, origMap->getComm());
250 coordImporter = ImportFactory::Build(origMap, targetMap);
251 }
252
253 RCP<xdMV> permutedCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), coords->getNumVectors());
254 permutedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
255
256 const ParameterList &pL = GetParameterList();
257 if (pL.isParameter("repartition: use subcommunicators") == true && pL.get<bool>("repartition: use subcommunicators") == true)
258 permutedCoords->replaceMap(permutedCoords->getMap()->removeEmptyProcesses());
259
260 Set(coarseLevel, "Coordinates", permutedCoords);
261 }
262 } // end rebalance P(1,1)
263 else {
264 RCP<ParameterList> params = rcp(new ParameterList());
265 params->set("printLoadBalancingInfo", true);
266 std::stringstream ss;
267 ss << "P(" << curBlockId << "," << curBlockId << ") not rebalanced:";
268 GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*Pii, ss.str(), params);
269 // store rebalanced P block
270 subBlockRebP.push_back(Pii);
271
272 // Store Coordinates on coarse level (generated by this)
273 // TAW: Note, that each sub-block manager overwrites the Coordinates. So far we only support one set of Coordinates
274 // for a multiphysics problem (i.e., we only support volume coupled problems with the same mesh)
275 if ((*it)->hasFactory("Coordinates") == true && coarseLevel.IsAvailable("Coordinates", (*it)->GetFactory("Coordinates").get()) == true) {
276 coarseLevel.Set("Coordinates", coarseLevel.Get<RCP<xdMV> >("Coordinates", (*it)->GetFactory("Coordinates").get()), this);
277 }
278 }
279
280 // fix striding information for rebalanced diagonal block Pii
281 // RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rgPMapExtractor = bOriginalTransferOp->getRangeMapExtractor(); // original map extractor
282 Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), rangeMapExtractor->getThyraMode()));
283 Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
284 if (orig_stridedRgMap != Teuchos::null) {
285 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
286 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = Pii->getRangeMap()->getLocalElementList();
287 stridedRgMap = StridedMapFactory::Build(
288 originalTransferOp->getRangeMap()->lib(),
289 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
290 nodeRangeMapii,
291 Pii->getRangeMap()->getIndexBase(),
292 stridingData,
293 originalTransferOp->getRangeMap()->getComm(),
294 orig_stridedRgMap->getStridedBlockId(),
295 orig_stridedRgMap->getOffset());
296 } else
297 stridedRgMap = Pii->getRangeMap();
298
299 // RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > doPMapExtractor = bOriginalTransferOp->getDomainMapExtractor(); // original map extractor
300 Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), domainMapExtractor->getThyraMode()));
301
302 Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
303 if (orig_stridedDoMap != Teuchos::null) {
304 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
305 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = Pii->getDomainMap()->getLocalElementList();
306 stridedDoMap = StridedMapFactory::Build(originalTransferOp->getDomainMap()->lib(),
307 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
308 nodeDomainMapii,
309 Pii->getDomainMap()->getIndexBase(),
310 stridingData,
311 originalTransferOp->getDomainMap()->getComm(),
312 orig_stridedDoMap->getStridedBlockId(),
313 orig_stridedDoMap->getOffset());
314 } else
315 stridedDoMap = Pii->getDomainMap();
316
317 TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null, Exceptions::RuntimeError, "MueLu::RebalanceBlockInterpolationFactory::Build: failed to generate striding information. error.");
318 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null, Exceptions::RuntimeError, "MueLu::RebalanceBlockInterpolationFactory::Build: failed to generate striding information. error.");
319
320 // replace stridedMaps view in diagonal sub block
321 if (Pii->IsView("stridedMaps")) Pii->RemoveView("stridedMaps");
322 Pii->CreateView("stridedMaps", stridedRgMap, stridedDoMap);
323
324 // append strided row map (= range map) to list of range maps.
325 Teuchos::RCP<const Map> rangeMapii = Pii->getRowMap("stridedMaps"); // strided range map
326 subBlockPRangeMaps.push_back(rangeMapii);
327 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = Pii->getRangeMap()->getLocalElementList();
328 // append the GIDs in the end. Do not sort if we have Thyra style GIDs
329 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMapii.begin(), nodeRangeMapii.end());
330 if (bThyraRangeGIDs == false)
331 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
332
333 // append strided col map (= domain map) to list of range maps.
334 Teuchos::RCP<const Map> domainMapii = Pii->getColMap("stridedMaps"); // strided domain map
335 subBlockPDomainMaps.push_back(domainMapii);
336 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = Pii->getDomainMap()->getLocalElementList();
337 // append the GIDs in the end. Do not sort if we have Thyra style GIDs
338 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMapii.begin(), nodeDomainMapii.end());
339 if (bThyraDomainGIDs == false)
340 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
341
342 curBlockId++; // increase block id index
343
344 } // end SubFactoryManager environment
345
346 // extract map index base from maps of blocked P
347 GO rangeIndexBase = originalTransferOp->getRangeMap()->getIndexBase();
348 GO domainIndexBase = originalTransferOp->getDomainMap()->getIndexBase();
349
350 RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rangePMapExtractor = bOriginalTransferOp->getRangeMapExtractor(); // original map extractor
351 Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0, fullRangeMapVector.size());
352 Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangePMapExtractor->getFullMap());
353 Teuchos::RCP<const Map> fullRangeMap = Teuchos::null;
354 if (stridedRgFullMap != Teuchos::null) {
355 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
356 fullRangeMap =
357 StridedMapFactory::Build(
358 originalTransferOp->getRangeMap()->lib(),
359 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
360 fullRangeMapGIDs,
361 rangeIndexBase,
362 stridedData,
363 originalTransferOp->getRangeMap()->getComm(),
364 stridedRgFullMap->getStridedBlockId(),
365 stridedRgFullMap->getOffset());
366 } else {
367 fullRangeMap =
368 MapFactory::Build(
369 originalTransferOp->getRangeMap()->lib(),
370 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
371 fullRangeMapGIDs,
372 rangeIndexBase,
373 originalTransferOp->getRangeMap()->getComm());
374 }
375
376 RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > domainAMapExtractor = bOriginalTransferOp->getDomainMapExtractor();
377 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0, fullDomainMapVector.size());
378 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainAMapExtractor->getFullMap());
379 Teuchos::RCP<const Map> fullDomainMap = Teuchos::null;
380 if (stridedDoFullMap != Teuchos::null) {
381 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap == Teuchos::null, Exceptions::BadCast, "MueLu::BlockedPFactory::Build: full map in domain map extractor has no striding information! error.");
382 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
383 fullDomainMap =
384 StridedMapFactory::Build(
385 originalTransferOp->getDomainMap()->lib(),
386 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
387 fullDomainMapGIDs,
388 domainIndexBase,
389 stridedData2,
390 originalTransferOp->getDomainMap()->getComm(),
391 stridedDoFullMap->getStridedBlockId(),
392 stridedDoFullMap->getOffset());
393 } else {
394 fullDomainMap =
395 MapFactory::Build(
396 originalTransferOp->getDomainMap()->lib(),
397 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
398 fullDomainMapGIDs,
399 domainIndexBase,
400 originalTransferOp->getDomainMap()->getComm());
401 }
402
403 // build map extractors
404 Teuchos::RCP<const MapExtractor> rebrangeMapExtractor =
405 MapExtractorFactory::Build(fullRangeMap, subBlockPRangeMaps, bThyraRangeGIDs);
406 Teuchos::RCP<const MapExtractor> rebdomainMapExtractor =
407 MapExtractorFactory::Build(fullDomainMap, subBlockPDomainMaps, bThyraDomainGIDs);
408
409 Teuchos::RCP<BlockedCrsMatrix> bRebP = Teuchos::rcp(new BlockedCrsMatrix(rebrangeMapExtractor, rebdomainMapExtractor, 10));
410 for (size_t i = 0; i < subBlockPRangeMaps.size(); i++) {
411 Teuchos::RCP<CrsMatrixWrap> crsOpii = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(subBlockRebP[i]);
412 TEUCHOS_TEST_FOR_EXCEPTION(crsOpii == Teuchos::null, Xpetra::Exceptions::BadCast, "MueLu::RebalanceBlockTransferFactory::Build: block P" << i << " is not of type CrsMatrixWrap.");
413 bRebP->setMatrix(i, i, crsOpii);
414 }
415 bRebP->fillComplete();
416
417 Set(coarseLevel, "P", Teuchos::rcp_dynamic_cast<Matrix>(bRebP));
418
419 // Finish up the coordinates (single source only)
420 if (UseSingleSource) {
421 RCP<xdBV> bcoarseCoords = rcp(new xdBV(rebrangeMapExtractor->getBlockedMap(), newCoordinates));
422 Set(coarseLevel, "Coordinates", bcoarseCoords);
423 }
424
425} // Build
426
427} // namespace MueLu
428
429#endif /* MUELU_REBALANCEBLOCKINTERPOLATIONFACTORY_DEF_HPP_ */
#define MUELU_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define MueLu_maxAll(rcpComm, in, out)
Exception indicating invalid cast attempted.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager)
Add a factory manager.
An exception safe way to call the method 'Level::SetFactoryManager()'.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
Namespace for MueLu classes and methods.
@ Statistics0
Print statistics that do not involve significant additional computation.