Palabos  Version 1.0
dataField3D.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 
00028 #ifndef DATA_FIELD_3D_HH
00029 #define DATA_FIELD_3D_HH
00030 
00031 #include "atomicBlock/dataField3D.h"
00032 #include "atomicBlock/atomicBlock3D.h"
00033 #include <algorithm>
00034 #include <typeinfo>
00035 #include <cstring>
00036 
00037 namespace plb {
00038 
00040 
00041 template<typename T>
00042 ScalarField3D<T>::ScalarField3D(plint nx_, plint ny_, plint nz_, T iniVal)
00043     : AtomicBlock3D(nx_, ny_, nz_),
00044       dataTransfer(*this)
00045 {
00046     allocateMemory();
00047     for (pluint iData=0; iData<getSize(); ++iData) {
00048         (*this)[iData] = iniVal;
00049     }
00050 }
00051 
00052 template<typename T>
00053 ScalarField3D<T>::~ScalarField3D() {
00054     releaseMemory();
00055 }
00056 
00057 template<typename T>
00058 ScalarField3D<T>::ScalarField3D(ScalarField3D<T> const& rhs)
00059     : AtomicBlock3D(rhs),
00060       dataTransfer(*this)
00061 {
00062     allocateMemory();
00063     for (pluint iData=0; iData<getSize(); ++iData) {
00064         (*this)[iData] = rhs[iData];
00065     }
00066 }
00067 
00068 template<typename T>
00069 ScalarField3D<T>& ScalarField3D<T>::operator=(ScalarField3D<T> const& rhs) {
00070     ScalarField3D<T> tmp(rhs);
00071     swap(tmp);
00072     return *this;
00073 }
00074 
00075 template<typename T>
00076 void ScalarField3D<T>::swap(ScalarField3D<T>& rhs) {
00077     AtomicBlock3D::swap(rhs);
00078     std::swap(rawData, rhs.rawData);
00079     std::swap(field, rhs.field);
00080 }
00081 
00082 template<typename T>
00083 void ScalarField3D<T>::reset() {
00084     for (plint index=0; index<this->getNx()*this->getNy()*this->getNz(); ++index) {
00085         (*this)[index] = T();
00086     }
00087 }
00088 
00089 template<typename T>
00090 ScalarFieldDataTransfer3D<T>& ScalarField3D<T>::getDataTransfer() {
00091     return dataTransfer;
00092 }
00093 
00094 template<typename T>
00095 ScalarFieldDataTransfer3D<T> const& ScalarField3D<T>::getDataTransfer() const {
00096     return dataTransfer;
00097 }
00098 
00099 template<typename T>
00100 void ScalarField3D<T>::allocateMemory() {
00101     rawData = new T [(pluint)this->getNx()*(pluint)this->getNy()*(pluint)this->getNz()];
00102     field   = new T** [(pluint)this->getNx()];
00103     for (plint iX=0; iX<this->getNx(); ++iX) {
00104         field[iX] = new T* [(pluint)this->getNy()];
00105         for (plint iY=0; iY<this->getNy(); ++iY) {
00106             field[iX][iY] = rawData + (pluint)this->getNz()*((pluint)iY+(pluint)this->getNy()*(pluint)iX);
00107         }
00108     }
00109 }
00110 
00111 template<typename T>
00112 void ScalarField3D<T>::releaseMemory() {
00113     for (plint iX=0; iX<this->getNx(); ++iX) {
00114       delete [] field[iX];
00115     }
00116     delete [] field;
00117     delete [] rawData; rawData = 0;
00118 }
00119 
00121 
00122 template<typename T>
00123 ScalarFieldDataTransfer3D<T>::ScalarFieldDataTransfer3D(ScalarField3D<T>& field_)
00124     : field(field_)
00125 { }
00126 
00127 template<typename T>
00128 plint ScalarFieldDataTransfer3D<T>::staticCellSize() const {
00129     return sizeof(T);
00130 }
00131 
00132 template<typename T>
00133 void ScalarFieldDataTransfer3D<T>::send(Box3D domain, std::vector<char>& buffer, modif::ModifT kind) const
00134 {
00135     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00136     plint cellSize = staticCellSize();
00137     pluint numBytes = domain.nCells()*cellSize;
00138     // Avoid dereferencing uninitialized pointer.
00139     if (numBytes==0) return;
00140     buffer.resize(numBytes);
00141 
00142     plint iData=0;
00143     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00144         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00145             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00146                 memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY,iZ)), sizeof(T));
00147                 iData += sizeof(T);
00148             }
00149         }
00150     }
00151 }
00152 
00153 template<typename T>
00154 void ScalarFieldDataTransfer3D<T>::receive (
00155         Box3D domain, std::vector<char> const& buffer, modif::ModifT kind )
00156 {
00157     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00158     PLB_PRECONDITION( domain.nCells()*staticCellSize() == (plint)buffer.size() );
00159 
00160     // Avoid dereferencing uninitialized pointer.
00161     if (buffer.empty()) return;
00162     plint iData=0;
00163     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00164         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00165             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00166                 memcpy((void*)(&field.get(iX,iY,iZ)), (const void*)(&buffer[iData]), sizeof(T));
00167                 iData += sizeof(T);
00168             }
00169         }
00170     }
00171 }
00172 
00173 template<typename T>
00174 void ScalarFieldDataTransfer3D<T>::attribute (
00175         Box3D toDomain, plint deltaX, plint deltaY, plint deltaZ,
00176         AtomicBlock3D const& from, modif::ModifT kind )
00177 {
00178     PLB_PRECONDITION (typeid(from) == typeid(ScalarField3D<T> const&));
00179     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00180     ScalarField3D<T> const& fromField = (ScalarField3D<T> const&) from;
00181     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00182         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00183             for (plint iZ=toDomain.z0; iZ<=toDomain.z1; ++iZ) {
00184                 field.get(iX,iY,iZ) = fromField.get(iX+deltaX,iY+deltaY,iZ+deltaZ);
00185             }
00186         }
00187     }
00188 }
00189 
00190 
00191 
00193 
00194 template<typename T, int nDim>
00195 TensorField3D<T,nDim>::TensorField3D(plint nx_, plint ny_, plint nz_)
00196     : AtomicBlock3D(nx_, ny_, nz_),
00197       dataTransfer(*this)
00198 {
00199     allocateMemory();
00200     for (plint iData=0; iData<this->getNx()*this->getNy()*this->getNz(); ++iData) {
00201         for (int iDim=0; iDim<nDim; ++iDim) {
00202             (*this)[iData][iDim] = T();
00203         }
00204     }
00205 }
00206 
00207 template<typename T, int nDim>
00208 TensorField3D<T,nDim>::TensorField3D(plint nx_, plint ny_, plint nz_, Array<T,nDim> const& iniVal)
00209     : AtomicBlock3D(nx_, ny_, nz_),
00210       dataTransfer(*this)
00211 {
00212     allocateMemory();
00213     for (plint iData=0; iData<this->getNx()*this->getNy()*this->getNz(); ++iData) {
00214         for (int iDim=0; iDim<nDim; ++iDim) {
00215             (*this)[iData][iDim] = iniVal[iDim];
00216         }
00217     }
00218 }
00219 
00220 template<typename T, int nDim>
00221 TensorField3D<T,nDim>::~TensorField3D() {
00222     releaseMemory();
00223 }
00224 
00225 template<typename T, int nDim>
00226 TensorField3D<T,nDim>::TensorField3D(TensorField3D<T,nDim> const& rhs)
00227     : AtomicBlock3D(rhs),
00228       dataTransfer(*this)
00229 {
00230     allocateMemory();
00231     for (plint iData=0; iData<this->getNx()*this->getNy()*this->getNz(); ++iData) {
00232         for (int iDim=0; iDim<nDim; ++iDim) {
00233             (*this)[iData][iDim] = rhs[iData][iDim];
00234         }
00235     }
00236 }
00237 
00238 template<typename T, int nDim>
00239 TensorField3D<T,nDim>& TensorField3D<T,nDim>::operator=(TensorField3D<T,nDim> const& rhs) {
00240     TensorField3D<T,nDim> tmp(rhs);
00241     swap(tmp);
00242     return *this;
00243 }
00244 
00245 template<typename T, int nDim>
00246 void TensorField3D<T,nDim>::swap(TensorField3D<T,nDim>& rhs) {
00247     AtomicBlock3D::swap(rhs);
00248     std::swap(rawData, rhs.rawData);
00249     std::swap(field, rhs.field);
00250 }
00251 
00252 template<typename T, int nDim>
00253 void TensorField3D<T,nDim>::reset() {
00254     for (plint index=0; index<this->getNx()*this->getNy()*this->getNz(); ++index) {
00255         for (int iDim=0; iDim<nDim; ++iDim) {
00256             (*this)[index][iDim] = T();
00257         }
00258     }
00259 }
00260 
00261 template<typename T, int nDim>
00262 TensorFieldDataTransfer3D<T,nDim>& TensorField3D<T,nDim>::getDataTransfer() {
00263     return dataTransfer;
00264 }
00265 
00266 template<typename T, int nDim>
00267 TensorFieldDataTransfer3D<T,nDim> const& TensorField3D<T,nDim>::getDataTransfer() const {
00268     return dataTransfer;
00269 }
00270 
00271 template<typename T, int nDim>
00272 void TensorField3D<T,nDim>::allocateMemory() {
00273     rawData = new Array<T,nDim>   [(pluint)this->getNx()*(pluint)this->getNy()*(pluint)this->getNz()];
00274     field   = new Array<T,nDim>** [(pluint)this->getNx()];
00275     for (plint iX=0; iX<this->getNx(); ++iX) {
00276         field[iX] = new Array<T,nDim>* [(pluint)this->getNy()];
00277         for (plint iY=0; iY<this->getNy(); ++iY) {
00278             field[iX][iY] = rawData + (pluint)this->getNz()*((pluint)iY+(pluint)this->getNy()*(pluint)iX);
00279         }
00280     }
00281 }
00282 
00283 template<typename T, int nDim>
00284 void TensorField3D<T,nDim>::releaseMemory() {
00285     for (plint iX=0; iX<this->getNx(); ++iX) {
00286         delete [] field[iX];
00287     }
00288     delete [] field;
00289     delete [] rawData; rawData = 0;
00290 }
00291 
00292 
00294 
00295 template<typename T, int nDim>
00296 TensorFieldDataTransfer3D<T,nDim>::TensorFieldDataTransfer3D(TensorField3D<T,nDim>& field_)
00297     : field(field_)
00298 { }
00299 
00300 template<typename T, int nDim>
00301 plint TensorFieldDataTransfer3D<T,nDim>::staticCellSize() const {
00302     return nDim*sizeof(T);
00303 }
00304 
00305 template<typename T, int nDim>
00306 void TensorFieldDataTransfer3D<T,nDim>::send(Box3D domain, std::vector<char>& buffer, modif::ModifT kind) const
00307 {
00308     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00309     plint cellSize = staticCellSize();
00310     pluint numBytes = domain.nCells()*cellSize;
00311     // Avoid dereferencing uninitialized pointer.
00312     if (numBytes==0) return;
00313     buffer.resize(numBytes);
00314 
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             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00319                 memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY,iZ)[0]), nDim*sizeof(T));
00320                 iData += nDim*sizeof(T);
00321             }
00322         }
00323     }
00324 }
00325 
00326 template<typename T, int nDim>
00327 void TensorFieldDataTransfer3D<T,nDim>::receive (
00328         Box3D domain, std::vector<char> const& buffer, modif::ModifT kind )
00329 {
00330     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00331     PLB_PRECONDITION( domain.nCells()*staticCellSize() == (plint)buffer.size() );
00332 
00333     // Avoid dereferencing uninitialized pointer.
00334     if (buffer.empty()) return;
00335     plint iData=0;
00336     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00337         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00338             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00339                 memcpy((void*)(&field.get(iX,iY,iZ)[0]), (const void*)(&buffer[iData]), nDim*sizeof(T));
00340                 iData += nDim*sizeof(T);
00341             }
00342         }
00343     }
00344 }
00345 
00346 template<typename T, int nDim>
00347 void TensorFieldDataTransfer3D<T,nDim>::attribute (
00348         Box3D toDomain, plint deltaX, plint deltaY, plint deltaZ,
00349         AtomicBlock3D const& from, modif::ModifT kind )
00350 {
00351     PLB_PRECONDITION (typeid(from) == typeid(TensorField3D<T,nDim> const&));
00352     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00353     TensorField3D<T,nDim> const& fromField = (TensorField3D<T,nDim> const&) from;
00354     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00355         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00356             for (plint iZ=toDomain.z0; iZ<=toDomain.z1; ++iZ) {
00357                 for (int iDim=0; iDim<nDim; ++iDim) {
00358                     field.get(iX,iY,iZ)[iDim] = fromField.get(iX+deltaX,iY+deltaY,iZ+deltaZ)[iDim];
00359                 }
00360             }
00361         }
00362     }
00363 }
00364 
00365 
00367 
00368 template<typename T>
00369 NTensorField3D<T>::NTensorField3D(plint nx_, plint ny_, plint nz_, plint ndim_)
00370     : NTensorFieldBase3D<T>(ndim_),
00371       AtomicBlock3D(nx_,ny_,nz_),
00372       dataTransfer(*this)
00373 {
00374     allocateMemory();
00375     reset();
00376 }
00377 
00378 template<typename T>
00379 NTensorField3D<T>::NTensorField3D(plint nx_, plint ny_, plint nz_, plint ndim_, T const* iniVal)
00380     : NTensorFieldBase3D<T>(ndim_),
00381       AtomicBlock3D(nx_,ny_,nz_),
00382       dataTransfer(*this)
00383 {
00384     allocateMemory();
00385     for ( plint iData=0; iData<this->getNx()*this->getNy()*this->getNz()*this->getNdim();
00386           iData+=this->getNdim() )
00387     {
00388         for (plint iDim=0; iDim<this->getNdim(); ++iDim)
00389         {
00390             (*this)[iData+iDim] = iniVal[iDim];
00391         }
00392     }
00393 }
00394 
00395 template<typename T>
00396 NTensorField3D<T>::~NTensorField3D() {
00397     releaseMemory();
00398 }
00399 
00400 template<typename T>
00401 NTensorField3D<T>::NTensorField3D(NTensorField3D<T> const& rhs) 
00402     : NTensorFieldBase3D<T>(rhs),
00403       AtomicBlock3D(rhs),
00404       dataTransfer(*this)
00405 {
00406     allocateMemory();
00407     for (plint iData=0; iData<this->getNx()*this->getNy()*this->getNz()*this->getNdim(); ++iData) {
00408         (*this)[iData] = rhs[iData];
00409     }
00410 }
00411 
00412 template<typename T>
00413 NTensorField3D<T>& NTensorField3D<T>::operator=(NTensorField3D<T> const& rhs) {
00414     NTensorField3D<T> tmp(rhs);
00415     swap(tmp);
00416     return *this;
00417 }
00418 
00419 template<typename T>
00420 void NTensorField3D<T>::swap(NTensorField3D<T>& rhs) {
00421     NTensorFieldBase3D<T>::swap(rhs);
00422     AtomicBlock3D::swap(rhs);
00423     std::swap(rawData, rhs.rawData);
00424     std::swap(field, rhs.field);
00425 }
00426 
00427 template<typename T>
00428 void NTensorField3D<T>::reset() {
00429     for (plint index=0; index<this->getNx()*this->getNy()*this->getNz()*this->getNdim(); ++index) {
00430         (*this)[index] = T();
00431     }
00432 }
00433 
00434 template<typename T>
00435 NTensorFieldDataTransfer3D<T>& NTensorField3D<T>::getDataTransfer() {
00436     return dataTransfer;
00437 }
00438 
00439 template<typename T>
00440 NTensorFieldDataTransfer3D<T> const& NTensorField3D<T>::getDataTransfer() const {
00441     return dataTransfer;
00442 }
00443 
00444 template<typename T>
00445 void NTensorField3D<T>::allocateMemory() {
00446     rawData = new T [(pluint)this->getNx()*(pluint)this->getNy()*
00447                      (pluint)this->getNz()*(pluint)this->getNdim()];
00448     field   = new T*** [(pluint)this->getNx()];
00449     for (plint iX=0; iX<this->getNx(); ++iX) {
00450         field[iX] = new T** [(pluint)this->getNy()];
00451         for (plint iY=0; iY<this->getNy(); ++iY) {
00452             field[iX][iY] = new T* [(plint)this->getNz()];
00453             for (plint iZ=0; iZ<this->getNz(); ++iZ) {
00454                 field[iX][iY][iZ] =
00455                     rawData + (pluint)this->getNdim()* (
00456                                   (pluint)iZ+(pluint)this->getNz()* (
00457                                       (pluint)iY+(pluint)this->getNy()*(pluint)iX ) );
00458             }
00459         }
00460     }
00461 }
00462 
00463 template<typename T>
00464 void NTensorField3D<T>::releaseMemory() {
00465     for (plint iX=0; iX<this->getNx(); ++iX) {
00466         for (plint iY=0; iY<this->getNy(); ++iY) {
00467             delete [] field[iX][iY];
00468         }
00469         delete [] field[iX];
00470     }
00471     delete [] field;
00472     delete [] rawData; rawData = 0;
00473 }
00474 
00475 
00477 
00478 template<typename T>
00479 NTensorFieldDataTransfer3D<T>::NTensorFieldDataTransfer3D(NTensorField3D<T>& field_)
00480     : field(field_)
00481 { }
00482 
00483 template<typename T>
00484 plint NTensorFieldDataTransfer3D<T>::staticCellSize() const {
00485     return field.getNdim()*sizeof(T);
00486 }
00487 
00488 template<typename T>
00489 void NTensorFieldDataTransfer3D<T>::send(Box3D domain, std::vector<char>& buffer, modif::ModifT kind) const
00490 {
00491 
00492     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00493     plint cellSize = staticCellSize();
00494     pluint numBytes = domain.nCells()*cellSize;
00495     buffer.resize(numBytes);
00496 
00497     plint iData=0;
00498     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00499         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00500             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00501                 memcpy((void*)(&buffer[iData]), (const void*)(&field.get(iX,iY,iZ)[0]), cellSize);
00502                 iData += cellSize;
00503             }
00504         }
00505     }
00506 }
00507 
00508 template<typename T>
00509 void NTensorFieldDataTransfer3D<T>::receive (
00510         Box3D domain, std::vector<char> const& buffer, modif::ModifT kind )
00511 {
00512     PLB_PRECONDITION( contained(domain, field.getBoundingBox()) );
00513     PLB_PRECONDITION( (pluint) domain.nCells()*staticCellSize() == buffer.size() );
00514     plint cellSize = staticCellSize();
00515 
00516     plint iData=0;
00517     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00518         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00519             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00520                 memcpy((void*)(&field.get(iX,iY,iZ)[0]), (const void*)(&buffer[iData]), cellSize);
00521                 iData += cellSize;
00522             }
00523         }
00524     }
00525 }
00526 
00527 template<typename T>
00528 void NTensorFieldDataTransfer3D<T>::attribute (
00529         Box3D toDomain, plint deltaX, plint deltaY, plint deltaZ,
00530         AtomicBlock3D const& from, modif::ModifT kind )
00531 {
00532     PLB_PRECONDITION (typeid(from) == typeid(NTensorField3D<T> const&));
00533     PLB_PRECONDITION( contained(toDomain, field.getBoundingBox()) );
00534     NTensorField3D<T> const& fromField = (NTensorField3D<T> const&) from;
00535     for (plint iX=toDomain.x0; iX<=toDomain.x1; ++iX) {
00536         for (plint iY=toDomain.y0; iY<=toDomain.y1; ++iY) {
00537             for (plint iZ=toDomain.z0; iZ<=toDomain.z1; ++iZ) {
00538                 for (int iDim=0; iDim<field.getNdim(); ++iDim) {
00539                     field.get(iX,iY,iZ)[iDim] = fromField.get(iX+deltaX,iY+deltaY,iZ+deltaZ)[iDim];
00540                 }
00541             }
00542         }
00543     }
00544 }
00545 
00546 }  // namespace plb
00547 
00548 #endif  // DATA_FIELD_3D_HH