/* 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 * A communincator provides a cuboids with cells of other * cuboids -- generic implementation. */ #ifndef COMMUNICATOR_3D_HH #define COMMUNICATOR_3D_HH #include "communication/mpiManager.h" #include #include "communication/communicator3D.h" #include "communication/cuboidNeighbourhood3D.h" #include "geometry/cuboidGeometry3D.h" #include "communication/superStructure3D.h" namespace olb { /////////////////// Class Communicator3D ////////////////////// template Communicator3D::Communicator3D(SuperStructure3D& superStructure):_superStructure(superStructure) { _initDone = false; } template void Communicator3D::init_nh() { _nC = _superStructure.getCuboidGeometry().getNc(); for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { CuboidNeighbourhood3D nh(_superStructure,_superStructure.getLoadBalancer().glob(iC)); _nh.push_back(nh); } } template void Communicator3D::add_cell(int iCloc, int iX, int iY, int iZ) { _nh[iCloc].add_inCell(iX,iY,iZ); } template void Communicator3D::add_cells(int overlap) { for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].add_inCells(overlap); } } template void Communicator3D::init() { reset(); for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].init_inCN(); for (int i=0; i<_nh[iC].get_inCellsSize(); i++) { int ID = _nh[iC].get_inCell(i).latticeR[0]; #ifdef PARALLEL_MODE_MPI if ( singleton::mpi().getRank() ==_superStructure.getLoadBalancer().rank(ID) ) #endif { Cell3D temp; temp.physR[0] = _nh[iC].get_inCell(i).physR[0]; temp.physR[1] = _nh[iC].get_inCell(i).physR[1]; temp.physR[2] = _nh[iC].get_inCell(i).physR[2]; _superStructure.getCuboidGeometry().getLatticeR(temp.latticeR, temp.physR); temp.latticeR[0] = _superStructure.getLoadBalancer().glob(iC); _nh[_superStructure.getLoadBalancer().loc(ID)].add_outCell(temp); } } } for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].init_outCN(); } #ifdef PARALLEL_MODE_MPI singleton::MpiNonBlockingHelper helper; for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].finish_comm(); } for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].bufSend_inCells(helper); } for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].recWrite_outCells(); } for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { singleton::mpi().waitAll(helper); } #endif } template void Communicator3D::reset() { if (_initDone) { for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].reset(); } _initDone = false; } } template void Communicator3D::send() { for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].buffer_outData(); #ifdef PARALLEL_MODE_MPI _nh[iC].send_outData(); #endif } } template void Communicator3D::receive() { for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { #ifdef PARALLEL_MODE_MPI _nh[iC].receive_inData(); #else for (int i=0; i<_nh[iC].get_inCsize(); i++) { _nh[iC].get_inData()[_nh[iC].get_inC(i)] = _nh[_nh[iC].get_inC(i)].get_outData()[iC]; } #endif } #ifdef PARALLEL_MODE_MPI for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].finish_comm(); } #endif } template void Communicator3D::write() { for (int iC=0; iC<_superStructure.getLoadBalancer().size(); iC++) { _nh[iC].write_inData(); } } } #endif