void SerialBlockCommunicator2D::copyOverlap (
        Overlap2D const& overlap,
        MultiBlock2D const& fromMultiBlock, MultiBlock2D& toMultiBlock,
        modif::ModifT whichData ) const
{
    MultiBlockManagement2D const& fromManagement = fromMultiBlock.getMultiBlockManagement();
    MultiBlockManagement2D const& toManagement = toMultiBlock.getMultiBlockManagement();
    plint fromEnvelopeWidth = fromManagement.getEnvelopeWidth();
    plint toEnvelopeWidth = toManagement.getEnvelopeWidth();
    SparseBlockStructure2D const& fromSparseBlock = fromManagement.getSparseBlockStructure();
    SparseBlockStructure2D const& toSparseBlock = toManagement.getSparseBlockStructure();
    plint originalId = overlap.getOriginalId();
    plint overlapId  = overlap.getOverlapId();
    SmartBulk2D originalBulk(fromSparseBlock, fromEnvelopeWidth, originalId);
    SmartBulk2D overlapBulk(toSparseBlock, toEnvelopeWidth, overlapId);

    Box2D originalCoords(originalBulk.toLocal(overlap.getOriginalCoordinates()));
    Box2D overlapCoords(overlapBulk.toLocal(overlap.getOverlapCoordinates()));

    PLB_PRECONDITION(originalCoords.x1-originalCoords.x0 == overlapCoords.x1-overlapCoords.x0);
    PLB_PRECONDITION(originalCoords.y1-originalCoords.y0 == overlapCoords.y1-overlapCoords.y0);

    AtomicBlock2D const* originalBlock = &fromMultiBlock.getComponent(originalId);
    AtomicBlock2D* overlapBlock = &toMultiBlock.getComponent(overlapId);
    plint deltaX = originalCoords.x0 - overlapCoords.x0;
    plint deltaY = originalCoords.y0 - overlapCoords.y0;

    overlapBlock -> getDataTransfer().attribute(overlapCoords, deltaX, deltaY,
                                                *originalBlock, whichData);
}
void Parallelizer3D::parallelizeLevel(plint whichLevel,
                                      std::vector<std::vector<Box3D> > const& originalBlocks,
                                      std::vector<Box3D> const& parallelRegions,
                                      std::vector<plint> const& regionIDs )
{
    PLB_PRECONDITION( parallelRegions.size() == regionIDs.size() );
    PLB_PRECONDITION( whichLevel < (plint)originalBlocks.size() );
    std::vector<Box3D> newBlocks;
    // IDs are going to be reattributed at the level whichLevel.
    if (finalMpiDistribution.size() <= (pluint)whichLevel) {
        finalMpiDistribution.resize(whichLevel+1);
    }
    for (pluint iRegion=0; iRegion<parallelRegions.size(); ++iRegion) {
        plint currentId = regionIDs[iRegion];
        for (pluint iBlock=0; iBlock<originalBlocks[whichLevel].size(); ++iBlock) {
            Box3D intersection;
            if ( intersect( originalBlocks[whichLevel][iBlock],
                            parallelRegions[iRegion], intersection ) )
            {
                newBlocks.push_back(intersection);
                finalMpiDistribution[whichLevel].push_back(currentId);
            }
        }
    }

    recomputedBlocks[whichLevel].insert( recomputedBlocks[whichLevel].end(),newBlocks.begin(),newBlocks.end() );
}
const char* AtomicBlockSerializer3D::getNextDataBuffer(pluint& bufferSize) const {
    PLB_PRECONDITION( !isEmpty() );
    if (ordering==IndexOrdering::forward || ordering==IndexOrdering::memorySaving) {
        bufferSize = domain.getNz() * block.getDataTransfer().staticCellSize();
        buffer.resize(bufferSize);
        block.getDataTransfer().send(Box3D(iX,iX,iY,iY, domain.z0, domain.z1),
                                     buffer, modif::staticVariables);
        ++iY;
        if (iY > domain.y1) {
            iY = domain.y0;
            ++iX;
        }
    }
    else {
        bufferSize = domain.getNx() * block.getDataTransfer().staticCellSize();
        buffer.resize(bufferSize);
        block.getDataTransfer().send(Box3D(domain.x0, domain.x1, iY,iY,iZ,iZ),
                                           buffer, modif::staticVariables);
        ++iY;
        if (iY > domain.y1) {
            iY = domain.y0;
            ++iZ;
        }
    }
    return &buffer[0];
}
Example #4
0
void PeriodicitySwitch3D::toggle(plint direction, bool periodic) {
    PLB_PRECONDITION( direction==0 || direction==1 || direction==2 );
    periodicity[direction] = periodic;
    // Make sure periodic envelope is filled with data, else all
    //   subsequent operations are wrong.
    block.signalPeriodicity();
    block.duplicateOverlaps(modif::dataStructure);
}
void AllFlagsTrueFunctional3D::processGenericBlocks (
        Box3D domain, std::vector<AtomicBlock3D*> blocks )
{
    PLB_PRECONDITION( blocks.size()==1 );
    if (!blocks[0]->getFlag()) {
        this->getStatistics().gatherIntSum(numFalseId, 1);
    }
}
Example #6
0
void XMLreader::mainProcessorIni( std::vector<TiXmlNode*> pParentVect )
{
    std::map<plint, TiXmlNode*> parents;
    for (pluint iParent=0; iParent<pParentVect.size(); ++iParent) {
        PLB_PRECONDITION( pParentVect[iParent]->Type()==TiXmlNode::DOCUMENT ||
                          pParentVect[iParent]->Type()==TiXmlNode::ELEMENT );

        TiXmlElement* pParentElement = pParentVect[iParent]->ToElement();
        plint id=0;
        if (pParentElement) {
            const char* attribute = pParentElement->Attribute("id");
            if (attribute) {
                std::stringstream attributestr(attribute);
                attributestr >> id;
            }
        }
        parents[id] = pParentVect[iParent];
    }

    plint numId = (plint)parents.size();
    global::mpi().bCast(&numId, 1);

    std::map<plint, TiXmlNode*>::iterator it = parents.begin();
    name = it->second->ValueStr();
    global::mpi().bCast(name);

    for (; it != parents.end(); ++it) {
        plint id = it->first;
        global::mpi().bCast(&id, 1);

        TiXmlNode* pParent = it->second;
        Data& data = data_map[id];
        data.text="";

        typedef std::map<std::string, std::vector<TiXmlNode*> > ChildMap;
        ChildMap childMap;
        TiXmlNode* pChild;
        for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) 
        {
            int type = pChild->Type();
            if ( type==TiXmlNode::ELEMENT ) {
                std::string name(pChild->Value());
                childMap[name].push_back(pChild);
            }
            else if ( type==TiXmlNode::TEXT ) {
                data.text = pChild->ToText()->ValueStr();
            }
        }
        global::mpi().bCast(data.text);
        plint numChildren = (plint) childMap.size();
        global::mpi().bCast(&numChildren, 1);

        for (ChildMap::iterator it = childMap.begin(); it != childMap.end(); ++it) {
            std::vector<TiXmlNode*> pChildVect = it->second;
            data.children.push_back( new XMLreader( pChildVect ) );
        }
    }
}
char* AtomicBlockUnSerializer3D::getNextDataBuffer(pluint& bufferSize) {
    PLB_PRECONDITION( !isFull() );
    if (ordering==IndexOrdering::forward || ordering==IndexOrdering::memorySaving) {
        bufferSize = domain.getNz() * block.getDataTransfer().staticCellSize();
    }
    else {
        bufferSize = domain.getNx() * block.getDataTransfer().staticCellSize();
    }
    buffer.resize(bufferSize);
    return &buffer[0];
}
void AtomicBlockUnSerializer2D::commitData() {
    PLB_PRECONDITION( !isFull() );
    if (ordering==IndexOrdering::forward || ordering==IndexOrdering::memorySaving) {
        block.getDataTransfer().receive(Box2D(iX,iX, domain.y0, domain.y1),
                                        buffer, modif::staticVariables);
        ++iX;
    }
    else {
        block.getDataTransfer().receive(Box2D(domain.x0, domain.x1, iY,iY),
                                        buffer, modif::staticVariables);
        ++iY;
    }
}
Example #9
0
void ParallellizeBySquares2D::parallelize(){
        // we must have the same number of blocks as processors
    PLB_PRECONDITION(xTiles*yTiles == processorNumber);
    
    plint totalCost = computeCost(originalBlocks, finestBoundingBox);
    plint idealCostPerProcessor = totalCost/processorNumber;
    
    pcout << "Total cost of computations = " << totalCost << std::endl;
    pcout << "We are using " << processorNumber << " processors...\n";
    pcout << "Ideal cost per processor = " << idealCostPerProcessor << std::endl;
    
    std::vector<plint> totalCosts(processorNumber);
    
    plint total = 0;
    for (plint iProc=0; iProc<processorNumber; ++iProc){
        plint blockCost = computeCost(originalBlocks,finestDivision[iProc]);
        totalCosts[iProc] += blockCost;
        mpiDistribution[iProc] = iProc;
        total += blockCost;
    }
    
    pcout << "---- Costs Per Processor ----\n";
    
    for (pluint i=0; i<totalCosts.size(); ++i){
        pcout << i << " : " << totalCosts[i] << std::endl;
        // check if everyone is doing something
        if (totalCosts[i] == 0){
            pcout << "\t >> processor " << i << " does not have work to do. Exiting.....\n";
            std::exit(1);
        }
    }
    
    pcout << "*******************************\n";
    pcout << "Sum of all costs = " << total << std::endl;
    pcout << "*******************************\n";
    
    // convert the original blocks to the new blocks
    recomputedBlocks.resize(originalBlocks.size());
    finalMpiDistribution.resize(originalBlocks.size());
    
    plint finestLevel= (plint)originalBlocks.size()-1;
    for (plint iLevel=finestLevel; iLevel>=0; --iLevel) {
        parallelizeLevel(iLevel, originalBlocks,finestDivision, mpiDistribution);
        // Adapt the regions to the next-coarser level.
        for (pluint iRegion=0; iRegion<finestDivision.size(); ++iRegion) {
            finestDivision[iRegion] = finestDivision[iRegion].divideAndFitSmaller(2);
        }
    }
}
void ParallelBlockCommunicator2D::communicate (
        std::vector<Overlap2D> const& overlaps,
        MultiBlock2D const& originMultiBlock,
        MultiBlock2D& destinationMultiBlock, modif::ModifT whichData ) const
{
    PLB_PRECONDITION( originMultiBlock.sizeOfCell() ==
                      destinationMultiBlock.sizeOfCell() );

    CommunicationStructure2D communication (
            overlaps,
            originMultiBlock.getMultiBlockManagement(),
            destinationMultiBlock.getMultiBlockManagement(),
            originMultiBlock.sizeOfCell() );
    global::profiler().start("mpiCommunication");
    communicate(communication, originMultiBlock, destinationMultiBlock, whichData);
    global::profiler().stop("mpiCommunication");
}
Example #11
0
void MultiBlock3D::addModifiedBlocks (
        plint level,
        std::vector<MultiBlock3D*> modifiedBlocks,
        std::vector<modif::ModifT> typeOfModification,
        std::vector<std::vector<BlockAndModif> >& multiBlockCollection,
        bool includesEnvelope )
{
    PLB_PRECONDITION( modifiedBlocks.size() == typeOfModification.size() );
    // Resize vector which collects modified blocks (resize needs to be
    //   done even when no block is added, to avoid memory violations
    //   during read access to the vector).
    if ((pluint)level >= multiBlockCollection.size()) {
        multiBlockCollection.resize(level+1);
    }
    // Unless envelope is already included in the domain of application of the data
    //   processor, subscribe modified blocks for an update of the envelope.
    if (!includesEnvelope) {
        for (pluint iNewBlock=0; iNewBlock<modifiedBlocks.size(); ++iNewBlock) {
            bool alreadyAdded=false;
            // Check if the block is already in the collection.
            // Note: It may seem stupid to use a linear-complexity algorithm to
            // find existing blocks. However, it would be a mistake to store the data
            // processors in a sorted structure. Indeed, sorting pointers leads to
            // an unpredictable order (because the pointers have an unpredictable value).
            // This is a problem in parallel programs, because different threads may find a
            // different order, and the communication pattern between processes gets messed up.
            for (pluint iOriginal=0; iOriginal<multiBlockCollection[level].size(); ++iOriginal) {
                MultiBlock3D* existingBlock = multiBlockCollection[level][iOriginal].first;
                if (existingBlock == modifiedBlocks[iNewBlock]) {
                    // If the block already exists, simply update the type of modification
                    // that applies to it.
                    modif::ModifT& existingModif = multiBlockCollection[level][iOriginal].second;
                    existingModif = combine( existingModif, typeOfModification[iNewBlock] );
                    alreadyAdded = true;
                }
            }
            // If the block is not already in the structure, add it.
            if (!alreadyAdded) {
                multiBlockCollection[level].push_back (
                        BlockAndModif( modifiedBlocks[iNewBlock], typeOfModification[iNewBlock] ) );
            }
        }
    }
}
MultiProcessing3D<OriginalGenerator,MutableGenerator>::MultiProcessing3D (
        OriginalGenerator& generator_,
        std::vector<MultiBlock3D*> multiBlocks_ )
    : generator(generator_),
      multiBlocks(multiBlocks_)
{
    PLB_PRECONDITION( multiBlocks.size()>=1 );
    firstMultiBlock = multiBlocks[0];

    // Subdivide the original generator into smaller generators which act
    //   on the intersection of all implied blocks. At this stage, all coordinates
    //   are global, thus relative to the multi-block, not to the individual
    //   atomic-blocks.
    subdivideGenerator();

    // Then, convert coordinates from a global representation to a local one,
    //   relative to the atomoic-blocks of the first multi-block.
    adjustCoordinates();
}
void IterateDynamicsFunctional3D::processGenericBlocks (
        Box3D domain, std::vector<AtomicBlock3D*> blocks )
{
    PLB_PRECONDITION( blocks.size()==1 );
    AtomicContainerBlock3D& container = *dynamic_cast<AtomicContainerBlock3D*>(blocks[0]);
    StoreDynamicsID* storeId = dynamic_cast<StoreDynamicsID*>(container.getData());
    std::vector<int> nextIDs(previousMaximum.size());
    for (pluint i=0; i<nextIDs.size(); ++i) {
        nextIDs[i] = -1;
    }
    if (!storeId->empty()) {
        nextIDs = storeId->getCurrent();
        util::extendVectorSize(nextIDs, previousMaximum.size());
        if (vectorEquals(nextIDs,previousMaximum)) {
            nextIDs = storeId->iterate();
            util::extendVectorSize(nextIDs, previousMaximum.size());
        }
    }
    for (pluint i=0; i<nextIDs.size(); ++i) {
        this->getStatistics().gatherMax(maxIds[i], (double)nextIDs[i]);
    }
}
void ParallellizeByCubes3D::parallelize(){
    // we must have the same number of blocks as processors
    PLB_PRECONDITION(xTiles*yTiles*zTiles == processorNumber);
    
    plint totalCost = computeCost(originalBlocks, finestBoundingBox);
    plint idealCostPerProcessor = totalCost/processorNumber;
    
    pcout << "Total cost of computations = " << totalCost << std::endl;
    pcout << "We are using " << processorNumber << " processors...\n";
    pcout << "Ideal cost per processor = " << idealCostPerProcessor << std::endl;
    
    std::vector<plint> totalCosts(processorNumber);
    
    // greedy load balancing part
//     plint currentProcessor = 0;
//     bool allAssigned = false;
//     plint iBlock = 0;
//     plint maxBlockCost = 0;
//     while ( (currentProcessor<processorNumber) && !allAssigned) {
//         plint blockCost = computeCost(originalBlocks, finestDivision[iBlock]);
//         if (blockCost > maxBlockCost) maxBlockCost = blockCost;
//         if ( totalCosts[currentProcessor] < idealCostPerProcessor ){
//             totalCosts[currentProcessor] += blockCost;
//             mpiDistribution[iBlock] = currentProcessor;
//             ++iBlock;
//         }
//         else {
//             currentProcessor++;
//         }
//         if (iBlock>=(plint)finestDivision.size()){
//             allAssigned = true;
//         }
//     } 
//     
//     if (maxBlockCost > idealCostPerProcessor){
//         pcout << "There is a problem : maxBlockCost=" << maxBlockCost << " and ideal cost=" << idealCostPerProcessor
//               << std::endl;
//     }
    
    plint total = 0;
    for (plint iProc=0; iProc<processorNumber; ++iProc){
        plint blockCost = computeCost(originalBlocks,finestDivision[iProc]);
        totalCosts[iProc] += blockCost;
        mpiDistribution[iProc] = iProc;
        total += blockCost;
    }
    
    pcout << "---- Costs Per Processor ----\n";
    
    for (pluint i=0; i<totalCosts.size(); ++i){
        pcout << i << " : " << totalCosts[i] << std::endl;
        // check if everyone is doing something
        if (totalCosts[i] == 0){
            pcout << "\t >> processor " << i << " does not have work to do. Exiting.....\n";
            std::exit(1);
        }
    }
    
    pcout << "*******************************\n";
    pcout << "Sum of all costs = " << total << std::endl;
    pcout << "*******************************\n";
    
    // convert the original blocks to the new blocks
    recomputedBlocks.resize(originalBlocks.size());
    finalMpiDistribution.resize(originalBlocks.size());
    
    plint finestLevel= (plint)originalBlocks.size()-1;
    for (plint iLevel=finestLevel; iLevel>=0; --iLevel) {
        parallelizeLevel(iLevel, originalBlocks,finestDivision, mpiDistribution);
        // Adapt the regions to the next-coarser level.
        for (pluint iRegion=0; iRegion<finestDivision.size(); ++iRegion) {
            finestDivision[iRegion] = finestDivision[iRegion].divideAndFitSmaller(2);
        }
    }
}
std::vector<Box2D> const& MultiGridManagement2D::getBulks(plint iLevel) const{
    PLB_PRECONDITION( iLevel>=0 && iLevel<(plint)bulks.size() );
    return bulks[iLevel];
}
void MultiGridManagement2D::coarsen(plint fineLevel, Box2D coarseDomain){
    // The coarsest multi-block, at level 0, cannot be further coarsened.
    PLB_PRECONDITION( fineLevel>=1 && fineLevel<(plint)bulks.size() );
    plint coarseLevel = fineLevel-1;

    // First, trim the domain coarseDomain in case it exceeds the extent of the
    //   multi-block, and determine whether coarseDomain touches one of the boundaries
    //   of the multi-block. This information is needed, because the coarse domain
    //   fully replaces the fine domain on boundaries of the multi-block, and there
    //   is therefore no need to create a coarse-fine coupling.
    bool touchLeft=false, touchRight=false, touchBottom=false, touchTop=false;
    trimDomain(coarseLevel, coarseDomain, touchLeft, touchRight, touchBottom, touchTop);

    // Convert the coarse domain to fine units.
    Box2D fineDomain(coarseDomain.multiply(2));
    // The reduced fine domain is the one which is going to be excluded from
    //   the original fine lattice.
    Box2D intermediateFineDomain(fineDomain.enlarge(-1));
    // The extended coarse domain it the one which is going to be added
    //   to the original coarse lattice.
    Box2D extendedCoarseDomain(coarseDomain.enlarge(1));
    
    // If the domain in question touches a boundary of the multi-block,
    //   both the reduced fine domain and the extended coarse domain are
    //   identified with the boundary location.
    if (touchLeft) {
        intermediateFineDomain.x0 -= 1;
        extendedCoarseDomain.x0   += 1;
    }
    if (touchRight) {
        intermediateFineDomain.x1 += 1;
        extendedCoarseDomain.x1   -= 1;
    }
    if (touchBottom) {
        intermediateFineDomain.y0 -= 1;
        extendedCoarseDomain.y0   += 1;
    }
    if (touchTop) {
        intermediateFineDomain.y1 += 1;
        extendedCoarseDomain.y1   -= 1;
    }

    // Extract reduced fine domain from the original fine multi-block.
    std::vector<Box2D> exceptedBlocks;
    for (pluint iBlock=0; iBlock<bulks[fineLevel].size(); ++iBlock) {
        except(bulks[fineLevel][iBlock], intermediateFineDomain, exceptedBlocks);
    }
    exceptedBlocks.swap(bulks[fineLevel]);

    // Add extended coarse domain to the original coarse multi-block.
    bulks[coarseLevel].push_back(extendedCoarseDomain);
    
    // Define coupling interfaces for all four sides of the refined domain, unless they
    //   touch a boundary of the multi-block.
    if (!touchLeft) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x0,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x0, 
                                                        coarseDomain.y0, coarseDomain.y1 ) );
                                                        
        // it is a left border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,-1));
        // it is an right border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,1));
    }
    if (!touchRight) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x1, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x1, coarseDomain.x1, 
                                                        coarseDomain.y0, coarseDomain.y1 ) );
                                                        
        // it is a right border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,1));
        // it is a left border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,-1));
    }
    if (!touchBottom) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y0 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x1, 
                                                        coarseDomain.y0, coarseDomain.y0 ) );
                                                        
        // it is a bottom border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,-1)); //TODO check this!!!
        // it is a top border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,1));        
    }
    if (!touchTop) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y1, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x1, 
                                                        coarseDomain.y1, coarseDomain.y1 ) );
                                                        
        // it is a top border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,1));
        // it is an bottom border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,-1));
    }
}
Box2D MultiGridManagement2D::getBoundingBox(plint level) const {
    PLB_PRECONDITION(level>=0 && level<(plint)bulks.size());
    return boundingBoxes[level];
}
CommunicationStructure2D::CommunicationStructure2D (
        std::vector<Overlap2D> const& overlaps,
        MultiBlockManagement2D const& originManagement,
        MultiBlockManagement2D const& destinationManagement,
        plint sizeOfCell )
{
    plint fromEnvelopeWidth = originManagement.getEnvelopeWidth();
    plint toEnvelopeWidth = destinationManagement.getEnvelopeWidth();
    SparseBlockStructure2D const& fromSparseBlock
        = originManagement.getSparseBlockStructure();
    SparseBlockStructure2D const& toSparseBlock
        = destinationManagement.getSparseBlockStructure();

    SendRecvPool sendPool, recvPool;
    for (pluint iOverlap=0; iOverlap<overlaps.size(); ++iOverlap) {
        Overlap2D const& overlap = overlaps[iOverlap];
        CommunicationInfo2D info;

        info.fromBlockId = overlap.getOriginalId();
        info.toBlockId   = overlap.getOverlapId();

        SmartBulk2D originalBulk(fromSparseBlock, fromEnvelopeWidth, info.fromBlockId);
        SmartBulk2D overlapBulk(toSparseBlock, toEnvelopeWidth, info.toBlockId);

        Box2D originalCoordinates(overlap.getOriginalCoordinates());
        Box2D overlapCoordinates(overlap.getOverlapCoordinates());
        info.fromDomain = originalBulk.toLocal(originalCoordinates);
        info.toDomain   = overlapBulk.toLocal(overlapCoordinates);
        info.absoluteOffset = Dot2D (
                overlapCoordinates.x0 - originalCoordinates.x0,
                overlapCoordinates.y0 - originalCoordinates.y0 );

        plint lx = info.fromDomain.x1-info.fromDomain.x0+1;
        plint ly = info.fromDomain.y1-info.fromDomain.y0+1;
        PLB_PRECONDITION(lx == info.toDomain.x1-info.toDomain.x0+1);
        PLB_PRECONDITION(ly == info.toDomain.y1-info.toDomain.y0+1);

        plint numberOfCells = lx*ly;

        ThreadAttribution const& fromAttribution = originManagement.getThreadAttribution();
        ThreadAttribution const& toAttribution = destinationManagement.getThreadAttribution();
        info.fromProcessId = fromAttribution.getMpiProcess(info.fromBlockId);
        info.toProcessId   = toAttribution.getMpiProcess(info.toBlockId);

        if ( fromAttribution.isLocal(info.fromBlockId) &&
             toAttribution.isLocal(info.toBlockId))
        {
            sendRecvPackage.push_back(info);
        }
        else if (fromAttribution.isLocal(info.fromBlockId))
        {
            sendPackage.push_back(info);
            sendPool.subscribeMessage(info.toProcessId, numberOfCells*sizeOfCell);
        }
        else if (toAttribution.isLocal(info.toBlockId))
        {
            recvPackage.push_back(info);
            recvPool.subscribeMessage(info.fromProcessId, numberOfCells*sizeOfCell);
        }
    }

    sendComm = SendPoolCommunicator(sendPool);
    recvComm = RecvPoolCommunicator(recvPool);
}
Example #19
0
bool PeriodicitySwitch3D::get(plint direction) const {
    PLB_PRECONDITION( direction==0 || direction==1 || direction==2 );

    return periodicity[direction];
}
Example #20
0
/// toggle on/off the periodicity in one direction
void MultiGridPeriodicitySwitch2D::toggle(int direction, bool periodicity){
    PLB_PRECONDITION( direction==0 || direction==1 );
    periodicityArray[direction] = periodicity;
    block->signalPeriodicity();
}
void MultiGridManagement2D::refineMultiGrid(plint coarseLevel, Box2D coarseDomain){
        
    // The finest multi-block, at level bulks.size()-1, cannot be further refined.
    PLB_PRECONDITION( coarseLevel>=0 && coarseLevel< (plint)bulks.size()-1 );
    plint fineLevel = coarseLevel+1;
    
    // First, trim the domain coarseDomain in case it exceeds the extent of the
    //   multi-block, and determine whether coarseDomain touches one of the boundaries
    //   of the multi-block. This information is needed, because the coarse domain
    //   fully replaces the fine domain on boundaries of the multi-block, and there
    //   is therefore no need to create a coarse-fine coupling.
    bool touchLeft=false, touchRight=false, touchBottom=false, touchTop=false;
    trimDomain(coarseLevel, coarseDomain, touchLeft, touchRight, touchBottom, touchTop);

    // The reduced coarse domain is the one which is going to be excluded from
    //   the original coarse lattice.
    Box2D reducedCoarseDomain(coarseDomain.enlarge(-1));
    // The extended coarse domain it the one which is going to be added
    //   to the original fine lattice.
    Box2D extendedCoarseDomain(coarseDomain.enlarge(overlapWidth));
    
    // If the domain in question touches a boundary of the multi-block,
    //   both the reduced and the extended coarse domain are
    //   identified with the boundary location.
    if (touchLeft) {
        reducedCoarseDomain.x0    -= 1;
        extendedCoarseDomain.x0   += overlapWidth;
    }
    if (touchRight) {
        reducedCoarseDomain.x1    += 1;
        extendedCoarseDomain.x1   -= overlapWidth;
    }
    if (touchBottom) {
        reducedCoarseDomain.y0    -= 1;
        extendedCoarseDomain.y0   += overlapWidth;
    }
    if (touchTop) {
        reducedCoarseDomain.y1    += 1;
        extendedCoarseDomain.y1   -= overlapWidth;
    }

    
    // Do not do anything to the coarse domain
    
    
    // Convert the extended coarse domain to fine units,
    //   and add to the original fine multi-block.
    Box2D extendedFineDomain(extendedCoarseDomain.multiply(2));
    bulks[fineLevel].push_back(extendedFineDomain);

    // Define coupling interfaces for all four sides of the coarsened domain, unless they
    //   touch a boundary of the multi-block.
    if (!touchLeft) {

        // it is a right border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,1));
        fineGridInterfaces[fineLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x0, 
                                                        extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        // it is a left border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,-1));
    }
    if (!touchRight) {

        // it is a left border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,-1));
        fineGridInterfaces[fineLevel].push_back( Box2D( extendedCoarseDomain.x1, extendedCoarseDomain.x1, 
                                                        extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        // it is a right border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,1));
    }
    if (!touchBottom) {
        
        fineGridInterfaces[fineLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1, 
                                                        extendedCoarseDomain.y0, extendedCoarseDomain.y0 ) );
        // it is an upper border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,1));
        // it is a lower border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,-1));
    }
    if (!touchTop) {
        
        // it is a lower border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,-1));
        fineGridInterfaces[fineLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1, 
                                                        extendedCoarseDomain.y1, extendedCoarseDomain.y1 ) );
        // it is an upper border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,1));
    }
    
    coarseGridInterfaces[coarseLevel].push_back(coarseDomain);
}