From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/communication/cuboidNeighbourhood3D.hh | 449 +++++++++++++++++++++++++++++ 1 file changed, 449 insertions(+) create mode 100644 src/communication/cuboidNeighbourhood3D.hh (limited to 'src/communication/cuboidNeighbourhood3D.hh') diff --git a/src/communication/cuboidNeighbourhood3D.hh b/src/communication/cuboidNeighbourhood3D.hh new file mode 100644 index 0000000..61c371a --- /dev/null +++ b/src/communication/cuboidNeighbourhood3D.hh @@ -0,0 +1,449 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2007, 2014 Mathias J. Krause + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * 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 + * The description of a 3D cuboid neighbourhood -- generic implementation. + */ + + +#ifndef CUBOID_NEIGHBOURHOOD_3D_HH +#define CUBOID_NEIGHBOURHOOD_3D_HH + +#include "communication/mpiManager.h" +#include +#include +#include "communication/cuboidNeighbourhood3D.h" +#include "geometry/cuboidGeometry3D.h" +#include "dynamics/dynamics.h" +#include "core/cell.h" +#include "communication/superStructure3D.h" + + +namespace olb { + + +//////////////// Class CuboidNeighbourhood3D ////////////////// + +template +CuboidNeighbourhood3D::CuboidNeighbourhood3D( + SuperStructure3D& superStructure, int iC):_superStructure(superStructure) +{ + _iCglob = iC; + _nC = _superStructure.getCuboidGeometry().getNc(); + _deltaC = _superStructure.getCuboidGeometry().get(iC).getDeltaR(); + _nData = _superStructure.getDataSize(); + _nDataType = _superStructure.getDataTypeSize(); + _initInCNdone = false; + _initOutCNdone = false; +} + +template +CuboidNeighbourhood3D::CuboidNeighbourhood3D ( + CuboidNeighbourhood3D const& rhs ):_superStructure(rhs._superStructure) +{ + _iCglob = rhs._iCglob; + _nC = rhs._nC; + _deltaC = rhs._deltaC; + _inCells = rhs._inCells; + _outCells = rhs._outCells; + _inC = rhs._inC; + _inN = rhs._inN; + _outC = rhs._outC; + _outN = rhs._outN; + _nData = rhs._nData; + _nDataType = rhs._nDataType; + _initInCNdone = false; + _initOutCNdone = false; +} + +template +CuboidNeighbourhood3D CuboidNeighbourhood3D::operator= ( + CuboidNeighbourhood3D rhs ) +{ + CuboidNeighbourhood3D tmp(rhs); + return tmp; +} + +template +CuboidNeighbourhood3D::~CuboidNeighbourhood3D() +{ + reset(); +} + + +template +Cell3D const& CuboidNeighbourhood3D::get_inCell(int i) const +{ + return _inCells[i]; +} + +template +int CuboidNeighbourhood3D::get_inCellsSize() const +{ + return _inCells.size(); +} + +template +int const& CuboidNeighbourhood3D::get_inC(int i) const +{ + return _inC[i]; +} + +template +int CuboidNeighbourhood3D::get_inCsize() const +{ + return _inC.size(); +} + +template +bool** CuboidNeighbourhood3D::get_inData() +{ + return _inData; +} + +template +bool** CuboidNeighbourhood3D::get_outData() +{ + return _outData; +} + + +template +void CuboidNeighbourhood3D::add_inCell(Cell3D cell) +{ + _inCells.push_back(cell); +} + +template +void CuboidNeighbourhood3D::add_outCell(Cell3D cell) +{ + _outCells.push_back(cell); +} + +template +void CuboidNeighbourhood3D::add_inCell(int iX, int iY, int iZ) +{ + + Cell3D found; + found.latticeR[0] = _iCglob; + found.latticeR[1] = iX; + found.latticeR[2] = iY; + found.latticeR[3] = iZ; + + _superStructure.getCuboidGeometry().getPhysR(found.physR, found.latticeR); + std::vector tmp(found.physR,found.physR + 3); + if (_superStructure.getCuboidGeometry().getC(tmp, found.latticeR[0]) ) { + for (unsigned i=0; i<_inCells.size(); i++) { + if (_inCells[i]==found) { + return; + } + } + _inCells.push_back(found); + } +} + +template +void CuboidNeighbourhood3D::add_inCells(int overlap) +{ + + int nX = _superStructure.getCuboidGeometry().get(_iCglob).getNx(); + int nY = _superStructure.getCuboidGeometry().get(_iCglob).getNy(); + int nZ = _superStructure.getCuboidGeometry().get(_iCglob).getNz(); + + for (int iX=0; iX nX + overlap - 1 || + iY < overlap || iY > nY + overlap - 1 || + iZ < overlap || iZ > nZ + overlap - 1 ) { + Cell3D found; + found.latticeR[0] = _iCglob; + found.latticeR[1] = iX - overlap; + found.latticeR[2] = iY - overlap; + found.latticeR[3] = iZ - overlap; + + _superStructure.getCuboidGeometry().getPhysR(found.physR, found.latticeR); + std::vector tmp(found.physR,found.physR + 3); + if (_superStructure.getCuboidGeometry().getC(tmp, found.latticeR[0]) ) { + _inCells.push_back(found); + } + } + } + } + } +} + +template +void CuboidNeighbourhood3D::init_inCN() +{ + + _inC.clear(); + _inN.clear(); + + _inData = new bool* [_nC]; + _inDataCoordinates = new T* [_nC]; + _tempInCN = new int [_nC]; + for (int i=0; i<_nC; i++) { + _tempInCN[i]=0; + } + + for (unsigned i=0; i<_inCells.size(); i++) { + _tempInCN[_inCells[i].latticeR[0]]++; + } + for (int i=0; i<_nC; i++) { + if (_tempInCN[i]!=0) { + _inC.push_back(i); + _inN.push_back(_tempInCN[i]); +#ifdef PARALLEL_MODE_MPI + _inData[i] = new bool [_tempInCN[i]*_nData*_nDataType]; + _inDataCoordinates[i] = new T [_tempInCN[i]*3]; +#endif + } +#ifdef PARALLEL_MODE_MPI + else { + _inData[i] = NULL; + _inDataCoordinates[i] = NULL; + } +#endif + } + +#ifdef PARALLEL_MODE_MPI + int counter=0; + for (int i=0; i<_nC; i++) { + // int dRank = _superStructure.getLoadBalancer().rank(i); + counter++; + } + _mpiNbHelper.allocate(counter); + counter=0; + for (int i=0; i<_nC; i++) { + int dRank = _superStructure.getLoadBalancer().rank(i); + singleton::mpi().iSend(&_tempInCN[i] , 1, dRank, _mpiNbHelper.get_mpiRequest(counter), _iCglob); + counter++; + } +#endif + + _initInCNdone = true; +} + +template +void CuboidNeighbourhood3D::init_outCN() +{ + + _outC.clear(); + _outN.clear(); + _outData = new bool* [_nC]; + _outDataCoordinates = new T* [_nC]; + + std::vector temp(_nC,0); + + for (unsigned i=0; i<_outCells.size(); i++) { + temp[_outCells[i].latticeR[0]]++; + } + + for (int i=0; i<_nC; i++) { +#ifdef PARALLEL_MODE_MPI + int sRank = _superStructure.getLoadBalancer().rank(i); + singleton::mpi().receive(&temp[i], 1, sRank, i); +#endif + if (temp[i]!=0) { + _outC.push_back(i); + _outN.push_back(temp[i]); + } + _outData[i] = new bool [temp[i]*_nData*_nDataType]; + _outDataCoordinates[i] = new T [temp[i]*3]; + } + + _initOutCNdone = true; +} + +#ifdef PARALLEL_MODE_MPI +template +void CuboidNeighbourhood3D::bufSend_inCells(singleton::MpiNonBlockingHelper& helper) +{ + + helper.free(); + + std::vector temp(_nC,0); + for (unsigned i=0; i<_inCells.size(); i++) { + int iC = _inCells[i].latticeR[0]; + if (singleton::mpi().getRank() != _superStructure.getLoadBalancer().rank(iC)) { + _inDataCoordinates[iC][3*temp[iC]] = _inCells[i].physR[0]; + _inDataCoordinates[iC][3*temp[iC]+1] = _inCells[i].physR[1]; + _inDataCoordinates[iC][3*temp[iC]+2] = _inCells[i].physR[2]; + temp[iC]++; + } + } + + int counter=0; + for (unsigned iC=0; iC<_inC.size(); iC++) { + //int dRank = _superStructure.get_load().rank(_inC[iC]); + //if ( singleton::mpi().getRank() != dRank ) + counter++; + } + + helper.allocate(counter); + counter=0; + for (unsigned iC=0; iC<_inC.size(); iC++) { + int dRank = _superStructure.getLoadBalancer().rank(_inC[iC]); + //if ( singleton::mpi().getRank() != dRank ) { + singleton::mpi().iSend( _inDataCoordinates[_inC[iC]], + _inN[iC]*3, dRank, helper.get_mpiRequest(counter), _iCglob); + counter++; + //} + } +} +#endif + +template +void CuboidNeighbourhood3D::recWrite_outCells() +{ + +#ifdef PARALLEL_MODE_MPI + for (unsigned iC=0; iC<_outC.size(); iC++) { + int sRank = _superStructure.getLoadBalancer().rank(_outC[iC]); + singleton::mpi().receive(_outDataCoordinates[_outC[iC]], _outN[iC]*3, sRank,_outC[iC]); + if ( singleton::mpi().getRank() != sRank ) { + //singleton::mpi().receive(_outDataCoordinates[_outC[iC]], _outN[iC]*3, sRank, _outC[iC]); + Cell3D found; + for (int i=0; i<_outN[iC]; i++) { + found.physR[0] = _outDataCoordinates[_outC[iC]][3*i]; + found.physR[1] = _outDataCoordinates[_outC[iC]][3*i+1]; + found.physR[2] = _outDataCoordinates[_outC[iC]][3*i+2]; + _superStructure.getCuboidGeometry().getLatticeR(found.latticeR, found.physR); + found.latticeR[0] = _outC[iC]; + _outCells.push_back(found); + } + } + } +#endif +} + +template +void CuboidNeighbourhood3D::finish_comm() +{ + +#ifdef PARALLEL_MODE_MPI + singleton::mpi().waitAll(_mpiNbHelper); +#endif + +} + +template +void CuboidNeighbourhood3D::buffer_outData() +{ + + std::vector temp(_nC,0); + int iCloc = _superStructure.getLoadBalancer().loc(_iCglob); + for (unsigned i=0; i<_outCells.size(); i++) { + int iC = _outCells[i].latticeR[0]; + // WARNING: Here is interpolation needed if globX, globY + // are not integers. This needs to be fixed if one will + // use unstructured grids. + //for (int iData=0; iData<_nData; iData++) { + // memcpy(_outData[iC] + (temp[iC]*_nData + iData)*_nDataType, _superStructure(iCloc,iX+overlap,iY+overlap,iZ+overlap,iData), _nDataType); + //} + memcpy(_outData[iC] + temp[iC]*_nData*_nDataType, _superStructure(iCloc,_outCells[i].latticeR[1],_outCells[i].latticeR[2],_outCells[i].latticeR[3],0), _nDataType*_nData); + temp[iC]++; + } +} + +template +void CuboidNeighbourhood3D::send_outData() +{ +#ifdef PARALLEL_MODE_MPI + for (unsigned iC=0; iC<_outC.size(); iC++) { + int dRank = _superStructure.getLoadBalancer().rank(_outC[iC]); + singleton::mpi().iSend( _outData[_outC[iC]], + _outN[iC]*_nData*_nDataType, dRank, _mpiNbHelper.get_mpiRequest(iC), _iCglob); + } +#endif +} + +template +void CuboidNeighbourhood3D::receive_inData() +{ +#ifdef PARALLEL_MODE_MPI + for (unsigned iC=0; iC<_inC.size(); iC++) { + int sRank = _superStructure.getLoadBalancer().rank(_inC[iC]); + singleton::mpi().receive(_inData[_inC[iC]], _inN[iC]*_nData*_nDataType, sRank,_inC[iC]); + } +#endif +} + +template +void CuboidNeighbourhood3D::write_inData() +{ + + int iCloc = _superStructure.getLoadBalancer().loc(_iCglob); + std::vector temp(_nC,0); + for (unsigned i=0; i<_inCells.size(); i++) { + int iC = _inCells[i].latticeR[0]; + //for (int iData=0; iData<_nData; iData++) { + // memcpy(_superStructure(iCloc,iX+overlap,iY+overlap,iZ+overlap,iData), _inData[iC] + (temp[iC]*_nData + iData)*_nDataType, _nDataType); + //} + //memcpy(_superStructure(iCloc,iX+overlap,iY+overlap,iZ+overlap,0), _inData[iC] + temp[iC]*_nData*_nDataType, _nData*_nDataType); + //temp[iC]++; + memcpy(_superStructure(iCloc,_inCells[i].latticeR[1],_inCells[i].latticeR[2],_inCells[i].latticeR[3],0), _inData[iC] + temp[iC]*_nData*_nDataType, _nData*_nDataType); + temp[iC]++; + } +} + +template +void CuboidNeighbourhood3D::reset() +{ + + if (_initInCNdone) { +#ifdef PARALLEL_MODE_MPI + for (int iC=0; iC<_nC; iC++) { + delete[] _inData[iC]; + delete[] _inDataCoordinates[iC]; + } +#endif + delete[] _inData; + delete[] _inDataCoordinates; + delete[] _tempInCN; + _initInCNdone = false; + } + if (_initOutCNdone) { + for (int iC=0; iC<_nC; iC++) { + delete[] _outData[iC]; + delete[] _outDataCoordinates[iC]; + } + delete[] _outData; + delete[] _outDataCoordinates; +#ifdef PARALLEL_MODE_MPI + _mpiNbHelper.free(); +#endif + _initOutCNdone = false; + } + _inCells.clear(); + _outCells.clear(); + _inC.clear(); + _outC.clear(); + _inN.clear(); + _outN.clear(); +} + +} // namespace olb + +#endif -- cgit v1.2.3