MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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>
21 #include <Xpetra_MapFactory.hpp>
22 #include <Xpetra_MapExtractor.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 
36 namespace MueLu {
37 
38 template <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 
60 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
62  FactManager_.push_back(FactManager);
63 }
64 
65 template <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 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  FactoryMonitor m(*this, "Build", coarseLevel);
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 
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(),
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(),
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(),
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(),
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(),
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(),
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_ */
Exception indicating invalid cast attempted.
#define MueLu_maxAll(rcpComm, in, out)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
iterator begin() const
GlobalOrdinal GO
T & get(const std::string &name, T def_value)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_type size() const
LocalOrdinal LO
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void sort(View &view, const size_t &size)
bool isParameter(const std::string &name) const
Print statistics that do not involve significant additional computation.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
iterator end() const
Node NO
Exception throws to report errors in the internal logical of the program.
#define MUELU_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
An exception safe way to call the method &#39;Level::SetFactoryManager()&#39;.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager)
Add a factory manager.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()