|
Palabos
Version 1.0
|
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