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

📄 multiblockhandler2d.hh

📁 open lattice boltzmann project www.openlb.org
💻 HH
📖 第 1 页 / 共 2 页
字号:
/*  This file is part of the OpenLB library * *  Copyright (C) 2007 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 * Handler for 2D multiblock structure -- generic implementation. */#ifndef MULTI_BLOCK_HANDLER_2D_HH#define MULTI_BLOCK_HANDLER_2D_HH#include "complexGrids/mpiManager/mpiManager.h"#include "multiBlockHandler2D.h"#include "parallelDynamics.h"#include "core/util.h"#include <algorithm>#include <numeric>namespace olb {////////////////////// Class SerialMultiBlockHandler2D /////////////////////template<typename T, template<typename U> class Lattice>SerialMultiBlockHandler2D<T,Lattice>::SerialMultiBlockHandler2D (        MultiDataDistribution2D const& dataDistribution_ )    : dataDistribution(dataDistribution_),      relevantIndexes(dataDistribution.getNumBlocks(), dataDistribution.getNumNormalOverlaps(),                      dataDistribution.getNumPeriodicOverlaps(), dataDistribution.getNx(),                      dataDistribution.getNy() ){ }template<typename T, template<typename U> class Lattice>int SerialMultiBlockHandler2D<T,Lattice>::getNx() const {    return dataDistribution.getNx();}template<typename T, template<typename U> class Lattice>int SerialMultiBlockHandler2D<T,Lattice>::getNy() const {    return dataDistribution.getNy();}template<typename T, template<typename U> class Lattice>MultiDataDistribution2D const& SerialMultiBlockHandler2D<T,Lattice>::getMultiDataDistribution() const {    return dataDistribution;}template<typename T, template<typename U> class Lattice>RelevantIndexes2D const& SerialMultiBlockHandler2D<T,Lattice>::getRelevantIndexes() const {    return relevantIndexes;}template<typename T, template<typename U> class Lattice>bool SerialMultiBlockHandler2D<T,Lattice>::getLocalEnvelope(int iBlock, int& lx, int& ly) const {    BlockParameters2D const& parameters = dataDistribution.getBlockParameters(iBlock);    lx = parameters.getEnvelopeLx();    ly = parameters.getEnvelopeLy();    return true;}template<typename T, template<typename U> class Lattice>T SerialMultiBlockHandler2D<T,Lattice>::reduceSum (T localSum) const {    return localSum;}template<typename T, template<typename U> class Lattice>T SerialMultiBlockHandler2D<T,Lattice>::reduceAverage (T localAverage, T localWeight) const {    return localAverage;}template<typename T, template<typename U> class Lattice>T SerialMultiBlockHandler2D<T,Lattice>::reduceMin (T localMin) const {    return localMin;}template<typename T, template<typename U> class Lattice>T SerialMultiBlockHandler2D<T,Lattice>::reduceMax (T localMax) const {    return localMax;}template<typename T, template<typename U> class Lattice>void SerialMultiBlockHandler2D<T,Lattice>::broadCastCell(Cell<T,Lattice>& cell, int fromBlock) const {    // Nothing to do in the serial case}template<typename T, template<typename U> class Lattice>void SerialMultiBlockHandler2D<T,Lattice>::broadCastScalar(T& scalar, int fromBlock) const {    // Nothing to do in the serial case}template<typename T, template<typename U> class Lattice>void SerialMultiBlockHandler2D<T,Lattice>::broadCastVector(T vect[Lattice<T>::d], int fromBlock) const {    // Nothing to do in the serial case}template<typename T, template<typename U> class Lattice>void SerialMultiBlockHandler2D<T,Lattice>::copyOverlap (        Overlap2D const& overlap, SerialMultiBlockHandler2D<T,Lattice>::BlockVector2D& lattices ) const{    int originalId = overlap.getOriginalId();    int overlapId  = overlap.getOverlapId();    BlockParameters2D const& originalParameters = dataDistribution.getBlockParameters(originalId);    BlockParameters2D const& overlapParameters  = dataDistribution.getBlockParameters(overlapId);    BlockCoordinates2D originalCoords(originalParameters.toLocal(overlap.getOriginalCoordinates()));    BlockCoordinates2D overlapCoords(overlapParameters.toLocal(overlap.getOverlapCoordinates()));    OLB_PRECONDITION(originalCoords.x1-originalCoords.x0 == overlapCoords.x1-overlapCoords.x0);    OLB_PRECONDITION(originalCoords.y1-originalCoords.y0 == overlapCoords.y1-overlapCoords.y0);    int origX = originalCoords.x0;    int overlapX = overlapCoords.x0;    for (; origX<=originalCoords.x1; ++origX, ++overlapX) {        int origY = originalCoords.y0;        int overlapY = overlapCoords.y0;        for (; origY<=originalCoords.y1; ++origY, ++overlapY) {            lattices[overlapId] -> get(overlapX, overlapY).attributeValues (                    lattices[originalId] -> get(origX, origY) );        }    }}template<typename T, template<typename U> class Lattice>void SerialMultiBlockHandler2D<T,Lattice>::connectBoundaries (        SerialMultiBlockHandler2D<T,Lattice>::BlockVector2D& lattices, bool periodicCommunication ) const{    for (int iOverlap=0; iOverlap<dataDistribution.getNumNormalOverlaps(); ++iOverlap) {        copyOverlap(dataDistribution.getNormalOverlap(iOverlap), lattices);    }    if (periodicCommunication) {        for (int iOverlap=0; iOverlap<dataDistribution.getNumPeriodicOverlaps(); ++iOverlap) {            copyOverlap(dataDistribution.getPeriodicOverlap(iOverlap), lattices);        }    }}template<typename T, template<typename U> class Lattice>Cell<T,Lattice>& SerialMultiBlockHandler2D<T,Lattice>::getDistributedCell (        std::vector<Cell<T,Lattice>*>& baseCell, bool hasBulkCell ) const{    OLB_PRECONDITION( baseCell.size()>0 && baseCell[0] );    return *baseCell[0];}template<typename T, template<typename U> class Lattice>Cell<T,Lattice> const& SerialMultiBlockHandler2D<T,Lattice>::getDistributedCell (        std::vector<Cell<T,Lattice> const*>& baseCell, bool hasBulkCell ) const{    OLB_PRECONDITION( baseCell.size()>0 && baseCell[0] );    return *baseCell[0];}template<typename T, template<typename U> class Lattice>int SerialMultiBlockHandler2D<T,Lattice>::locateLocally(int iX, int iY,                                                        std::vector<int>& foundId,                                                        std::vector<int>& foundX,                                                        std::vector<int>& foundY,                                                        bool& hasBulkCell, int guess) const{    // In serial there's only one processor, we're therefore sure    //   the bulk cell with coordinates (iX,iY) can be found locally.    hasBulkCell = true;    // In serial, it is sufficient to find the bulk-cell representation    //   of cell (iX,iY). Although it might also be present in envelopes,    //   these envelope representations are properly treated because all    //   of them have a pointer to the same dynamics object.    int bulkId = dataDistribution.locate(iX,iY, guess);    BlockParameters2D const& parameters = dataDistribution.getBlockParameters(bulkId);    foundId.push_back(bulkId);    foundX.push_back(parameters.toLocalX(iX));    foundY.push_back(parameters.toLocalY(iY));    return bulkId;}#ifdef PARALLEL_MODE_MPI////////////////////// Class DataTransmittor3D /////////////////////template<typename T, template<typename U> class Lattice>BlockingDataTransmittor2D<T,Lattice>::BlockingDataTransmittor2D (        Overlap2D const& overlap, MultiDataDistribution2D const& dataDistribution ){    originalId = overlap.getOriginalId();    overlapId  = overlap.getOverlapId();    BlockParameters2D const& originalParameters = dataDistribution.getBlockParameters(originalId);    BlockParameters2D const& overlapParameters  = dataDistribution.getBlockParameters(overlapId);    originalProc = originalParameters.getProcId();    overlapProc  = overlapParameters.getProcId();    int myProc   = singleton::mpi().getRank();    originalCoords = originalParameters.toLocal(overlap.getOriginalCoordinates());    overlapCoords  = overlapParameters.toLocal(overlap.getOverlapCoordinates());    int lx = originalCoords.x1-originalCoords.x0+1;    int ly = originalCoords.y1-originalCoords.y0+1;    OLB_PRECONDITION(lx == overlapCoords.x1-overlapCoords.x0+1);    OLB_PRECONDITION(ly == overlapCoords.y1-overlapCoords.y0+1);    sizeOfCell = Lattice<T>::q + Lattice<T>::ExternalField::numScalars;    bufferSize = lx*ly*sizeOfCell;    buffer.resize(bufferSize);    if (originalProc==myProc && overlapProc==myProc) {        myRole = senderAndReceiver;    }    else if (originalProc==myProc) {        myRole = sender;    }    else if (overlapProc==myProc) {        myRole = receiver;    }    else {        myRole = nothing;    }}template<typename T, template<typename U> class Lattice>void BlockingDataTransmittor2D<T,Lattice>::prepareTransmission(BlockVector2D& lattices) {    if (myRole==sender) {        T* bufferP = &buffer[0];        BlockLattice2D<T,Lattice>* lattice = lattices[originalId];        int iData=0;        for (int iX=originalCoords.x0; iX<=originalCoords.x1; ++iX) {            for (int iY=originalCoords.y0; iY<=originalCoords.y1; ++iY) {                lattice -> get(iX,iY).serialize(bufferP+iData);                iData += sizeOfCell;            }        }    }}template<typename T, template<typename U> class Lattice>void BlockingDataTransmittor2D<T,Lattice>::executeTransmission(BlockVector2D& lattices) {    switch(myRole) {        case senderAndReceiver:        {            int origX = originalCoords.x0;            int overlapX = overlapCoords.x0;            for (; origX<=originalCoords.x1; ++origX, ++overlapX) {                int origY = originalCoords.y0;                int overlapY = overlapCoords.y0;                for (; origY<=originalCoords.y1; ++origY, ++overlapY) {                    lattices[overlapId] -> get(overlapX, overlapY).attributeValues (                            lattices[originalId] -> get(origX, origY) );                }            }            break;        }        case sender:            singleton::mpi().send(&buffer[0], bufferSize, overlapProc);            break;        case receiver:            singleton::mpi().receive(&buffer[0], bufferSize, originalProc);            break;        case nothing:            break;    }}template<typename T, template<typename U> class Lattice>void BlockingDataTransmittor2D<T,Lattice>::finalizeTransmission(BlockVector2D& lattices) {    if (myRole==receiver) {        T* bufferP = &buffer[0];        BlockLattice2D<T,Lattice>* lattice = lattices[overlapId];        int iData=0;        for (int iX=overlapCoords.x0; iX<=overlapCoords.x1; ++iX) {            for (int iY=overlapCoords.y0; iY<=overlapCoords.y1; ++iY) {                lattice -> get(iX,iY).unSerialize(bufferP+iData);                iData += sizeOfCell;            }        }    }}template<typename T, template<typename U> class Lattice>NonBlockingDataTransmittor2D<T,Lattice>::NonBlockingDataTransmittor2D (        Overlap2D const& overlap, MultiDataDistribution2D const& dataDistribution ){    originalId = overlap.getOriginalId();    overlapId  = overlap.getOverlapId();    BlockParameters2D const& originalParameters = dataDistribution.getBlockParameters(originalId);    BlockParameters2D const& overlapParameters  = dataDistribution.getBlockParameters(overlapId);    originalProc = originalParameters.getProcId();    overlapProc  = overlapParameters.getProcId();    int myProc   = singleton::mpi().getRank();    originalCoords = originalParameters.toLocal(overlap.getOriginalCoordinates());    overlapCoords  = overlapParameters.toLocal(overlap.getOverlapCoordinates());    int lx = originalCoords.x1-originalCoords.x0+1;    int ly = originalCoords.y1-originalCoords.y0+1;    OLB_PRECONDITION(lx == overlapCoords.x1-overlapCoords.x0+1);    OLB_PRECONDITION(ly == overlapCoords.y1-overlapCoords.y0+1);    sizeOfCell = Lattice<T>::q + Lattice<T>::ExternalField::numScalars;    bufferSize = lx*ly*sizeOfCell;    buffer.resize(bufferSize);    if (originalProc==myProc && overlapProc==myProc) {        myRole = senderAndReceiver;    }    else if (originalProc==myProc) {        myRole = sender;    }

⌨️ 快捷键说明

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