void BlockedCoarseMapFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Level ¤tLevel) const { FactoryMonitor m(*this, "BlockedCoarseMap factory", currentLevel); RCP<const FactoryBase> prevCoarseMapFact = this->GetFactory("CoarseMap"); RCP<const Map> subPDomainMap = currentLevel.Get<RCP<const Map> >("CoarseMap", prevCoarseMapFact.get() /*prevCoarseMapFact_.get()*/); GlobalOrdinal maxGlobalIndex = subPDomainMap->getMaxAllGlobalIndex(); RCP<Aggregates> aggregates = Factory::Get< RCP<Aggregates> >(currentLevel, "Aggregates"); GlobalOrdinal numAggs = aggregates->GetNumAggregates(); // extract communicator RCP<const Teuchos::Comm<int> > comm = aggregates->GetMap()->getComm(); // determine nullspace dimension RCP<MultiVector> nullspace = Factory::Get< RCP<MultiVector> >(currentLevel, "Nullspace"); const size_t NSDim = nullspace->getNumVectors(); LocalOrdinal stridedBlockId = CoarseMapFactory::getStridedBlockId(); // check for consistency of striding information with NSDim and nCoarseDofs if( stridedBlockId== -1 ) { // this means we have no real strided map but only a block map with constant blockSize "NSDim" TEUCHOS_TEST_FOR_EXCEPTION(CoarseMapFactory::stridingInfo_.size() > 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); CoarseMapFactory::stridingInfo_.clear(); CoarseMapFactory::stridingInfo_.push_back(NSDim); TEUCHOS_TEST_FOR_EXCEPTION(CoarseMapFactory::stridingInfo_.size() != 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); } else { // stridedBlockId_ > -1, set by user TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId > Teuchos::as<LO>(CoarseMapFactory::stridingInfo_.size() - 1) , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): it is stridingInfo_.size() <= stridedBlockId_. error."); size_t stridedBlockSize = CoarseMapFactory::stridingInfo_[stridedBlockId]; TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockSize != NSDim , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): dimension of strided block != NSDim. error."); } CoarseMapFactory::GetOStream(Statistics2) << "domainGIDOffset: " << maxGlobalIndex + 1 << " block size: " << CoarseMapFactory::getFixedBlockSize() << " stridedBlockId: " << stridedBlockId << std::endl; // number of coarse level dofs (fixed by number of aggregates and blocksize data) GlobalOrdinal nCoarseDofs = numAggs * CoarseMapFactory::getFixedBlockSize(); GlobalOrdinal indexBase = aggregates->GetMap()->getIndexBase(); RCP<const Map> coarseMap = StridedMapFactory::Build(aggregates->GetMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), nCoarseDofs, indexBase, CoarseMapFactory::stridingInfo_, comm, stridedBlockId, maxGlobalIndex + 1); this->Set(currentLevel, "CoarseMap", coarseMap); } // Build
void CoarseMapFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level ¤tLevel) const { FactoryMonitor m(*this, "Build", currentLevel); RCP<Aggregates> aggregates = Get< RCP<Aggregates> >(currentLevel, "Aggregates"); RCP<MultiVector> nullspace = Get< RCP<MultiVector> >(currentLevel, "Nullspace"); GlobalOrdinal numAggs = aggregates->GetNumAggregates(); const size_t NSDim = nullspace->getNumVectors(); RCP<const Teuchos::Comm<int> > comm = aggregates->GetMap()->getComm(); // check for consistency of striding information with NSDim and nCoarseDofs if (stridedBlockId_== -1) { // this means we have no real strided map but only a block map with constant blockSize "NSDim" TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() > 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); stridingInfo_.clear(); stridingInfo_.push_back(NSDim); TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() != 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); } else { // stridedBlockId_ > -1, set by user TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId_ > Teuchos::as<LO>(stridingInfo_.size() - 1) , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): it is stridingInfo_.size() <= stridedBlockId_. error."); size_t stridedBlockSize = stridingInfo_[stridedBlockId_]; TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockSize != NSDim , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): dimension of strided block != NSDim. error."); } GetOStream(Statistics1, 0) << "domainGIDOffset: " << domainGidOffset_ << " block size: " << getFixedBlockSize() << " stridedBlockId: " << stridedBlockId_ << std::endl; // number of coarse level dofs (fixed by number of aggregates and blocksize data) GlobalOrdinal nCoarseDofs = numAggs * getFixedBlockSize(); GlobalOrdinal indexBase = aggregates->GetMap()->getIndexBase(); RCP<const Map> coarseMap = StridedMapFactory::Build(aggregates->GetMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), nCoarseDofs, indexBase, stridingInfo_, comm, stridedBlockId_, domainGidOffset_); Set(currentLevel, "CoarseMap", coarseMap); } // Build
void CoordinatesTransferFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level & fineLevel, Level &coarseLevel) const { FactoryMonitor m(*this, "Build", coarseLevel); GetOStream(Runtime0, 0) << "Transferring coordinates" << std::endl; const ParameterList & pL = GetParameterList(); int writeStart = pL.get< int >("write start"); int writeEnd = pL.get< int >("write end"); RCP<Aggregates> aggregates = Get< RCP<Aggregates> > (fineLevel, "Aggregates"); RCP<MultiVector> fineCoords = Get< RCP<MultiVector> >(fineLevel, "Coordinates"); RCP<const Map> coarseMap = Get< RCP<const Map> > (fineLevel, "CoarseMap"); // coarseMap is being used to set up the domain map of tentative P, and therefore, the row map of Ac // Therefore, if we amalgamate coarseMap, logical nodes in the coordinates vector would correspond to // logical blocks in the matrix ArrayView<const GO> elementAList = coarseMap->getNodeElementList(); LO blkSize = 1; if (rcp_dynamic_cast<const StridedMap>(coarseMap) != Teuchos::null) blkSize = rcp_dynamic_cast<const StridedMap>(coarseMap)->getFixedBlockSize(); GO indexBase = coarseMap->getIndexBase(); size_t numElements = elementAList.size() / blkSize; Array<GO> elementList(numElements); // Amalgamate the map for (LO i = 0; i < Teuchos::as<LO>(numElements); i++) elementList[i] = (elementAList[i*blkSize]-indexBase)/blkSize + indexBase; RCP<const Map> coarseCoordMap = MapFactory ::Build(coarseMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), elementList, indexBase, coarseMap->getComm()); RCP<MultiVector> coarseCoords = MultiVectorFactory::Build(coarseCoordMap, fineCoords->getNumVectors()); // Maps RCP<const Map> uniqueMap = fineCoords->getMap(); RCP<const Map> nonUniqueMap = aggregates->GetMap(); // Create overlapped fine coordinates to reduce global communication RCP<const Import> importer = ImportFactory ::Build(uniqueMap, nonUniqueMap); RCP<MultiVector> ghostedCoords = MultiVectorFactory::Build(nonUniqueMap, fineCoords->getNumVectors()); ghostedCoords->doImport(*fineCoords, *importer, Xpetra::INSERT); // Get some info about aggregates int myPID = uniqueMap->getComm()->getRank(); LO numAggs = aggregates->GetNumAggregates(); ArrayRCP<LO> aggSizes = aggregates->ComputeAggregateSizes(); const ArrayRCP<const LO> vertex2AggID = aggregates->GetVertex2AggId()->getData(0); const ArrayRCP<const LO> procWinner = aggregates->GetProcWinner()->getData(0); // Fill in coarse coordinates for (size_t j = 0; j < fineCoords->getNumVectors(); j++) { ArrayRCP<const Scalar> fineCoordsData = ghostedCoords->getData(j); ArrayRCP<Scalar> coarseCoordsData = coarseCoords->getDataNonConst(j); for (LO lnode = 0; lnode < vertex2AggID.size(); lnode++) if (procWinner[lnode] == myPID) coarseCoordsData[vertex2AggID[lnode]] += fineCoordsData[lnode]; for (LO agg = 0; agg < numAggs; agg++) coarseCoordsData[agg] /= aggSizes[agg]; } Set<RCP<MultiVector> >(coarseLevel, "Coordinates", coarseCoords); if (writeStart == 0 && fineLevel.GetLevelID() == 0 && writeStart <= writeEnd) { std::ostringstream buf; buf << fineLevel.GetLevelID(); std::string fileName = "coordinates_before_rebalance_level_" + buf.str() + ".m"; Utils::Write(fileName,*fineCoords); } if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd) { std::ostringstream buf; buf << coarseLevel.GetLevelID(); std::string fileName = "coordinates_before_rebalance_level_" + buf.str() + ".m"; Utils::Write(fileName,*coarseCoords); } } // Build
void CoarseMapFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level ¤tLevel) const { FactoryMonitor m(*this, "Build", currentLevel); RCP<Aggregates> aggregates = Get< RCP<Aggregates> >(currentLevel, "Aggregates"); RCP<MultiVector> nullspace = Get< RCP<MultiVector> >(currentLevel, "Nullspace"); GlobalOrdinal numAggs = aggregates->GetNumAggregates(); const size_t NSDim = nullspace->getNumVectors(); RCP<const Teuchos::Comm<int> > comm = aggregates->GetMap()->getComm(); // read in offset information from parameter list and fill the internal member variable GlobalOrdinal domainGidOffset = 0; std::vector<GlobalOrdinal> domainGidOffsets; domainGidOffsets.clear(); const ParameterList & pL = GetParameterList(); if(pL.isParameter("Domain GID offsets")) { std::string strDomainGIDs = pL.get<std::string>("Domain GID offsets"); if(strDomainGIDs.empty() == false) { Teuchos::Array<GlobalOrdinal> arrayVal = Teuchos::fromStringToArray<GlobalOrdinal>(strDomainGIDs); domainGidOffsets = Teuchos::createVector(arrayVal); if(currentLevel.GetLevelID() < Teuchos::as<int>(domainGidOffsets.size()) ) { domainGidOffset = domainGidOffsets[currentLevel.GetLevelID()]; } } } LocalOrdinal stridedBlockId = pL.get<LocalOrdinal>("Strided block id"); // read in stridingInfo from parameter list and fill the internal member variable // read the data only if the parameter "Striding info" exists and is non-empty //const ParameterList & pL = GetParameterList(); if(pL.isParameter("Striding info")) { std::string strStridingInfo = pL.get<std::string>("Striding info"); if(strStridingInfo.empty() == false) { Teuchos::Array<size_t> arrayVal = Teuchos::fromStringToArray<size_t>(strStridingInfo); stridingInfo_ = Teuchos::createVector(arrayVal); } } // check for consistency of striding information with NSDim and nCoarseDofs if (stridedBlockId== -1) { // this means we have no real strided map but only a block map with constant blockSize "NSDim" TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() > 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); stridingInfo_.clear(); stridingInfo_.push_back(NSDim); TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() != 1, Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): stridingInfo_.size() but must be one"); } else { // stridedBlockId > -1, set by user TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId > Teuchos::as<LO>(stridingInfo_.size() - 1) , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): it is stridingInfo_.size() <= stridedBlockId_. error."); size_t stridedBlockSize = stridingInfo_[stridedBlockId]; TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockSize != NSDim , Exceptions::RuntimeError, "MueLu::CoarseMapFactory::Build(): dimension of strided block != NSDim. error."); } GetOStream(Statistics2) << "domainGIDOffset: " << domainGidOffset << " block size: " << getFixedBlockSize() << " stridedBlockId: " << stridedBlockId << std::endl; // number of coarse level dofs (fixed by number of aggregates and blocksize data) GlobalOrdinal nCoarseDofs = numAggs * getFixedBlockSize(); GlobalOrdinal indexBase = aggregates->GetMap()->getIndexBase(); RCP<const Map> coarseMap = StridedMapFactory::Build(aggregates->GetMap()->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), nCoarseDofs, indexBase, stridingInfo_, comm, stridedBlockId, domainGidOffset); Set(currentLevel, "CoarseMap", coarseMap); } // Build