⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multidatageometry3d.cpp

📁 open lattice boltzmann project www.openlb.org
💻 CPP
字号:
/*  This file is part of the OpenLB library * *  Copyright (C) 2007, 2008 Jonas Latt and Bernd Stahl *  Address: Rue General Dufour 24,  1211 Geneva 4, Switzerland  *  E-mail: jonas.latt@gmail.com * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 *  of the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public  *  License along with this program; if not, write to the Free  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *  Boston, MA  02110-1301, USA.*//** \file * Geometry specifications for 3D multiblocks -- implementation. */#include "complexGrids/mpiManager/mpiManager.h"#include "multiDataGeometry3D.h"#include "core/olbDebug.h"namespace olb {    ////////////////////// Class BlockParameters3D /////////////////////////////BlockParameters3D::BlockParameters3D(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_,                                     int envelopeWidth_, int procId_,                                     bool leftX, bool rightX, bool leftY, bool rightY, bool leftZ, bool rightZ)    : envelopeWidth(envelopeWidth_),      procId(procId_),      bulk(x0_, x1_, y0_, y1_, z0_, z1_),      envelope(x0_-envelopeWidth, x1_+envelopeWidth, y0_-envelopeWidth,               y1_+envelopeWidth, z0_-envelopeWidth, z1_+envelopeWidth),      nonPeriodicEnvelope(envelope){    if (leftX) {        nonPeriodicEnvelope.x0 += envelopeWidth;    }    if (rightX) {        nonPeriodicEnvelope.x1 -= envelopeWidth;    }    if (leftY) {        nonPeriodicEnvelope.y0 += envelopeWidth;    }    if (rightY) {        nonPeriodicEnvelope.y1 -= envelopeWidth;    }    if (leftZ) {        nonPeriodicEnvelope.z0 += envelopeWidth;    }    if (rightZ) {        nonPeriodicEnvelope.z1 -= envelopeWidth;    }}////////////////////// Class MultiDataDistribution3D /////////////////////MultiDataDistribution3D::MultiDataDistribution3D(int nx_, int ny_, int nz_)    : nx(nx_), ny(ny_), nz(nz_){ }MultiDataDistribution3D& MultiDataDistribution3D::operator=(MultiDataDistribution3D const& rhs) {    nx = rhs.nx;    ny = rhs.ny;    nz = rhs.nz;    blocks = rhs.blocks;    normalOverlaps = rhs.normalOverlaps;    periodicOverlaps = rhs.periodicOverlaps;    return (*this);}BlockParameters3D const& MultiDataDistribution3D::getBlockParameters(int whichBlock) const {    OLB_PRECONDITION( whichBlock < getNumBlocks() );    return blocks[whichBlock];}Overlap3D const& MultiDataDistribution3D::getNormalOverlap(int whichOverlap) const {    OLB_PRECONDITION( whichOverlap < getNumNormalOverlaps() );    return normalOverlaps[whichOverlap];}Overlap3D const& MultiDataDistribution3D::getPeriodicOverlap(int whichOverlap) const {    OLB_PRECONDITION( whichOverlap < getNumPeriodicOverlaps() );    return periodicOverlaps[whichOverlap];}void MultiDataDistribution3D::addBlock(int x0, int x1, int y0, int y1, int z0, int z1,                                       int envelopeWidth, int procId){    OLB_PRECONDITION( x0>=0 && y0>=0 && z0>=0);    OLB_PRECONDITION( x1<nx && y1<ny && z1<nz);    OLB_PRECONDITION( x0 <= x1 && y0 <= y1 && z0 <= z1);    BlockParameters3D newBlock(x0, x1, y0, y1, z0, z1, envelopeWidth, procId,                               x0==0, x1==nx-1, y0==0, y1==ny-1, z0==0, z1==nz-1);    computeNormalOverlaps(newBlock);    blocks.push_back(newBlock);    computePeriodicOverlaps();}int MultiDataDistribution3D::locate(int x, int y, int z, int guess) const {    OLB_PRECONDITION( x>=0 && x < nx );    OLB_PRECONDITION( y>=0 && y < ny );    OLB_PRECONDITION( z>=0 && z < nz );    OLB_PRECONDITION( guess < getNumBlocks() );    for (int iBlock=0; iBlock<(int)getNumBlocks(); ++iBlock, guess = (guess+1)%blocks.size()) {        BlockCoordinates3D const& coord = blocks[guess].getBulk();        if (util::contained(x, y, z, coord.x0, coord.x1, coord.y0, coord.y1, coord.z0, coord.z1)) {            return guess;        }    }    return -1;}int MultiDataDistribution3D::locateInEnvelopes(int x, int y, int z,                                               std::vector<int>& foundId, int guess) const {    OLB_PRECONDITION( x>=0 && x < nx );    OLB_PRECONDITION( y>=0 && y < ny );    OLB_PRECONDITION( z>=0 && z < nz );    int found = locate(x,y,z, guess);    if (found == -1) {        found = 0;    }    else {        foundId.push_back(found);        for (int iNeighbor=0; iNeighbor < (int)neighbors[found].size(); ++iNeighbor) {            int nextNeighbor = neighbors[found][iNeighbor];            BlockCoordinates3D const& coord = blocks[nextNeighbor].getEnvelope();            if (util::contained(x, y, z, coord.x0, coord.x1, coord.y0, coord.y1, coord.z0, coord.z1)) {                foundId.push_back(nextNeighbor);            }        }    }    return found;}void MultiDataDistribution3D::computeNormalOverlaps(BlockParameters3D const& newBlock) {    neighbors.resize(getNumBlocks()+1);    BlockCoordinates3D intersection;    int iNew = getNumBlocks();    for (int iBlock=0; iBlock<getNumBlocks(); ++iBlock) {        if (util::intersect(blocks[iBlock].getBulk(), newBlock.getNonPeriodicEnvelope(), intersection)) {            normalOverlaps.push_back(Overlap3D(iBlock, iNew, intersection));            neighbors[iBlock].push_back(iNew);        }        if (util::intersect(newBlock.getBulk(), blocks[iBlock].getNonPeriodicEnvelope(), intersection)) {            normalOverlaps.push_back(Overlap3D(iNew, iBlock, intersection));            neighbors[iNew].push_back(iBlock);        }    }}void MultiDataDistribution3D::computePeriodicOverlaps() {    int iNew = getNumBlocks()-1;    BlockParameters3D const& newBlock = blocks[iNew];    BlockCoordinates3D intersection;    for (int dx=-1; dx<=+1; dx+=1) {        for (int dy=-1; dy<=+1; dy+=1) {            for (int dz=-1; dz<=+1; dz+=1) {                if (dx!=0 || dy!=0 || dz!=0) {                    int shiftX = dx*getNx();                    int shiftY = dy*getNy();                    int shiftZ = dz*getNz();                    BlockCoordinates3D newBulk(newBlock.getBulk().shift(shiftX,shiftY,shiftZ));                    BlockCoordinates3D newEnvelope(newBlock.getEnvelope().shift(shiftX,shiftY,shiftZ));                    for (int iBlock=0; iBlock<getNumBlocks(); ++iBlock) {                        if (util::intersect(blocks[iBlock].getBulk(), newEnvelope, intersection)) {                            periodicOverlaps.push_back( Overlap3D(iBlock, iNew, intersection,                                                                  shiftX, shiftY, shiftZ) );                            neighbors[iBlock].push_back(iNew);                        }                        if (!(iBlock==iNew) &&                            util::intersect(newBulk, blocks[iBlock].getEnvelope(), intersection))                        {                            intersection = intersection.shift(-shiftX,-shiftY, -shiftZ);                            periodicOverlaps.push_back( Overlap3D(iNew, iBlock, intersection,                                                                  -shiftX, -shiftY, -shiftZ) );                            neighbors[iNew].push_back(iBlock);                        }                    }                }            }        }    }}size_t MultiDataDistribution3D::getNumAllocatedBulkCells() const {    int numCells = 0;    for (unsigned iBlock=0; iBlock<blocks.size(); ++iBlock) {        numCells += (size_t)blocks[iBlock].getBulkLx() *                    (size_t)blocks[iBlock].getBulkLy() *                    (size_t)blocks[iBlock].getBulkLz();    }    return numCells;}bool MultiDataDistribution3D::getNextChunkX(int iX, int iY, int iZ, int& nextLattice, int& nextChunkSize) const {    nextLattice = locate(iX,iY,iZ);    if (nextLattice == -1) {        int exploreX = iX+1;        while(exploreX<getNx() && locate(exploreX,iY,iZ)==-1) {            ++exploreX;        }        nextChunkSize = exploreX-iX;        return false;    }    else {        nextChunkSize = blocks[nextLattice].getBulk().x1-iX+1;        return true;    }}bool MultiDataDistribution3D::getNextChunkY(int iX, int iY, int iZ, int& nextLattice, int& nextChunkSize) const {    nextLattice = locate(iX,iY,iZ);    if (nextLattice == -1) {        int exploreY = iY+1;        while(exploreY<getNy() && locate(iX,exploreY,iZ)==-1) {            ++exploreY;        }        nextChunkSize = exploreY-iY;        return false;    }    else {        nextChunkSize = blocks[nextLattice].getBulk().y1-iY+1;        return true;    }}bool MultiDataDistribution3D::getNextChunkZ(int iX, int iY, int iZ, int& nextLattice, int& nextChunkSize) const {    nextLattice = locate(iX,iY,iZ);    if (nextLattice == -1) {        int exploreZ = iZ+1;        while(exploreZ<getNz() && locate(iX,iY,exploreZ)==-1) {            ++exploreZ;        }        nextChunkSize = exploreZ-iZ;        return false;    }    else {        nextChunkSize = blocks[nextLattice].getBulk().z1-iZ+1;        return true;    }}RelevantIndexes3D::RelevantIndexes3D(int numBlocks, int numNormalOverlaps,                                     int numPeriodicOverlaps, int nx, int ny, int nz){    listAllIndexes(numBlocks, numNormalOverlaps, numPeriodicOverlaps, nx, ny, nz);}RelevantIndexes3D::RelevantIndexes3D(MultiDataDistribution3D const& dataDistribution, int whichRank) {    computeRelevantIndexesInParallel(dataDistribution, whichRank);}void RelevantIndexes3D::listAllIndexes (        int numBlocks, int numNormalOverlaps, int numPeriodicOverlaps, int nx, int ny, int nz){    myBlocks.resize(numBlocks);    nearbyBlocks.resize(numBlocks);    for (int iBlock=0; iBlock<numBlocks; ++iBlock) {        myBlocks[iBlock]     = iBlock;        nearbyBlocks[iBlock] = iBlock;    }    normalOverlaps.resize(numNormalOverlaps);    for (int iOverlap=0; iOverlap<numNormalOverlaps; ++iOverlap) {        normalOverlaps[iOverlap] = iOverlap;    }    periodicOverlaps.resize(numPeriodicOverlaps);    periodicOverlapWithMe.resize(numPeriodicOverlaps);    for (int iOverlap=0; iOverlap<numPeriodicOverlaps; ++iOverlap) {        periodicOverlaps[iOverlap] = iOverlap;        periodicOverlapWithMe[iOverlap] = iOverlap;    }    boundingBox = BlockCoordinates3D(0,nx-1, 0,ny-1, 0,nz-1);}void RelevantIndexes3D::computeRelevantIndexesInParallel(MultiDataDistribution3D const& dataDistribution,                                                         int whichRank){    for (int iBlock=0; iBlock<dataDistribution.getNumBlocks(); ++iBlock) {        if (dataDistribution.getBlockParameters(iBlock).getProcId() == whichRank) {            BlockCoordinates3D const& newBlock = dataDistribution.getBlockParameters(iBlock).getEnvelope();            if (myBlocks.empty()) {                boundingBox = newBlock;            }            else {                if (newBlock.x0 < boundingBox.x0) boundingBox.x0 = newBlock.x0;                if (newBlock.x1 > boundingBox.x1) boundingBox.x1 = newBlock.x1;                if (newBlock.y0 < boundingBox.y0) boundingBox.y0 = newBlock.y0;                if (newBlock.y1 > boundingBox.y1) boundingBox.y1 = newBlock.y1;                if (newBlock.z0 < boundingBox.z0) boundingBox.z0 = newBlock.z0;                if (newBlock.z1 > boundingBox.z1) boundingBox.z1 = newBlock.z1;            }            myBlocks.push_back(iBlock);            nearbyBlocks.push_back(iBlock);        }    }    for (int iOverlap=0; iOverlap<dataDistribution.getNumNormalOverlaps(); ++iOverlap) {        Overlap3D const& overlap = dataDistribution.getNormalOverlap(iOverlap);        int originalProc = dataDistribution.getBlockParameters(overlap.getOriginalId()).getProcId();        int overlapProc = dataDistribution.getBlockParameters(overlap.getOverlapId()).getProcId();        if (originalProc == whichRank) {            nearbyBlocks.push_back( overlap.getOverlapId() );        }        if (originalProc == whichRank || overlapProc == whichRank) {            normalOverlaps.push_back(iOverlap);        }    }    for (int iOverlap=0; iOverlap<dataDistribution.getNumPeriodicOverlaps(); ++iOverlap) {        Overlap3D const& overlap = dataDistribution.getPeriodicOverlap(iOverlap);        int originalProc = dataDistribution.getBlockParameters(overlap.getOriginalId()).getProcId();        int overlapProc = dataDistribution.getBlockParameters(overlap.getOverlapId()).getProcId();        if (originalProc == whichRank) {            nearbyBlocks.push_back( overlap.getOverlapId() );        }        if (overlapProc == whichRank) {            periodicOverlapWithMe.push_back(iOverlap);        }        if (originalProc == whichRank || overlapProc == whichRank) {            periodicOverlaps.push_back(iOverlap);        }    }    // Erase duplicates in nearbyBlocks    std::sort(nearbyBlocks.begin(), nearbyBlocks.end());    std::vector<int>::iterator newEnd = unique(nearbyBlocks.begin(), nearbyBlocks.end());    nearbyBlocks.erase(newEnd, nearbyBlocks.end());}}  // namespace olb

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -