SmartBulk3D::SmartBulk3D( MultiBlockManagement3D const& management, plint blockId ) : sparseBlock(management.getSparseBlockStructure()), envelopeWidth(management.getEnvelopeWidth()) { sparseBlock.getBulk(blockId, bulk); }
MultiBlockManagement3D RandomRedistribute3D::redistribute ( MultiBlockManagement3D const& original ) const { ThreadAttribution const& originalAttribution = original.getThreadAttribution(); SparseBlockStructure3D const& originalSparseBlock = original.getSparseBlockStructure(); std::map<plint,Box3D> const& domains = originalSparseBlock.getBulks(); std::vector<std::pair<plint,plint> > blockToProc(domains.size()); std::map<plint,Box3D>::const_iterator it = domains.begin(); for (plint pos=0; it != domains.end(); ++it, ++pos) { plint blockId = it->first; plint procId = originalAttribution.getMpiProcess(blockId); blockToProc[pos] = std::pair<plint,plint>(blockId,procId); } srand(rseed); plint numExchange = (plint)blockToProc.size()*10; for (plint iExch=0; iExch<numExchange; ++iExch) { plint id1 = rand() % blockToProc.size(); plint id2 = rand() % blockToProc.size(); std::swap(blockToProc[id1].second, blockToProc[id2].second); } ExplicitThreadAttribution* newAttribution = new ExplicitThreadAttribution; for (pluint i=0; i<blockToProc.size(); ++i) { newAttribution->addBlock(blockToProc[i].first, blockToProc[i].second); } return MultiBlockManagement3D ( originalSparseBlock, newAttribution, original.getEnvelopeWidth(), original.getRefinementLevel() ); }
MultiBlockManagement3D align( MultiBlockManagement3D const& originalManagement, MultiBlockManagement3D const& partnerManagement ) { std::vector<plint> newIds; std::map<plint,std::vector<plint> > remappedFromPartner; SparseBlockStructure3D resultStructure = alignDistribution3D(originalManagement.getSparseBlockStructure(), partnerManagement.getSparseBlockStructure(), newIds, remappedFromPartner); // 1. Parallelize the left-over blocks (the ones which don't overlap // with partnerManagement) evenly. ExplicitThreadAttribution attribution; plint numBlocks = (plint) newIds.size(); plint numProcs = global::mpi().getSize(); plint iBlock=0; for (plint iProc=0; iProc<numProcs; ++iProc) { plint localNumBlocks = numBlocks/numProcs; if (iProc<numBlocks%numProcs) { ++localNumBlocks; } for (plint iLocal=0; iLocal<localNumBlocks; ++iLocal) { attribution.addBlock(newIds[iBlock], iProc); ++iBlock; } } // 2. Merge remapped ids into the thread attribution, and return a // corresponding MultiBlockManagement3D object. return MultiBlockManagement3D ( resultStructure, attribution.merge ( partnerManagement.getThreadAttribution(), remappedFromPartner ), originalManagement.getEnvelopeWidth(), originalManagement.getRefinementLevel() ); }
MultiBlockManagement3D reparallelize(MultiBlockManagement3D const& management, plint blockLx, plint blockLy, plint blockLz) { SparseBlockStructure3D resultStructure = reparallelize(management.getSparseBlockStructure(), blockLx, blockLy, blockLz); plint numBlocks = resultStructure.nextIncrementalId(); plint numProcs = global::mpi().getSize(); // Create a thread attribution from scratch, by partitioning the // available blocks equally. ExplicitThreadAttribution* threadAttribution = new ExplicitThreadAttribution; plint iBlock=0; for (plint iProc=0; iProc<numProcs; ++iProc) { plint localNumBlocks = numBlocks/numProcs; if (iProc<numBlocks%numProcs) { ++localNumBlocks; } for (plint iLocal=0; iLocal<localNumBlocks; ++iLocal) { threadAttribution->addBlock(iBlock, iProc); ++iBlock; } } return MultiBlockManagement3D ( resultStructure, threadAttribution, management.getEnvelopeWidth(), management.getRefinementLevel() ); }
MultiBlockManagement3D scale(MultiBlockManagement3D const& originalManagement, plint relativeLevel) { return MultiBlockManagement3D ( scale(originalManagement.getSparseBlockStructure(), relativeLevel), originalManagement.getThreadAttribution().clone(), originalManagement.getEnvelopeWidth(), originalManagement.getRefinementLevel()+relativeLevel ); }
MultiBlockManagement3D intersect( MultiBlockManagement3D const& management1, MultiBlockManagement3D const& management2, bool crop ) { return MultiBlockManagement3D ( intersect(management1.getSparseBlockStructure(), management2.getSparseBlockStructure(), crop), management1.getThreadAttribution().clone(), management1.getEnvelopeWidth(), management1.getRefinementLevel() ); }
MultiBlockManagement3D intersect ( MultiBlockManagement3D const& originalManagement, Box3D subDomain, bool crop ) { return MultiBlockManagement3D ( intersect(originalManagement.getSparseBlockStructure(), subDomain, crop), originalManagement.getThreadAttribution().clone(), originalManagement.getEnvelopeWidth(), originalManagement.getRefinementLevel() ); }
MultiBlockManagement3D except( MultiBlockManagement3D const& management, Box3D exceptedBlock ) { std::map<plint,std::vector<plint> > remappedIds; SparseBlockStructure3D resultStructure = except( management.getSparseBlockStructure(), exceptedBlock, remappedIds ); return MultiBlockManagement3D ( resultStructure, management.getThreadAttribution().merge ( management.getThreadAttribution(), remappedIds ), management.getEnvelopeWidth(), management.getRefinementLevel() ); }
MultiBlockManagement3D extend( MultiBlockManagement3D const& management, Box3D addedBulk, Box3D addedUniqueBulk ) { std::vector<plint> newIds; SparseBlockStructure3D resultStructure = extend( management.getSparseBlockStructure(), addedBulk, addedBulk, newIds ); std::vector<plint> mpiProcesses(newIds.size()), localThreads(newIds.size()); for (pluint iNew=0; iNew<newIds.size(); ++iNew) { // Default-attribute the newly created blocks to the main process. mpiProcesses[iNew] = global::mpi().bossId(); localThreads[iNew] = 0; } return MultiBlockManagement3D ( resultStructure, management.getThreadAttribution().extend ( newIds, mpiProcesses, localThreads ), management.getEnvelopeWidth(), management.getRefinementLevel() ); }
MultiBlockManagement3D align( std::vector<Box3D> const& originalDomain, MultiBlockManagement3D const& alignWith, plint envelopeWidth, plint refinementLevel, bool crop ) { Box3D bbox(alignWith.getBoundingBox()); if (crop && !originalDomain.empty()) { bbox = originalDomain[0]; for (pluint i=1; i<originalDomain.size(); ++i) { bbox = bound(bbox, originalDomain[i]); } } SparseBlockStructure3D originalSparseBlock(bbox); for (plint i=0; i<(plint)originalDomain.size(); ++i) { originalSparseBlock.addBlock(originalDomain[i], i); } MultiBlockManagement3D originalManagement ( originalSparseBlock, defaultMultiBlockPolicy3D().getThreadAttribution(), envelopeWidth, refinementLevel ); return align(originalManagement, alignWith); }
MultiBlockManagement3D block_union( MultiBlockManagement3D const& management1, MultiBlockManagement3D const& management2 ) { std::map<plint,std::vector<plint> > remappedIds; SparseBlockStructure3D resultStructure = block_union( management1.getSparseBlockStructure(), management2.getSparseBlockStructure(), remappedIds ); return MultiBlockManagement3D ( resultStructure, management1.getThreadAttribution().merge ( management2.getThreadAttribution(), remappedIds ), management1.getEnvelopeWidth(), management1.getRefinementLevel() ); }