47 #ifndef MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_ 
   48 #define MUELU_REBALANCEBLOCKACFACTORY_DEF_HPP_ 
   50 #include <Xpetra_Matrix.hpp> 
   51 #include <Xpetra_CrsMatrix.hpp> 
   52 #include <Xpetra_CrsMatrixWrap.hpp> 
   53 #include <Xpetra_MatrixFactory.hpp> 
   54 #include <Xpetra_MapExtractor.hpp> 
   55 #include <Xpetra_MapExtractorFactory.hpp> 
   56 #include <Xpetra_StridedMap.hpp> 
   57 #include <Xpetra_StridedMapFactory.hpp> 
   58 #include <Xpetra_BlockedCrsMatrix.hpp> 
   60 #include <Xpetra_VectorFactory.hpp> 
   65 #include "MueLu_HierarchyUtils.hpp" 
   68 #include "MueLu_PerfUtils.hpp" 
   69 #include "MueLu_RAPFactory.hpp" 
   73   template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   76   template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   80 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name)) 
   82 #undef SET_VALID_ENTRY 
   85     validParamList->
set<
RCP<const FactoryBase> >(
"Importer", Teuchos::null, 
"Generating factory of the matrix Importer for rebalancing");
 
   86     validParamList->
set<
RCP<const FactoryBase> >(
"SubImporters", Teuchos::null, 
"Generating factory of the matrix sub-Importers for rebalancing");
 
   88     return validParamList;
 
   91   template <
class Scalar,
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   93     FactManager_.push_back(FactManager);
 
   96   template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   98     Input(coarseLevel, 
"A");
 
  100     std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
 
  101     for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
 
  105       coarseLevel.
DeclareInput(
"Importer",(*it)->GetFactory(
"Importer").get(), 
this);
 
  109     if(FactManager_.size() == 0) {
 
  110       Input(coarseLevel,
"SubImporters");
 
  115   template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  121     RCP<Matrix> originalAc = Get< RCP<Matrix> >(coarseLevel, 
"A");
 
  125     TEUCHOS_TEST_FOR_EXCEPTION(bA->Rows() != bA->Cols(), 
Exceptions::RuntimeError, 
"MueLu::RebalanceBlockAcFactory::Build: Blocked operator has " << bA->Rows() << 
" and " << bA->Cols() << 
". We only support square matrices (with same number of blocks and columns).");
 
  128     std::vector<GO> fullRangeMapVector;
 
  129     std::vector<GO> fullDomainMapVector;
 
  130     std::vector<RCP<const Map> > subBlockARangeMaps;
 
  131     std::vector<RCP<const Map> > subBlockADomainMaps;
 
  132     subBlockARangeMaps.reserve(bA->Rows());
 
  133     subBlockADomainMaps.reserve(bA->Cols());
 
  146     bool bThyraRangeGIDs  = rangeMapExtractor->getThyraMode();
 
  147     bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
 
  150     std::vector<RCP<Matrix> > subBlockRebA =
 
  151         std::vector<RCP<Matrix> >(bA->Cols() * bA->Rows(), Teuchos::null);
 
  155     std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bA->Rows(), Teuchos::null);
 
  156     std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
 
  158     for(it = FactManager_.begin(); it!=FactManager_.end(); ++it) {
 
  163       importers[idx] = rebalanceImporter;
 
  166     if(FactManager_.size() == 0) {
 
  167       importers = Get<std::vector<RCP<const Import> > >(coarseLevel,
"SubImporters");
 
  172     bool bRestrictComm = 
false;
 
  174     if (pL.
get<
bool>(
"repartition: use subcommunicators") == 
true)
 
  175       bRestrictComm = 
true;
 
  179       XpetraList->
set(
"Restrict Communicator",
true);
 
  181       XpetraList->
set(
"Restrict Communicator",
false);
 
  190     for(
size_t i=0; i<bA->Rows(); i++) {
 
  191       for(
size_t j=0; j<bA->Cols(); j++) {
 
  195         std::stringstream ss; ss << 
"Rebalancing matrix block A(" << i << 
"," << j << 
")";
 
  200         if( importers[i] != Teuchos::null &&
 
  201             importers[j] != Teuchos::null &&
 
  202             Aij != Teuchos::null) {
 
  215           TEUCHOS_TEST_FOR_EXCEPTION(rebAijImport.
is_null() == 
true,
Exceptions::RuntimeError, 
"MueLu::RebalanceBlockAcFactory::Build: Importer associated with block " << j << 
" is null.");
 
  218           TEUCHOS_TEST_FOR_EXCEPTION(cAwij.is_null() == 
true,
Exceptions::RuntimeError, 
"MueLu::RebalanceBlockAcFactory::Build: Block (" << i << 
"," << j << 
") is not of type CrsMatrix. We cannot rebalanced (nested) operators.");
 
  226           rebAij = MatrixFactory::Build(cAij, *(importers[i]), *(importers[j]), targetDomainMap, targetRangeMap, XpetraList);
 
  233         subBlockRebA[i*bA->Cols() + j] = rebAij;
 
  235         if (!rebAij.is_null()) {
 
  237           if(rebalancedComm.
is_null()) rebalancedComm = rebAij->getRowMap()->getComm();
 
  241           params->
set(
"printLoadBalancingInfo", 
true);
 
  242           std::stringstream ss2; ss2 << 
"A(" << i << 
"," << j << 
") rebalanced:";
 
  252       if ( subBlockRebA[i*bA->Cols() + i].is_null() == false ) {
 
  253         RCP<Matrix> rebAii = subBlockRebA[i*bA->Cols() + i];
 
  254         Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<
const StridedMap>(rangeMapExtractor->getMap(i,rangeMapExtractor->getThyraMode()));
 
  256         if(orig_stridedRgMap != Teuchos::null) {
 
  257           std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
 
  259           stridedRgMap = StridedMapFactory::Build(
 
  260               bA->getRangeMap()->lib(),
 
  263               rebAii->getRangeMap()->getIndexBase(),
 
  266               orig_stridedRgMap->getStridedBlockId(),
 
  267               orig_stridedRgMap->getOffset());
 
  269         Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<
const StridedMap>(domainMapExtractor->getMap(i,domainMapExtractor->getThyraMode()));
 
  271         if(orig_stridedDoMap != Teuchos::null) {
 
  272           std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
 
  274           stridedDoMap = StridedMapFactory::Build(
 
  275               bA->getDomainMap()->lib(),
 
  278               rebAii->getDomainMap()->getIndexBase(),
 
  281               orig_stridedDoMap->getStridedBlockId(),
 
  282               orig_stridedDoMap->getOffset());
 
  286           stridedRgMap->removeEmptyProcesses();
 
  287           stridedDoMap->removeEmptyProcesses();
 
  290         TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,
Exceptions::RuntimeError, 
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
 
  291         TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,
Exceptions::RuntimeError, 
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
 
  294         if(rebAii->IsView(
"stridedMaps")) rebAii->RemoveView(
"stridedMaps");
 
  295         rebAii->CreateView(
"stridedMaps", stridedRgMap, stridedDoMap);
 
  297         subBlockARangeMaps.push_back(rebAii->getRowMap(
"stridedMaps"));
 
  300         fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMap.
begin(), nodeRangeMap.
end());
 
  301         if(bThyraRangeGIDs == 
false)
 
  302           sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
 
  304         subBlockADomainMaps.push_back(rebAii->getColMap(
"stridedMaps"));
 
  307         fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMap.
begin(), nodeDomainMap.
end());
 
  308         if(bThyraDomainGIDs == 
false)
 
  309           sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
 
  316     if (rebalancedComm == Teuchos::null) {
 
  317       GetOStream(
Debug,-1) << 
"RebalanceBlockedAc: deactivate proc " << originalAc->getRowMap()->getComm()->getRank() << std::endl;
 
  320       coarseLevel.Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA), 
this);
 
  326     GO rangeIndexBase  = bA->getRangeMap()->getIndexBase();
 
  327     GO domainIndexBase = bA->getDomainMap()->getIndexBase();
 
  329     Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0,fullRangeMapVector.size());
 
  332     if(stridedRgFullMap != Teuchos::null) {
 
  333       std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
 
  335           StridedMapFactory::Build(
 
  336               bA->getRangeMap()->lib(),
 
  342               stridedRgFullMap->getStridedBlockId(),
 
  343               stridedRgFullMap->getOffset());
 
  347               bA->getRangeMap()->lib(),
 
  353     Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0,fullDomainMapVector.size());
 
  357     if(stridedDoFullMap != Teuchos::null) {
 
  358       TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap==Teuchos::null, 
Exceptions::BadCast, 
"MueLu::RebalanceBlockedAc::Build: full map in domain map extractor has no striding information! error.");
 
  359       std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
 
  361           StridedMapFactory::Build(
 
  362               bA->getDomainMap()->lib(),
 
  368               stridedDoFullMap->getStridedBlockId(),
 
  369               stridedDoFullMap->getOffset());
 
  374               bA->getDomainMap()->lib(),
 
  382       fullRangeMap->removeEmptyProcesses();
 
  383       fullDomainMap->removeEmptyProcesses();
 
  390     TEUCHOS_TEST_FOR_EXCEPTION(rangeMapExtractor->NumMaps()  != rebRangeMapExtractor->NumMaps(), 
Exceptions::BadCast, 
"MueLu::RebalanceBlockedAc::Build: Rebalanced RangeMapExtractor has " << rebRangeMapExtractor << 
" sub maps. Original RangeMapExtractor has " << rangeMapExtractor->NumMaps() << 
". They must match!");
 
  391     TEUCHOS_TEST_FOR_EXCEPTION(domainMapExtractor->NumMaps() != rebDomainMapExtractor->NumMaps(), 
Exceptions::BadCast, 
"MueLu::RebalanceBlockedAc::Build: Rebalanced DomainMapExtractor has " << rebDomainMapExtractor << 
" sub maps. Original DomainMapExtractor has " << domainMapExtractor->NumMaps() << 
". They must match!");
 
  394     for(
size_t i=0; i<bA->Rows(); i++) {
 
  395       for(
size_t j=0; j<bA->Cols(); j++) {
 
  397        reb_bA->setMatrix(i,j,subBlockRebA[i*bA->Cols() + j]);
 
  401     reb_bA->fillComplete();
 
  404     coarseLevel.Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA), 
this);
 
  409     if (rebalanceFacts_.begin() != rebalanceFacts_.end()) {
 
  413       for (std::vector<
RCP<const FactoryBase> >::const_iterator it2 = rebalanceFacts_.begin(); it2 != rebalanceFacts_.end(); ++it2) {
 
  414         GetOStream(
Runtime0) << 
"RebalanceBlockedAc: call rebalance factory " << (*it2).get() << 
": " << (*it2)->description() << std::endl;
 
  415         (*it2)->CallBuild(coarseLevel);
 
  420   template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  427     rebalanceFacts_.push_back(factory);
 
Exception indicating invalid cast attempted. 
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager)
Add a factory manager. 
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers. 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define SET_VALID_ENTRY(name)
Print additional debugging information. 
One-liner description of what is happening. 
Print statistics that do not involve significant additional computation. 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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. 
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 'Level::SetFactoryManager()'. 
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() 
RebalanceBlockAcFactory()