Palabos  Version 1.0
dataField2D.hh
Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00029 #ifndef DATA_FIELD_2D_HH
00030 #define DATA_FIELD_2D_HH
00031 
00032 #include "atomicBlock/dataField2D.h"
00033 #include "atomicBlock/atomicBlock2D.h"
00034 #include <algorithm>
00035 #include <typeinfo>
00036 #include <cstring>
00037 
00038 namespace plb {
00039 
00041 
00042 template<typename T>
00043 ScalarField2D<T>::ScalarField2D(plint nx_, plint ny_, T iniVal)
00044     : AtomicBlock2D(nx_, ny_),
00045       dataTransfer(*this)
00046 {
00047     allocateMemory();
00048     for (pluint iData=0; iData<getSize(); ++iData) {
00049         (*this)[iData] = iniVal;
00050     }
00051 }
00052 
00053 template<typename T>
00054 ScalarField2D<T>::~ScalarField2D() {
00055     releaseMemory();
00056 }
00057 
00058 template<typename T>
00059 ScalarField2D<T>::ScalarField2D(ScalarField2D<T> const& rhs) 
00060     : AtomicBlock2D(rhs),
00061       dataTransfer(*this)
00062 {
00063     allocateMemory();
00064     for (pluint iData=0; iData<getSize(); ++iData) {
00065         (*this)[iData] = rhs[iData];
00066     }
00067 }
00068 
00069 template<typename T>
00070 ScalarField2D<T>& ScalarField2D<T>::operator=(ScalarField2D<T> const& rhs) {
00071     ScalarField2D<T> tmp(rhs);
00072     swap(tmp);
00073     return *this;
00074 }
00075 
00076 template<typename T>
00077 void ScalarField2D<T>::swap(ScalarField2D<T>& rhs) {
00078     AtomicBlock2D::swap(rhs);
00079     std::swap(rawData, rhs.rawData);
00080     std::swap(field, rhs.field);
00081 }
00082 
00083 
00084 template<typename T>
00085 void ScalarField2D<T>::reset() {
00086     for (plint index=0; index<this->getNx()*this->getNy(); ++index) {
00087         (*this)[index] = T();
00088     }
00089 }
00090 
00091 template<typename T>
00092 ScalarFieldDataTransfer2D<T>& ScalarField2D<T>::getDataTransfer() {
00093     return dataTransfer;
00094 }
00095 
00096 template<typename T>
00097 ScalarFieldDataTransfer2D<T> const& ScalarField2D<T>::getDataTransfer() const {
00098     return dataTransfer;
00099 }
00100 
00101 template<typename T>
00102 void ScalarField2D<T>::allocateMemory() {
00103     rawData = new T[(pluint)this->getNx()*(pluint)this->getNy()];
00104     field   = new T* [(pluint)this->getNx()];
00105     for (plint iX=0; iX<this->getNx(); ++iX) {
00106         field[iX] = rawData + (pluint)iX*(pluint)this->getNy();
00107     }
00108 }
00109 
00110 template<typename T>
00111 void ScalarField2D<T>::releaseMemory() {
00112     delete [] field;
00113     delete [] rawData; rawData = 0;
00114 }
00115 
00117 
00118 template<typename T>
00119 ScalarFieldDataTransfer2D<T>::ScalarFieldDataTransfer2D(ScalarField2D<T>& field_)
00120     : field(field_)
00121 { }
00122 
00123 template<typename T>
00124 plint ScalarFieldDataTransfer2D<T>::staticCellSize() const {
00125     return sizeof(T);
00126 }
00127 
00128 template<typename T>
00129 void ScalarFieldDataTransfer2D<T>::send(Box2D domain, std::vector<char>& buffer, modif::ModifT kind) const
00130 {
00131     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00132     plint cellSize = staticCellSize();
00133     pluint numBytes = domain.nCells()*cellSize;
00134     // Avoid dereferencing uninitialized pointer.
00135     if (numBytes==0) return;
00136     buffer.resize(numBytes);
00137 
00138     plint iData=0;
00139     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00140         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00141             memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY)), sizeof(T));
00142             iData += sizeof(T);
00143         }
00144     }
00145 }
00146 
00147 template<typename T>
00148 void ScalarFieldDataTransfer2D<T>::receive (
00149         Box2D domain, std::vector<char> const& buffer, modif::ModifT kind )
00150 {
00151     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00152     PLB_PRECONDITION( domain.nCells()*staticCellSize() == (plint) buffer.size() );
00153 
00154     // Avoid dereferencing uninitialized pointer.
00155     if (buffer.empty()) return;
00156     plint iData=0;
00157     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00158         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00159             memcpy((void*)(&field.get(iX,iY)), (const void*)(&buffer[iData]), sizeof(T));
00160             iData += sizeof(T);
00161         }
00162     }
00163 }
00164 
00165 template<typename T>
00166 void ScalarFieldDataTransfer2D<T>::attribute (
00167         Box2D toDomain, plint deltaX, plint deltaY,
00168         AtomicBlock2D const& from, modif::ModifT kind )
00169 {
00170     PLB_PRECONDITION (typeid(from) == typeid(ScalarField2D<T> const&));
00171     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00172     ScalarField2D<T> const& fromField = (ScalarField2D<T> const&) from;
00173     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00174         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00175             field.get(iX,iY) = fromField.get(iX+deltaX,iY+deltaY);
00176         }
00177     }
00178 }
00179 
00180 
00182 
00183 template<typename T, int nDim>
00184 TensorField2D<T,nDim>::TensorField2D(plint nx_, plint ny_)
00185     : AtomicBlock2D(nx_,ny_),
00186       dataTransfer(*this)
00187 {
00188     allocateMemory();
00189     for (plint iData=0; iData<this->getNx()*this->getNy(); ++iData) {
00190         for (int iDim=0; iDim<nDim; ++iDim) {
00191             (*this)[iData][iDim] = T();
00192         }
00193     }
00194 }
00195 
00196 template<typename T, int nDim>
00197 TensorField2D<T,nDim>::TensorField2D(plint nx_, plint ny_, Array<T,nDim> const& iniVal)
00198     : AtomicBlock2D(nx_,ny_),
00199       dataTransfer(*this)
00200 {
00201     allocateMemory();
00202     for (plint iData=0; iData<this->getNx()*this->getNy(); ++iData) {
00203         for (int iDim=0; iDim<nDim; ++iDim) {
00204             (*this)[iData][iDim] = iniVal[iDim];
00205         }
00206     }
00207 }
00208 
00209 template<typename T, int nDim>
00210 TensorField2D<T,nDim>::~TensorField2D() {
00211     releaseMemory();
00212 }
00213 
00214 template<typename T, int nDim>
00215 TensorField2D<T,nDim>::TensorField2D(TensorField2D<T,nDim> const& rhs) 
00216     : AtomicBlock2D(rhs),
00217       dataTransfer(*this)
00218 {
00219     allocateMemory();
00220     for (plint iData=0; iData<this->getNx()*this->getNy(); ++iData) {
00221         for (int iDim=0; iDim<nDim; ++iDim) {
00222             (*this)[iData][iDim] = rhs[iData][iDim];
00223         }
00224     }
00225 }
00226 
00227 template<typename T, int nDim>
00228 TensorField2D<T,nDim>& TensorField2D<T,nDim>::operator=(TensorField2D<T,nDim> const& rhs) {
00229     TensorField2D<T,nDim> tmp(rhs);
00230     swap(tmp);
00231     return *this;
00232 }
00233 
00234 template<typename T, int nDim>
00235 void TensorField2D<T,nDim>::swap(TensorField2D<T,nDim>& rhs) {
00236     AtomicBlock2D::swap(rhs);
00237     std::swap(rawData, rhs.rawData);
00238     std::swap(field, rhs.field);
00239 }
00240 
00241 template<typename T, int nDim>
00242 void TensorField2D<T,nDim>::reset() {
00243     for (plint index=0; index<this->getNx()*this->getNy(); ++index) {
00244         for (int iDim=0; iDim<nDim; ++iDim) {
00245             (*this)[index][iDim] = T();
00246         }
00247     }
00248 }
00249 
00250 template<typename T, int nDim>
00251 TensorFieldDataTransfer2D<T,nDim>& TensorField2D<T,nDim>::getDataTransfer() {
00252     return dataTransfer;
00253 }
00254 
00255 template<typename T, int nDim>
00256 TensorFieldDataTransfer2D<T,nDim> const& TensorField2D<T,nDim>::getDataTransfer() const {
00257     return dataTransfer;
00258 }
00259 
00260 template<typename T, int nDim>
00261 void TensorField2D<T,nDim>::allocateMemory() {
00262     rawData = new Array<T,nDim>[(pluint)this->getNx()*(pluint)this->getNy()];
00263     field   = new Array<T,nDim>* [(pluint)this->getNx()];
00264     for (plint iX=0; iX<this->getNx(); ++iX) {
00265         field[iX] = rawData + (pluint)iX*(pluint)this->getNy();
00266     }
00267 }
00268 
00269 template<typename T, int nDim>
00270 void TensorField2D<T,nDim>::releaseMemory() {
00271     delete [] field;
00272     delete [] rawData; rawData = 0;
00273 }
00274 
00276 
00277 template<typename T, int nDim>
00278 TensorFieldDataTransfer2D<T,nDim>::TensorFieldDataTransfer2D(TensorField2D<T,nDim>& field_)
00279     : field(field_)
00280 { }
00281 
00282 template<typename T, int nDim>
00283 plint TensorFieldDataTransfer2D<T,nDim>::staticCellSize() const {
00284     return nDim*sizeof(T);
00285 }
00286 
00287 template<typename T, int nDim>
00288 void TensorFieldDataTransfer2D<T,nDim>::send(Box2D domain, std::vector<char>& buffer, modif::ModifT kind) const
00289 {
00290     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00291     plint cellSize = staticCellSize();
00292     pluint numBytes = domain.nCells()*cellSize;
00293     // Avoid dereferencing uninitialized pointer.
00294     if (numBytes==0) return;
00295     buffer.resize(numBytes);
00296 
00297     plint iData=0;
00298     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00299         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00300             memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY)[0]), nDim*sizeof(T));
00301             iData += nDim*sizeof(T);
00302         }
00303     }
00304 }
00305 
00306 template<typename T, int nDim>
00307 void TensorFieldDataTransfer2D<T,nDim>::receive(
00308         Box2D domain, std::vector<char> const& buffer, modif::ModifT kind )
00309 {
00310     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00311     PLB_PRECONDITION( domain.nCells()*staticCellSize() == (plint) buffer.size() );
00312 
00313     // Avoid dereferencing uninitialized pointer.
00314     if (buffer.empty()) return;
00315     plint iData=0;
00316     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00317         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00318             memcpy((void*)(&field.get(iX,iY)[0]), (const void*)(&buffer[iData]), nDim*sizeof(T));
00319             iData += nDim*sizeof(T);
00320         }
00321     }
00322 }
00323 
00324 template<typename T, int nDim>
00325 void TensorFieldDataTransfer2D<T,nDim>::attribute (
00326         Box2D toDomain, plint deltaX, plint deltaY,
00327         AtomicBlock2D const& from, modif::ModifT kind )
00328 {
00329     PLB_PRECONDITION (typeid(from) == typeid(TensorField2D<T,nDim> const&));
00330     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00331     TensorField2D<T,nDim> const& fromField = (TensorField2D<T,nDim> const&) from;
00332     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00333         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00334             for (int iDim=0; iDim<nDim; ++iDim) {
00335                 field.get(iX,iY)[iDim] = fromField.get(iX+deltaX,iY+deltaY)[iDim];
00336             }
00337         }
00338     }
00339 }
00340 
00342 
00343 template<typename T>
00344 NTensorField2D<T>::NTensorField2D(plint nx_, plint ny_, plint ndim_)
00345     : NTensorFieldBase2D<T>(ndim_),
00346       AtomicBlock2D(nx_,ny_),
00347       dataTransfer(*this)
00348 {
00349     allocateMemory();
00350     reset();
00351 }
00352 
00353 template<typename T>
00354 NTensorField2D<T>::NTensorField2D(plint nx_, plint ny_, plint ndim_, T const* iniVal)
00355     : NTensorFieldBase2D<T>(ndim_),
00356       AtomicBlock2D(nx_,ny_),
00357       dataTransfer(*this)
00358 {
00359     allocateMemory();
00360     for ( plint iData=0; iData<this->getNx()*this->getNy()*this->getNdim();
00361           iData+=this->getNdim() )
00362     {
00363         for (plint iDim=0; iDim<this->getNdim(); ++iDim)
00364         {
00365             (*this)[iData+iDim] = iniVal[iDim];
00366         }
00367     }
00368 }
00369 
00370 template<typename T>
00371 NTensorField2D<T>::~NTensorField2D() {
00372     releaseMemory();
00373 }
00374 
00375 template<typename T>
00376 NTensorField2D<T>::NTensorField2D(NTensorField2D<T> const& rhs) 
00377     : NTensorFieldBase2D<T>(rhs),
00378       AtomicBlock2D(rhs),
00379       dataTransfer(*this)
00380 {
00381     allocateMemory();
00382     for (plint iData=0; iData<this->getNx()*this->getNy()*this->getNdim(); ++iData) {
00383         (*this)[iData] = rhs[iData];
00384     }
00385 }
00386 
00387 template<typename T>
00388 NTensorField2D<T>& NTensorField2D<T>::operator=(NTensorField2D<T> const& rhs) {
00389     NTensorField2D<T> tmp(rhs);
00390     swap(tmp);
00391     return *this;
00392 }
00393 
00394 template<typename T>
00395 void NTensorField2D<T>::swap(NTensorField2D<T>& rhs) {
00396     NTensorFieldBase2D<T>::swap(rhs);
00397     AtomicBlock2D::swap(rhs);
00398     std::swap(rawData, rhs.rawData);
00399     std::swap(field, rhs.field);
00400 }
00401 
00402 template<typename T>
00403 void NTensorField2D<T>::reset() {
00404     for (plint index=0; index<this->getNx()*this->getNy()*this->getNdim(); ++index) {
00405         (*this)[index] = T();
00406     }
00407 }
00408 
00409 template<typename T>
00410 NTensorFieldDataTransfer2D<T>& NTensorField2D<T>::getDataTransfer() {
00411     return dataTransfer;
00412 }
00413 
00414 template<typename T>
00415 NTensorFieldDataTransfer2D<T> const& NTensorField2D<T>::getDataTransfer() const {
00416     return dataTransfer;
00417 }
00418 
00419 template<typename T>
00420 void NTensorField2D<T>::allocateMemory() {
00421     rawData = new T[(pluint)this->getNx()*(pluint)this->getNy()*(pluint)this->getNdim()];
00422     field   = new T** [(pluint)this->getNx()];
00423     for (plint iX=0; iX<this->getNx(); ++iX) {
00424         field[iX] = new T* [(pluint)this->getNy()];
00425         for (plint iY=0; iY<this->getNy(); ++iY) {
00426             field[iX][iY] = rawData + (pluint)this->getNdim()*((pluint)iY+(pluint)this->getNy()*(pluint)iX);
00427         }
00428     }
00429 }
00430 
00431 template<typename T>
00432 void NTensorField2D<T>::releaseMemory() {
00433     for (plint iX=0; iX<this->getNx(); ++iX) {
00434         delete [] field[iX];
00435     }
00436     delete [] field;
00437     delete [] rawData; rawData = 0;
00438 }
00439 
00441 
00442 template<typename T>
00443 NTensorFieldDataTransfer2D<T>::NTensorFieldDataTransfer2D(NTensorField2D<T>& field_)
00444     : field(field_)
00445 { }
00446 
00447 template<typename T>
00448 plint NTensorFieldDataTransfer2D<T>::staticCellSize() const {
00449     return field.getNdim()*sizeof(T);
00450 }
00451 
00452 template<typename T>
00453 void NTensorFieldDataTransfer2D<T>::send(Box2D domain, std::vector<char>& buffer, modif::ModifT kind) const
00454 {
00455     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00456     plint cellSize = staticCellSize();
00457     pluint numBytes = domain.nCells()*cellSize;
00458     buffer.resize(numBytes);
00459 
00460     plint iData=0;
00461     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00462         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00463             memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY)[0]), cellSize);
00464             iData += cellSize;
00465         }
00466     }
00467 }
00468 
00469 template<typename T>
00470 void NTensorFieldDataTransfer2D<T>::receive (
00471         Box2D domain, std::vector<char> const& buffer, modif::ModifT kind )
00472 {
00473     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00474     PLB_PRECONDITION( (pluint) domain.nCells()*staticCellSize() == buffer.size() );
00475     plint cellSize = staticCellSize();
00476 
00477     plint iData=0;
00478     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00479         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00480             memcpy((void*)(&field.get(iX,iY)[0]), (const void*)(&buffer[iData]), cellSize);
00481             iData += cellSize;
00482         }
00483     }
00484 }
00485 
00486 template<typename T>
00487 void NTensorFieldDataTransfer2D<T>::attribute (
00488         Box2D toDomain, plint deltaX, plint deltaY,
00489         AtomicBlock2D const& from, modif::ModifT kind )
00490 {
00491     PLB_PRECONDITION (typeid(from) == typeid(NTensorField2D<T> const&));
00492     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00493     NTensorField2D<T> const& fromField = (NTensorField2D<T> const&) from;
00494     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00495         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00496             for (int iDim=0; iDim<field.getNdim(); ++iDim) {
00497                 field.get(iX,iY)[iDim] = fromField.get(iX+deltaX,iY+deltaY)[iDim];
00498             }
00499         }
00500     }
00501 }
00502 
00503 }  // namespace plb
00504 
00505 #endif   // DATA_FIELD_2D_HH