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.
void Input(Level &level, const std::string &varName) const
T Get(Level &level, const std::string &varName) const
void Set(Level &level, const std::string &varName, const T &data) const
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())
virtual const Teuchos::ParameterList & GetParameterList() const
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.
std::vector< Teuchos::RCP< const FactoryManagerBase > > FactManager_
Input factories.
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.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Statistics0
Print statistics that do not involve significant additional computation.