bool CheckConsistency() { if(getStridedBlockId() == -1) { //if(isContiguous() == false) return false; if(getNodeNumElements() % getFixedBlockSize() != 0) return false; if(getGlobalNumElements() % getFixedBlockSize() != 0) return false; } else { Teuchos::ArrayView< const GlobalOrdinal > dofGids = getNodeElementList(); //std::sort(dofGids.begin(),dofGids.end()); // determine nStridedOffset size_t nStridedOffset = 0; for(int j=0; j<stridedBlockId_; j++) { nStridedOffset += stridingInfo_[j]; } //size_t nDofsPerNode = stridingInfo_[stridedBlockId_]; const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset); const GlobalOrdinal goZeroOffset = (dofGids[0] - nStridedOffset - offset_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()); /*printf("goZeroOffset: %i\n",goZeroOffset); printf("dofGids[0]: %i \n",dofGids[0]); printf("stridedOffset: %i\n",nStridedOffset); printf("offset_: %i\n",offset_); printf("goStridedOffset: %i\n",goStridedOffset); printf("getFixedBlkSize: %i\n",getFixedBlockSize());*/ GlobalOrdinal cnt = 0; for(size_t i = 0; i<Teuchos::as<size_t>(dofGids.size())/stridingInfo_[stridedBlockId_]; i+=stridingInfo_[stridedBlockId_]) { for(size_t j=0; j<stridingInfo_[stridedBlockId_]; j++) { const GlobalOrdinal gid = dofGids[i+j]; if((gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt != 0) { //std::cout << "gid: " << gid << " GID: " << (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt << std::endl; return false; } } cnt++; } } return true; }
StridedMap(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1) : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId) { indexBase_ = indexBase; TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?"); TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId < -1, Exceptions::RuntimeError, "StridedMap::StridedMap: stridedBlockId must not be smaller than -1."); // the following tests are not valid if stridedBlockId != 1 if (stridedBlockId == -1) { TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements."); TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of elementList.size()."); } else { // numGlobalElements can be -1! FIXME //TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of numGlobalElements."); TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of elementList.size()."); } // calculate offset_ // find minimum GID over all procs GlobalOrdinal minGidOnCurProc = 999999; // TODO use scalar traits for max possible gid. for(Teuchos_Ordinal k=0; k<elementList.size(); ++k) { // TODO fix occurence of Teuchos_Ordinal if(elementList[k] < minGidOnCurProc) minGidOnCurProc = elementList[k]; } Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_)); // calculate striding index size_t nStridedOffset = 0; for(int j=0; j<stridedBlockId; j++) { nStridedOffset += stridingInfo[j]; } const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset); // adapt offset_ offset_ -= goStridedOffset - indexBase_; // TODO check me }
// returns number of strided block id which gid belongs to. size_t GID2StridingBlockId( GlobalOrdinal gid ) const { GlobalOrdinal tgid = gid - offset_; tgid = tgid % getFixedBlockSize(); size_t nStridedOffset = 0; size_t stridedBlockId = 0; for(size_t j=0; j<stridingInfo_.size(); j++) { nStridedOffset += stridingInfo_[j]; if(Teuchos::as<size_t>(tgid) < nStridedOffset) { stridedBlockId = j; break; } } return stridedBlockId; }
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
/// returns true, if this is a blocked map (i.e. more than 1 dof per node) /// either strided or just 1 block per node bool isBlocked() { return getFixedBlockSize() > 1 ? true : false; }
//! EpetraMap constructor to wrap a Epetra_Map object StridedEpetraMap(const Teuchos::RCP<const Epetra_BlockMap> &map, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset = 0) : EpetraMap(map), StridedMap<int, int>(stridingInfo, stridedBlockId, offset) { int nDofsPerNode = Teuchos::as<int>(getFixedBlockSize()); TEUCHOS_TEST_FOR_EXCEPTION(map_->NumMyPoints() % nDofsPerNode != 0, Exceptions::RuntimeError, "StridedEpetraMap::StridedEpetraMap: wrong distribution of dofs among processors."); TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedEpetraMap::StridedEpetraMap: CheckConsistency() == false"); }
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