MueLu  Version of the Day
MueLu_RebalanceBlockAcFactory_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 /*
47  * MueLu_RebalanceBlockAcFactory_def.hpp
48  *
49  * Created on: Aug 15, 2013
50  * Author: tobias
51  */
52 
53 #ifndef MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_
54 #define MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_
55 
56 #ifdef HAVE_MUELU_EXPERIMENTAL
57 
58 #include <Xpetra_Matrix.hpp>
59 #include <Xpetra_CrsMatrix.hpp>
60 #include <Xpetra_CrsMatrixWrap.hpp>
61 #include <Xpetra_MatrixFactory.hpp>
62 #include <Xpetra_MapExtractor.hpp>
63 #include <Xpetra_MapExtractorFactory.hpp>
64 #include <Xpetra_StridedMap.hpp>
65 #include <Xpetra_StridedMapFactory.hpp>
66 #include <Xpetra_BlockedCrsMatrix.hpp>
67 
69 
71 #include "MueLu_HierarchyHelpers.hpp"
72 #include "MueLu_MasterList.hpp"
73 #include "MueLu_Monitor.hpp"
74 #include "MueLu_PerfUtils.hpp"
75 #include "MueLu_RAPFactory.hpp"
76 
77 namespace MueLu {
78 
79  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
81 
82  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
84  RCP<ParameterList> validParamList = rcp(new ParameterList());
85 
86 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
87  // SET_VALID_ENTRY("repartition: use subcommunicators");
88 #undef SET_VALID_ENTRY
89 
90  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A for rebalancing");
91 
92  return validParamList;
93  }
94 
95  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
97  FactManager_.push_back(FactManager);
98  }
99 
100  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
102  Input(coarseLevel, "A");
103 
104  std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
105  for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
106  SetFactoryManager fineSFM (rcpFromRef(fineLevel), *it);
107  SetFactoryManager coarseSFM(rcpFromRef(coarseLevel), *it);
108 
109  coarseLevel.DeclareInput("Importer",(*it)->GetFactory("Importer").get(), this);
110  }
111  }
112 
113  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
115  FactoryMonitor m(*this, "Computing blocked Ac", coarseLevel);
116 
117  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
118 
119  RCP<Matrix> originalAc = Get< RCP<Matrix> >(coarseLevel, "A");
120 
121  RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalAc);
122  TEUCHOS_TEST_FOR_EXCEPTION(bA==Teuchos::null, Exceptions::BadCast, "MueLu::BlockedPFactory::Build: input matrix A is not of type BlockedCrsMatrix! error.");
123 
124  // plausibility check
125  TEUCHOS_TEST_FOR_EXCEPTION(bA->Rows() != 2,Exceptions::RuntimeError, "MueLu::BlockedPFactory::Build: number of block rows of A is not equal 2. error.");
126  TEUCHOS_TEST_FOR_EXCEPTION(bA->Cols() != 2,Exceptions::RuntimeError, "MueLu::BlockedPFactory::Build: number of block columns of A is not equal 2. error.");
127 
128  // store map extractors
129  Teuchos::RCP<const MapExtractorClass> rangeMapExtractor = bA->getRangeMapExtractor();
130  Teuchos::RCP<const MapExtractorClass> domainMapExtractor = bA->getDomainMapExtractor();
131 
132  std::vector<GO> fullRangeMapVector;
133  std::vector<GO> fullDomainMapVector;
134 
135  std::vector<RCP<const Map> > subBlockARangeMaps;
136  std::vector<RCP<const Map> > subBlockADomainMaps;
137  subBlockARangeMaps.reserve(bA->Rows());
138  subBlockADomainMaps.reserve(bA->Cols());
139 
140  std::vector<Teuchos::RCP<Matrix> > subBlockRebA;
141  subBlockRebA.reserve(bA->Cols() * bA->Rows());
142 
143  for(size_t i=0; i<bA->Rows(); i++) {
144  for(size_t j=0; j<bA->Cols(); j++) {
145  // extract matrix block
146  Teuchos::RCP<CrsMatrix> Amij = bA->getMatrix(i, j);
147  Teuchos::RCP<CrsMatrixWrap> Awij = Teuchos::rcp(new CrsMatrixWrap(Amij));
148  Teuchos::RCP<Matrix> Aij = Teuchos::rcp_dynamic_cast<Matrix>(Awij);
149  //subBlockRebA[i*bA->Cols() + j] = Aij;
150  subBlockRebA.push_back(Aij);
151  }
152  }
153 
154  size_t curBlockId = 0;
155  std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
156  for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
157  SetFactoryManager fineSFM (rcpFromRef(fineLevel), *it);
158  SetFactoryManager coarseSFM(rcpFromRef(coarseLevel), *it);
159 
160  Teuchos::RCP<const Import> rebalanceImporter = coarseLevel.Get<Teuchos::RCP<const Import> >("Importer", (*it)->GetFactory("Importer").get());
161 
162  // rebalance diagonal block
163 
164  // extract matrix block
165  Teuchos::RCP<Matrix> Aii = subBlockRebA[curBlockId*bA->Cols() + curBlockId];
166 
167  Teuchos::RCP<Matrix> rebAii;
168  if(rebalanceImporter != Teuchos::null) {
169  std::stringstream ss; ss << "Rebalancing matrix block A(" << curBlockId << "," << curBlockId << ")";
170  SubFactoryMonitor subM(*this, ss.str(), coarseLevel);
171  RCP<const Map> targetMap = rebalanceImporter->getTargetMap();
172 
173  //const ParameterList & pL = GetParameterList();
174 
175  ParameterList XpetraList;
176  //if (pL.get<bool>("repartition: use subcommunicators") == true) {
177  //GetOStream(Runtime0) << "Replacing maps with a subcommunicator" << std::endl;
178  XpetraList.set("Restrict Communicator",false /*true*/ /*XXX*/);
179  //}
180  // NOTE: If the communicator is restricted away, Build returns Teuchos::null.
181  rebAii = MatrixFactory::Build(Aii, *rebalanceImporter, targetMap, targetMap, rcp(&XpetraList,false));
182 
183  /*if (!rebAii.is_null())
184  rebAii->SetFixedBlockSize(Aii->GetFixedBlockSize());*/
185 
186  if (!rebAii.is_null()) {
187  RCP<ParameterList> params = rcp(new ParameterList());
188  params->set("printLoadBalancingInfo", true);
189  std::stringstream ss2; ss2 << "A(" << curBlockId << "," << curBlockId << ") rebalanced:";
190  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAii, ss2.str(), params);
191  }
192 
193  } // rebalance matrix block A(i,i)
194  else {
195  rebAii = Aii;
196  /*RCP<ParameterList> params = rcp(new ParameterList());
197  params->set("printLoadBalancingInfo", true);
198  std::stringstream ss2; ss2 << "A(" << curBlockId << "," << curBlockId << ") not rebalanced:";
199  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAii, ss2.str(), params);*/
200  }
201 
202  // fix striding information for rebalanced diagonal block rebAii
203  // Note: we do not care about the off-diagonal blocks. We just make sure, that the
204  // diagonal blocks have the corresponding striding information from the map extractors
205  RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rgAMapExtractor = bA->getRangeMapExtractor(); // original map extractor
206  Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rgAMapExtractor->getMap(Teuchos::as<size_t>(curBlockId)));
207  Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
208  if(orig_stridedRgMap != Teuchos::null) {
209  std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
210  Teuchos::ArrayView< const GlobalOrdinal > nodeRangeMapii = rebAii->getRangeMap()->getNodeElementList();
211  stridedRgMap = StridedMapFactory::Build(
212  bA->getRangeMap()->lib(),
213  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
214  nodeRangeMapii,
215  rebAii->getRangeMap()->getIndexBase(),
216  stridingData,
217  bA->getRangeMap()->getComm(),
218  orig_stridedRgMap->getStridedBlockId(),
219  orig_stridedRgMap->getOffset());
220  }
221  RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > doAMapExtractor = bA->getDomainMapExtractor(); // original map extractor
222  Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(doAMapExtractor->getMap(Teuchos::as<size_t>(curBlockId)));
223  Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
224  if(orig_stridedDoMap != Teuchos::null) {
225  std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
226  Teuchos::ArrayView< const GlobalOrdinal > nodeDomainMapii = rebAii->getDomainMap()->getNodeElementList();
227  stridedDoMap = StridedMapFactory::Build(
228  bA->getDomainMap()->lib(),
229  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
230  nodeDomainMapii,
231  rebAii->getDomainMap()->getIndexBase(),
232  stridingData,
233  bA->getDomainMap()->getComm(),
234  orig_stridedDoMap->getStridedBlockId(),
235  orig_stridedDoMap->getOffset());
236  }
237 
238  TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,Exceptions::RuntimeError, "MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
239  TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,Exceptions::RuntimeError, "MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
240 
241  // replace stridedMaps view in diagonal sub block
242  if(rebAii->IsView("stridedMaps")) rebAii->RemoveView("stridedMaps");
243  rebAii->CreateView("stridedMaps", stridedRgMap, stridedDoMap);
244 
245  subBlockRebA[curBlockId*bA->Cols() + curBlockId] = rebAii;
246 
247  // rebalance off-diagonal matrix blocks in same row
248  for(size_t j=0; j<bA->Cols(); j++) {
249  if(j==curBlockId) continue; // jump over block diagonal matrix block
250 
251  // extract matrix block
252  Teuchos::RCP<Matrix> Aij = subBlockRebA[curBlockId*bA->Cols() + j];
253 
254  Teuchos::RCP<Matrix> rebAij;
255  if(rebalanceImporter!=Teuchos::null) {
256  std::stringstream ss3; ss3 << "Rebalancing matrix block A(" << curBlockId << "," << j << ")";
257  SubFactoryMonitor subM(*this, ss3.str(), coarseLevel);
258  RCP<const Map> targetMap = rebalanceImporter->getTargetMap();
259 
260  Teuchos::RCP<Map> dummy; // The 3rd argument says to use the original domain map
261  rebAij = MatrixFactory::Build(Aij, *rebalanceImporter, dummy, targetMap);
262 
263  // copy strided map info from non-rebalanced to rebalanced matrix
264  if (!rebAij.is_null() && Aij->IsView("stridedMaps"))
265  rebAij->CreateView("stridedMaps", Aij);
266 
267  if (!rebAij.is_null()) {
268  RCP<ParameterList> params = rcp(new ParameterList());
269  params->set("printLoadBalancingInfo", true);
270  std::stringstream ss4; ss4 << "A(" << curBlockId << "," << j << ") rebalanced:";
271  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAij, ss4.str(), params);
272  }
273  } // rebalance matrix block A(i,j)
274  else {
275  rebAij = Aij;
276  /*RCP<ParameterList> params = rcp(new ParameterList());
277  params->set("printLoadBalancingInfo", true);
278  std::stringstream ss2; ss2 << "A(" << curBlockId << "," << j << ") not rebalanced:";
279  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAij, ss2.str(), params);*/
280  }
281 
282  subBlockRebA[curBlockId*bA->Cols() + j] = rebAij;
283  } // end loop over all columns
284 
285  // rebalance off-diagonal matrix blocks in same column
286  for(size_t i=0; i<bA->Rows(); i++) {
287  if(i==curBlockId) continue; // jump over block diagonal matrix block
288 
289  // extract matrix block
290  Teuchos::RCP<Matrix> Aij = subBlockRebA[i*bA->Cols() + curBlockId];
291 
292  Teuchos::RCP<Matrix> rebAij;
293  if(rebalanceImporter!=Teuchos::null) {
294  std::stringstream ss; ss << "Rebalancing matrix block (" << i << "," << curBlockId << ")";
295  SubFactoryMonitor subM(*this, ss.str(), coarseLevel);
296  RCP<const Map> targetMap = rebalanceImporter->getTargetMap();
297 
298  rebAij = Aij; // just a copy
299  Teuchos::RCP<const CrsMatrixWrap> rebAwij = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(rebAij);
300  Teuchos::RCP<CrsMatrix> rebAmij = rebAwij->getCrsMatrix();
301  Teuchos::RCP<const Import> rebAijImport = ImportFactory::Build(targetMap,Aij->getColMap());
302  rebAmij->replaceDomainMapAndImporter(targetMap,rebAijImport);
303 
304  // copy strided map info from non-rebalanced to rebalanced matrix
305  if (!rebAij.is_null() && Aij->IsView("stridedMaps"))
306  rebAij->CreateView("stridedMaps", Aij);
307 
308  if (!rebAij.is_null()) {
309  RCP<ParameterList> params = rcp(new ParameterList());
310  params->set("printLoadBalancingInfo", true);
311  std::stringstream ss2; ss2 << "A(" << i << "," << curBlockId << ") rebalanced:";
312  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAij, ss2.str(), params);
313  }
314  } // rebalance matrix block A(1,0)
315  else {
316  rebAij = Aij;
317  /*RCP<ParameterList> params = rcp(new ParameterList());
318  params->set("printLoadBalancingInfo", true);
319  std::stringstream ss2; ss2 << "A(" << i << "," << curBlockId << ") not rebalanced:";
320  GetOStream(Statistics0) << PerfUtils::PrintMatrixInfo(*rebAij, ss2.str(), params);*/
321  }
322 
323  subBlockRebA[i*bA->Cols() + curBlockId] = rebAij;
324  } // end loop over all rows
325 
326 
327  // build full range and full domain map (strided)
328  subBlockARangeMaps.push_back(rebAii->getRowMap("stridedMaps")/*rebAii->getRangeMap()*/);
329  Teuchos::ArrayView< const GlobalOrdinal > nodeRangeMap = rebAii->getRangeMap()->getNodeElementList();
330  fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMap.begin(), nodeRangeMap.end());
331  sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
332 
333  subBlockADomainMaps.push_back(rebAii->getColMap("stridedMaps")/*rebAii->getDomainMap()*/);
334  Teuchos::ArrayView< const GlobalOrdinal > nodeDomainMap = rebAii->getDomainMap()->getNodeElementList();
335  fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMap.begin(), nodeDomainMap.end());
336  sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
337 
338  curBlockId++;
339  } // end loop over all block rows
340 
341  // now, subBlockRebA contains all rebalanced matrix blocks
342 
343  // extract map index base from maps of blocked A
344  GO rangeIndexBase = 0;
345  GO domainIndexBase = 0;
346  rangeIndexBase = bA->getRangeMap()->getIndexBase();
347  domainIndexBase= bA->getDomainMap()->getIndexBase();
348 
349  Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0,fullRangeMapVector.size());
350  Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getFullMap());
351  Teuchos::RCP<const Map > fullRangeMap = Teuchos::null;
352  if(stridedRgFullMap != Teuchos::null) {
353  std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
354  fullRangeMap =
355  StridedMapFactory::Build(
356  bA->getRangeMap()->lib(),
357  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
358  fullRangeMapGIDs,
359  rangeIndexBase,
360  stridedData,
361  bA->getRangeMap()->getComm(),
362  stridedRgFullMap->getStridedBlockId(),
363  stridedRgFullMap->getOffset());
364  } else {
365  fullRangeMap =
366  MapFactory::Build(
367  bA->getRangeMap()->lib(),
368  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
369  fullRangeMapGIDs,
370  rangeIndexBase,
371  bA->getRangeMap()->getComm());
372  }
373 
374  Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0,fullDomainMapVector.size());
375 
376  Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getFullMap());
377  Teuchos::RCP<const Map > fullDomainMap = Teuchos::null;
378  if(stridedDoFullMap != Teuchos::null) {
379  TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap==Teuchos::null, Exceptions::BadCast, "MueLu::BlockedPFactory::Build: full map in domain map extractor has no striding information! error.");
380  std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
381  fullDomainMap =
382  StridedMapFactory::Build(
383  bA->getDomainMap()->lib(),
384  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
385  fullDomainMapGIDs,
386  domainIndexBase,
387  stridedData2,
388  bA->getDomainMap()->getComm(),
389  stridedDoFullMap->getStridedBlockId(),
390  stridedDoFullMap->getOffset());
391  } else {
392 
393  fullDomainMap =
394  MapFactory::Build(
395  bA->getDomainMap()->lib(),
396  Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
397  fullDomainMapGIDs,
398  domainIndexBase,
399  bA->getDomainMap()->getComm());
400  }
401 
402  // build map extractors
403  Teuchos::RCP<const MapExtractorClass> rebRangeMapExtractor = MapExtractorFactoryClass::Build(fullRangeMap, subBlockARangeMaps);
404  Teuchos::RCP<const MapExtractorClass> rebDomainMapExtractor = MapExtractorFactoryClass::Build(fullDomainMap, subBlockADomainMaps);
405 
406  Teuchos::RCP<BlockedCrsMatrix> reb_bA = Teuchos::rcp(new BlockedCrsMatrix(rebRangeMapExtractor,rebDomainMapExtractor,10));
407  for(size_t i=0; i<bA->Rows(); i++) {
408  for(size_t j=0; j<bA->Cols(); j++) {
409  Teuchos::RCP<const CrsMatrixWrap> crsOpij = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(subBlockRebA[i*bA->Cols() + j]);
410  Teuchos::RCP<CrsMatrix> crsMatij = crsOpij->getCrsMatrix();
411  reb_bA->setMatrix(i,j,crsMatij);
412  }
413  }
414  reb_bA->fillComplete();
415  //reb_bA->describe(*out,Teuchos::VERB_EXTREME);
416  coarseLevel.Set("A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA), this);
417 
418  // rebalance additional data:
419  // be aware, that we just call the rebalance factories without switching to local
420  // factory managers, i.e. the rebalance factories have to be defined with the appropriate
421  // factories by the user!
422  if (rebalanceFacts_.begin() != rebalanceFacts_.end()) {
423  SubFactoryMonitor m2(*this, "Rebalance additional data", coarseLevel);
424 
425  // call Build of all user-given transfer factories
426  for (std::vector<RCP<const FactoryBase> >::const_iterator it2 = rebalanceFacts_.begin(); it2 != rebalanceFacts_.end(); ++it2) {
427  GetOStream(Runtime0) << "RebalanceBlockedAc: call rebalance factory " << (*it2).get() << ": " << (*it2)->description() << std::endl;
428  (*it2)->CallBuild(coarseLevel);
429  }
430  }
431  } //Build()
432 
433  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
435 
436  /*TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::rcp_dynamic_cast<const TwoLevelFactoryBase>(factory) == Teuchos::null, Exceptions::BadCast,
437  "MueLu::RAPFactory::AddTransferFactory: Transfer factory is not derived from TwoLevelFactoryBase. "
438  "This is very strange. (Note: you can remove this exception if there's a good reason for)");
439  TEUCHOS_TEST_FOR_EXCEPTION(hasDeclaredInput_, Exceptions::RuntimeError, "MueLu::RAPFactory::AddTransferFactory: Factory is being added after we have already declared input");*/
440  rebalanceFacts_.push_back(factory);
441  } //AddRebalanceFactory()
442 
443 } //namespace MueLu
444 
445 #endif /* HAVE_MUELU_EXPERIMENTAL */
446 #endif /* MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_ */
Exception indicating invalid cast attempted.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager)
Add a factory manager.
Timer to be used in factories. Similar to Monitor but with additional timers.
One-liner description of what is happening.
Namespace for MueLu classes and methods.
Print statistics that do not involve significant additional computation.
void AddRebalanceFactory(const RCP< const FactoryBase > &factory)
Add rebalancing factory in the end of list of rebalancing factories in RebalanceAcFactory.
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
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 DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
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.
Exception throws to report errors in the internal logical of the program.
An exception safe way to call the method &#39;Level::SetFactoryManager()&#39;.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()