SmartBulk3D::SmartBulk3D( MultiBlockManagement3D const& management,
                          plint blockId )
    : sparseBlock(management.getSparseBlockStructure()),
      envelopeWidth(management.getEnvelopeWidth())
{
    sparseBlock.getBulk(blockId, bulk);
}
Example #2
0
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() );
            
}