$treeview $search $mathjax
|
Palabos
Version 1.1
$projectbrief
|
$projectbrief
|
$searchbox |
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_ANALYSIS_FUNCTIONAL_3D_HH 00029 #define DATA_ANALYSIS_FUNCTIONAL_3D_HH 00030 00031 #include "dataProcessors/dataAnalysisFunctional3D.h" 00032 #include "core/plbDebug.h" 00033 #include "core/util.h" 00034 #include "core/blockStatistics.h" 00035 #include "latticeBoltzmann/momentTemplates.h" 00036 #include "latticeBoltzmann/geometricOperationTemplates.h" 00037 #include "finiteDifference/fdStencils1D.h" 00038 #include "atomicBlock/atomicBlock3D.h" 00039 #include "atomicBlock/blockLattice3D.h" 00040 #include "atomicBlock/dataField3D.h" 00041 #include <cmath> 00042 #include <limits> 00043 00044 namespace plb { 00045 00047 namespace fdLattice { 00048 00049 template<typename T, template<typename U> class Descriptor> 00050 inline Array<T,3> firstOrderBulkVorticity ( 00051 BlockLattice3D<T,Descriptor> const& lattice, plint iX, plint iY, plint iZ ) 00052 { 00053 Array<T,3> u000; 00054 lattice.get(iX ,iY ,iZ ).computeVelocity(u000); 00055 Array<T,3> u001; 00056 lattice.get(iX ,iY ,iZ+1).computeVelocity(u001); 00057 Array<T,3> u010; 00058 lattice.get(iX ,iY+1,iZ ).computeVelocity(u010); 00059 Array<T,3> u100; 00060 lattice.get(iX+1,iY ,iZ ).computeVelocity(u100); 00061 00062 Array<T,3> vorticity; 00063 T dyuz = u010[2] - u000[2]; 00064 T dzuy = u001[1] - u000[1]; 00065 vorticity[0] = dyuz - dzuy; 00066 00067 T dzux = u001[0] - u000[0]; 00068 T dxuz = u100[2] - u000[2]; 00069 vorticity[1] = dzux - dxuz; 00070 00071 T dxuy = u100[1] - u000[1]; 00072 T dyux = u010[0] - u000[0]; 00073 vorticity[2] = dxuy - dyux; 00074 00075 return vorticity; 00076 } 00077 00078 } // fdLattice 00079 00080 00082 namespace fdDataField { 00083 00084 template<typename T> 00085 inline T bulkXderiv ( 00086 ScalarField3D<T> const& field, plint iX, plint iY, plint iZ ) 00087 { 00088 T dxu = fd::ctl_diff( field.get(iX+1,iY,iZ), 00089 field.get(iX-1,iY,iZ) ); 00090 return dxu; 00091 } 00092 00093 template<typename T> 00094 inline T bulkYderiv ( 00095 ScalarField3D<T> const& field, plint iX, plint iY, plint iZ ) 00096 { 00097 T dyu = fd::ctl_diff( field.get(iX,iY+1,iZ), 00098 field.get(iX,iY-1,iZ) ); 00099 return dyu; 00100 } 00101 00102 template<typename T> 00103 inline T bulkZderiv ( 00104 ScalarField3D<T> const& field, plint iX, plint iY, plint iZ ) 00105 { 00106 T dzu = fd::ctl_diff( field.get(iX,iY,iZ+1), 00107 field.get(iX,iY,iZ-1) ); 00108 return dzu; 00109 } 00110 00111 template<typename T> 00112 inline T planeXderiv ( 00113 ScalarField3D<T> const& field, int direction, int orientation, 00114 plint iX, plint iY, plint iZ ) 00115 { 00116 if (direction==0) { 00117 return -orientation * 00118 fd::o1_fwd_diff( field.get(iX ,iY,iZ), 00119 field.get(iX-1*orientation,iY,iZ) ); 00120 } 00121 else { 00122 return bulkXderiv(field, iX,iY,iZ); 00123 } 00124 } 00125 00126 template<typename T> 00127 inline T planeYderiv ( 00128 ScalarField3D<T> const& field, int direction, int orientation, 00129 plint iX, plint iY, plint iZ ) 00130 { 00131 if (direction==1) { 00132 return -orientation * 00133 fd::o1_fwd_diff( field.get(iX,iY ,iZ), 00134 field.get(iX,iY-1*orientation,iZ) ); 00135 } 00136 else { 00137 return bulkYderiv(field, iX,iY,iZ); 00138 } 00139 } 00140 00141 template<typename T> 00142 inline T planeZderiv ( 00143 ScalarField3D<T> const& field, int direction, int orientation, 00144 plint iX, plint iY, plint iZ ) 00145 { 00146 if (direction==2) { 00147 return -orientation * 00148 fd::o1_fwd_diff( field.get(iX,iY,iZ ), 00149 field.get(iX,iY,iZ-1*orientation) ); 00150 } 00151 else { 00152 return bulkZderiv(field, iX,iY,iZ); 00153 } 00154 } 00155 00156 template<typename T> 00157 inline T edgeXderiv ( 00158 ScalarField3D<T> const& field, 00159 int plane, int direction1, int direction2, 00160 plint iX, plint iY, plint iZ ) 00161 { 00162 if (plane==0) { 00163 return bulkXderiv(field, iX,iY,iZ); 00164 } 00165 else { 00166 int orientation = plane==1 ? direction2 : direction1; 00167 return -orientation * 00168 fd::o1_fwd_diff( field.get(iX ,iY,iZ), 00169 field.get(iX-1*orientation,iY,iZ) ); 00170 } 00171 } 00172 00173 template<typename T> 00174 inline T edgeYderiv ( 00175 ScalarField3D<T> const& field, 00176 int plane, int direction1, int direction2, 00177 plint iX, plint iY, plint iZ ) 00178 { 00179 if (plane==1) { 00180 return bulkYderiv(field, iX,iY,iZ); 00181 } 00182 else { 00183 int orientation = plane==0 ? direction1 : direction2; 00184 return -orientation * 00185 fd::o1_fwd_diff( field.get(iX,iY ,iZ), 00186 field.get(iX,iY-1*orientation,iZ) ); 00187 } 00188 } 00189 00190 template<typename T> 00191 inline T edgeZderiv ( 00192 ScalarField3D<T> const& field, 00193 int plane, int direction1, int direction2, 00194 plint iX, plint iY, plint iZ ) 00195 { 00196 if (plane==2) { 00197 return bulkZderiv(field, iX,iY,iZ); 00198 } 00199 else { 00200 int orientation = plane==0 ? direction2 : direction1; 00201 return -orientation * 00202 fd::o1_fwd_diff( field.get(iX,iY,iZ ), 00203 field.get(iX,iY,iZ-1*orientation) ); 00204 } 00205 } 00206 00207 template<typename T> 00208 inline T cornerXderiv ( 00209 ScalarField3D<T> const& field, 00210 int normalX, int normalY, int normalZ, 00211 plint iX, plint iY, plint iZ ) 00212 { 00213 int orientation = normalX; 00214 return -orientation * 00215 fd::o1_fwd_diff( field.get(iX ,iY,iZ), 00216 field.get(iX-1*orientation,iY,iZ) ); 00217 } 00218 00219 template<typename T> 00220 inline T cornerYderiv ( 00221 ScalarField3D<T> const& field, 00222 int normalX, int normalY, int normalZ, 00223 plint iX, plint iY, plint iZ ) 00224 { 00225 int orientation = normalY; 00226 return -orientation * 00227 fd::o1_fwd_diff( field.get(iX,iY ,iZ), 00228 field.get(iX,iY-1*orientation,iZ) ); 00229 } 00230 00231 template<typename T> 00232 inline T cornerZderiv ( 00233 ScalarField3D<T> const& field, 00234 int normalX, int normalY, int normalZ, 00235 plint iX, plint iY, plint iZ ) 00236 { 00237 int orientation = normalZ; 00238 return -orientation * 00239 fd::o1_fwd_diff( field.get(iX,iY,iZ ), 00240 field.get(iX,iY,iZ-1*orientation) ); 00241 } 00242 00243 } // fdDataField 00244 00245 /* *************** PART I ******************************************** */ 00246 /* *************** Analysis of the block-lattice ********************* */ 00247 /* ******************************************************************* */ 00248 00249 /* *************** Reductive Data Functionals for BlockLattice ******* */ 00250 00251 template<typename T, template<typename U> class Descriptor> 00252 BoxSumRhoBarFunctional3D<T,Descriptor>::BoxSumRhoBarFunctional3D() 00253 : sumRhoBarId(this->getStatistics().subscribeSum()) 00254 { } 00255 00256 template<typename T, template<typename U> class Descriptor> 00257 void BoxSumRhoBarFunctional3D<T,Descriptor>::process ( 00258 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00259 { 00260 BlockStatistics& statistics = this->getStatistics(); 00261 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00262 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00263 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00264 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 00265 statistics.gatherSum ( 00266 sumRhoBarId, cell.getDynamics().computeRhoBar(cell) 00267 ); 00268 } 00269 } 00270 } 00271 } 00272 00273 template<typename T, template<typename U> class Descriptor> 00274 BoxSumRhoBarFunctional3D<T,Descriptor>* 00275 BoxSumRhoBarFunctional3D<T,Descriptor>::clone() const 00276 { 00277 return new BoxSumRhoBarFunctional3D(*this); 00278 } 00279 00280 template<typename T, template<typename U> class Descriptor> 00281 T BoxSumRhoBarFunctional3D<T,Descriptor>::getSumRhoBar() const { 00282 return this->getStatistics().getSum(sumRhoBarId); 00283 } 00284 00285 00286 template<typename T, template<typename U> class Descriptor> 00287 BoxSumEnergyFunctional3D<T,Descriptor>::BoxSumEnergyFunctional3D() 00288 : sumEnergyId(this->getStatistics().subscribeSum()) 00289 { } 00290 00291 template<typename T, template<typename U> class Descriptor> 00292 void BoxSumEnergyFunctional3D<T,Descriptor>::process ( 00293 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00294 { 00295 BlockStatistics& statistics = this->getStatistics(); 00296 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00297 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00298 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00299 Array<T,Descriptor<T>::d> velocity; 00300 lattice.get(iX,iY,iZ).computeVelocity(velocity); 00301 T uNormSqr = VectorTemplate<T,Descriptor>::normSqr(velocity); 00302 statistics.gatherSum(sumEnergyId, uNormSqr); 00303 } 00304 } 00305 } 00306 } 00307 00308 template<typename T, template<typename U> class Descriptor> 00309 BoxSumEnergyFunctional3D<T,Descriptor>* 00310 BoxSumEnergyFunctional3D<T,Descriptor>::clone() const 00311 { 00312 return new BoxSumEnergyFunctional3D(*this); 00313 } 00314 00315 template<typename T, template<typename U> class Descriptor> 00316 T BoxSumEnergyFunctional3D<T,Descriptor>::getSumEnergy() const { 00317 return this->getStatistics().getSum(sumEnergyId) / (T)2; 00318 } 00319 00320 template<typename T, template<typename U> class Descriptor> 00321 void BoxSumEnergyFunctional3D<T,Descriptor>::getDimensionsX(std::vector<int>& dimensions) const 00322 { 00323 dimensions.resize(1); 00324 dimensions[0] = 2; 00325 } 00326 00327 template<typename T, template<typename U> class Descriptor> 00328 void BoxSumEnergyFunctional3D<T,Descriptor>::getDimensionsT(std::vector<int>& dimensions) const 00329 { 00330 dimensions.resize(1); 00331 dimensions[0] = -2; 00332 } 00333 00334 00335 /* ******** DensitySingleProbe3D *********************************** */ 00336 00337 template<typename T, template<typename U> class Descriptor> 00338 DensitySingleProbe3D<T,Descriptor>::DensitySingleProbe3D ( 00339 std::vector<Array<T,3> > const& positions_ ) 00340 : positions(positions_) 00341 { 00342 densityIds.resize(positions.size()); 00343 for (pluint i=0; i<positions.size(); ++i) { 00344 densityIds[i] = this->getStatistics().subscribeSum(); 00345 } 00346 } 00347 00348 template<typename T, template<typename U> class Descriptor> 00349 void DensitySingleProbe3D<T,Descriptor>::process ( 00350 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00351 { 00352 std::vector<Dot3D> cellPos(8); 00353 std::vector<T> weights(8); 00354 T density; 00355 for (pluint i=0; i<positions.size(); ++i) { 00356 density=0.; 00357 Array<T,3> position(positions[i]); 00358 Dot3D referenceCellPos((plint)position[0], (plint)position[1], (plint)position[2]); 00359 referenceCellPos -= lattice.getLocation(); 00360 if (contained(referenceCellPos, domain)) { 00361 linearInterpolationCoefficients(lattice, position, cellPos, weights); 00362 for (plint iCell=0; iCell<8; ++iCell) { 00363 Cell<T,Descriptor> const& cell = lattice.get(cellPos[iCell].x,cellPos[iCell].y,cellPos[iCell].z); 00364 T cellDensity = cell.computeDensity(); 00365 density+=weights[iCell]*cellDensity; 00366 } 00367 } 00368 this->getStatistics().gatherSum(densityIds[i], density); 00369 } 00370 } 00371 00372 template<typename T, template<typename U> class Descriptor> 00373 DensitySingleProbe3D<T,Descriptor>* 00374 DensitySingleProbe3D<T,Descriptor>::clone() const 00375 { 00376 return new DensitySingleProbe3D<T,Descriptor>(*this); 00377 } 00378 00379 template<typename T, template<typename U> class Descriptor> 00380 std::vector<T> DensitySingleProbe3D<T,Descriptor>::getDensities() const { 00381 std::vector<T> densities(positions.size()); 00382 for (pluint i=0; i<positions.size(); ++i) { 00383 densities[i] = this->getStatistics().getSum(densityIds[i]); 00384 } 00385 return densities; 00386 } 00387 00388 00389 /* ******** VelocitySingleProbe3D *********************************** */ 00390 00391 template<typename T, template<typename U> class Descriptor> 00392 VelocitySingleProbe3D<T,Descriptor>::VelocitySingleProbe3D ( 00393 std::vector<Array<T,3> > const& positions_ ) 00394 : positions(positions_) 00395 { 00396 velIds.resize(positions.size()); 00397 for (pluint iVel=0; iVel<positions.size(); ++iVel) { 00398 velIds[iVel][0] = this->getStatistics().subscribeSum(); 00399 velIds[iVel][1] = this->getStatistics().subscribeSum(); 00400 velIds[iVel][2] = this->getStatistics().subscribeSum(); 00401 } 00402 } 00403 00404 template<typename T, template<typename U> class Descriptor> 00405 void VelocitySingleProbe3D<T,Descriptor>::process ( 00406 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00407 { 00408 std::vector<Dot3D> cellPos(8); 00409 std::vector<T> weights(8); 00410 Array<T,3> velocity; 00411 for (pluint iVel=0; iVel<positions.size(); ++iVel) { 00412 velocity.resetToZero(); 00413 Array<T,3> position(positions[iVel]); 00414 Dot3D referenceCellPos((plint)position[0], (plint)position[1], (plint)position[2]); 00415 referenceCellPos -= lattice.getLocation(); 00416 if (contained(referenceCellPos, domain)) { 00417 linearInterpolationCoefficients(lattice, position, cellPos, weights); 00418 for (plint iCell=0; iCell<8; ++iCell) { 00419 Cell<T,Descriptor> const& cell = lattice.get(cellPos[iCell].x,cellPos[iCell].y,cellPos[iCell].z); 00420 Array<T,3> cellVelocity; 00421 cell.computeVelocity(cellVelocity); 00422 velocity+=weights[iCell]*cellVelocity; 00423 } 00424 } 00425 this->getStatistics().gatherSum(velIds[iVel][0], velocity[0]); 00426 this->getStatistics().gatherSum(velIds[iVel][1], velocity[1]); 00427 this->getStatistics().gatherSum(velIds[iVel][2], velocity[2]); 00428 } 00429 } 00430 00431 template<typename T, template<typename U> class Descriptor> 00432 VelocitySingleProbe3D<T,Descriptor>* 00433 VelocitySingleProbe3D<T,Descriptor>::clone() const 00434 { 00435 return new VelocitySingleProbe3D<T,Descriptor>(*this); 00436 } 00437 00438 template<typename T, template<typename U> class Descriptor> 00439 std::vector<Array<T,3> > VelocitySingleProbe3D<T,Descriptor>::getVelocities() const { 00440 std::vector<Array<T,3> > velocities(positions.size()); 00441 for (pluint iVel=0; iVel<positions.size(); ++iVel) { 00442 velocities[iVel][0] = this->getStatistics().getSum(velIds[iVel][0]); 00443 velocities[iVel][1] = this->getStatistics().getSum(velIds[iVel][1]); 00444 velocities[iVel][2] = this->getStatistics().getSum(velIds[iVel][2]); 00445 } 00446 return velocities; 00447 } 00448 00449 00450 /* ******** VorticitySingleProbe3D *********************************** */ 00451 00452 template<typename T, template<typename U> class Descriptor> 00453 VorticitySingleProbe3D<T,Descriptor>::VorticitySingleProbe3D ( 00454 std::vector<Array<T,3> > const& positions_ ) 00455 : positions(positions_) 00456 { 00457 vorticityIds.resize(positions.size()); 00458 for (pluint iVel=0; iVel<positions.size(); ++iVel) { 00459 vorticityIds[iVel][0] = this->getStatistics().subscribeSum(); 00460 vorticityIds[iVel][1] = this->getStatistics().subscribeSum(); 00461 vorticityIds[iVel][2] = this->getStatistics().subscribeSum(); 00462 } 00463 } 00464 00465 template<typename T, template<typename U> class Descriptor> 00466 void VorticitySingleProbe3D<T,Descriptor>::process ( 00467 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00468 { 00469 Array<T,3> vorticity; 00470 for (pluint iVort=0; iVort<positions.size(); ++iVort) { 00471 vorticity.resetToZero(); 00472 Array<T,3> position(positions[iVort]); 00473 Dot3D referenceCellPos((plint)position[0], (plint)position[1], (plint)position[2]); 00474 referenceCellPos -= lattice.getLocation(); 00475 if (contained(referenceCellPos, domain)) { 00476 vorticity = fdLattice::firstOrderBulkVorticity(lattice, referenceCellPos.x, referenceCellPos.y, referenceCellPos.z); 00477 } 00478 this->getStatistics().gatherSum(vorticityIds[iVort][0], vorticity[0]); 00479 this->getStatistics().gatherSum(vorticityIds[iVort][1], vorticity[1]); 00480 this->getStatistics().gatherSum(vorticityIds[iVort][2], vorticity[2]); 00481 } 00482 } 00483 00484 template<typename T, template<typename U> class Descriptor> 00485 VorticitySingleProbe3D<T,Descriptor>* 00486 VorticitySingleProbe3D<T,Descriptor>::clone() const 00487 { 00488 return new VorticitySingleProbe3D<T,Descriptor>(*this); 00489 } 00490 00491 template<typename T, template<typename U> class Descriptor> 00492 std::vector<Array<T,3> > VorticitySingleProbe3D<T,Descriptor>::getVorticities() const { 00493 std::vector<Array<T,3> > vorticities(positions.size()); 00494 for (pluint iVort=0; iVort<positions.size(); ++iVort) { 00495 vorticities[iVort][0] = this->getStatistics().getSum(vorticityIds[iVort][0]); 00496 vorticities[iVort][1] = this->getStatistics().getSum(vorticityIds[iVort][1]); 00497 vorticities[iVort][2] = this->getStatistics().getSum(vorticityIds[iVort][2]); 00498 } 00499 return vorticities; 00500 } 00501 00502 00503 /* *************** Data Functionals for BlockLattice ***************** */ 00504 00505 template<typename T, template<typename U> class Descriptor> 00506 void CopyPopulationsFunctional3D<T,Descriptor>::process ( 00507 Box3D domain, BlockLattice3D<T,Descriptor>& latticeFrom, 00508 BlockLattice3D<T,Descriptor>& latticeTo ) 00509 { 00510 Dot3D offset = computeRelativeDisplacement(latticeFrom, latticeTo); 00511 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00512 plint ofX = iX + offset.x; 00513 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00514 plint ofY = iY + offset.y; 00515 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00516 latticeTo.get(ofX,ofY,iZ+offset.z). 00517 attributeValues(latticeFrom.get(iX,iY,iZ)); 00518 } 00519 } 00520 } 00521 } 00522 00523 template<typename T, template<typename U> class Descriptor> 00524 CopyPopulationsFunctional3D<T,Descriptor>* CopyPopulationsFunctional3D<T,Descriptor>::clone() const 00525 { 00526 return new CopyPopulationsFunctional3D<T,Descriptor>(*this); 00527 } 00528 00529 template<typename T, template<typename U> class Descriptor> 00530 void CopyPopulationsFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00531 modified[0] = modif::nothing; 00532 modified[1] = modif::staticVariables; 00533 } 00534 00535 template<typename T, template<typename U> class Descriptor> 00536 BlockDomain::DomainT CopyPopulationsFunctional3D<T,Descriptor>::appliesTo() const { 00537 return BlockDomain::bulkAndEnvelope; 00538 } 00539 00540 template<typename T1, template<typename U1> class Descriptor1, typename T2, template<typename U2> class Descriptor2> 00541 void CopyConvertPopulationsFunctional3D<T1,Descriptor1, T2,Descriptor2>::process ( 00542 Box3D domain, BlockLattice3D<T1,Descriptor1>& latticeFrom, 00543 BlockLattice3D<T2,Descriptor2>& latticeTo ) 00544 { 00545 Dot3D offset = computeRelativeDisplacement(latticeFrom, latticeTo); 00546 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00547 plint ofX = iX + offset.x; 00548 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00549 plint ofY = iY + offset.y; 00550 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00551 latticeTo.get(ofX,ofY,iZ+offset.z). 00552 attributeValues(latticeFrom.get(iX,iY,iZ)); 00553 } 00554 } 00555 } 00556 } 00557 00558 template<typename T1, template<typename U1> class Descriptor1, typename T2, template<typename U2> class Descriptor2> 00559 CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>* CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>::clone() const 00560 { 00561 return new CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>(*this); 00562 } 00563 00564 template<typename T1, template<typename U1> class Descriptor1, typename T2, template<typename U2> class Descriptor2> 00565 void CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00566 modified[0] = modif::nothing; 00567 modified[1] = modif::staticVariables; 00568 } 00569 00570 template<typename T1, template<typename U1> class Descriptor1, typename T2, template<typename U2> class Descriptor2> 00571 BlockDomain::DomainT CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>::appliesTo() const { 00572 return BlockDomain::bulkAndEnvelope; 00573 } 00574 00575 00576 template<typename T, template<typename U> class Descriptor> 00577 void LatticeCopyAllFunctional3D<T,Descriptor>::process ( 00578 Box3D domain, BlockLattice3D<T,Descriptor>& latticeFrom, 00579 BlockLattice3D<T,Descriptor>& latticeTo ) 00580 { 00581 std::vector<char> data; 00582 Dot3D offset = computeRelativeDisplacement(latticeFrom, latticeTo); 00583 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00584 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00585 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00586 Cell<T,Descriptor> const& fromCell = latticeFrom.get(iX,iY,iZ); 00587 Cell<T,Descriptor>& toCell = latticeTo.get(iX+offset.x,iY+offset.y,iZ+offset.z); 00588 toCell.attributeValues(fromCell); 00589 00590 data.clear(); 00591 HierarchicSerializer serializer(data, fromCell.getDynamics().getId()); 00592 fromCell.getDynamics().serialize(serializer); 00593 00594 HierarchicUnserializer unSerializer(data, 0); 00595 toCell.getDynamics().unserialize(unSerializer); 00596 } 00597 } 00598 } 00599 } 00600 00601 template<typename T, template<typename U> class Descriptor> 00602 LatticeCopyAllFunctional3D<T,Descriptor>* LatticeCopyAllFunctional3D<T,Descriptor>::clone() const 00603 { 00604 return new LatticeCopyAllFunctional3D<T,Descriptor>(*this); 00605 } 00606 00607 template<typename T, template<typename U> class Descriptor> 00608 void LatticeCopyAllFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00609 modified[0] = modif::nothing; 00610 modified[1] = modif::staticVariables; 00611 } 00612 00613 template<typename T, template<typename U> class Descriptor> 00614 BlockDomain::DomainT LatticeCopyAllFunctional3D<T,Descriptor>::appliesTo() const { 00615 return BlockDomain::bulkAndEnvelope; 00616 } 00617 00618 00619 00620 template<typename T, template<typename U> class Descriptor> 00621 void LatticeRegenerateFunctional3D<T,Descriptor>::process ( 00622 Box3D domain, BlockLattice3D<T,Descriptor>& latticeFrom, 00623 BlockLattice3D<T,Descriptor>& latticeTo ) 00624 { 00625 Dot3D offset = computeRelativeDisplacement(latticeFrom, latticeTo); 00626 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00627 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00628 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00629 latticeTo.get(iX+offset.x,iY+offset.y,iZ+offset.z).attributeValues(latticeFrom.get(iX,iY,iZ)); 00630 latticeTo.attributeDynamics(iX+offset.x,iY+offset.y,iZ+offset.z, 00631 latticeFrom.get(iX,iY,iZ).getDynamics().clone()); 00632 latticeTo.get(iX+offset.x,iY+offset.y,iZ+offset.z). 00633 attributeValues(latticeFrom.get(iX,iY,iZ)); 00634 } 00635 } 00636 } 00637 } 00638 00639 template<typename T, template<typename U> class Descriptor> 00640 LatticeRegenerateFunctional3D<T,Descriptor>* LatticeRegenerateFunctional3D<T,Descriptor>::clone() const 00641 { 00642 return new LatticeRegenerateFunctional3D<T,Descriptor>(*this); 00643 } 00644 00645 template<typename T, template<typename U> class Descriptor> 00646 void LatticeRegenerateFunctional3D<T,Descriptor>::getTypeOfModification ( 00647 std::vector<modif::ModifT>& modified ) const 00648 { 00649 modified[0] = modif::nothing; 00650 // Full dynamics object must be recreated, because this data processor 00651 // re-attributes a new dynamics and acts on the bulk only. 00652 modified[1] = modif::dataStructure; 00653 } 00654 00655 template<typename T, template<typename U> class Descriptor> 00656 void BoxDensityFunctional3D<T,Descriptor>::process ( 00657 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00658 { 00659 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00660 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00661 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00662 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00663 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) 00664 = lattice.get(iX,iY,iZ).computeDensity(); 00665 } 00666 } 00667 } 00668 } 00669 00670 template<typename T, template<typename U> class Descriptor> 00671 BoxDensityFunctional3D<T,Descriptor>* BoxDensityFunctional3D<T,Descriptor>::clone() const 00672 { 00673 return new BoxDensityFunctional3D<T,Descriptor>(*this); 00674 } 00675 00676 template<typename T, template<typename U> class Descriptor> 00677 void BoxDensityFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00678 modified[0] = modif::nothing; 00679 modified[1] = modif::staticVariables; 00680 } 00681 00682 template<typename T, template<typename U> class Descriptor> 00683 BlockDomain::DomainT BoxDensityFunctional3D<T,Descriptor>::appliesTo() const { 00684 return BlockDomain::bulkAndEnvelope; 00685 } 00686 00687 00688 template<typename T, template<typename U> class Descriptor> 00689 void BoxRhoBarFunctional3D<T,Descriptor>::process ( 00690 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00691 { 00692 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00693 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00694 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00695 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00696 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 00697 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) 00698 = cell.getDynamics().computeRhoBar(cell); 00699 } 00700 } 00701 } 00702 } 00703 00704 template<typename T, template<typename U> class Descriptor> 00705 BoxRhoBarFunctional3D<T,Descriptor>* BoxRhoBarFunctional3D<T,Descriptor>::clone() const 00706 { 00707 return new BoxRhoBarFunctional3D<T,Descriptor>(*this); 00708 } 00709 00710 template<typename T, template<typename U> class Descriptor> 00711 void BoxRhoBarFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00712 modified[0] = modif::nothing; 00713 modified[1] = modif::staticVariables; 00714 } 00715 00716 template<typename T, template<typename U> class Descriptor> 00717 BlockDomain::DomainT BoxRhoBarFunctional3D<T,Descriptor>::appliesTo() const { 00718 return BlockDomain::bulkAndEnvelope; 00719 } 00720 00721 00722 template<typename T, template<typename U> class Descriptor> 00723 void BoxRhoBarJfunctional3D<T,Descriptor>::processGenericBlocks ( 00724 Box3D domain, std::vector<AtomicBlock3D*> fields ) 00725 { 00726 BlockLattice3D<T,Descriptor>& lattice = *dynamic_cast<BlockLattice3D<T,Descriptor>*>(fields[0]); 00727 ScalarField3D<T>& rhoBarField = *dynamic_cast<ScalarField3D<T>*>(fields[1]); 00728 TensorField3D<T,3>& jField = *dynamic_cast<TensorField3D<T,3>*>(fields[2]); 00729 Dot3D offset1 = computeRelativeDisplacement(lattice, rhoBarField); 00730 Dot3D offset2 = computeRelativeDisplacement(lattice, jField); 00731 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00732 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00733 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00734 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 00735 momentTemplates<T,Descriptor>::get_rhoBar_j ( 00736 cell, 00737 rhoBarField.get(iX+offset1.x,iY+offset1.y,iZ+offset1.z), 00738 jField.get(iX+offset2.x,iY+offset2.y,iZ+offset2.z) ); 00739 } 00740 } 00741 } 00742 } 00743 00744 template<typename T, template<typename U> class Descriptor> 00745 BoxRhoBarJfunctional3D<T,Descriptor>* BoxRhoBarJfunctional3D<T,Descriptor>::clone() const 00746 { 00747 return new BoxRhoBarJfunctional3D<T,Descriptor>(*this); 00748 } 00749 00750 template<typename T, template<typename U> class Descriptor> 00751 void BoxRhoBarJfunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00752 modified[0] = modif::nothing; // lattice 00753 modified[1] = modif::staticVariables; // rhoBar 00754 modified[2] = modif::staticVariables; // j 00755 } 00756 00757 template<typename T, template<typename U> class Descriptor> 00758 void PackedRhoBarJfunctional3D<T,Descriptor>::process ( 00759 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, 00760 NTensorField3D<T>& rhoBarJField ) 00761 { 00762 Dot3D offset = computeRelativeDisplacement(lattice, rhoBarJField); 00763 T rhoBar; 00764 Array<T,3> j; 00765 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00766 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00767 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00768 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 00769 momentTemplates<T,Descriptor>::get_rhoBar_j(cell, rhoBar, j); 00770 T* rhoBarJ = rhoBarJField.get(iX+offset.x,iY+offset.y,iZ+offset.z); 00771 *rhoBarJ = rhoBar; 00772 j.to_cArray(rhoBarJ+1); 00773 } 00774 } 00775 } 00776 } 00777 00778 template<typename T, template<typename U> class Descriptor> 00779 PackedRhoBarJfunctional3D<T,Descriptor>* PackedRhoBarJfunctional3D<T,Descriptor>::clone() const 00780 { 00781 return new PackedRhoBarJfunctional3D<T,Descriptor>(*this); 00782 } 00783 00784 template<typename T, template<typename U> class Descriptor> 00785 void PackedRhoBarJfunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00786 modified[0] = modif::nothing; // lattice 00787 modified[1] = modif::staticVariables; // rhoBarJ 00788 } 00789 00790 00791 template<typename T, template<typename U> class Descriptor> 00792 void BoxKineticEnergyFunctional3D<T,Descriptor>::process ( 00793 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00794 { 00795 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00796 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00797 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00798 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00799 Array<T,Descriptor<T>::d> velocity; 00800 lattice.get(iX,iY,iZ).computeVelocity(velocity); 00801 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) 00802 = VectorTemplate<T,Descriptor>::normSqr(velocity) / (T)2; 00803 } 00804 } 00805 } 00806 } 00807 00808 template<typename T, template<typename U> class Descriptor> 00809 BoxKineticEnergyFunctional3D<T,Descriptor>* BoxKineticEnergyFunctional3D<T,Descriptor>::clone() const 00810 { 00811 return new BoxKineticEnergyFunctional3D<T,Descriptor>(*this); 00812 } 00813 00814 template<typename T, template<typename U> class Descriptor> 00815 void BoxKineticEnergyFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00816 modified[0] = modif::nothing; 00817 modified[1] = modif::staticVariables; 00818 } 00819 00820 template<typename T, template<typename U> class Descriptor> 00821 BlockDomain::DomainT BoxKineticEnergyFunctional3D<T,Descriptor>::appliesTo() const { 00822 return BlockDomain::bulkAndEnvelope; 00823 } 00824 00825 00826 00827 template<typename T, template<typename U> class Descriptor> 00828 void BoxVelocityNormFunctional3D<T,Descriptor>::process ( 00829 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00830 { 00831 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00832 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00833 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00834 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00835 Array<T,Descriptor<T>::d> velocity; 00836 lattice.get(iX,iY,iZ).computeVelocity(velocity); 00837 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) 00838 = sqrt( VectorTemplate<T,Descriptor>::normSqr(velocity) ); 00839 } 00840 } 00841 } 00842 } 00843 00844 template<typename T, template<typename U> class Descriptor> 00845 BoxVelocityNormFunctional3D<T,Descriptor>* BoxVelocityNormFunctional3D<T,Descriptor>::clone() const 00846 { 00847 return new BoxVelocityNormFunctional3D<T,Descriptor>(*this); 00848 } 00849 00850 template<typename T, template<typename U> class Descriptor> 00851 void BoxVelocityNormFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00852 modified[0] = modif::nothing; 00853 modified[1] = modif::staticVariables; 00854 } 00855 00856 template<typename T, template<typename U> class Descriptor> 00857 BlockDomain::DomainT BoxVelocityNormFunctional3D<T,Descriptor>::appliesTo() const { 00858 return BlockDomain::bulkAndEnvelope; 00859 } 00860 00861 template<typename T, template<typename U> class Descriptor> 00862 BoxVelocityComponentFunctional3D<T,Descriptor>::BoxVelocityComponentFunctional3D(int iComponent_) 00863 : iComponent(iComponent_) 00864 { } 00865 00866 template<typename T, template<typename U> class Descriptor> 00867 void BoxVelocityComponentFunctional3D<T,Descriptor>::process ( 00868 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00869 { 00870 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00871 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00872 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00873 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00874 Array<T,Descriptor<T>::d> velocity; 00875 lattice.get(iX,iY,iZ).computeVelocity(velocity); 00876 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) = velocity[iComponent]; 00877 } 00878 } 00879 } 00880 } 00881 00882 template<typename T, template<typename U> class Descriptor> 00883 BoxVelocityComponentFunctional3D<T,Descriptor>* BoxVelocityComponentFunctional3D<T,Descriptor>::clone() const 00884 { 00885 return new BoxVelocityComponentFunctional3D<T,Descriptor>(*this); 00886 } 00887 00888 template<typename T, template<typename U> class Descriptor> 00889 void BoxVelocityComponentFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00890 modified[0] = modif::nothing; 00891 modified[1] = modif::staticVariables; 00892 } 00893 00894 template<typename T, template<typename U> class Descriptor> 00895 BlockDomain::DomainT BoxVelocityComponentFunctional3D<T,Descriptor>::appliesTo() const { 00896 return BlockDomain::bulkAndEnvelope; 00897 } 00898 00899 00900 template<typename T, template<typename U> class Descriptor> 00901 void BoxVelocityFunctional3D<T,Descriptor>::process ( 00902 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, TensorField3D<T,Descriptor<T>::d>& tensorField) 00903 { 00904 Dot3D offset = computeRelativeDisplacement(lattice, tensorField); 00905 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00906 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00907 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00908 lattice.get(iX,iY,iZ).computeVelocity ( 00909 tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z) ); 00910 } 00911 } 00912 } 00913 } 00914 00915 template<typename T, template<typename U> class Descriptor> 00916 BoxVelocityFunctional3D<T,Descriptor>* BoxVelocityFunctional3D<T,Descriptor>::clone() const 00917 { 00918 return new BoxVelocityFunctional3D<T,Descriptor>(*this); 00919 } 00920 00921 template<typename T, template<typename U> class Descriptor> 00922 void BoxVelocityFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00923 modified[0] = modif::nothing; 00924 modified[1] = modif::staticVariables; 00925 } 00926 00927 00928 template<typename T, template<typename U> class Descriptor> 00929 BlockDomain::DomainT BoxVelocityFunctional3D<T,Descriptor>::appliesTo() const { 00930 return BlockDomain::bulkAndEnvelope; 00931 } 00932 00933 00934 template<typename T, template<typename U> class Descriptor> 00935 void BoxTemperatureFunctional3D<T,Descriptor>::process ( 00936 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 00937 { 00938 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 00939 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00940 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00941 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00942 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) 00943 = lattice.get(iX,iY,iZ).computeTemperature(); 00944 } 00945 } 00946 } 00947 } 00948 00949 template<typename T, template<typename U> class Descriptor> 00950 BoxTemperatureFunctional3D<T,Descriptor>* BoxTemperatureFunctional3D<T,Descriptor>::clone() const 00951 { 00952 return new BoxTemperatureFunctional3D<T,Descriptor>(*this); 00953 } 00954 00955 template<typename T, template<typename U> class Descriptor> 00956 void BoxTemperatureFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00957 modified[0] = modif::nothing; 00958 modified[1] = modif::staticVariables; 00959 } 00960 00961 template<typename T, template<typename U> class Descriptor> 00962 BlockDomain::DomainT BoxTemperatureFunctional3D<T,Descriptor>::appliesTo() const { 00963 return BlockDomain::bulkAndEnvelope; 00964 } 00965 00966 00967 template<typename T, template<typename U> class Descriptor> 00968 void BoxDeviatoricStressFunctional3D<T,Descriptor>::process ( 00969 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, 00970 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) 00971 { 00972 Dot3D offset = computeRelativeDisplacement(lattice, PiNeq); 00973 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00974 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00975 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00976 lattice.get(iX,iY,iZ).computeDeviatoricStress ( 00977 PiNeq.get(iX+offset.x,iY+offset.y,iZ+offset.z) ); 00978 } 00979 } 00980 } 00981 } 00982 00983 template<typename T, template<typename U> class Descriptor> 00984 BoxDeviatoricStressFunctional3D<T,Descriptor>* BoxDeviatoricStressFunctional3D<T,Descriptor>::clone() const 00985 { 00986 return new BoxDeviatoricStressFunctional3D<T,Descriptor>(*this); 00987 } 00988 00989 template<typename T, template<typename U> class Descriptor> 00990 void BoxDeviatoricStressFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00991 modified[0] = modif::nothing; 00992 modified[1] = modif::staticVariables; 00993 } 00994 00995 template<typename T, template<typename U> class Descriptor> 00996 BlockDomain::DomainT BoxDeviatoricStressFunctional3D<T,Descriptor>::appliesTo() const { 00997 return BlockDomain::bulkAndEnvelope; 00998 } 00999 01000 01001 template<typename T, template<typename U> class Descriptor> 01002 void BoxStrainRateFromStressFunctional3D<T,Descriptor>::process ( 01003 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, 01004 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>& S ) 01005 { 01006 Dot3D offset = computeRelativeDisplacement(lattice, S); 01007 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01008 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01009 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01010 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 01011 Array<T,SymmetricTensor<T,Descriptor>::n>& element 01012 = S.get(iX+offset.x,iY+offset.y,iZ+offset.z); 01013 cell.computeDeviatoricStress(element); 01014 T omega = cell.getDynamics().getOmega(); 01015 T rhoBar = cell.getDynamics().computeRhoBar(cell); 01016 T prefactor = - omega * Descriptor<T>::invCs2 * 01017 Descriptor<T>::invRho(rhoBar) / (T)2; 01018 for (int iTensor=0; iTensor<SymmetricTensor<T,Descriptor>::n; ++iTensor) { 01019 element[iTensor] *= prefactor; 01020 } 01021 } 01022 } 01023 } 01024 } 01025 01026 template<typename T, template<typename U> class Descriptor> 01027 BoxStrainRateFromStressFunctional3D<T,Descriptor>* BoxStrainRateFromStressFunctional3D<T,Descriptor>::clone() const 01028 { 01029 return new BoxStrainRateFromStressFunctional3D<T,Descriptor>(*this); 01030 } 01031 01032 template<typename T, template<typename U> class Descriptor> 01033 void BoxStrainRateFromStressFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01034 modified[0] = modif::nothing; 01035 modified[1] = modif::staticVariables; 01036 } 01037 01038 template<typename T, template<typename U> class Descriptor> 01039 BlockDomain::DomainT BoxStrainRateFromStressFunctional3D<T,Descriptor>::appliesTo() const { 01040 return BlockDomain::bulkAndEnvelope; 01041 } 01042 01043 template<typename T> 01044 void BoxQcriterionFunctional3D<T>::processGenericBlocks(Box3D domain, std::vector<AtomicBlock3D*> fields) { 01045 TensorField3D<T,3>& vorticity = *dynamic_cast<TensorField3D<T,3>*>(fields[0]); 01046 TensorField3D<T,6>& strain = *dynamic_cast<TensorField3D<T,6>*>(fields[1]); 01047 ScalarField3D<T>& qCriterion = *dynamic_cast<ScalarField3D<T>*>(fields[2]); 01048 Dot3D offset1 = computeRelativeDisplacement(vorticity, strain); 01049 Dot3D offset2 = computeRelativeDisplacement(vorticity, qCriterion); 01050 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01051 plint oX1 = iX + offset1.x; 01052 plint oX2 = iX + offset2.x; 01053 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01054 plint oY1 = iY + offset1.y; 01055 plint oY2 = iY + offset2.y; 01056 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01057 plint oZ1 = iZ + offset1.z; 01058 plint oZ2 = iZ + offset2.z; 01059 01060 T vortNorm = VectorTemplateImpl<T,3>::normSqr(vorticity.get(iX,iY,iZ)); 01061 T normStrain = SymmetricTensorImpl<T,3>::tensorNormSqr(strain.get(oX1,oY1,oZ1)); 01062 01063 qCriterion.get(oX2,oY2,oZ2) = (vortNorm-(T)2*normStrain)/(T)4; 01064 } 01065 } 01066 } 01067 } 01068 01069 template<typename T> 01070 BoxQcriterionFunctional3D<T>* BoxQcriterionFunctional3D<T>::clone() const { 01071 return new BoxQcriterionFunctional3D<T>(*this); 01072 } 01073 01074 template<typename T> 01075 void BoxQcriterionFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01076 modified[0] = modif::nothing; 01077 modified[1] = modif::nothing; 01078 modified[2] = modif::staticVariables; 01079 } 01080 01081 template<typename T> 01082 BlockDomain::DomainT BoxQcriterionFunctional3D<T>::appliesTo() const { 01083 return BlockDomain::bulkAndEnvelope; 01084 } 01085 01086 01087 template<typename T, template<typename U> class Descriptor> 01088 BoxPopulationFunctional3D<T,Descriptor>::BoxPopulationFunctional3D(plint iComponent_) 01089 : iComponent(iComponent_) 01090 { } 01091 01092 template<typename T, template<typename U> class Descriptor> 01093 void BoxPopulationFunctional3D<T,Descriptor>::process ( 01094 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 01095 { 01096 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 01097 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01098 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01099 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01100 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) = lattice.get(iX,iY,iZ)[iComponent]; 01101 } 01102 } 01103 } 01104 } 01105 01106 template<typename T, template<typename U> class Descriptor> 01107 BoxPopulationFunctional3D<T,Descriptor>* BoxPopulationFunctional3D<T,Descriptor>::clone() const 01108 { 01109 return new BoxPopulationFunctional3D<T,Descriptor>(*this); 01110 } 01111 01112 template<typename T, template<typename U> class Descriptor> 01113 void BoxPopulationFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01114 modified[0] = modif::nothing; 01115 modified[1] = modif::staticVariables; 01116 } 01117 01118 template<typename T, template<typename U> class Descriptor> 01119 BlockDomain::DomainT BoxPopulationFunctional3D<T,Descriptor>::appliesTo() const { 01120 return BlockDomain::bulkAndEnvelope; 01121 } 01122 01123 01124 template<typename T, template<typename U> class Descriptor> 01125 BoxEquilibriumFunctional3D<T,Descriptor>::BoxEquilibriumFunctional3D(plint iComponent_) 01126 : iComponent(iComponent_) 01127 { } 01128 01129 template<typename T, template<typename U> class Descriptor> 01130 void BoxEquilibriumFunctional3D<T,Descriptor>::process ( 01131 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& equilibrium) 01132 { 01133 Dot3D offset = computeRelativeDisplacement(lattice, equilibrium); 01134 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01135 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01136 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01137 T rhoBar; 01138 Array<T,Descriptor<T>::d> j; 01139 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 01140 cell.getDynamics().computeRhoBarJ(cell, rhoBar, j); 01141 T jSqr = normSqr(j); 01142 equilibrium.get(iX+offset.x,iY+offset.y,iZ+offset.z) = 01143 cell.computeEquilibrium(iComponent, rhoBar, j, jSqr); 01144 } 01145 } 01146 } 01147 } 01148 01149 template<typename T, template<typename U> class Descriptor> 01150 BoxEquilibriumFunctional3D<T,Descriptor>* BoxEquilibriumFunctional3D<T,Descriptor>::clone() const 01151 { 01152 return new BoxEquilibriumFunctional3D<T,Descriptor>(*this); 01153 } 01154 01155 template<typename T, template<typename U> class Descriptor> 01156 void BoxEquilibriumFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01157 modified[0] = modif::nothing; 01158 modified[1] = modif::staticVariables; 01159 } 01160 01161 template<typename T, template<typename U> class Descriptor> 01162 BlockDomain::DomainT BoxEquilibriumFunctional3D<T,Descriptor>::appliesTo() const { 01163 return BlockDomain::bulkAndEnvelope; 01164 } 01165 01166 01167 template<typename T, template<typename U> class Descriptor> 01168 BoxAllPopulationsFunctional3D<T,Descriptor>::BoxAllPopulationsFunctional3D() 01169 { } 01170 01171 template<typename T, template<typename U> class Descriptor> 01172 void BoxAllPopulationsFunctional3D<T,Descriptor>::process ( 01173 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, TensorField3D<T,Descriptor<T>::q>& tensorField) 01174 { 01175 Dot3D offset = computeRelativeDisplacement(lattice, tensorField); 01176 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01177 plint oX = iX+offset.x; 01178 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01179 plint oY = iY+offset.y; 01180 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01181 for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) { 01182 tensorField.get(oX,oY,iZ+offset.z)[iPop] = lattice.get(iX,iY,iZ)[iPop]; 01183 } 01184 } 01185 } 01186 } 01187 } 01188 01189 template<typename T, template<typename U> class Descriptor> 01190 BoxAllPopulationsFunctional3D<T,Descriptor>* BoxAllPopulationsFunctional3D<T,Descriptor>::clone() const 01191 { 01192 return new BoxAllPopulationsFunctional3D<T,Descriptor>(*this); 01193 } 01194 01195 template<typename T, template<typename U> class Descriptor> 01196 void BoxAllPopulationsFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01197 modified[0] = modif::nothing; 01198 modified[1] = modif::staticVariables; 01199 } 01200 01201 template<typename T, template<typename U> class Descriptor> 01202 BlockDomain::DomainT BoxAllPopulationsFunctional3D<T,Descriptor>::appliesTo() const { 01203 return BlockDomain::bulkAndEnvelope; 01204 } 01205 01206 template<typename T, template<typename U> class Descriptor> 01207 BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>::BoxAllPopulationsToLatticeFunctional3D() 01208 { } 01209 01210 template<typename T, template<typename U> class Descriptor> 01211 void BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>::process ( 01212 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, TensorField3D<T,Descriptor<T>::q>& tensorField) 01213 { 01214 Dot3D offset = computeRelativeDisplacement(lattice, tensorField); 01215 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01216 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01217 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01218 for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) { 01219 lattice.get(iX,iY,iZ)[iPop] = tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z)[iPop]; 01220 } 01221 } 01222 } 01223 } 01224 } 01225 01226 template<typename T, template<typename U> class Descriptor> 01227 BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>* BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>::clone() const 01228 { 01229 return new BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>(*this); 01230 } 01231 01232 template<typename T, template<typename U> class Descriptor> 01233 void BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01234 modified[0] = modif::staticVariables; 01235 modified[1] = modif::nothing; 01236 } 01237 01238 template<typename T, template<typename U> class Descriptor> 01239 BlockDomain::DomainT BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>::appliesTo() const { 01240 return BlockDomain::bulkAndEnvelope; 01241 } 01242 01243 template<typename T, template<typename U> class Descriptor> 01244 void BoxOmegaFunctional3D<T,Descriptor>::process ( 01245 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& scalarField) 01246 { 01247 Dot3D offset = computeRelativeDisplacement(lattice, scalarField); 01248 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01249 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01250 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01251 Cell<T,Descriptor> const& cell = lattice.get(iX,iY,iZ); 01252 scalarField.get(iX+offset.x,iY+offset.y,iZ+offset.z) = cell.getDynamics().getOmega(); 01253 } 01254 } 01255 } 01256 } 01257 01258 template<typename T, template<typename U> class Descriptor> 01259 BoxOmegaFunctional3D<T,Descriptor>* BoxOmegaFunctional3D<T,Descriptor>::clone() const 01260 { 01261 return new BoxOmegaFunctional3D<T,Descriptor>(*this); 01262 } 01263 01264 template<typename T, template<typename U> class Descriptor> 01265 void BoxOmegaFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01266 modified[0] = modif::nothing; 01267 modified[1] = modif::staticVariables; 01268 } 01269 01270 template<typename T, template<typename U> class Descriptor> 01271 BlockDomain::DomainT BoxOmegaFunctional3D<T,Descriptor>::appliesTo() const { 01272 return BlockDomain::bulkAndEnvelope; 01273 } 01274 01275 /* *************** PART II ******************************************* */ 01276 /* *************** Analysis of the scalar-field ********************** */ 01277 /* ******************************************************************* */ 01278 01279 /* *************** Reductive Data Functionals for scalar-field ******* */ 01280 01281 template<typename T> 01282 BoxScalarSumFunctional3D<T>::BoxScalarSumFunctional3D() 01283 : sumScalarId(this->getStatistics().subscribeSum()) 01284 { } 01285 01286 template<typename T> 01287 void BoxScalarSumFunctional3D<T>::process ( 01288 Box3D domain, ScalarField3D<T>& scalarField ) 01289 { 01290 BlockStatistics& statistics = this->getStatistics(); 01291 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01292 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01293 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01294 statistics.gatherSum(sumScalarId, (double)scalarField.get(iX,iY,iZ)); 01295 } 01296 } 01297 } 01298 } 01299 01300 template<typename T> 01301 BoxScalarSumFunctional3D<T>* BoxScalarSumFunctional3D<T>::clone() const 01302 { 01303 return new BoxScalarSumFunctional3D<T>(*this); 01304 } 01305 01306 template<typename T> 01307 T BoxScalarSumFunctional3D<T>::getSumScalar() const { 01308 double doubleSum = this->getStatistics().getSum(sumScalarId); 01309 // The sum is internally computed on floating-point values. If T is 01310 // integer, the value must be rounded at the end. 01311 if (std::numeric_limits<T>::is_integer) { 01312 return (T) util::roundToInt(doubleSum); 01313 } 01314 return (T) doubleSum; 01315 } 01316 01317 01318 template<typename T> 01319 MaskedBoxScalarAverageFunctional3D<T>::MaskedBoxScalarAverageFunctional3D(int flag_) 01320 : averageScalarId(this->getStatistics().subscribeAverage()), 01321 flag(flag_) 01322 { } 01323 01324 template<typename T> 01325 void MaskedBoxScalarAverageFunctional3D<T>::process ( 01326 Box3D domain, 01327 ScalarField3D<T>& scalarField, 01328 ScalarField3D<int>& mask ) 01329 { 01330 Dot3D offset = computeRelativeDisplacement(scalarField, mask); 01331 BlockStatistics& statistics = this->getStatistics(); 01332 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01333 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01334 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01335 if (mask.get(iX+offset.x, iY+offset.y, iZ+offset.z)==flag) { 01336 statistics.gatherAverage(averageScalarId, (double)scalarField.get(iX,iY,iZ)); 01337 statistics.incrementStats(); 01338 } 01339 } 01340 } 01341 } 01342 } 01343 01344 template<typename T> 01345 MaskedBoxScalarAverageFunctional3D<T>* MaskedBoxScalarAverageFunctional3D<T>::clone() const 01346 { 01347 return new MaskedBoxScalarAverageFunctional3D<T>(*this); 01348 } 01349 01350 template<typename T> 01351 T MaskedBoxScalarAverageFunctional3D<T>::getAverageScalar() const { 01352 double doubleAverage = this->getStatistics().getAverage(averageScalarId); 01353 // The average is internally computed on floating-point values. If T is 01354 // integer, the value must be rounded at the end. 01355 if (std::numeric_limits<T>::is_integer) { 01356 return (T) util::roundToInt(doubleAverage); 01357 } 01358 return (T) doubleAverage; 01359 } 01360 01361 01362 template<typename T> 01363 BoxScalarMinFunctional3D<T>::BoxScalarMinFunctional3D() 01364 : maxScalarId(this->getStatistics().subscribeMax()) 01365 { } 01366 01367 template<typename T> 01368 void BoxScalarMinFunctional3D<T>::process ( 01369 Box3D domain, ScalarField3D<T>& scalarField ) 01370 { 01371 BlockStatistics& statistics = this->getStatistics(); 01372 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01373 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01374 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01375 // BlockStatistics computes only maximum, no minimum. Therefore, 01376 // the relation min(x) = -max(-x) is used. 01377 statistics.gatherMax(maxScalarId, -(double)scalarField.get(iX,iY,iZ)); 01378 } 01379 } 01380 } 01381 } 01382 01383 template<typename T> 01384 BoxScalarMinFunctional3D<T>* BoxScalarMinFunctional3D<T>::clone() const 01385 { 01386 return new BoxScalarMinFunctional3D<T>(*this); 01387 } 01388 01389 template<typename T> 01390 T BoxScalarMinFunctional3D<T>::getMinScalar() const { 01391 // The minus sign accounts for the relation min(x) = -max(-x). 01392 // The sum is internally computed on floating-point values. If T is 01393 // integer, the value must be rounded at the end. 01394 double doubleMin = - this->getStatistics().getMax(maxScalarId); 01395 if (std::numeric_limits<T>::is_integer) { 01396 return (T) util::roundToInt(doubleMin); 01397 } 01398 return (T) doubleMin; 01399 } 01400 01401 01402 template<typename T> 01403 BoxScalarMaxFunctional3D<T>::BoxScalarMaxFunctional3D() 01404 : maxScalarId(this->getStatistics().subscribeMax()) 01405 { } 01406 01407 template<typename T> 01408 void BoxScalarMaxFunctional3D<T>::process ( 01409 Box3D domain, ScalarField3D<T>& scalarField ) 01410 { 01411 BlockStatistics& statistics = this->getStatistics(); 01412 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01413 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01414 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01415 statistics.gatherMax(maxScalarId, (double)scalarField.get(iX,iY,iZ)); 01416 } 01417 } 01418 } 01419 } 01420 01421 template<typename T> 01422 BoxScalarMaxFunctional3D<T>* BoxScalarMaxFunctional3D<T>::clone() const 01423 { 01424 return new BoxScalarMaxFunctional3D<T>(*this); 01425 } 01426 01427 template<typename T> 01428 T BoxScalarMaxFunctional3D<T>::getMaxScalar() const { 01429 // The sum is internally computed on floating-point values. If T is 01430 // integer, the value must be rounded at the end. 01431 double doubleMax = this->getStatistics().getMax(maxScalarId); 01432 if (std::numeric_limits<T>::is_integer) { 01433 return (T) util::roundToInt(doubleMax); 01434 } 01435 return (T) doubleMax; 01436 } 01437 01438 01439 template<typename T> 01440 BoundedBoxScalarSumFunctional3D<T>::BoundedBoxScalarSumFunctional3D() 01441 : sumScalarId(this->getStatistics().subscribeSum()) 01442 { } 01443 01444 template<typename T> 01445 void BoundedBoxScalarSumFunctional3D<T>::processBulk ( 01446 Box3D domain, ScalarField3D<T>& scalarField ) 01447 { 01448 BlockStatistics& statistics = this->getStatistics(); 01449 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01450 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01451 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01452 statistics.gatherSum(sumScalarId, (double)scalarField.get(iX,iY,iZ)); 01453 } 01454 } 01455 } 01456 } 01457 01458 template<typename T> 01459 void BoundedBoxScalarSumFunctional3D<T>::processPlane ( 01460 int direction, int orientation, 01461 Box3D domain, ScalarField3D<T>& scalarField ) 01462 { 01463 BlockStatistics& statistics = this->getStatistics(); 01464 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01465 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01466 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01467 // Plane boundary nodes have a weight of 0.5, because only 50% of the 01468 // cell centered at the node is inside the computational domain. 01469 statistics.gatherSum(sumScalarId, (double)scalarField.get(iX,iY,iZ) / 2.); 01470 } 01471 } 01472 } 01473 } 01474 01475 template<typename T> 01476 void BoundedBoxScalarSumFunctional3D<T>::processEdge ( 01477 int plane, int normal1, int normal2, 01478 Box3D domain, ScalarField3D<T>& scalarField ) 01479 { 01480 BlockStatistics& statistics = this->getStatistics(); 01481 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01482 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01483 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01484 // Edge nodes have a weight of 0.25, because only 25% of the 01485 // cell centered at the node is inside the computational domain. 01486 statistics.gatherSum(sumScalarId, (double)scalarField.get(iX,iY,iZ) / 4.); 01487 } 01488 } 01489 } 01490 } 01491 01492 template<typename T> 01493 void BoundedBoxScalarSumFunctional3D<T>::processCorner ( 01494 int normalX, int normalY, int normalZ, 01495 Box3D domain, ScalarField3D<T>& scalarField ) 01496 { 01497 BlockStatistics& statistics = this->getStatistics(); 01498 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01499 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01500 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01501 // Corner nodes have a weight of 0.125, because only 1/8 of the 01502 // cell centered at the node is inside the computational domain. 01503 statistics.gatherSum(sumScalarId, (double)scalarField.get(iX,iY,iZ) / 8.); 01504 } 01505 } 01506 } 01507 } 01508 01509 template<typename T> 01510 BoundedBoxScalarSumFunctional3D<T>* BoundedBoxScalarSumFunctional3D<T>::clone() const 01511 { 01512 return new BoundedBoxScalarSumFunctional3D<T>(*this); 01513 } 01514 01515 template<typename T> 01516 T BoundedBoxScalarSumFunctional3D<T>::getSumScalar() const { 01517 double doubleSum = this->getStatistics().getSum(sumScalarId); 01518 // The sum is internally computed on floating-point values. If T is 01519 // integer, the value must be rounded at the end. 01520 if (std::numeric_limits<T>::is_integer) { 01521 return (T) util::roundToInt(doubleSum); 01522 } 01523 return (T) doubleSum; 01524 } 01525 01526 template<typename T1, typename T2> 01527 void CopyConvertScalarFunctional3D<T1,T2>::process ( 01528 Box3D domain, ScalarField3D<T1>& field1, 01529 ScalarField3D<T2>& field2 ) 01530 { 01531 Dot3D offset = computeRelativeDisplacement(field1, field2); 01532 01533 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01534 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01535 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01536 field2.get(iX+offset.x,iY+offset.y,iZ+offset.z) = 01537 (T2) field1.get(iX,iY,iZ); 01538 } 01539 } 01540 } 01541 } 01542 01543 template<typename T1, typename T2> 01544 CopyConvertScalarFunctional3D<T1,T2>* CopyConvertScalarFunctional3D<T1,T2>::clone() const 01545 { 01546 return new CopyConvertScalarFunctional3D<T1,T2>(*this); 01547 } 01548 01549 template<typename T1, typename T2> 01550 void CopyConvertScalarFunctional3D<T1,T2>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01551 modified[0] = modif::nothing; 01552 modified[1] = modif::staticVariables; 01553 } 01554 01555 template<typename T1, typename T2> 01556 BlockDomain::DomainT CopyConvertScalarFunctional3D<T1,T2>::appliesTo() const { 01557 return BlockDomain::bulk; 01558 } 01559 01560 01561 01562 /* *************** Data Functionals for scalar-fields **************** */ 01563 01564 template<typename T> 01565 void ExtractScalarSubDomainFunctional3D<T>::process ( 01566 Box3D domain, ScalarField3D<T>& field1, 01567 ScalarField3D<T>& field2 ) 01568 { 01569 Dot3D offset = computeRelativeDisplacement(field1, field2); 01570 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01571 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01572 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01573 field2.get(iX+offset.x,iY+offset.y,iZ+offset.z) = field1.get(iX,iY,iZ); 01574 } 01575 } 01576 } 01577 } 01578 01579 template<typename T> 01580 ExtractScalarSubDomainFunctional3D<T>* ExtractScalarSubDomainFunctional3D<T>::clone() const 01581 { 01582 return new ExtractScalarSubDomainFunctional3D<T>(*this); 01583 } 01584 01585 template<typename T> 01586 void ExtractScalarSubDomainFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01587 modified[0] = modif::nothing; 01588 modified[1] = modif::staticVariables; 01589 } 01590 01591 template<typename T> 01592 BlockDomain::DomainT ExtractScalarSubDomainFunctional3D<T>::appliesTo() const { 01593 return BlockDomain::bulkAndEnvelope; 01594 } 01595 01596 /* ******** compute sqrt functional 3D ************************************* */ 01597 01598 template<typename T> 01599 void ComputeScalarSqrtFunctional3D<T>::process ( 01600 Box3D domain, ScalarField3D<T>& A, 01601 ScalarField3D<T>& B ) 01602 { 01603 Dot3D offset = computeRelativeDisplacement(A, B); 01604 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01605 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01606 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01607 PLB_ASSERT( A.get(iX,iY,iZ) >= T()); 01608 B.get(iX+offset.x,iY+offset.y,iZ+offset.z) = std::sqrt( A.get(iX,iY,iZ) ); 01609 } 01610 } 01611 } 01612 } 01613 01614 template<typename T> 01615 ComputeScalarSqrtFunctional3D<T>* ComputeScalarSqrtFunctional3D<T>::clone() const 01616 { 01617 return new ComputeScalarSqrtFunctional3D<T>(*this); 01618 } 01619 01620 template<typename T> 01621 void ComputeScalarSqrtFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01622 modified[0] = modif::nothing; 01623 modified[1] = modif::staticVariables; 01624 } 01625 01626 template<typename T> 01627 BlockDomain::DomainT ComputeScalarSqrtFunctional3D<T>::appliesTo() const { 01628 return BlockDomain::bulkAndEnvelope; 01629 } 01630 01631 01632 /* ******** compute sqrt functional 3D ************************************* */ 01633 01634 template<typename T> 01635 void ComputeAbsoluteValueFunctional3D<T>::process ( 01636 Box3D domain, ScalarField3D<T>& A, 01637 ScalarField3D<T>& B ) 01638 { 01639 Dot3D offset = computeRelativeDisplacement(A, B); 01640 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01641 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01642 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01643 B.get(iX+offset.x,iY+offset.y,iZ+offset.z) = fabs( A.get(iX,iY,iZ) ); 01644 } 01645 } 01646 } 01647 } 01648 01649 template<typename T> 01650 ComputeAbsoluteValueFunctional3D<T>* ComputeAbsoluteValueFunctional3D<T>::clone() const 01651 { 01652 return new ComputeAbsoluteValueFunctional3D<T>(*this); 01653 } 01654 01655 template<typename T> 01656 void ComputeAbsoluteValueFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01657 modified[0] = modif::nothing; 01658 modified[1] = modif::staticVariables; 01659 } 01660 01661 template<typename T> 01662 BlockDomain::DomainT ComputeAbsoluteValueFunctional3D<T>::appliesTo() const { 01663 return BlockDomain::bulkAndEnvelope; 01664 } 01665 01666 /* ******** compute sqrt functional 3D ************************************* */ 01667 01668 template<typename T, int nDim> 01669 void ComputeTensorSqrtFunctional3D<T,nDim>::process ( 01670 Box3D domain, TensorField3D<T,nDim>& A, 01671 TensorField3D<T,nDim>& B ) 01672 { 01673 Dot3D offset = computeRelativeDisplacement(A, B); 01674 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01675 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01676 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01677 for (plint iD = 0; iD < nDim; ++iD) { 01678 PLB_ASSERT( A.get(iX,iY,iZ)[iD] >= T()); 01679 B.get(iX+offset.x,iY+offset.y,iZ+offset.z)[iD] = std::sqrt( A.get(iX,iY,iZ)[iD] ); 01680 } 01681 } 01682 } 01683 } 01684 } 01685 01686 template<typename T, int nDim> 01687 ComputeTensorSqrtFunctional3D<T,nDim>* ComputeTensorSqrtFunctional3D<T,nDim>::clone() const 01688 { 01689 return new ComputeTensorSqrtFunctional3D<T,nDim>(*this); 01690 } 01691 01692 template<typename T, int nDim> 01693 void ComputeTensorSqrtFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01694 modified[0] = modif::nothing; 01695 modified[1] = modif::staticVariables; 01696 } 01697 01698 template<typename T, int nDim> 01699 BlockDomain::DomainT ComputeTensorSqrtFunctional3D<T,nDim>::appliesTo() const { 01700 return BlockDomain::bulkAndEnvelope; 01701 } 01702 01703 01704 /* ******** A_lt_alpha_functional3D ************************************* */ 01705 01706 template<typename T> 01707 A_lt_alpha_functional3D<T>::A_lt_alpha_functional3D(T alpha_) 01708 : alpha(alpha_) 01709 { } 01710 01711 template<typename T> 01712 void A_lt_alpha_functional3D<T>::process ( 01713 Box3D domain, ScalarField3D<T>& A, ScalarField3D<int>& result ) 01714 { 01715 Dot3D offset = computeRelativeDisplacement(A, result); 01716 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01717 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01718 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01719 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = 01720 A.get(iX,iY,iZ) < alpha ? 1 : 0; 01721 } 01722 } 01723 } 01724 } 01725 01726 template<typename T> 01727 A_lt_alpha_functional3D<T>* A_lt_alpha_functional3D<T>::clone() const { 01728 return new A_lt_alpha_functional3D<T>(*this); 01729 } 01730 01731 template<typename T> 01732 void A_lt_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01733 modified[0] = modif::nothing; 01734 modified[1] = modif::staticVariables; 01735 } 01736 01737 template<typename T> 01738 BlockDomain::DomainT A_lt_alpha_functional3D<T>::appliesTo() const { 01739 return BlockDomain::bulkAndEnvelope; 01740 } 01741 01742 01743 /* ******** A_gt_alpha_functional3D ************************************* */ 01744 01745 template<typename T> 01746 A_gt_alpha_functional3D<T>::A_gt_alpha_functional3D(T alpha_) 01747 : alpha(alpha_) 01748 { } 01749 01750 template<typename T> 01751 void A_gt_alpha_functional3D<T>::process ( 01752 Box3D domain, ScalarField3D<T>& A, ScalarField3D<int>& result ) 01753 { 01754 Dot3D offset = computeRelativeDisplacement(A, result); 01755 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01756 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01757 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01758 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = 01759 A.get(iX,iY,iZ) > alpha ? 1 : 0; 01760 } 01761 } 01762 } 01763 } 01764 01765 template<typename T> 01766 A_gt_alpha_functional3D<T>* A_gt_alpha_functional3D<T>::clone() const { 01767 return new A_gt_alpha_functional3D<T>(*this); 01768 } 01769 01770 template<typename T> 01771 void A_gt_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01772 modified[0] = modif::nothing; 01773 modified[1] = modif::staticVariables; 01774 } 01775 01776 template<typename T> 01777 BlockDomain::DomainT A_gt_alpha_functional3D<T>::appliesTo() const { 01778 return BlockDomain::bulkAndEnvelope; 01779 } 01780 01781 01782 /* ******** A_plus_alpha_functional3D ************************************* */ 01783 01784 template<typename T> 01785 A_plus_alpha_functional3D<T>::A_plus_alpha_functional3D(T alpha_) 01786 : alpha(alpha_) 01787 { } 01788 01789 template<typename T> 01790 void A_plus_alpha_functional3D<T>::process ( 01791 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01792 { 01793 Dot3D offset = computeRelativeDisplacement(A, result); 01794 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01795 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01796 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01797 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = A.get(iX,iY,iZ) + alpha; 01798 } 01799 } 01800 } 01801 } 01802 01803 template<typename T> 01804 A_plus_alpha_functional3D<T>* A_plus_alpha_functional3D<T>::clone() const { 01805 return new A_plus_alpha_functional3D<T>(*this); 01806 } 01807 01808 template<typename T> 01809 void A_plus_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01810 modified[0] = modif::nothing; 01811 modified[1] = modif::staticVariables; 01812 } 01813 01814 template<typename T> 01815 BlockDomain::DomainT A_plus_alpha_functional3D<T>::appliesTo() const { 01816 return BlockDomain::bulkAndEnvelope; 01817 } 01818 01819 01820 /* ******** A_minus_alpha_functional3D ************************************** */ 01821 01822 template<typename T> 01823 A_minus_alpha_functional3D<T>::A_minus_alpha_functional3D(T alpha_) 01824 : alpha(alpha_) 01825 { } 01826 01827 template<typename T> 01828 void A_minus_alpha_functional3D<T>::process ( 01829 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01830 { 01831 Dot3D offset = computeRelativeDisplacement(A, result); 01832 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01833 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01834 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01835 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = A.get(iX,iY,iZ) - alpha; 01836 } 01837 } 01838 } 01839 } 01840 01841 template<typename T> 01842 A_minus_alpha_functional3D<T>* A_minus_alpha_functional3D<T>::clone() const { 01843 return new A_minus_alpha_functional3D<T>(*this); 01844 } 01845 01846 template<typename T> 01847 void A_minus_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01848 modified[0] = modif::nothing; 01849 modified[1] = modif::staticVariables; 01850 } 01851 01852 template<typename T> 01853 BlockDomain::DomainT A_minus_alpha_functional3D<T>::appliesTo() const { 01854 return BlockDomain::bulkAndEnvelope; 01855 } 01856 01857 01858 /* ******** Alpha_minus_A_functional3D ************************************* */ 01859 01860 template<typename T> 01861 Alpha_minus_A_functional3D<T>::Alpha_minus_A_functional3D(T alpha_) 01862 : alpha(alpha_) 01863 { } 01864 01865 template<typename T> 01866 void Alpha_minus_A_functional3D<T>::process ( 01867 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01868 { 01869 Dot3D offset = computeRelativeDisplacement(A, result); 01870 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01871 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01872 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01873 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = alpha - A.get(iX,iY,iZ); 01874 } 01875 } 01876 } 01877 } 01878 01879 template<typename T> 01880 Alpha_minus_A_functional3D<T>* Alpha_minus_A_functional3D<T>::clone() const { 01881 return new Alpha_minus_A_functional3D<T>(*this); 01882 } 01883 01884 template<typename T> 01885 void Alpha_minus_A_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01886 modified[0] = modif::nothing; 01887 modified[1] = modif::staticVariables; 01888 } 01889 01890 template<typename T> 01891 BlockDomain::DomainT Alpha_minus_A_functional3D<T>::appliesTo() const { 01892 return BlockDomain::bulkAndEnvelope; 01893 } 01894 01895 01896 01897 /* ******** A_times_alpha_functional3D ************************************* */ 01898 01899 template<typename T> 01900 A_times_alpha_functional3D<T>::A_times_alpha_functional3D(T alpha_) 01901 : alpha(alpha_) 01902 { } 01903 01904 template<typename T> 01905 void A_times_alpha_functional3D<T>::process ( 01906 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01907 { 01908 Dot3D offset = computeRelativeDisplacement(A, result); 01909 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01910 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01911 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01912 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = A.get(iX,iY,iZ) * alpha; 01913 } 01914 } 01915 } 01916 } 01917 01918 template<typename T> 01919 A_times_alpha_functional3D<T>* A_times_alpha_functional3D<T>::clone() const { 01920 return new A_times_alpha_functional3D<T>(*this); 01921 } 01922 01923 template<typename T> 01924 void A_times_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01925 modified[0] = modif::nothing; 01926 modified[1] = modif::staticVariables; 01927 } 01928 01929 template<typename T> 01930 BlockDomain::DomainT A_times_alpha_functional3D<T>::appliesTo() const { 01931 return BlockDomain::bulkAndEnvelope; 01932 } 01933 01934 01935 /* ******** A_dividedBy_alpha_functional3D ************************************* */ 01936 01937 template<typename T> 01938 A_dividedBy_alpha_functional3D<T>::A_dividedBy_alpha_functional3D(T alpha_) 01939 : alpha(alpha_) 01940 { } 01941 01942 template<typename T> 01943 void A_dividedBy_alpha_functional3D<T>::process ( 01944 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01945 { 01946 Dot3D offset = computeRelativeDisplacement(A, result); 01947 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01948 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01949 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01950 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = A.get(iX,iY,iZ) / alpha; 01951 } 01952 } 01953 } 01954 } 01955 01956 template<typename T> 01957 A_dividedBy_alpha_functional3D<T>* A_dividedBy_alpha_functional3D<T>::clone() const { 01958 return new A_dividedBy_alpha_functional3D<T>(*this); 01959 } 01960 01961 template<typename T> 01962 void A_dividedBy_alpha_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 01963 modified[0] = modif::nothing; 01964 modified[1] = modif::staticVariables; 01965 } 01966 01967 template<typename T> 01968 BlockDomain::DomainT A_dividedBy_alpha_functional3D<T>::appliesTo() const { 01969 return BlockDomain::bulkAndEnvelope; 01970 } 01971 01972 01973 /* ******** Alpha_dividedBy_A_functional3D ************************************* */ 01974 01975 template<typename T> 01976 Alpha_dividedBy_A_functional3D<T>::Alpha_dividedBy_A_functional3D(T alpha_) 01977 : alpha(alpha_) 01978 { } 01979 01980 template<typename T> 01981 void Alpha_dividedBy_A_functional3D<T>::process ( 01982 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& result ) 01983 { 01984 Dot3D offset = computeRelativeDisplacement(A, result); 01985 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01986 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01987 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01988 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = alpha / A.get(iX,iY,iZ); 01989 } 01990 } 01991 } 01992 } 01993 01994 template<typename T> 01995 Alpha_dividedBy_A_functional3D<T>* Alpha_dividedBy_A_functional3D<T>::clone() const { 01996 return new Alpha_dividedBy_A_functional3D<T>(*this); 01997 } 01998 01999 template<typename T> 02000 void Alpha_dividedBy_A_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02001 modified[0] = modif::nothing; 02002 modified[1] = modif::staticVariables; 02003 } 02004 02005 template<typename T> 02006 BlockDomain::DomainT Alpha_dividedBy_A_functional3D<T>::appliesTo() const { 02007 return BlockDomain::bulkAndEnvelope; 02008 } 02009 02010 02011 02012 /* ******** A_plus_alpha_inplace_functional3D ************************************* */ 02013 02014 template<typename T> 02015 A_plus_alpha_inplace_functional3D<T>::A_plus_alpha_inplace_functional3D(T alpha_) 02016 : alpha(alpha_) 02017 { } 02018 02019 template<typename T> 02020 void A_plus_alpha_inplace_functional3D<T>::process ( 02021 Box3D domain, ScalarField3D<T>& A) 02022 { 02023 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02024 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02025 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02026 A.get(iX,iY,iZ) += alpha; 02027 } 02028 } 02029 } 02030 } 02031 02032 template<typename T> 02033 A_plus_alpha_inplace_functional3D<T>* A_plus_alpha_inplace_functional3D<T>::clone() const { 02034 return new A_plus_alpha_inplace_functional3D<T>(*this); 02035 } 02036 02037 template<typename T> 02038 void A_plus_alpha_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02039 modified[0] = modif::staticVariables; 02040 } 02041 02042 template<typename T> 02043 BlockDomain::DomainT A_plus_alpha_inplace_functional3D<T>::appliesTo() const { 02044 return BlockDomain::bulkAndEnvelope; 02045 } 02046 02047 02048 /* ******** A_minus_alpha_inplace_functional3D ************************************** */ 02049 02050 template<typename T> 02051 A_minus_alpha_inplace_functional3D<T>::A_minus_alpha_inplace_functional3D(T alpha_) 02052 : alpha(alpha_) 02053 { } 02054 02055 template<typename T> 02056 void A_minus_alpha_inplace_functional3D<T>::process ( 02057 Box3D domain, ScalarField3D<T>& A) 02058 { 02059 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02060 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02061 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02062 A.get(iX,iY,iZ) -= alpha; 02063 } 02064 } 02065 } 02066 } 02067 02068 template<typename T> 02069 A_minus_alpha_inplace_functional3D<T>* A_minus_alpha_inplace_functional3D<T>::clone() const { 02070 return new A_minus_alpha_inplace_functional3D<T>(*this); 02071 } 02072 02073 template<typename T> 02074 void A_minus_alpha_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02075 modified[0] = modif::staticVariables; 02076 } 02077 02078 template<typename T> 02079 BlockDomain::DomainT A_minus_alpha_inplace_functional3D<T>::appliesTo() const { 02080 return BlockDomain::bulkAndEnvelope; 02081 } 02082 02083 02084 /* ******** A_times_alpha_inplace_functional3D ************************************* */ 02085 02086 template<typename T> 02087 A_times_alpha_inplace_functional3D<T>::A_times_alpha_inplace_functional3D(T alpha_) 02088 : alpha(alpha_) 02089 { } 02090 02091 template<typename T> 02092 void A_times_alpha_inplace_functional3D<T>::process ( 02093 Box3D domain, ScalarField3D<T>& A ) 02094 { 02095 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02096 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02097 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02098 A.get(iX,iY,iZ) *= alpha; 02099 } 02100 } 02101 } 02102 } 02103 02104 template<typename T> 02105 A_times_alpha_inplace_functional3D<T>* A_times_alpha_inplace_functional3D<T>::clone() const { 02106 return new A_times_alpha_inplace_functional3D<T>(*this); 02107 } 02108 02109 template<typename T> 02110 void A_times_alpha_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02111 modified[0] = modif::staticVariables; 02112 } 02113 02114 template<typename T> 02115 BlockDomain::DomainT A_times_alpha_inplace_functional3D<T>::appliesTo() const { 02116 return BlockDomain::bulkAndEnvelope; 02117 } 02118 02119 02120 /* ******** A_dividedBy_alpha_inplace_functional3D ************************************* */ 02121 02122 template<typename T> 02123 A_dividedBy_alpha_inplace_functional3D<T>::A_dividedBy_alpha_inplace_functional3D(T alpha_) 02124 : alpha(alpha_) 02125 { } 02126 02127 template<typename T> 02128 void A_dividedBy_alpha_inplace_functional3D<T>::process ( 02129 Box3D domain, ScalarField3D<T>& A ) 02130 { 02131 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02132 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02133 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02134 A.get(iX,iY,iZ) /= alpha; 02135 } 02136 } 02137 } 02138 } 02139 02140 template<typename T> 02141 A_dividedBy_alpha_inplace_functional3D<T>* A_dividedBy_alpha_inplace_functional3D<T>::clone() const { 02142 return new A_dividedBy_alpha_inplace_functional3D<T>(*this); 02143 } 02144 02145 template<typename T> 02146 void A_dividedBy_alpha_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02147 modified[0] = modif::staticVariables; 02148 } 02149 02150 template<typename T> 02151 BlockDomain::DomainT A_dividedBy_alpha_inplace_functional3D<T>::appliesTo() const { 02152 return BlockDomain::bulkAndEnvelope; 02153 } 02154 02155 02156 /* ******** A_lt_B_functional3D ****************************************** */ 02157 02158 template<typename T> 02159 void A_lt_B_functional3D<T>::processGenericBlocks ( 02160 Box3D domain, std::vector<AtomicBlock3D*> fields ) 02161 { 02162 PLB_PRECONDITION( fields.size()==3 ); 02163 ScalarField3D<T>& A = *dynamic_cast<ScalarField3D<T>*>(fields[0]); 02164 ScalarField3D<T>& B = *dynamic_cast<ScalarField3D<T>*>(fields[1]); 02165 ScalarField3D<int>& result = *dynamic_cast<ScalarField3D<int>*>(fields[2]); 02166 Dot3D offsetB = computeRelativeDisplacement(A,B); 02167 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02168 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02169 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02170 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02171 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02172 = A.get(iX,iY,iZ) < B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z) ? 1:0; 02173 } 02174 } 02175 } 02176 } 02177 02178 template<typename T> 02179 A_lt_B_functional3D<T>* A_lt_B_functional3D<T>::clone() const { 02180 return new A_lt_B_functional3D<T>(*this); 02181 } 02182 02183 template<typename T> 02184 void A_lt_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02185 modified[0] = modif::nothing; 02186 modified[1] = modif::nothing; 02187 modified[2] = modif::staticVariables; 02188 } 02189 02190 template<typename T> 02191 BlockDomain::DomainT A_lt_B_functional3D<T>::appliesTo() const { 02192 return BlockDomain::bulkAndEnvelope; 02193 } 02194 02195 02196 /* ******** A_gt_B_functional3D ****************************************** */ 02197 02198 template<typename T> 02199 void A_gt_B_functional3D<T>::processGenericBlocks ( 02200 Box3D domain, std::vector<AtomicBlock3D*> fields ) 02201 { 02202 PLB_PRECONDITION( fields.size()==3 ); 02203 ScalarField3D<T>& A = *dynamic_cast<ScalarField3D<T>*>(fields[0]); 02204 ScalarField3D<T>& B = *dynamic_cast<ScalarField3D<T>*>(fields[1]); 02205 ScalarField3D<int>& result = *dynamic_cast<ScalarField3D<int>*>(fields[2]); 02206 Dot3D offsetB = computeRelativeDisplacement(A,B); 02207 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02208 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02209 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02210 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02211 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02212 = A.get(iX,iY,iZ) > B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z) ? 1:0; 02213 } 02214 } 02215 } 02216 } 02217 02218 template<typename T> 02219 A_gt_B_functional3D<T>* A_gt_B_functional3D<T>::clone() const { 02220 return new A_gt_B_functional3D<T>(*this); 02221 } 02222 02223 template<typename T> 02224 void A_gt_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02225 modified[0] = modif::nothing; 02226 modified[1] = modif::nothing; 02227 modified[2] = modif::staticVariables; 02228 } 02229 02230 template<typename T> 02231 BlockDomain::DomainT A_gt_B_functional3D<T>::appliesTo() const { 02232 return BlockDomain::bulkAndEnvelope; 02233 } 02234 02235 02236 /* ******** A_plus_B_functional3D ****************************************** */ 02237 02238 template<typename T> 02239 void A_plus_B_functional3D<T>::process ( 02240 Box3D domain, std::vector<ScalarField3D<T>*> fields ) 02241 { 02242 PLB_PRECONDITION( fields.size()==3 ); 02243 ScalarField3D<T>& A = *fields[0]; 02244 ScalarField3D<T>& B = *fields[1]; 02245 ScalarField3D<T>& result = *fields[2]; 02246 Dot3D offsetB = computeRelativeDisplacement(A,B); 02247 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02248 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02249 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02250 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02251 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02252 = A.get(iX,iY,iZ) + B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 02253 } 02254 } 02255 } 02256 } 02257 02258 template<typename T> 02259 A_plus_B_functional3D<T>* A_plus_B_functional3D<T>::clone() const { 02260 return new A_plus_B_functional3D<T>(*this); 02261 } 02262 02263 template<typename T> 02264 void A_plus_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02265 modified[0] = modif::nothing; 02266 modified[1] = modif::nothing; 02267 modified[2] = modif::staticVariables; 02268 } 02269 02270 template<typename T> 02271 BlockDomain::DomainT A_plus_B_functional3D<T>::appliesTo() const { 02272 return BlockDomain::bulkAndEnvelope; 02273 } 02274 02275 02276 /* ******** A_minus_B_functional3D ****************************************** */ 02277 02278 template<typename T> 02279 void A_minus_B_functional3D<T>::process ( 02280 Box3D domain, std::vector<ScalarField3D<T>*> fields ) 02281 { 02282 PLB_PRECONDITION( fields.size()==3 ); 02283 ScalarField3D<T>& A = *fields[0]; 02284 ScalarField3D<T>& B = *fields[1]; 02285 ScalarField3D<T>& result = *fields[2]; 02286 Dot3D offsetB = computeRelativeDisplacement(A,B); 02287 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02288 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02289 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02290 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02291 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02292 = A.get(iX,iY,iZ) - B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 02293 } 02294 } 02295 } 02296 } 02297 02298 template<typename T> 02299 A_minus_B_functional3D<T>* A_minus_B_functional3D<T>::clone() const { 02300 return new A_minus_B_functional3D<T>(*this); 02301 } 02302 02303 template<typename T> 02304 void A_minus_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02305 modified[0] = modif::nothing; 02306 modified[1] = modif::nothing; 02307 modified[2] = modif::staticVariables; 02308 } 02309 02310 template<typename T> 02311 BlockDomain::DomainT A_minus_B_functional3D<T>::appliesTo() const { 02312 return BlockDomain::bulkAndEnvelope; 02313 } 02314 02315 02316 /* ******** A_times_B_functional3D ****************************************** */ 02317 02318 template<typename T> 02319 void A_times_B_functional3D<T>::process ( 02320 Box3D domain, std::vector<ScalarField3D<T>*> fields ) 02321 { 02322 PLB_PRECONDITION( fields.size()==3 ); 02323 ScalarField3D<T>& A = *fields[0]; 02324 ScalarField3D<T>& B = *fields[1]; 02325 ScalarField3D<T>& result = *fields[2]; 02326 Dot3D offsetB = computeRelativeDisplacement(A,B); 02327 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02328 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02329 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02330 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02331 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02332 = A.get(iX,iY,iZ) * B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 02333 } 02334 } 02335 } 02336 } 02337 02338 template<typename T> 02339 A_times_B_functional3D<T>* A_times_B_functional3D<T>::clone() const { 02340 return new A_times_B_functional3D<T>(*this); 02341 } 02342 02343 template<typename T> 02344 void A_times_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02345 modified[0] = modif::nothing; 02346 modified[1] = modif::nothing; 02347 modified[2] = modif::staticVariables; 02348 } 02349 02350 template<typename T> 02351 BlockDomain::DomainT A_times_B_functional3D<T>::appliesTo() const { 02352 return BlockDomain::bulkAndEnvelope; 02353 } 02354 02355 02356 /* ******** A_dividedBy_B_functional3D ****************************************** */ 02357 02358 template<typename T> 02359 void A_dividedBy_B_functional3D<T>::process ( 02360 Box3D domain, std::vector<ScalarField3D<T>*> fields ) 02361 { 02362 PLB_PRECONDITION( fields.size()==3 ); 02363 ScalarField3D<T>& A = *fields[0]; 02364 ScalarField3D<T>& B = *fields[1]; 02365 ScalarField3D<T>& result = *fields[2]; 02366 Dot3D offsetB = computeRelativeDisplacement(A,B); 02367 Dot3D offsetResult = computeRelativeDisplacement(A,result); 02368 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02369 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02370 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02371 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 02372 = A.get(iX,iY,iZ) / B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 02373 } 02374 } 02375 } 02376 } 02377 02378 template<typename T> 02379 A_dividedBy_B_functional3D<T>* A_dividedBy_B_functional3D<T>::clone() const { 02380 return new A_dividedBy_B_functional3D<T>(*this); 02381 } 02382 02383 template<typename T> 02384 void A_dividedBy_B_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02385 modified[0] = modif::nothing; 02386 modified[1] = modif::nothing; 02387 modified[2] = modif::staticVariables; 02388 } 02389 02390 template<typename T> 02391 BlockDomain::DomainT A_dividedBy_B_functional3D<T>::appliesTo() const { 02392 return BlockDomain::bulkAndEnvelope; 02393 } 02394 02395 02396 /* ******** A_plus_B_inplace_functional3D ****************************************** */ 02397 02398 template<typename T> 02399 void A_plus_B_inplace_functional3D<T>::process ( 02400 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& B) 02401 { 02402 Dot3D offset = computeRelativeDisplacement(A,B); 02403 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02404 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02405 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02406 A.get(iX,iY,iZ) += B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 02407 } 02408 } 02409 } 02410 } 02411 02412 template<typename T> 02413 A_plus_B_inplace_functional3D<T>* A_plus_B_inplace_functional3D<T>::clone() const { 02414 return new A_plus_B_inplace_functional3D<T>(*this); 02415 } 02416 02417 template<typename T> 02418 void A_plus_B_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02419 modified[0] = modif::staticVariables; 02420 modified[1] = modif::nothing; 02421 } 02422 02423 template<typename T> 02424 BlockDomain::DomainT A_plus_B_inplace_functional3D<T>::appliesTo() const { 02425 return BlockDomain::bulkAndEnvelope; 02426 } 02427 02428 02429 /* ******** A_minus_B_inplace_functional3D ****************************************** */ 02430 02431 template<typename T> 02432 void A_minus_B_inplace_functional3D<T>::process ( 02433 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& B) 02434 { 02435 Dot3D offset = computeRelativeDisplacement(A,B); 02436 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02437 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02438 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02439 A.get(iX,iY,iZ) -= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 02440 } 02441 } 02442 } 02443 } 02444 02445 template<typename T> 02446 A_minus_B_inplace_functional3D<T>* A_minus_B_inplace_functional3D<T>::clone() const { 02447 return new A_minus_B_inplace_functional3D<T>(*this); 02448 } 02449 02450 template<typename T> 02451 void A_minus_B_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02452 modified[0] = modif::staticVariables; 02453 modified[1] = modif::nothing; 02454 } 02455 02456 template<typename T> 02457 BlockDomain::DomainT A_minus_B_inplace_functional3D<T>::appliesTo() const { 02458 return BlockDomain::bulkAndEnvelope; 02459 } 02460 02461 02462 /* ******** A_times_B_inplace_functional3D ****************************************** */ 02463 02464 template<typename T> 02465 void A_times_B_inplace_functional3D<T>::process ( 02466 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& B) 02467 { 02468 Dot3D offset = computeRelativeDisplacement(A,B); 02469 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02470 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02471 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02472 A.get(iX,iY,iZ) *= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 02473 } 02474 } 02475 } 02476 } 02477 02478 template<typename T> 02479 A_times_B_inplace_functional3D<T>* A_times_B_inplace_functional3D<T>::clone() const { 02480 return new A_times_B_inplace_functional3D<T>(*this); 02481 } 02482 02483 template<typename T> 02484 void A_times_B_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02485 modified[0] = modif::staticVariables; 02486 modified[1] = modif::nothing; 02487 } 02488 02489 template<typename T> 02490 BlockDomain::DomainT A_times_B_inplace_functional3D<T>::appliesTo() const { 02491 return BlockDomain::bulkAndEnvelope; 02492 } 02493 02494 02495 /* ******** A_dividedBy_B_inplace_functional3D ****************************************** */ 02496 02497 template<typename T> 02498 void A_dividedBy_B_inplace_functional3D<T>::process ( 02499 Box3D domain, ScalarField3D<T>& A, ScalarField3D<T>& B) 02500 { 02501 Dot3D offset = computeRelativeDisplacement(A,B); 02502 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02503 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02504 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02505 A.get(iX,iY,iZ) -= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 02506 } 02507 } 02508 } 02509 } 02510 02511 template<typename T> 02512 A_dividedBy_B_inplace_functional3D<T>* A_dividedBy_B_inplace_functional3D<T>::clone() const { 02513 return new A_dividedBy_B_inplace_functional3D<T>(*this); 02514 } 02515 02516 template<typename T> 02517 void A_dividedBy_B_inplace_functional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02518 modified[0] = modif::staticVariables; 02519 modified[1] = modif::nothing; 02520 } 02521 02522 template<typename T> 02523 BlockDomain::DomainT A_dividedBy_B_inplace_functional3D<T>::appliesTo() const { 02524 return BlockDomain::bulkAndEnvelope; 02525 } 02526 02527 02528 /* *************** PART III ****************************************** */ 02529 /* *************** Analysis of the tensor-field ********************** */ 02530 /* ******************************************************************* */ 02531 02533 namespace fdDataField { 02534 02535 template<typename T, int nDim> 02536 inline T bulkXderiv ( 02537 TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ, int iD ) 02538 { 02539 T dxu = fd::ctl_diff( velocity.get(iX+1,iY,iZ)[iD], 02540 velocity.get(iX-1,iY,iZ)[iD] ); 02541 return dxu; 02542 } 02543 02544 template<typename T, int nDim> 02545 inline T bulkYderiv ( 02546 TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ, int iD ) 02547 { 02548 T dyu = fd::ctl_diff( velocity.get(iX,iY+1,iZ)[iD], 02549 velocity.get(iX,iY-1,iZ)[iD] ); 02550 return dyu; 02551 } 02552 02553 template<typename T, int nDim> 02554 inline T bulkZderiv ( 02555 TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ, int iD ) 02556 { 02557 T dzu = fd::ctl_diff( velocity.get(iX,iY,iZ+1)[iD], 02558 velocity.get(iX,iY,iZ-1)[iD] ); 02559 return dzu; 02560 } 02561 02562 template<typename T, int nDim> 02563 inline T planeXderiv ( 02564 TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02565 plint iX, plint iY, plint iZ, int iD ) 02566 { 02567 if (direction==0) { 02568 return -orientation * 02569 fd::o1_fwd_diff( velocity.get(iX ,iY,iZ)[iD], 02570 velocity.get(iX-1*orientation,iY,iZ)[iD] ); 02571 } 02572 else { 02573 return bulkXderiv(velocity, iX,iY,iZ, iD); 02574 } 02575 } 02576 02577 template<typename T, int nDim> 02578 inline T planeYderiv ( 02579 TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02580 plint iX, plint iY, plint iZ, int iD ) 02581 { 02582 if (direction==1) { 02583 return -orientation * 02584 fd::o1_fwd_diff( velocity.get(iX,iY ,iZ)[iD], 02585 velocity.get(iX,iY-1*orientation,iZ)[iD] ); 02586 } 02587 else { 02588 return bulkYderiv(velocity, iX,iY,iZ, iD); 02589 } 02590 } 02591 02592 template<typename T, int nDim> 02593 inline T planeZderiv ( 02594 TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02595 plint iX, plint iY, plint iZ, int iD ) 02596 { 02597 if (direction==2) { 02598 return -orientation * 02599 fd::o1_fwd_diff( velocity.get(iX,iY,iZ )[iD], 02600 velocity.get(iX,iY,iZ-1*orientation)[iD] ); 02601 } 02602 else { 02603 return bulkZderiv(velocity, iX,iY,iZ, iD); 02604 } 02605 } 02606 02607 template<typename T, int nDim> 02608 inline T edgeXderiv ( 02609 TensorField3D<T,nDim> const& velocity, 02610 int plane, int direction1, int direction2, 02611 plint iX, plint iY, plint iZ, int iD ) 02612 { 02613 if (plane==0) { 02614 return bulkXderiv(velocity, iX,iY,iZ, iD); 02615 } 02616 else { 02617 int orientation = plane==1 ? direction2 : direction1; 02618 return -orientation * 02619 fd::o1_fwd_diff( velocity.get(iX ,iY,iZ)[iD], 02620 velocity.get(iX-1*orientation,iY,iZ)[iD] ); 02621 } 02622 } 02623 02624 template<typename T, int nDim> 02625 inline T edgeYderiv ( 02626 TensorField3D<T,nDim> const& velocity, 02627 int plane, int direction1, int direction2, 02628 plint iX, plint iY, plint iZ, int iD ) 02629 { 02630 if (plane==1) { 02631 return bulkYderiv(velocity, iX,iY,iZ, iD); 02632 } 02633 else { 02634 int orientation = plane==0 ? direction1 : direction2; 02635 return -orientation * 02636 fd::o1_fwd_diff( velocity.get(iX,iY ,iZ)[iD], 02637 velocity.get(iX,iY-1*orientation,iZ)[iD] ); 02638 } 02639 } 02640 02641 template<typename T, int nDim> 02642 inline T edgeZderiv ( 02643 TensorField3D<T,nDim> const& velocity, 02644 int plane, int direction1, int direction2, 02645 plint iX, plint iY, plint iZ, int iD ) 02646 { 02647 if (plane==2) { 02648 return bulkZderiv(velocity, iX,iY,iZ, iD); 02649 } 02650 else { 02651 int orientation = plane==0 ? direction2 : direction1; 02652 return -orientation * 02653 fd::o1_fwd_diff( velocity.get(iX,iY,iZ )[iD], 02654 velocity.get(iX,iY,iZ-1*orientation)[iD] ); 02655 } 02656 } 02657 02658 template<typename T, int nDim> 02659 inline T cornerXderiv ( 02660 TensorField3D<T,nDim> const& velocity, 02661 int normalX, int normalY, int normalZ, 02662 plint iX, plint iY, plint iZ, int iD ) 02663 { 02664 int orientation = normalX; 02665 return -orientation * 02666 fd::o1_fwd_diff( velocity.get(iX ,iY,iZ)[iD], 02667 velocity.get(iX-1*orientation,iY,iZ)[iD] ); 02668 } 02669 02670 template<typename T, int nDim> 02671 inline T cornerYderiv ( 02672 TensorField3D<T,nDim> const& velocity, 02673 int normalX, int normalY, int normalZ, 02674 plint iX, plint iY, plint iZ, int iD ) 02675 { 02676 int orientation = normalY; 02677 return -orientation * 02678 fd::o1_fwd_diff( velocity.get(iX,iY ,iZ)[iD], 02679 velocity.get(iX,iY-1*orientation,iZ)[iD] ); 02680 } 02681 02682 template<typename T, int nDim> 02683 inline T cornerZderiv ( 02684 TensorField3D<T,nDim> const& velocity, 02685 int normalX, int normalY, int normalZ, 02686 plint iX, plint iY, plint iZ, int iD ) 02687 { 02688 int orientation = normalZ; 02689 return -orientation * 02690 fd::o1_fwd_diff( velocity.get(iX,iY,iZ )[iD], 02691 velocity.get(iX,iY,iZ-1*orientation)[iD] ); 02692 } 02693 02694 02695 template<typename T, int nDim> 02696 inline T bulkVorticityX(TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ ) 02697 { 02698 T dyuz = fdDataField::bulkYderiv(velocity, iX,iY,iZ, 2); 02699 T dzuy = fdDataField::bulkZderiv(velocity, iX,iY,iZ, 1); 02700 02701 return dyuz - dzuy; 02702 } 02703 02704 template<typename T, int nDim> 02705 inline T bulkVorticityY(TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ ) 02706 { 02707 T dzux = fdDataField::bulkZderiv(velocity, iX,iY,iZ, 0); 02708 T dxuz = fdDataField::bulkXderiv(velocity, iX,iY,iZ, 2); 02709 02710 return dzux - dxuz; 02711 } 02712 02713 template<typename T, int nDim> 02714 inline T bulkVorticityZ(TensorField3D<T,nDim> const& velocity, plint iX, plint iY, plint iZ ) 02715 { 02716 T dxuy = fdDataField::bulkXderiv(velocity, iX,iY,iZ, 1); 02717 T dyux = fdDataField::bulkYderiv(velocity, iX,iY,iZ, 0); 02718 02719 return dxuy - dyux; 02720 } 02721 02722 template<typename T, int nDim> 02723 inline T planeVorticityX( TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02724 plint iX, plint iY, plint iZ ) 02725 { 02726 T dyuz = fdDataField::planeYderiv(velocity,direction,orientation, iX,iY,iZ, 2); 02727 T dzuy = fdDataField::planeZderiv(velocity,direction,orientation, iX,iY,iZ, 1); 02728 02729 return dyuz - dzuy; 02730 } 02731 02732 template<typename T, int nDim> 02733 inline T planeVorticityY( TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02734 plint iX, plint iY, plint iZ ) 02735 { 02736 T dzux = fdDataField::planeZderiv(velocity,direction,orientation, iX,iY,iZ, 0); 02737 T dxuz = fdDataField::planeXderiv(velocity,direction,orientation, iX,iY,iZ, 2); 02738 02739 return dzux - dxuz; 02740 } 02741 02742 template<typename T, int nDim> 02743 inline T planeVorticityZ( TensorField3D<T,nDim> const& velocity, int direction, int orientation, 02744 plint iX, plint iY, plint iZ ) 02745 { 02746 T dxuy = fdDataField::planeXderiv(velocity,direction,orientation, iX,iY,iZ, 1); 02747 T dyux = fdDataField::planeYderiv(velocity,direction,orientation, iX,iY,iZ, 0); 02748 02749 return dxuy - dyux; 02750 } 02751 02752 template<typename T, int nDim> 02753 inline T edgeVorticityX( TensorField3D<T,nDim> const& velocity, int plane, int normal1, int normal2, 02754 plint iX, plint iY, plint iZ ) 02755 { 02756 T dyuz = fdDataField::edgeYderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 2); 02757 T dzuy = fdDataField::edgeZderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 1); 02758 02759 return dyuz - dzuy; 02760 } 02761 02762 template<typename T, int nDim> 02763 inline T edgeVorticityY( TensorField3D<T,nDim> const& velocity, int plane, int normal1, int normal2, 02764 plint iX, plint iY, plint iZ ) 02765 { 02766 T dzux = fdDataField::edgeZderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 0); 02767 T dxuz = fdDataField::edgeXderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 2); 02768 02769 return dzux - dxuz; 02770 } 02771 02772 template<typename T, int nDim> 02773 inline T edgeVorticityZ( TensorField3D<T,nDim> const& velocity, int plane, int normal1, int normal2, 02774 plint iX, plint iY, plint iZ ) 02775 { 02776 T dxuy = fdDataField::edgeXderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 1); 02777 T dyux = fdDataField::edgeYderiv(velocity,plane,normal1,normal2, iX,iY,iZ, 0); 02778 02779 return dxuy - dyux; 02780 } 02781 02782 template<typename T, int nDim> 02783 inline T cornerVorticityX( TensorField3D<T,nDim> const& velocity, int normalX, int normalY, int normalZ, 02784 plint iX, plint iY, plint iZ ) 02785 { 02786 T dyuz = fdDataField::cornerYderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 2); 02787 T dzuy = fdDataField::cornerZderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 1); 02788 02789 return dyuz - dzuy; 02790 } 02791 02792 template<typename T, int nDim> 02793 inline T cornerVorticityY( TensorField3D<T,nDim> const& velocity, int normalX, int normalY, int normalZ, 02794 plint iX, plint iY, plint iZ ) 02795 { 02796 T dzux = fdDataField::cornerZderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 0); 02797 T dxuz = fdDataField::cornerXderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 2); 02798 02799 return dzux - dxuz; 02800 } 02801 02802 template<typename T, int nDim> 02803 inline T cornerVorticityZ( TensorField3D<T,nDim> const& velocity, int normalX, int normalY, int normalZ, 02804 plint iX, plint iY, plint iZ ) 02805 { 02806 T dxuy = fdDataField::cornerXderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 1); 02807 T dyux = fdDataField::cornerYderiv(velocity,normalX,normalY,normalZ, iX,iY,iZ, 0); 02808 02809 return dxuy - dyux; 02810 } 02811 02812 } // fdDataField 02813 02814 02815 template<typename T1, typename T2, int nDim> 02816 void CopyConvertTensorFunctional3D<T1,T2,nDim>::process ( 02817 Box3D domain, TensorField3D<T1,nDim>& field1, 02818 TensorField3D<T2,nDim>& field2 ) 02819 { 02820 Dot3D offset = computeRelativeDisplacement(field1, field2); 02821 02822 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02823 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02824 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02825 for (int iDim=0; iDim<nDim; ++iDim) { 02826 field2.get(iX+offset.x,iY+offset.y,iZ+offset.z)[iDim] = 02827 (T2) field1.get(iX,iY,iZ)[iDim]; 02828 } 02829 } 02830 } 02831 } 02832 } 02833 02834 template<typename T1, typename T2, int nDim> 02835 CopyConvertTensorFunctional3D<T1,T2,nDim>* CopyConvertTensorFunctional3D<T1,T2,nDim>::clone() const 02836 { 02837 return new CopyConvertTensorFunctional3D<T1,T2,nDim>(*this); 02838 } 02839 02840 template<typename T1, typename T2, int nDim> 02841 void CopyConvertTensorFunctional3D<T1,T2,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02842 modified[0] = modif::nothing; 02843 modified[1] = modif::staticVariables; 02844 } 02845 02846 template<typename T1, typename T2, int nDim> 02847 BlockDomain::DomainT CopyConvertTensorFunctional3D<T1,T2,nDim>::appliesTo() const { 02848 return BlockDomain::bulk; 02849 } 02850 02851 02852 template<typename T, int nDim> 02853 void ExtractTensorSubDomainFunctional3D<T,nDim>::process ( 02854 Box3D domain, TensorField3D<T,nDim>& field1, 02855 TensorField3D<T,nDim>& field2 ) 02856 { 02857 Dot3D offset = computeRelativeDisplacement(field1, field2); 02858 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02859 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02860 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02861 for (int iDim=0; iDim<nDim; ++iDim) { 02862 field2.get(iX+offset.x,iY+offset.y,iZ+offset.z)[iDim] 02863 = field1.get(iX,iY,iZ)[iDim]; 02864 } 02865 } 02866 } 02867 } 02868 } 02869 02870 template<typename T, int nDim> 02871 ExtractTensorSubDomainFunctional3D<T,nDim>* ExtractTensorSubDomainFunctional3D<T,nDim>::clone() const 02872 { 02873 return new ExtractTensorSubDomainFunctional3D<T,nDim>(*this); 02874 } 02875 02876 template<typename T, int nDim> 02877 void ExtractTensorSubDomainFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02878 modified[0] = modif::nothing; 02879 modified[1] = modif::staticVariables; 02880 } 02881 02882 template<typename T, int nDim> 02883 BlockDomain::DomainT ExtractTensorSubDomainFunctional3D<T,nDim>::appliesTo() const { 02884 return BlockDomain::bulk; 02885 } 02886 02887 02888 template<typename T, int nDim> 02889 ExtractTensorComponentFunctional3D<T,nDim>::ExtractTensorComponentFunctional3D(int iComponent_) 02890 : iComponent(iComponent_) 02891 { } 02892 02893 template<typename T, int nDim> 02894 void ExtractTensorComponentFunctional3D<T,nDim>::process ( 02895 Box3D domain, ScalarField3D<T>& scalarField, 02896 TensorField3D<T,nDim>& tensorField ) 02897 { 02898 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 02899 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02900 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02901 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02902 scalarField.get(iX,iY,iZ) 02903 = tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z)[iComponent]; 02904 } 02905 } 02906 } 02907 } 02908 02909 template<typename T, int nDim> 02910 ExtractTensorComponentFunctional3D<T,nDim>* ExtractTensorComponentFunctional3D<T,nDim>::clone() const 02911 { 02912 return new ExtractTensorComponentFunctional3D<T,nDim>(*this); 02913 } 02914 02915 template<typename T, int nDim> 02916 void ExtractTensorComponentFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02917 modified[0] = modif::staticVariables; 02918 modified[1] = modif::nothing; 02919 } 02920 02921 template<typename T, int nDim> 02922 BlockDomain::DomainT ExtractTensorComponentFunctional3D<T,nDim>::appliesTo() const { 02923 return BlockDomain::bulkAndEnvelope; 02924 } 02925 02926 02927 template<typename T, int nDim> 02928 void ComputeNormFunctional3D<T,nDim>::process ( 02929 Box3D domain, ScalarField3D<T>& scalarField, 02930 TensorField3D<T,nDim>& tensorField ) 02931 { 02932 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 02933 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02934 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02935 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02936 scalarField.get(iX,iY,iZ) = std::sqrt( VectorTemplateImpl<T,nDim>::normSqr ( 02937 tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z) ) ); 02938 } 02939 } 02940 } 02941 } 02942 02943 template<typename T, int nDim> 02944 ComputeNormFunctional3D<T,nDim>* ComputeNormFunctional3D<T,nDim>::clone() const 02945 { 02946 return new ComputeNormFunctional3D<T,nDim>(*this); 02947 } 02948 02949 template<typename T, int nDim> 02950 void ComputeNormFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02951 modified[0] = modif::staticVariables; 02952 modified[1] = modif::nothing; 02953 } 02954 02955 template<typename T, int nDim> 02956 BlockDomain::DomainT ComputeNormFunctional3D<T,nDim>::appliesTo() const { 02957 return BlockDomain::bulkAndEnvelope; 02958 } 02959 02960 02961 template<typename T, int nDim> 02962 void ComputeNormSqrFunctional3D<T,nDim>::process ( 02963 Box3D domain, ScalarField3D<T>& scalarField, 02964 TensorField3D<T,nDim>& tensorField ) 02965 { 02966 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 02967 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 02968 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 02969 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 02970 scalarField.get(iX,iY,iZ) = VectorTemplateImpl<T,nDim>::normSqr ( 02971 tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z) ); 02972 } 02973 } 02974 } 02975 } 02976 02977 template<typename T, int nDim> 02978 ComputeNormSqrFunctional3D<T,nDim>* ComputeNormSqrFunctional3D<T,nDim>::clone() const 02979 { 02980 return new ComputeNormSqrFunctional3D<T,nDim>(*this); 02981 } 02982 02983 template<typename T, int nDim> 02984 void ComputeNormSqrFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 02985 modified[0] = modif::staticVariables; 02986 modified[1] = modif::nothing; 02987 } 02988 02989 template<typename T, int nDim> 02990 BlockDomain::DomainT ComputeNormSqrFunctional3D<T,nDim>::appliesTo() const { 02991 return BlockDomain::bulkAndEnvelope; 02992 } 02993 02994 02995 template<typename T> 02996 void ComputeSymmetricTensorNormFunctional3D<T>::process ( 02997 Box3D domain, ScalarField3D<T>& scalarField, 02998 TensorField3D<T,6>& tensorField ) 02999 { 03000 typedef SymmetricTensorImpl<T,3> tensor; 03001 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 03002 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03003 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03004 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03005 Array<T,6>& el = tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03006 scalarField.get(iX,iY,iZ) = std::sqrt ( 03007 // Count diagonal components once ... 03008 util::sqr(el[tensor::xx]) + util::sqr(el[tensor::yy]) + util::sqr(el[tensor::zz]) + 03009 // .. and off-diagonal components twice, due to symmetry. 03010 (T)2 * (util::sqr(el[tensor::xy]) + util::sqr(el[tensor::xz]) +util::sqr(el[tensor::yz])) ); 03011 } 03012 } 03013 } 03014 } 03015 03016 template<typename T> 03017 ComputeSymmetricTensorNormFunctional3D<T>* ComputeSymmetricTensorNormFunctional3D<T>::clone() const 03018 { 03019 return new ComputeSymmetricTensorNormFunctional3D<T>(*this); 03020 } 03021 03022 template<typename T> 03023 void ComputeSymmetricTensorNormFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03024 modified[0] = modif::staticVariables; 03025 modified[1] = modif::nothing; 03026 } 03027 03028 template<typename T> 03029 BlockDomain::DomainT ComputeSymmetricTensorNormFunctional3D<T>::appliesTo() const { 03030 return BlockDomain::bulkAndEnvelope; 03031 } 03032 03033 03034 template<typename T> 03035 void ComputeSymmetricTensorNormSqrFunctional3D<T>::process ( 03036 Box3D domain, ScalarField3D<T>& scalarField, 03037 TensorField3D<T,6>& tensorField ) 03038 { 03039 typedef SymmetricTensorImpl<T,3> tensor; 03040 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 03041 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03042 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03043 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03044 Array<T,6>& el = tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03045 scalarField.get(iX,iY,iZ) = 03046 // Count diagonal components once ... 03047 util::sqr(el[tensor::xx]) + util::sqr(el[tensor::yy]) + util::sqr(el[tensor::zz]) + 03048 // .. and off-diagonal components twice, due to symmetry. 03049 (T)2 * (util::sqr(el[tensor::xy]) + util::sqr(el[tensor::xz]) +util::sqr(el[tensor::yz])); 03050 } 03051 } 03052 } 03053 } 03054 03055 template<typename T> 03056 ComputeSymmetricTensorNormSqrFunctional3D<T>* ComputeSymmetricTensorNormSqrFunctional3D<T>::clone() const 03057 { 03058 return new ComputeSymmetricTensorNormSqrFunctional3D<T>(*this); 03059 } 03060 03061 template<typename T> 03062 void ComputeSymmetricTensorNormSqrFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03063 modified[0] = modif::staticVariables; 03064 modified[1] = modif::nothing; 03065 } 03066 03067 template<typename T> 03068 BlockDomain::DomainT ComputeSymmetricTensorNormSqrFunctional3D<T>::appliesTo() const { 03069 return BlockDomain::bulkAndEnvelope; 03070 } 03071 03072 03073 03074 template<typename T> 03075 void ComputeSymmetricTensorTraceFunctional3D<T>::process ( 03076 Box3D domain, ScalarField3D<T>& scalarField, 03077 TensorField3D<T,6>& tensorField ) 03078 { 03079 typedef SymmetricTensorImpl<T,3> tensor; 03080 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 03081 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03082 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03083 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03084 Array<T,6>& el = tensorField.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03085 scalarField.get(iX,iY,iZ) = el[tensor::xx] + el[tensor::yy] + el[tensor::zz]; 03086 } 03087 } 03088 } 03089 } 03090 03091 template<typename T> 03092 ComputeSymmetricTensorTraceFunctional3D<T>* ComputeSymmetricTensorTraceFunctional3D<T>::clone() const 03093 { 03094 return new ComputeSymmetricTensorTraceFunctional3D<T>(*this); 03095 } 03096 03097 template<typename T> 03098 void ComputeSymmetricTensorTraceFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03099 modified[0] = modif::staticVariables; 03100 modified[1] = modif::nothing; 03101 } 03102 03103 template<typename T> 03104 BlockDomain::DomainT ComputeSymmetricTensorTraceFunctional3D<T>::appliesTo() const { 03105 return BlockDomain::bulkAndEnvelope; 03106 } 03107 03108 03109 template<typename T> 03110 void BoxBulkGradientFunctional3D<T>::process ( 03111 Box3D domain, ScalarField3D<T>& phi, 03112 TensorField3D<T,3>& gradient ) 03113 { 03114 Dot3D offset = computeRelativeDisplacement(phi, gradient); 03115 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03116 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03117 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03118 plint iX2 = iX+offset.x; 03119 plint iY2 = iY+offset.y; 03120 plint iZ2 = iZ+offset.z; 03121 gradient.get(iX2,iY2,iZ2)[0] = 03122 fdDataField::bulkXderiv(phi, iX,iY,iZ); 03123 gradient.get(iX2,iY2,iZ2)[1] = 03124 fdDataField::bulkYderiv(phi, iX,iY,iZ); 03125 gradient.get(iX2,iY2,iZ2)[2] = 03126 fdDataField::bulkZderiv(phi, iX,iY,iZ); 03127 } 03128 } 03129 } 03130 } 03131 03132 template<typename T> 03133 BoxBulkGradientFunctional3D<T>* BoxBulkGradientFunctional3D<T>::clone() const 03134 { 03135 return new BoxBulkGradientFunctional3D<T>(*this); 03136 } 03137 03138 template<typename T> 03139 void BoxBulkGradientFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03140 modified[0] = modif::nothing; 03141 modified[1] = modif::staticVariables; 03142 } 03143 03144 template<typename T> 03145 BlockDomain::DomainT BoxBulkGradientFunctional3D<T>::appliesTo() const { 03146 return BlockDomain::bulk; 03147 } 03148 03149 03150 03151 template<typename T> 03152 void BoxGradientFunctional3D<T>::processBulk ( 03153 Box3D domain, ScalarField3D<T>& phi, TensorField3D<T,3>& gradient ) 03154 { 03155 Dot3D offset = computeRelativeDisplacement(phi, gradient); 03156 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03157 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03158 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03159 plint iX2 = iX+offset.x; 03160 plint iY2 = iY+offset.y; 03161 plint iZ2 = iZ+offset.z; 03162 gradient.get(iX2,iY2,iZ2)[0] = 03163 fdDataField::bulkXderiv(phi, iX,iY,iZ); 03164 gradient.get(iX2,iY2,iZ2)[1] = 03165 fdDataField::bulkYderiv(phi, iX,iY,iZ); 03166 gradient.get(iX2,iY2,iZ2)[2] = 03167 fdDataField::bulkZderiv(phi, iX,iY,iZ); 03168 } 03169 } 03170 } 03171 } 03172 03173 template<typename T> 03174 void BoxGradientFunctional3D<T>::processPlane ( 03175 int direction, int orientation, Box3D domain, 03176 ScalarField3D<T>& phi, TensorField3D<T,3>& gradient ) 03177 { 03178 Dot3D offset = computeRelativeDisplacement(phi, gradient); 03179 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03180 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03181 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03182 plint iX2 = iX+offset.x; 03183 plint iY2 = iY+offset.y; 03184 plint iZ2 = iZ+offset.z; 03185 gradient.get(iX2,iY2,iZ2)[0] = 03186 fdDataField::planeXderiv(phi,direction,orientation, iX,iY,iZ); 03187 gradient.get(iX2,iY2,iZ2)[1] = 03188 fdDataField::planeYderiv(phi,direction,orientation, iX,iY,iZ); 03189 gradient.get(iX2,iY2,iZ2)[2] = 03190 fdDataField::planeZderiv(phi,direction,orientation, iX,iY,iZ); 03191 } 03192 } 03193 } 03194 } 03195 03196 template<typename T> 03197 void BoxGradientFunctional3D<T>::processEdge ( 03198 int plane, int normal1, int normal2, Box3D domain, 03199 ScalarField3D<T>& phi, TensorField3D<T,3>& gradient ) 03200 { 03201 Dot3D offset = computeRelativeDisplacement(phi, gradient); 03202 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03203 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03204 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03205 plint iX2 = iX+offset.x; 03206 plint iY2 = iY+offset.y; 03207 plint iZ2 = iZ+offset.z; 03208 gradient.get(iX2,iY2,iZ2)[0] = 03209 fdDataField::edgeXderiv(phi,plane,normal1,normal2, iX,iY,iZ); 03210 gradient.get(iX2,iY2,iZ2)[1] = 03211 fdDataField::edgeYderiv(phi,plane,normal1,normal2, iX,iY,iZ); 03212 gradient.get(iX2,iY2,iZ2)[2] = 03213 fdDataField::edgeZderiv(phi,plane,normal1,normal2, iX,iY,iZ); 03214 } 03215 } 03216 } 03217 } 03218 03219 template<typename T> 03220 void BoxGradientFunctional3D<T>::processCorner ( 03221 int normalX, int normalY, int normalZ, Box3D domain, 03222 ScalarField3D<T>& phi, TensorField3D<T,3>& gradient ) 03223 { 03224 03225 Dot3D offset = computeRelativeDisplacement(phi, gradient); 03226 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03227 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03228 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03229 plint iX2 = iX+offset.x; 03230 plint iY2 = iY+offset.y; 03231 plint iZ2 = iZ+offset.z; 03232 gradient.get(iX2,iY2,iZ2)[0] = 03233 fdDataField::cornerXderiv(phi,normalX,normalY,normalZ, iX,iY,iZ); 03234 gradient.get(iX2,iY2,iZ2)[1] = 03235 fdDataField::cornerYderiv(phi,normalX,normalY,normalZ, iX,iY,iZ); 03236 gradient.get(iX2,iY2,iZ2)[2] = 03237 fdDataField::cornerZderiv(phi,normalX,normalY,normalZ, iX,iY,iZ); 03238 } 03239 } 03240 } 03241 } 03242 03243 03244 template<typename T> 03245 BoxGradientFunctional3D<T>* BoxGradientFunctional3D<T>::clone() const 03246 { 03247 return new BoxGradientFunctional3D<T>(*this); 03248 } 03249 03250 template<typename T> 03251 void BoxGradientFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03252 modified[0] = modif::nothing; 03253 modified[1] = modif::staticVariables; 03254 } 03255 03256 03257 template<typename T> 03258 BlockDomain::DomainT BoxGradientFunctional3D<T>::appliesTo() const { 03259 // Don't apply to envelope, because nearest neighbors need to be accessed. 03260 return BlockDomain::bulk; 03261 } 03262 03263 03264 template<typename T, int nDim> 03265 void BoxBulkVorticityFunctional3D<T,nDim>::process ( 03266 Box3D domain, TensorField3D<T,nDim>& velocity, 03267 TensorField3D<T,nDim>& vorticity ) 03268 { 03269 Dot3D offset = computeRelativeDisplacement(velocity, vorticity); 03270 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03271 plint iX2 = iX+offset.x; 03272 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03273 plint iY2 = iY+offset.y; 03274 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03275 plint iZ2 = iZ+offset.z; 03276 vorticity.get(iX2,iY2,iZ2)[0] = 03277 fdDataField::bulkVorticityX(velocity, iX,iY,iZ); 03278 vorticity.get(iX2,iY2,iZ2)[1] = 03279 fdDataField::bulkVorticityY(velocity, iX,iY,iZ); 03280 vorticity.get(iX2,iY2,iZ2)[2] = 03281 fdDataField::bulkVorticityZ(velocity, iX,iY,iZ); 03282 } 03283 } 03284 } 03285 } 03286 03287 template<typename T, int nDim> 03288 BoxBulkVorticityFunctional3D<T,nDim>* BoxBulkVorticityFunctional3D<T,nDim>::clone() const 03289 { 03290 return new BoxBulkVorticityFunctional3D<T,nDim>(*this); 03291 } 03292 03293 template<typename T, int nDim> 03294 void BoxBulkVorticityFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03295 modified[0] = modif::nothing; 03296 modified[1] = modif::staticVariables; 03297 } 03298 03299 template<typename T, int nDim> 03300 BlockDomain::DomainT BoxBulkVorticityFunctional3D<T,nDim>::appliesTo() const { 03301 return BlockDomain::bulk; 03302 } 03303 03304 03305 template<typename T, int nDim> 03306 void BoxVorticityFunctional3D<T,nDim>::processBulk ( 03307 Box3D domain, TensorField3D<T,nDim>& velocity, TensorField3D<T,nDim>& vorticity ) 03308 { 03309 Dot3D offset = computeRelativeDisplacement(velocity, vorticity); 03310 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03311 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03312 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03313 plint iX2 = iX+offset.x; 03314 plint iY2 = iY+offset.y; 03315 plint iZ2 = iZ+offset.z; 03316 vorticity.get(iX2,iY2,iZ2)[0] = 03317 fdDataField::bulkVorticityX(velocity, iX,iY,iZ); 03318 vorticity.get(iX2,iY2,iZ2)[1] = 03319 fdDataField::bulkVorticityY(velocity, iX,iY,iZ); 03320 vorticity.get(iX2,iY2,iZ2)[2] = 03321 fdDataField::bulkVorticityZ(velocity, iX,iY,iZ); 03322 } 03323 } 03324 } 03325 } 03326 03327 template<typename T, int nDim> 03328 void BoxVorticityFunctional3D<T,nDim>::processPlane ( 03329 int direction, int orientation, Box3D domain, 03330 TensorField3D<T,nDim>& velocity, TensorField3D<T,nDim>& vorticity ) 03331 { 03332 Dot3D offset = computeRelativeDisplacement(velocity, vorticity); 03333 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03334 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03335 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03336 plint iX2 = iX+offset.x; 03337 plint iY2 = iY+offset.y; 03338 plint iZ2 = iZ+offset.z; 03339 vorticity.get(iX2,iY2,iZ2)[0] = 03340 fdDataField::planeVorticityX(velocity,direction,orientation, iX,iY,iZ); 03341 vorticity.get(iX2,iY2,iZ2)[1] = 03342 fdDataField::planeVorticityY(velocity,direction,orientation, iX,iY,iZ); 03343 vorticity.get(iX2,iY2,iZ2)[2] = 03344 fdDataField::planeVorticityZ(velocity,direction,orientation, iX,iY,iZ); 03345 } 03346 } 03347 } 03348 } 03349 03350 template<typename T, int nDim> 03351 void BoxVorticityFunctional3D<T,nDim>::processEdge ( 03352 int plane, int normal1, int normal2, Box3D domain, 03353 TensorField3D<T,nDim>& velocity, TensorField3D<T,nDim>& vorticity ) 03354 { 03355 Dot3D offset = computeRelativeDisplacement(velocity, vorticity); 03356 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03357 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03358 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03359 plint iX2 = iX+offset.x; 03360 plint iY2 = iY+offset.y; 03361 plint iZ2 = iZ+offset.z; 03362 vorticity.get(iX2,iY2,iZ2)[0] = 03363 fdDataField::edgeVorticityX(velocity,plane,normal1,normal2, iX,iY,iZ); 03364 vorticity.get(iX2,iY2,iZ2)[1] = 03365 fdDataField::edgeVorticityY(velocity,plane,normal1,normal2, iX,iY,iZ); 03366 vorticity.get(iX2,iY2,iZ2)[2] = 03367 fdDataField::edgeVorticityZ(velocity,plane,normal1,normal2, iX,iY,iZ); 03368 } 03369 } 03370 } 03371 } 03372 03373 template<typename T, int nDim> 03374 void BoxVorticityFunctional3D<T,nDim>::processCorner ( 03375 int normalX, int normalY, int normalZ, Box3D domain, 03376 TensorField3D<T,nDim>& velocity, TensorField3D<T,nDim>& vorticity ) 03377 { 03378 03379 Dot3D offset = computeRelativeDisplacement(velocity, vorticity); 03380 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03381 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03382 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03383 plint iX2 = iX+offset.x; 03384 plint iY2 = iY+offset.y; 03385 plint iZ2 = iZ+offset.z; 03386 vorticity.get(iX2,iY2,iZ2)[0] = 03387 fdDataField::cornerVorticityX(velocity,normalX,normalY,normalZ, iX,iY,iZ); 03388 vorticity.get(iX2,iY2,iZ2)[1] = 03389 fdDataField::cornerVorticityY(velocity,normalX,normalY,normalZ, iX,iY,iZ); 03390 vorticity.get(iX2,iY2,iZ2)[2] = 03391 fdDataField::cornerVorticityZ(velocity,normalX,normalY,normalZ, iX,iY,iZ); 03392 } 03393 } 03394 } 03395 } 03396 03397 03398 template<typename T, int nDim> 03399 BoxVorticityFunctional3D<T,nDim>* BoxVorticityFunctional3D<T,nDim>::clone() const 03400 { 03401 return new BoxVorticityFunctional3D<T,nDim>(*this); 03402 } 03403 03404 template<typename T, int nDim> 03405 void BoxVorticityFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03406 modified[0] = modif::nothing; 03407 modified[1] = modif::staticVariables; 03408 } 03409 03410 03411 template<typename T, int nDim> 03412 BlockDomain::DomainT BoxVorticityFunctional3D<T,nDim>::appliesTo() const { 03413 // Don't apply to envelope, because nearest neighbors need to be accessed. 03414 return BlockDomain::bulk; 03415 } 03416 03417 03418 template<typename T, int nDim> 03419 void BoxBulkStrainRateFunctional3D<T,nDim>::process ( 03420 Box3D domain, TensorField3D<T,nDim>& velocity, 03421 TensorField3D<T,SymmetricTensorImpl<T,nDim>::n>& S ) 03422 { 03423 typedef SymmetricTensorImpl<T,nDim> tensor; 03424 Dot3D offset = computeRelativeDisplacement(velocity, S); 03425 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03426 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03427 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03428 plint iX2 = iX+offset.x; 03429 plint iY2 = iY+offset.y; 03430 plint iZ2 = iZ+offset.z; 03431 Array<T,SymmetricTensorImpl<T,nDim>::n>& el = S.get(iX2,iY2,iZ2); 03432 el[tensor::xx] = fdDataField::bulkXderiv(velocity, iX, iY, iZ, 0); 03433 el[tensor::xy] = ( fdDataField::bulkXderiv(velocity, iX, iY, iZ, 1) + 03434 fdDataField::bulkYderiv(velocity, iX, iY, iZ, 0) ) / (T)2; 03435 el[tensor::xz] = ( fdDataField::bulkXderiv(velocity, iX, iY, iZ, 2) + 03436 fdDataField::bulkZderiv(velocity, iX, iY, iZ, 0) ) / (T)2; 03437 el[tensor::yy] = fdDataField::bulkYderiv(velocity, iX, iY, iZ, 1); 03438 el[tensor::yz] = ( fdDataField::bulkYderiv(velocity, iX, iY, iZ, 2) + 03439 fdDataField::bulkZderiv(velocity, iX, iY, iZ, 1) ) / (T)2; 03440 el[tensor::zz] = fdDataField::bulkZderiv(velocity, iX, iY, iZ, 2); 03441 } 03442 } 03443 } 03444 } 03445 03446 template<typename T, int nDim> 03447 BoxBulkStrainRateFunctional3D<T,nDim>* BoxBulkStrainRateFunctional3D<T,nDim>::clone() const 03448 { 03449 return new BoxBulkStrainRateFunctional3D<T,nDim>(*this); 03450 } 03451 03452 template<typename T, int nDim> 03453 void BoxBulkStrainRateFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03454 modified[0] = modif::nothing; 03455 modified[1] = modif::staticVariables; 03456 } 03457 03458 template<typename T, int nDim> 03459 BlockDomain::DomainT BoxBulkStrainRateFunctional3D<T,nDim>::appliesTo() const { 03460 // return BlockDomain::bulkAndEnvelope; 03461 return BlockDomain::bulk; 03462 } 03463 03464 03465 template<typename T, int nDim> 03466 void BoxStrainRateFunctional3D<T,nDim>::processBulk ( 03467 Box3D domain, TensorField3D<T,nDim>& velocity, TensorField3D<T,SymmetricTensorImpl<T,nDim>::n>& S ) 03468 { 03469 typedef SymmetricTensorImpl<T,nDim> tensor; 03470 Dot3D offset = computeRelativeDisplacement(velocity, S); 03471 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03472 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03473 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03474 plint iX2 = iX+offset.x; 03475 plint iY2 = iY+offset.y; 03476 plint iZ2 = iZ+offset.z; 03477 Array<T,SymmetricTensorImpl<T,nDim>::n>& el = S.get(iX2,iY2,iZ2); 03478 el[tensor::xx] = fdDataField::bulkXderiv(velocity, iX, iY, iZ, 0); 03479 el[tensor::xy] = ( fdDataField::bulkXderiv(velocity, iX, iY, iZ, 1) + 03480 fdDataField::bulkYderiv(velocity, iX, iY, iZ, 0) ) / (T)2; 03481 el[tensor::xz] = ( fdDataField::bulkXderiv(velocity, iX, iY, iZ, 2) + 03482 fdDataField::bulkZderiv(velocity, iX, iY, iZ, 0) ) / (T)2; 03483 el[tensor::yy] = fdDataField::bulkYderiv(velocity, iX, iY, iZ, 1); 03484 el[tensor::yz] = ( fdDataField::bulkYderiv(velocity, iX, iY, iZ, 2) + 03485 fdDataField::bulkZderiv(velocity, iX, iY, iZ, 1) ) / (T)2; 03486 el[tensor::zz] = fdDataField::bulkZderiv(velocity, iX, iY, iZ, 2); 03487 } 03488 } 03489 } 03490 } 03491 03492 template<typename T, int nDim> 03493 void BoxStrainRateFunctional3D<T,nDim>::processPlane ( 03494 int direction, int orientation, Box3D domain, 03495 TensorField3D<T,nDim>& velocity, TensorField3D<T,SymmetricTensorImpl<T,nDim>::n>& S ) 03496 { 03497 typedef SymmetricTensorImpl<T,nDim> tensor; 03498 Dot3D offset = computeRelativeDisplacement(velocity, S); 03499 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03500 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03501 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03502 plint iX2 = iX+offset.x; 03503 plint iY2 = iY+offset.y; 03504 plint iZ2 = iZ+offset.z; 03505 Array<T,SymmetricTensorImpl<T,nDim>::n>& el = S.get(iX2,iY2,iZ2); 03506 el[tensor::xx] = fdDataField::planeXderiv(velocity, direction,orientation, iX, iY, iZ, 0); 03507 el[tensor::xy] = ( fdDataField::planeXderiv(velocity, direction,orientation, iX, iY, iZ, 1) + 03508 fdDataField::planeYderiv(velocity, direction,orientation, iX, iY, iZ, 0) ) / (T)2; 03509 el[tensor::xz] = ( fdDataField::planeXderiv(velocity, direction,orientation, iX, iY, iZ, 2) + 03510 fdDataField::planeZderiv(velocity, direction,orientation, iX, iY, iZ, 0) ) / (T)2; 03511 el[tensor::yy] = fdDataField::planeYderiv(velocity, direction,orientation, iX, iY, iZ, 1); 03512 el[tensor::yz] = ( fdDataField::planeYderiv(velocity, direction,orientation, iX, iY, iZ, 2) + 03513 fdDataField::planeZderiv(velocity, direction,orientation, iX, iY, iZ, 1) ) / (T)2; 03514 el[tensor::zz] = fdDataField::planeZderiv(velocity, direction,orientation, iX, iY, iZ, 2); 03515 } 03516 } 03517 } 03518 } 03519 03520 template<typename T, int nDim> 03521 void BoxStrainRateFunctional3D<T,nDim>::processEdge ( 03522 int plane, int normal1, int normal2, Box3D domain, 03523 TensorField3D<T,nDim>& velocity, TensorField3D<T,SymmetricTensorImpl<T,nDim>::n>& S ) 03524 { 03525 typedef SymmetricTensorImpl<T,nDim> tensor; 03526 Dot3D offset = computeRelativeDisplacement(velocity, S); 03527 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03528 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03529 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03530 plint iX2 = iX+offset.x; 03531 plint iY2 = iY+offset.y; 03532 plint iZ2 = iZ+offset.z; 03533 Array<T,SymmetricTensorImpl<T,nDim>::n>& el = S.get(iX2,iY2,iZ2); 03534 el[tensor::xx] = fdDataField::edgeXderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 0); 03535 el[tensor::xy] = ( fdDataField::edgeXderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 1) + 03536 fdDataField::edgeYderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 0) ) / (T)2; 03537 el[tensor::xz] = ( fdDataField::edgeXderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 2) + 03538 fdDataField::edgeZderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 0) ) / (T)2; 03539 el[tensor::yy] = fdDataField::edgeYderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 1); 03540 el[tensor::yz] = ( fdDataField::edgeYderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 2) + 03541 fdDataField::edgeZderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 1) ) / (T)2; 03542 el[tensor::zz] = fdDataField::edgeZderiv(velocity, plane,normal1,normal2, iX, iY, iZ, 2); 03543 } 03544 } 03545 } 03546 } 03547 03548 template<typename T, int nDim> 03549 void BoxStrainRateFunctional3D<T,nDim>::processCorner ( 03550 int normalX, int normalY, int normalZ, Box3D domain, 03551 TensorField3D<T,nDim>& velocity, TensorField3D<T,SymmetricTensorImpl<T,nDim>::n>& S ) 03552 { 03553 03554 typedef SymmetricTensorImpl<T,nDim> tensor; 03555 Dot3D offset = computeRelativeDisplacement(velocity, S); 03556 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03557 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03558 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03559 plint iX2 = iX+offset.x; 03560 plint iY2 = iY+offset.y; 03561 plint iZ2 = iZ+offset.z; 03562 Array<T,SymmetricTensorImpl<T,nDim>::n>& el = S.get(iX2,iY2,iZ2); 03563 el[tensor::xx] = fdDataField::cornerXderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 0); 03564 el[tensor::xy] = ( fdDataField::cornerXderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 1) + 03565 fdDataField::cornerYderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 0) ) / (T)2; 03566 el[tensor::xz] = ( fdDataField::cornerXderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 2) + 03567 fdDataField::cornerZderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 0) ) / (T)2; 03568 el[tensor::yy] = fdDataField::cornerYderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 1); 03569 el[tensor::yz] = ( fdDataField::cornerYderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 2) + 03570 fdDataField::cornerZderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 1) ) / (T)2; 03571 el[tensor::zz] = fdDataField::cornerZderiv(velocity, normalX,normalY,normalZ, iX, iY, iZ, 2); 03572 } 03573 } 03574 } 03575 } 03576 03577 03578 template<typename T, int nDim> 03579 BoxStrainRateFunctional3D<T,nDim>* BoxStrainRateFunctional3D<T,nDim>::clone() const 03580 { 03581 return new BoxStrainRateFunctional3D<T,nDim>(*this); 03582 } 03583 03584 template<typename T, int nDim> 03585 void BoxStrainRateFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03586 modified[0] = modif::nothing; 03587 modified[1] = modif::staticVariables; 03588 } 03589 03590 template<typename T, int nDim> 03591 BlockDomain::DomainT BoxStrainRateFunctional3D<T,nDim>::appliesTo() const { 03592 // Don't apply to envelope, because nearest neighbors need to be accessed. 03593 return BlockDomain::bulk; 03594 } 03595 03596 03597 /* ******** BoxBulkDivergenceFunctional3D ****************************************** */ 03598 03599 template<typename T, int nDim> 03600 void BoxBulkDivergenceFunctional3D<T,nDim>::process ( 03601 Box3D domain, ScalarField3D<T>& divergence, 03602 TensorField3D<T,nDim>& velocity ) 03603 { 03604 Dot3D offset = computeRelativeDisplacement(divergence, velocity); 03605 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03606 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03607 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03608 plint iX2 = iX+offset.x; 03609 plint iY2 = iY+offset.y; 03610 plint iZ2 = iZ+offset.z; 03611 divergence.get(iX,iY,iZ) = 03612 fdDataField::bulkXderiv(velocity, iX2,iY2,iZ2, 0) + 03613 fdDataField::bulkYderiv(velocity, iX2,iY2,iZ2, 1) + 03614 fdDataField::bulkZderiv(velocity, iX2,iY2,iZ2, 2); 03615 } 03616 } 03617 } 03618 } 03619 03620 template<typename T, int nDim> 03621 BoxBulkDivergenceFunctional3D<T,nDim>* BoxBulkDivergenceFunctional3D<T,nDim>::clone() const 03622 { 03623 return new BoxBulkDivergenceFunctional3D<T,nDim>(*this); 03624 } 03625 03626 template<typename T, int nDim> 03627 void BoxBulkDivergenceFunctional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03628 modified[0] = modif::staticVariables; // Divergence. 03629 modified[1] = modif::nothing; // Velocity. 03630 } 03631 03632 template<typename T, int nDim> 03633 BlockDomain::DomainT BoxBulkDivergenceFunctional3D<T,nDim>::appliesTo() const { 03634 return BlockDomain::bulk; 03635 } 03636 03637 03638 /* ******** Tensor__B_functional3D ****************************************** */ 03639 03640 template<typename T, int nDim> 03641 void Tensor_A_plus_B_functional3D<T,nDim>::process ( 03642 Box3D domain, std::vector<TensorField3D<T,nDim>*> fields ) 03643 { 03644 PLB_PRECONDITION( fields.size()==3 ); 03645 TensorField3D<T,nDim>& A = *fields[0]; 03646 TensorField3D<T,nDim>& B = *fields[1]; 03647 TensorField3D<T,nDim>& result = *fields[2]; 03648 Dot3D offsetB = computeRelativeDisplacement(A,B); 03649 Dot3D offsetResult = computeRelativeDisplacement(A,result); 03650 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03651 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03652 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03653 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 03654 = A.get(iX,iY,iZ) + B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 03655 } 03656 } 03657 } 03658 } 03659 03660 template<typename T, int nDim> 03661 Tensor_A_plus_B_functional3D<T,nDim>* Tensor_A_plus_B_functional3D<T,nDim>::clone() const { 03662 return new Tensor_A_plus_B_functional3D<T,nDim>(*this); 03663 } 03664 03665 template<typename T, int nDim> 03666 void Tensor_A_plus_B_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03667 modified[0] = modif::nothing; 03668 modified[1] = modif::nothing; 03669 modified[2] = modif::staticVariables; 03670 } 03671 03672 template<typename T, int nDim> 03673 BlockDomain::DomainT Tensor_A_plus_B_functional3D<T,nDim>::appliesTo() const { 03674 return BlockDomain::bulkAndEnvelope; 03675 } 03676 03677 03678 /* ******** Tensor_A_minus_B_functional3D ************************************ */ 03679 03680 template<typename T, int nDim> 03681 void Tensor_A_minus_B_functional3D<T,nDim>::process ( 03682 Box3D domain, std::vector<TensorField3D<T,nDim>*> fields ) 03683 { 03684 PLB_PRECONDITION( fields.size()==3 ); 03685 TensorField3D<T,nDim>& A = *fields[0]; 03686 TensorField3D<T,nDim>& B = *fields[1]; 03687 TensorField3D<T,nDim>& result = *fields[2]; 03688 Dot3D offsetB = computeRelativeDisplacement(A,B); 03689 Dot3D offsetResult = computeRelativeDisplacement(A,result); 03690 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03691 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03692 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03693 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 03694 = A.get(iX,iY,iZ) - B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 03695 } 03696 } 03697 } 03698 } 03699 03700 template<typename T, int nDim> 03701 Tensor_A_minus_B_functional3D<T,nDim>* Tensor_A_minus_B_functional3D<T,nDim>::clone() const { 03702 return new Tensor_A_minus_B_functional3D<T,nDim>(*this); 03703 } 03704 03705 template<typename T, int nDim> 03706 void Tensor_A_minus_B_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03707 modified[0] = modif::nothing; 03708 modified[1] = modif::nothing; 03709 modified[2] = modif::staticVariables; 03710 } 03711 03712 template<typename T, int nDim> 03713 BlockDomain::DomainT Tensor_A_minus_B_functional3D<T,nDim>::appliesTo() const { 03714 return BlockDomain::bulkAndEnvelope; 03715 } 03716 03717 03718 /* ******** Tensor_A_times_B_functional3D ************************************ */ 03719 03720 template<typename T, int nDim> 03721 void Tensor_A_times_B_functional3D<T,nDim>::process ( 03722 Box3D domain, std::vector<TensorField3D<T,nDim>*> fields ) 03723 { 03724 PLB_PRECONDITION( fields.size()==3 ); 03725 TensorField3D<T,nDim>& A = *fields[0]; 03726 TensorField3D<T,nDim>& B = *fields[1]; 03727 TensorField3D<T,nDim>& result = *fields[2]; 03728 Dot3D offsetB = computeRelativeDisplacement(A,B); 03729 Dot3D offsetResult = computeRelativeDisplacement(A,result); 03730 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03731 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03732 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03733 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 03734 = A.get(iX,iY,iZ) * B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 03735 } 03736 } 03737 } 03738 } 03739 03740 template<typename T, int nDim> 03741 Tensor_A_times_B_functional3D<T,nDim>* Tensor_A_times_B_functional3D<T,nDim>::clone() const { 03742 return new Tensor_A_times_B_functional3D<T,nDim>(*this); 03743 } 03744 03745 template<typename T, int nDim> 03746 void Tensor_A_times_B_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03747 modified[0] = modif::nothing; 03748 modified[1] = modif::nothing; 03749 modified[2] = modif::staticVariables; 03750 } 03751 03752 template<typename T, int nDim> 03753 BlockDomain::DomainT Tensor_A_times_B_functional3D<T,nDim>::appliesTo() const { 03754 return BlockDomain::bulkAndEnvelope; 03755 } 03756 03757 03758 /* ******** Tensor_A_dividedBy_B_functional3D ************************************ */ 03759 03760 template<typename T, int nDim> 03761 void Tensor_A_dividedBy_B_functional3D<T,nDim>::process ( 03762 Box3D domain, std::vector<TensorField3D<T,nDim>*> fields ) 03763 { 03764 PLB_PRECONDITION( fields.size()==3 ); 03765 TensorField3D<T,nDim>& A = *fields[0]; 03766 TensorField3D<T,nDim>& B = *fields[1]; 03767 TensorField3D<T,nDim>& result = *fields[2]; 03768 Dot3D offsetB = computeRelativeDisplacement(A,B); 03769 Dot3D offsetResult = computeRelativeDisplacement(A,result); 03770 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03771 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03772 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03773 result.get(iX+offsetResult.x,iY+offsetResult.y,iZ+offsetResult.z) 03774 = A.get(iX,iY,iZ) / B.get(iX+offsetB.x,iY+offsetB.y,iZ+offsetB.z); 03775 } 03776 } 03777 } 03778 } 03779 03780 template<typename T, int nDim> 03781 Tensor_A_dividedBy_B_functional3D<T,nDim>* Tensor_A_dividedBy_B_functional3D<T,nDim>::clone() const { 03782 return new Tensor_A_dividedBy_B_functional3D<T,nDim>(*this); 03783 } 03784 03785 template<typename T, int nDim> 03786 void Tensor_A_dividedBy_B_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03787 modified[0] = modif::nothing; 03788 modified[1] = modif::nothing; 03789 modified[2] = modif::staticVariables; 03790 } 03791 03792 template<typename T, int nDim> 03793 BlockDomain::DomainT Tensor_A_dividedBy_B_functional3D<T,nDim>::appliesTo() const { 03794 return BlockDomain::bulkAndEnvelope; 03795 } 03796 03797 03798 /* ******** Tensor_A_plus_B_inplace_functional3D ************************************ */ 03799 03800 template<typename T, int nDim> 03801 void Tensor_A_plus_B_inplace_functional3D<T,nDim>::process ( 03802 Box3D domain, TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 03803 { 03804 Dot3D offset = computeRelativeDisplacement(A,B); 03805 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03806 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03807 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03808 A.get(iX,iY,iZ) += B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03809 } 03810 } 03811 } 03812 } 03813 03814 template<typename T, int nDim> 03815 Tensor_A_plus_B_inplace_functional3D<T,nDim>* Tensor_A_plus_B_inplace_functional3D<T,nDim>::clone() const { 03816 return new Tensor_A_plus_B_inplace_functional3D<T,nDim>(*this); 03817 } 03818 03819 template<typename T, int nDim> 03820 void Tensor_A_plus_B_inplace_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03821 modified[0] = modif::staticVariables; 03822 modified[1] = modif::nothing; 03823 } 03824 03825 template<typename T, int nDim> 03826 BlockDomain::DomainT Tensor_A_plus_B_inplace_functional3D<T,nDim>::appliesTo() const { 03827 return BlockDomain::bulkAndEnvelope; 03828 } 03829 03830 03831 /* ******** Tensor_A_minus_B_inplace_functional3D ************************************ */ 03832 03833 template<typename T, int nDim> 03834 void Tensor_A_minus_B_inplace_functional3D<T,nDim>::process ( 03835 Box3D domain, TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 03836 { 03837 Dot3D offset = computeRelativeDisplacement(A,B); 03838 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03839 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03840 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03841 A.get(iX,iY,iZ) -= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03842 } 03843 } 03844 } 03845 } 03846 03847 template<typename T, int nDim> 03848 Tensor_A_minus_B_inplace_functional3D<T,nDim>* Tensor_A_minus_B_inplace_functional3D<T,nDim>::clone() const { 03849 return new Tensor_A_minus_B_inplace_functional3D<T,nDim>(*this); 03850 } 03851 03852 template<typename T, int nDim> 03853 void Tensor_A_minus_B_inplace_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03854 modified[0] = modif::staticVariables; 03855 modified[1] = modif::nothing; 03856 } 03857 03858 template<typename T, int nDim> 03859 BlockDomain::DomainT Tensor_A_minus_B_inplace_functional3D<T,nDim>::appliesTo() const { 03860 return BlockDomain::bulkAndEnvelope; 03861 } 03862 03863 03864 /* ******** Tensor_A_times_B_inplace_functional3D ************************************ */ 03865 03866 template<typename T, int nDim> 03867 void Tensor_A_times_B_inplace_functional3D<T,nDim>::process ( 03868 Box3D domain, TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 03869 { 03870 Dot3D offset = computeRelativeDisplacement(A,B); 03871 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03872 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03873 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03874 A.get(iX,iY,iZ) *= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03875 } 03876 } 03877 } 03878 } 03879 03880 template<typename T, int nDim> 03881 Tensor_A_times_B_inplace_functional3D<T,nDim>* Tensor_A_times_B_inplace_functional3D<T,nDim>::clone() const { 03882 return new Tensor_A_times_B_inplace_functional3D<T,nDim>(*this); 03883 } 03884 03885 template<typename T, int nDim> 03886 void Tensor_A_times_B_inplace_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 03887 modified[0] = modif::staticVariables; 03888 modified[1] = modif::nothing; 03889 } 03890 03891 template<typename T, int nDim> 03892 BlockDomain::DomainT Tensor_A_times_B_inplace_functional3D<T,nDim>::appliesTo() const { 03893 return BlockDomain::bulkAndEnvelope; 03894 } 03895 03896 03897 /* ******** Tensor_A_times_alpha_inplace_functional3D ************************************ */ 03898 03899 template<typename T, int nDim> 03900 Tensor_A_times_alpha_inplace_functional3D<T,nDim>:: 03901 Tensor_A_times_alpha_inplace_functional3D(T alpha_) 03902 : alpha(alpha_) 03903 { } 03904 03905 template<typename T, int nDim> 03906 void Tensor_A_times_alpha_inplace_functional3D<T,nDim>::process ( 03907 Box3D domain, TensorField3D<T,nDim>& A) 03908 { 03909 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03910 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03911 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03912 A.get(iX,iY,iZ) *= alpha; 03913 } 03914 } 03915 } 03916 } 03917 03918 template<typename T, int nDim> 03919 Tensor_A_times_alpha_inplace_functional3D<T,nDim>* 03920 Tensor_A_times_alpha_inplace_functional3D<T,nDim>::clone() const 03921 { 03922 return new Tensor_A_times_alpha_inplace_functional3D<T,nDim>(*this); 03923 } 03924 03925 template<typename T, int nDim> 03926 void Tensor_A_times_alpha_inplace_functional3D<T,nDim>:: 03927 getTypeOfModification(std::vector<modif::ModifT>& modified) const 03928 { 03929 modified[0] = modif::staticVariables; 03930 } 03931 03932 template<typename T, int nDim> 03933 BlockDomain::DomainT Tensor_A_times_alpha_inplace_functional3D<T,nDim>::appliesTo() const { 03934 return BlockDomain::bulkAndEnvelope; 03935 } 03936 03937 /* ******** Tensor_A_times_alpha_functional3D ************************************ */ 03938 03939 template<typename T, int nDim> 03940 Tensor_A_times_alpha_functional3D<T,nDim>:: 03941 Tensor_A_times_alpha_functional3D(T alpha_) 03942 : alpha(alpha_) 03943 { } 03944 03945 template<typename T, int nDim> 03946 void Tensor_A_times_alpha_functional3D<T,nDim>::process ( 03947 Box3D domain, TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& result) 03948 { 03949 Dot3D offset = computeRelativeDisplacement(A, result); 03950 03951 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03952 plint bX = iX + offset.x; 03953 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03954 plint bY = iY + offset.y; 03955 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03956 plint bZ = iZ + offset.z; 03957 result.get(bX,bY,bZ) = alpha*A.get(iX,iY,iZ); 03958 } 03959 } 03960 } 03961 } 03962 03963 template<typename T, int nDim> 03964 Tensor_A_times_alpha_functional3D<T,nDim>* 03965 Tensor_A_times_alpha_functional3D<T,nDim>::clone() const 03966 { 03967 return new Tensor_A_times_alpha_functional3D<T,nDim>(*this); 03968 } 03969 03970 template<typename T, int nDim> 03971 void Tensor_A_times_alpha_functional3D<T,nDim>:: 03972 getTypeOfModification(std::vector<modif::ModifT>& modified) const 03973 { 03974 modified[0] = modif::nothing; 03975 modified[1] = modif::staticVariables; 03976 } 03977 03978 template<typename T, int nDim> 03979 BlockDomain::DomainT Tensor_A_times_alpha_functional3D<T,nDim>::appliesTo() const { 03980 return BlockDomain::bulkAndEnvelope; 03981 } 03982 03983 03984 /* ******** Tensor_A_dividedBy_B_inplace_functional3D ************************************ */ 03985 03986 template<typename T, int nDim> 03987 void Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>::process ( 03988 Box3D domain, TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 03989 { 03990 Dot3D offset = computeRelativeDisplacement(A,B); 03991 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 03992 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 03993 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 03994 A.get(iX,iY,iZ) /= B.get(iX+offset.x,iY+offset.y,iZ+offset.z); 03995 } 03996 } 03997 } 03998 } 03999 04000 template<typename T, int nDim> 04001 Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>* Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>::clone() const { 04002 return new Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>(*this); 04003 } 04004 04005 template<typename T, int nDim> 04006 void Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 04007 modified[0] = modif::staticVariables; 04008 modified[1] = modif::nothing; 04009 } 04010 04011 template<typename T, int nDim> 04012 BlockDomain::DomainT Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>::appliesTo() const { 04013 return BlockDomain::bulkAndEnvelope; 04014 } 04015 04016 04017 04018 /* ************* Class LBMsmoothen3D ******************* */ 04019 04020 template<typename T, template<typename U> class Descriptor> 04021 void LBMsmoothen3D<T,Descriptor>::process ( 04022 Box3D domain, ScalarField3D<T>& data, ScalarField3D<T>& result) 04023 { 04024 typedef Descriptor<T> D; 04025 Dot3D offset = computeRelativeDisplacement(data, result); 04026 // Define dimensions of a viscosity. 04027 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 04028 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 04029 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 04030 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) = (T)0; 04031 for (plint iPop=0; iPop<D::q; ++iPop) { 04032 plint nextX = iX+D::c[iPop][0]; 04033 plint nextY = iY+D::c[iPop][1]; 04034 plint nextZ = iZ+D::c[iPop][2]; 04035 result.get(iX+offset.x,iY+offset.y,iZ+offset.z) += 04036 D::t[iPop] * data.get(nextX,nextY,nextZ); 04037 } 04038 } 04039 } 04040 } 04041 } 04042 04043 template<typename T, template<typename U> class Descriptor> 04044 LBMsmoothen3D<T,Descriptor>* 04045 LBMsmoothen3D<T,Descriptor>::clone() const 04046 { 04047 return new LBMsmoothen3D<T,Descriptor>(*this); 04048 } 04049 04050 template<typename T, template<typename U> class Descriptor> 04051 BlockDomain::DomainT LBMsmoothen3D<T,Descriptor>::appliesTo() const 04052 { 04053 return BlockDomain::bulk; 04054 } 04055 04056 template<typename T, template<typename U> class Descriptor> 04057 void LBMsmoothen3D<T,Descriptor>::getTypeOfModification ( 04058 std::vector<modif::ModifT>& modified) const 04059 { 04060 modified[0] = modif::nothing; 04061 modified[1] = modif::staticVariables; 04062 } 04063 04064 } // namespace plb 04065 04066 #endif // DATA_ANALYSIS_FUNCTIONAL_3D_HH
1.6.3
1.6.3