$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_WRAPPER_3D_HH 00029 #define DATA_ANALYSIS_WRAPPER_3D_HH 00030 00031 #include "dataProcessors/dataAnalysisWrapper3D.h" 00032 #include "dataProcessors/dataAnalysisFunctional3D.h" 00033 #include "atomicBlock/reductiveDataProcessorWrapper3D.h" 00034 #include "atomicBlock/dataProcessorWrapper3D.h" 00035 #include "multiBlock/reductiveMultiDataProcessorWrapper3D.h" 00036 #include "multiBlock/multiDataProcessorWrapper3D.h" 00037 #include "multiBlock/multiBlockGenerator3D.h" 00038 00039 namespace plb { 00040 00041 /* ******************************************************************* */ 00042 /* *************** PART I. Atomic-block wrappers: Block-Lattice ****** */ 00043 /* ******************************************************************* */ 00044 00045 /* *************** Reductive functions ******************************* */ 00046 00047 template<typename T, template<typename U> class Descriptor> 00048 T computeAverageDensity(BlockLattice3D<T,Descriptor>& lattice, Box3D domain) { 00049 BoxSumRhoBarFunctional3D<T,Descriptor> functional; 00050 applyProcessingFunctional(functional, domain, lattice); 00051 return Descriptor<T>::fullRho( functional.getSumRhoBar() / (T) domain.nCells() ); 00052 } 00053 00054 template<typename T, template<typename U> class Descriptor> 00055 T computeAverageDensity(BlockLattice3D<T,Descriptor>& lattice) { 00056 return computeAverageDensity(lattice, lattice.getBoundingBox()); 00057 } 00058 00059 00060 template<typename T, template<typename U> class Descriptor> 00061 T computeAverageRhoBar(BlockLattice3D<T,Descriptor>& lattice, Box3D domain) { 00062 BoxSumRhoBarFunctional3D<T,Descriptor> functional; 00063 applyProcessingFunctional(functional, domain, lattice); 00064 return functional.getSumRhoBar() / (T) domain.nCells(); 00065 } 00066 00067 template<typename T, template<typename U> class Descriptor> 00068 T computeAverageRhoBar(BlockLattice3D<T,Descriptor>& lattice) { 00069 return computeAverageRhoBar(lattice, lattice.getBoundingBox()); 00070 } 00071 00072 00073 template<typename T, template<typename U> class Descriptor> 00074 T computeAverageEnergy(BlockLattice3D<T,Descriptor>& lattice, Box3D domain) 00075 { 00076 BoxSumEnergyFunctional3D<T,Descriptor> functional; 00077 applyProcessingFunctional(functional, domain, lattice); 00078 return functional.getSumEnergy() / (T) domain.nCells();; 00079 } 00080 00081 template<typename T, template<typename U> class Descriptor> 00082 T computeAverageEnergy(BlockLattice3D<T,Descriptor>& lattice) { 00083 return computeAverageEnergy(lattice, lattice.getBoundingBox()); 00084 } 00085 00086 template<typename T, template<typename U> class Descriptor, class BoolMask> 00087 plint count(BlockLattice3D<T,Descriptor>& lattice, Box3D domain, BoolMask boolMask) 00088 { 00089 CountLatticeElementsFunctional3D<T,Descriptor,BoolMask> functional(boolMask); 00090 applyProcessingFunctional(functional, domain, lattice); 00091 return functional.getCount(); 00092 } 00093 00094 template<typename T, template<typename U> class Descriptor, class BoolMask> 00095 plint count(BlockLattice3D<T,Descriptor>& lattice, BoolMask boolMask) 00096 { 00097 return count(lattice, lattice.getBoundingBox(), boolMask); 00098 } 00099 00100 /* *************** Density ******************************************* */ 00101 00102 template<typename T, template<typename U> class Descriptor> 00103 void computeDensity(BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& density) 00104 { 00105 applyProcessingFunctional ( 00106 new BoxDensityFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, density ); 00107 } 00108 00109 template<typename T, template<typename U> class Descriptor> 00110 std::auto_ptr<ScalarField3D<T> > computeDensity(BlockLattice3D<T,Descriptor>& lattice) 00111 { 00112 ScalarField3D<T>* density 00113 = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00114 computeDensity(lattice, *density); 00115 return std::auto_ptr<ScalarField3D<T> >(density); 00116 } 00117 00118 00119 /* *************** RhoBar ******************************************* */ 00120 00121 template<typename T, template<typename U> class Descriptor> 00122 void computeRhoBar(BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& rhoBar) 00123 { 00124 applyProcessingFunctional ( 00125 new BoxRhoBarFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, rhoBar ); 00126 } 00127 00128 template<typename T, template<typename U> class Descriptor> 00129 std::auto_ptr<ScalarField3D<T> > computeRhoBar(BlockLattice3D<T,Descriptor>& lattice) 00130 { 00131 ScalarField3D<T>* rhoBar 00132 = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00133 computeRhoBar(lattice, *rhoBar); 00134 return std::auto_ptr<ScalarField3D<T> >(rhoBar); 00135 } 00136 00137 00138 /* *************** Kinetic Energy ************************************ */ 00139 00140 template<typename T, template<typename U> class Descriptor> 00141 void computeKineticEnergy(BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& energy) 00142 { 00143 applyProcessingFunctional ( 00144 new BoxKineticEnergyFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, energy ); 00145 } 00146 00147 template<typename T, template<typename U> class Descriptor> 00148 std::auto_ptr<ScalarField3D<T> > computeKineticEnergy(BlockLattice3D<T,Descriptor>& lattice) 00149 { 00150 ScalarField3D<T>* energy 00151 = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00152 computeKineticEnergy(lattice, *energy); 00153 return std::auto_ptr<ScalarField3D<T> >(energy); 00154 } 00155 00156 00157 /* *************** Velocity Norm ************************************* */ 00158 00159 template<typename T, template<typename U> class Descriptor> 00160 void computeVelocityNorm(BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& velocityNorm) 00161 { 00162 applyProcessingFunctional ( 00163 new BoxVelocityNormFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, velocityNorm ); 00164 } 00165 00166 template<typename T, template<typename U> class Descriptor> 00167 std::auto_ptr<ScalarField3D<T> > computeVelocityNorm(BlockLattice3D<T,Descriptor>& lattice) 00168 { 00169 ScalarField3D<T>* velocityNorm 00170 = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00171 computeVelocityNorm(lattice, *velocityNorm); 00172 return std::auto_ptr<ScalarField3D<T> >(velocityNorm); 00173 } 00174 00175 00176 /* *************** Velocity Component ******************************** */ 00177 00178 template<typename T, template<typename U> class Descriptor> 00179 void computeVelocityComponent(BlockLattice3D<T,Descriptor>& lattice, 00180 ScalarField3D<T>& velocityComponent, 00181 plint iComponent) 00182 { 00183 applyProcessingFunctional ( 00184 new BoxVelocityComponentFunctional3D<T,Descriptor>(iComponent), 00185 lattice.getBoundingBox(), lattice, velocityComponent ); 00186 } 00187 00188 template<typename T, template<typename U> class Descriptor> 00189 std::auto_ptr<ScalarField3D<T> > computeVelocityComponent ( 00190 BlockLattice3D<T,Descriptor>& lattice, plint iComponent ) 00191 { 00192 ScalarField3D<T>* velocityComponent 00193 = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00194 computeVelocityComponent(lattice, *velocityComponent, iComponent); 00195 return std::auto_ptr<ScalarField3D<T> >(velocityComponent); 00196 } 00197 00198 00199 /* *************** Velocity ****************************************** */ 00200 00201 template<typename T, template<typename U> class Descriptor> 00202 void computeVelocity(BlockLattice3D<T,Descriptor>& lattice, 00203 TensorField3D<T,Descriptor<T>::d>& velocity) 00204 { 00205 applyProcessingFunctional ( 00206 new BoxVelocityFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, velocity ); 00207 } 00208 00209 template<typename T, template<typename U> class Descriptor> 00210 std::auto_ptr<TensorField3D<T,Descriptor<T>::d> > computeVelocity(BlockLattice3D<T,Descriptor>& lattice) 00211 { 00212 TensorField3D<T,Descriptor<T>::d>* velocity 00213 = new TensorField3D<T,Descriptor<T>::d>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00214 computeVelocity(lattice, *velocity); 00215 return std::auto_ptr<TensorField3D<T,Descriptor<T>::d> >(velocity); 00216 } 00217 00218 00219 00220 /* *************** Deviatoric Stress ********************************* */ 00221 00222 template<typename T, template<typename U> class Descriptor> 00223 void computeDeviatoricStress(BlockLattice3D<T,Descriptor>& lattice, 00224 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>& PiNeq) 00225 { 00226 applyProcessingFunctional ( 00227 new BoxDeviatoricStressFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, PiNeq ); 00228 } 00229 00230 template<typename T, template<typename U> class Descriptor> 00231 std::auto_ptr<TensorField3D<T,SymmetricTensor<T,Descriptor>::n> > computeDeviatoricStress(BlockLattice3D<T,Descriptor>& lattice) 00232 { 00233 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>* PiNeq 00234 = new TensorField3D<T,SymmetricTensor<T,Descriptor>::n>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00235 computeDeviatoricStress(lattice, *PiNeq); 00236 return std::auto_ptr<TensorField3D<T,SymmetricTensor<T,Descriptor>::n> >(PiNeq); 00237 } 00238 00239 00240 /* *************** Strain Rate from Stress *************************** */ 00241 00242 template<typename T, template<typename U> class Descriptor> 00243 void computeStrainRateFromStress(BlockLattice3D<T,Descriptor>& lattice, 00244 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>& S) 00245 { 00246 applyProcessingFunctional ( 00247 new BoxStrainRateFromStressFunctional3D<T,Descriptor>, lattice.getBoundingBox(), lattice, S ); 00248 } 00249 00250 template<typename T, template<typename U> class Descriptor> 00251 std::auto_ptr<TensorField3D<T,SymmetricTensor<T,Descriptor>::n> > computeStrainRateFromStress(BlockLattice3D<T,Descriptor>& lattice) 00252 { 00253 TensorField3D<T,SymmetricTensor<T,Descriptor>::n>* S 00254 = new TensorField3D<T,SymmetricTensor<T,Descriptor>::n>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00255 computeStrainRateFromStress(lattice, *S); 00256 return std::auto_ptr<TensorField3D<T,SymmetricTensor<T,Descriptor>::n> >(S); 00257 } 00258 00259 00260 00261 /* *************** Population *************************************** */ 00262 00263 template<typename T, template<typename U> class Descriptor> 00264 void computePopulation(BlockLattice3D<T,Descriptor>& lattice, ScalarField3D<T>& population, plint iPop) 00265 { 00266 applyProcessingFunctional ( 00267 new BoxPopulationFunctional3D<T,Descriptor>(iPop), lattice.getBoundingBox(), lattice, population ); 00268 } 00269 00270 template<typename T, template<typename U> class Descriptor> 00271 std::auto_ptr<ScalarField3D<T> > computePopulation(BlockLattice3D<T,Descriptor>& lattice, plint iPop) 00272 { 00273 ScalarField3D<T>* population = new ScalarField3D<T>(lattice.getNx(), lattice.getNy(), lattice.getNz()); 00274 computePopulation(lattice, *population, iPop); 00275 return std::auto_ptr<ScalarField3D<T> >(population); 00276 } 00277 00278 template<typename T, template<typename U> class Descriptor> 00279 void computeAllPopulations(BlockLattice3D<T,Descriptor>& lattice, 00280 TensorField3D<T,Descriptor<T>::q>& populations, 00281 Box3D domain) 00282 { 00283 applyProcessingFunctional ( 00284 new BoxAllPopulationsFunctional3D<T,Descriptor>(), domain, lattice, populations ); 00285 } 00286 00287 template<typename T, template<typename U> class Descriptor> 00288 std::auto_ptr<ScalarField3D<T> > computeAllPopulations(BlockLattice3D<T,Descriptor>& lattice) 00289 { 00290 TensorField3D<T,Descriptor<T>::q>* populations = 00291 new TensorField3D<T,Descriptor<T>::q>(lattice); 00292 computeAllPopulations(lattice, *populations); 00293 return std::auto_ptr<TensorField3D<T,Descriptor<T>::q> >(populations); 00294 } 00295 00296 template<typename T, template<typename U> class Descriptor> 00297 void copyPopulations(BlockLattice3D<T,Descriptor>& latticeFrom, BlockLattice3D<T,Descriptor>& latticeTo, 00298 Box3D domain) 00299 { 00300 applyProcessingFunctional ( 00301 new CopyPopulationsFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 00302 } 00303 00304 template<typename T1, template<typename U1> class Descriptor1, typename T2, template<typename U2> class Descriptor2> 00305 void copyConvertPopulations(MultiBlockLattice3D<T1,Descriptor1>& latticeFrom, MultiBlockLattice3D<T2,Descriptor2>& latticeTo, 00306 Box3D domain) 00307 { 00308 applyProcessingFunctional( new CopyConvertPopulationsFunctional3D<T1,Descriptor1,T2,Descriptor2>(), domain, latticeFrom, latticeTo ); 00309 } 00310 00311 template<typename T, template<typename U> class Descriptor> 00312 void copyAll(BlockLattice3D<T,Descriptor>& latticeFrom, 00313 BlockLattice3D<T,Descriptor>& latticeTo, Box3D domain) 00314 { 00315 applyProcessingFunctional ( 00316 new LatticeCopyAllFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 00317 } 00318 00319 template<typename T, template<typename U> class Descriptor> 00320 void copyRegenerate(BlockLattice3D<T,Descriptor>& latticeFrom, 00321 BlockLattice3D<T,Descriptor>& latticeTo, Box3D domain) 00322 { 00323 applyProcessingFunctional ( 00324 new LatticeRegenerateFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 00325 } 00326 00327 00328 /* *************** Omega ******************************************* */ 00329 00330 template<typename T, template<typename U> class Descriptor> 00331 void computeOmega(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& omega, Box3D domain) 00332 { 00333 applyProcessingFunctional ( 00334 new BoxOmegaFunctional3D<T,Descriptor>, domain, lattice, omega ); 00335 } 00336 00337 template<typename T, template<typename U> class Descriptor> 00338 void computeOmega(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& omega) 00339 { 00340 computeOmega(lattice, omega, lattice.getBoundingBox()); 00341 } 00342 00343 template<typename T, template<typename U> class Descriptor> 00344 std::auto_ptr<MultiScalarField3D<T> > computeOmega(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 00345 { 00346 std::auto_ptr<MultiScalarField3D<T> > omega = 00347 generateMultiScalarField<T>(lattice, domain); 00348 computeOmega(lattice, *omega, domain); 00349 return omega; 00350 } 00351 00352 template<typename T, template<typename U> class Descriptor> 00353 std::auto_ptr<MultiScalarField3D<T> > computeOmega(MultiBlockLattice3D<T,Descriptor>& lattice) { 00354 return computeOmega(lattice, lattice.getBoundingBox()); 00355 } 00356 00357 00358 /* ******************************************************************* */ 00359 /* *************** PART II. Atomic-block wrappers: Scalar-Field ****** */ 00360 /* ******************************************************************* */ 00361 00362 /* *************** Reductive functions ******************************* */ 00363 00364 template<typename T> 00365 T computeSum(ScalarField3D<T>& scalarField, Box3D domain) { 00366 BoxScalarSumFunctional3D<T> functional; 00367 applyProcessingFunctional(functional, domain, scalarField); 00368 return functional.getSumScalar(); 00369 } 00370 00371 template<typename T> 00372 T computeSum(ScalarField3D<T>& scalarField) { 00373 return computeSum(scalarField, scalarField.getBoundingBox()); 00374 } 00375 00376 template<typename T> 00377 T computeBoundedSum(ScalarField3D<T>& scalarField, Box3D domain) { 00378 BoundedBoxScalarSumFunctional3D<T> functional; 00379 plint envelopeWidth=1; 00380 applyProcessingFunctional(functional, domain, scalarField, envelopeWidth); 00381 return functional.getSumScalar(); 00382 } 00383 00384 template<typename T> 00385 T computeBoundedSum(ScalarField3D<T>& scalarField) { 00386 return computeBoundedSum(scalarField, scalarField.getBoundingBox()); 00387 } 00388 00389 template<typename T> 00390 T computeAverage(ScalarField3D<T>& scalarField, Box3D domain) { 00391 BoxScalarSumFunctional3D<T> functional; 00392 applyProcessingFunctional(functional, domain, scalarField); 00393 return functional.getSumScalar() / (T) domain.nCells(); 00394 } 00395 00396 template<typename T> 00397 T computeAverage(ScalarField3D<T>& scalarField) { 00398 return computeAverage(scalarField, scalarField.getBoundingBox()); 00399 } 00400 00401 00402 template<typename T> 00403 T computeAverage(ScalarField3D<T>& scalarField, ScalarField3D<int>& mask, int flag, Box3D domain) 00404 { 00405 MaskedBoxScalarAverageFunctional3D<T> functional(flag); 00406 applyProcessingFunctional(functional, domain, scalarField, mask); 00407 return functional.getAverageScalar(); 00408 } 00409 00410 template<typename T> 00411 T computeAverage(ScalarField3D<T>& scalarField, ScalarField3D<int>& mask, int flag) { 00412 return computeAverage(scalarField, mask, flag, scalarField.getBoundingBox()); 00413 } 00414 00415 00416 template<typename T> 00417 T computeMin(ScalarField3D<T>& scalarField, Box3D domain) { 00418 BoxScalarMinFunctional3D<T> functional; 00419 applyProcessingFunctional(functional, domain, scalarField); 00420 return functional.getMinScalar(); 00421 } 00422 00423 template<typename T> 00424 T computeMin(ScalarField3D<T>& scalarField) { 00425 return computeMin(scalarField, scalarField.getBoundingBox()); 00426 } 00427 00428 00429 template<typename T> 00430 T computeMax(ScalarField3D<T>& scalarField, Box3D domain) { 00431 BoxScalarMaxFunctional3D<T> functional; 00432 applyProcessingFunctional(functional, domain, scalarField); 00433 return functional.getMaxScalar(); 00434 } 00435 00436 template<typename T> 00437 T computeMax(ScalarField3D<T>& scalarField) { 00438 return computeMax(scalarField, scalarField.getBoundingBox()); 00439 } 00440 00441 00442 template<typename T> 00443 T computeBoundedAverage(ScalarField3D<T>& scalarField, Box3D domain) { 00444 BoundedBoxScalarSumFunctional3D<T> functional; 00445 plint envelopeWidth=1; 00446 applyProcessingFunctional(functional, domain, scalarField, envelopeWidth); 00447 return functional.getSumScalar() / 00448 (T) ( (domain.getNx()-1)*(domain.getNy()-1)*(domain.getNz()-1) ); 00449 } 00450 00451 template<typename T> 00452 T computeBoundedAverage(ScalarField3D<T>& scalarField) { 00453 return computeBoundedAverage(scalarField, scalarField.getBoundingBox()); 00454 } 00455 00456 00457 template<typename T, class BoolMask> 00458 plint count(ScalarField3D<T>& field, Box3D domain, BoolMask boolMask) 00459 { 00460 CountScalarElementsFunctional3D<T,BoolMask> functional(boolMask); 00461 applyProcessingFunctional(functional, domain, field); 00462 return functional.getCount(); 00463 } 00464 00465 template<typename T, class BoolMask> 00466 plint count(ScalarField3D<T>& field, BoolMask boolMask) 00467 { 00468 return count(field, field.getBoundingBox(), boolMask); 00469 } 00470 00471 /* *************** ScalarField - Scalar operations *************** */ 00472 00473 template<typename T> 00474 void add(ScalarField3D<T>& field, T scalar, ScalarField3D<T>& result) 00475 { 00476 applyProcessingFunctional ( 00477 new A_plus_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00478 } 00479 00480 template<typename T> 00481 std::auto_ptr<ScalarField3D<T> > add(ScalarField3D<T>& field, T scalar) 00482 { 00483 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00484 add(field, scalar, *result); 00485 return std::auto_ptr<ScalarField3D<T> >(result); 00486 } 00487 00488 00489 template<typename T> 00490 void add(T scalar, ScalarField3D<T>& field, ScalarField3D<T>& result) 00491 { 00492 applyProcessingFunctional ( 00493 new A_plus_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00494 } 00495 00496 template<typename T> 00497 std::auto_ptr<ScalarField3D<T> > add(T scalar, ScalarField3D<T>& field) 00498 { 00499 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00500 add(scalar, field, *result); 00501 return std::auto_ptr<ScalarField3D<T> >(result); 00502 } 00503 00504 00505 template<typename T> 00506 void subtract(ScalarField3D<T>& field, T scalar, ScalarField3D<T>& result) 00507 { 00508 applyProcessingFunctional ( 00509 new A_minus_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00510 } 00511 00512 template<typename T> 00513 std::auto_ptr<ScalarField3D<T> > subtract(ScalarField3D<T>& field, T scalar) 00514 { 00515 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00516 subtract(field, scalar, *result); 00517 return std::auto_ptr<ScalarField3D<T> >(result); 00518 } 00519 00520 00521 template<typename T> 00522 void subtract(T scalar, ScalarField3D<T>& field, ScalarField3D<T>& result) 00523 { 00524 applyProcessingFunctional ( 00525 new Alpha_minus_A_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00526 } 00527 00528 template<typename T> 00529 std::auto_ptr<ScalarField3D<T> > subtract(T scalar, ScalarField3D<T>& field) 00530 { 00531 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00532 subtract(scalar, field, *result); 00533 return std::auto_ptr<ScalarField3D<T> >(result); 00534 } 00535 00536 00537 template<typename T> 00538 void multiply(ScalarField3D<T>& field, T scalar, ScalarField3D<T>& result) 00539 { 00540 applyProcessingFunctional ( 00541 new A_times_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00542 } 00543 00544 template<typename T> 00545 std::auto_ptr<ScalarField3D<T> > multiply(ScalarField3D<T>& field, T scalar) 00546 { 00547 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00548 multiply(field, scalar, *result); 00549 return std::auto_ptr<ScalarField3D<T> >(result); 00550 } 00551 00552 00553 template<typename T> 00554 void multiply(T scalar, ScalarField3D<T>& field, ScalarField3D<T>& result) 00555 { 00556 applyProcessingFunctional ( 00557 new A_times_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00558 } 00559 00560 template<typename T> 00561 std::auto_ptr<ScalarField3D<T> > multiply(T scalar, ScalarField3D<T>& field) 00562 { 00563 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00564 multiply(scalar, field, *result); 00565 return std::auto_ptr<ScalarField3D<T> >(result); 00566 } 00567 00568 00569 template<typename T> 00570 void divide(ScalarField3D<T>& field, T scalar, ScalarField3D<T>& result) 00571 { 00572 applyProcessingFunctional ( 00573 new A_dividedBy_alpha_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00574 } 00575 00576 template<typename T> 00577 std::auto_ptr<ScalarField3D<T> > divide(ScalarField3D<T>& field, T scalar) 00578 { 00579 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00580 divide(field, scalar, *result); 00581 return std::auto_ptr<ScalarField3D<T> >(result); 00582 } 00583 00584 00585 template<typename T> 00586 void divide(T scalar, ScalarField3D<T>& field, ScalarField3D<T>& result) 00587 { 00588 applyProcessingFunctional ( 00589 new Alpha_dividedBy_A_functional3D<T>(scalar), field.getBoundingBox(), field, result ); 00590 } 00591 00592 template<typename T> 00593 std::auto_ptr<ScalarField3D<T> > divide(T scalar, ScalarField3D<T>& field) 00594 { 00595 ScalarField3D<T>* result = new ScalarField3D<T>(field.getNx(), field.getNy(), field.getNz()); 00596 divide(scalar, field, *result); 00597 return std::auto_ptr<ScalarField3D<T> >(result); 00598 } 00599 00600 /* *************** ScalarField - Scalar inplace operations *************** */ 00601 00602 template<typename T> 00603 void addInPlace(ScalarField3D<T>& field, T scalar) { 00604 applyProcessingFunctional ( 00605 new A_plus_alpha_inplace_functional3D<T>(scalar), field.getBoundingBox(), field); 00606 } 00607 00608 template<typename T> 00609 void subtractInPlace(ScalarField3D<T>& field, T scalar) { 00610 applyProcessingFunctional ( 00611 new A_minus_alpha_inplace_functional3D<T>(scalar), field.getBoundingBox(), field); 00612 } 00613 00614 template<typename T> 00615 void multiplyInPlace(ScalarField3D<T>& field, T scalar) { 00616 applyProcessingFunctional ( 00617 new A_times_alpha_inplace_functional3D<T>(scalar), field.getBoundingBox(), field); 00618 } 00619 00620 template<typename T> 00621 void divideInPlace(ScalarField3D<T>& field, T scalar) { 00622 applyProcessingFunctional ( 00623 new A_dividedBy_alpha_inplace_functional3D<T>(scalar), field.getBoundingBox(), field); 00624 } 00625 00626 00627 /* *************** ScalarField - ScalarField operations *************** */ 00628 00629 template<typename T1, typename T2> 00630 void copy(ScalarField3D<T1>& field, ScalarField3D<T2>& convertedField) 00631 { 00632 applyProcessingFunctional ( 00633 new CopyConvertScalarFunctional3D<T1,T2>, field.getBoundingBox(), field, convertedField ); 00634 } 00635 00636 template<typename T1, typename T2> 00637 std::auto_ptr<ScalarField3D<T2> > copyConvert(ScalarField3D<T1>& field) 00638 { 00639 ScalarField3D<T2>* convertedField = new ScalarField3D<T2>(field.getNx(), field.getNy(), field.getNz()); 00640 plb::copy(field, *convertedField); 00641 return std::auto_ptr<ScalarField3D<T2> >(convertedField); 00642 } 00643 00644 00645 template<typename T> 00646 void add(ScalarField3D<T>& A, ScalarField3D<T>& B, ScalarField3D<T>& result) 00647 { 00648 std::vector<ScalarField3D<T>* > fields; 00649 fields.push_back(&A); 00650 fields.push_back(&B); 00651 fields.push_back(&result); 00652 applyProcessingFunctional ( 00653 new A_plus_B_functional3D<T>, A.getBoundingBox(), fields ); 00654 } 00655 00656 template<typename T> 00657 std::auto_ptr<ScalarField3D<T> > add(ScalarField3D<T>& A, ScalarField3D<T>& B) 00658 { 00659 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00660 add(A, B, *result); 00661 return std::auto_ptr<ScalarField3D<T> >(result); 00662 } 00663 00664 00665 template<typename T> 00666 void subtract(ScalarField3D<T>& A, ScalarField3D<T>& B, ScalarField3D<T>& result) 00667 { 00668 std::vector<ScalarField3D<T>* > fields; 00669 fields.push_back(&A); 00670 fields.push_back(&B); 00671 fields.push_back(&result); 00672 applyProcessingFunctional ( 00673 new A_minus_B_functional3D<T>, A.getBoundingBox(), fields ); 00674 } 00675 00676 template<typename T> 00677 std::auto_ptr<ScalarField3D<T> > subtract(ScalarField3D<T>& A, ScalarField3D<T>& B) 00678 { 00679 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00680 subtract(A, B, *result); 00681 return std::auto_ptr<ScalarField3D<T> >(result); 00682 } 00683 00684 00685 template<typename T> 00686 void multiply(ScalarField3D<T>& A, ScalarField3D<T>& B, ScalarField3D<T>& result) 00687 { 00688 std::vector<ScalarField3D<T>* > fields; 00689 fields.push_back(&A); 00690 fields.push_back(&B); 00691 fields.push_back(&result); 00692 applyProcessingFunctional ( 00693 new A_times_B_functional3D<T>, A.getBoundingBox(), fields ); 00694 } 00695 00696 template<typename T> 00697 std::auto_ptr<ScalarField3D<T> > multiply(ScalarField3D<T>& A, ScalarField3D<T>& B) 00698 { 00699 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00700 multiply(A, B, *result); 00701 return std::auto_ptr<ScalarField3D<T> >(result); 00702 } 00703 00704 00705 template<typename T> 00706 void divide(ScalarField3D<T>& A, ScalarField3D<T>& B, ScalarField3D<T>& result) 00707 { 00708 std::vector<ScalarField3D<T>* > fields; 00709 fields.push_back(&A); 00710 fields.push_back(&B); 00711 fields.push_back(&result); 00712 applyProcessingFunctional ( 00713 new A_dividedBy_B_functional3D<T>, A.getBoundingBox(), fields ); 00714 } 00715 00716 template<typename T> 00717 std::auto_ptr<ScalarField3D<T> > divide(ScalarField3D<T>& A, ScalarField3D<T>& B) 00718 { 00719 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00720 divide(A, B, *result); 00721 return std::auto_ptr<ScalarField3D<T> >(result); 00722 } 00723 00724 /* *************** ScalarField operations *************** */ 00725 00726 template<typename T> 00727 void computeSqrt(ScalarField3D<T>& A, ScalarField3D<T>& result, Box3D domain) 00728 { 00729 applyProcessingFunctional ( 00730 new ComputeScalarSqrtFunctional3D<T>, domain, A, result ); 00731 } 00732 00733 template<typename T> 00734 std::auto_ptr<ScalarField3D<T> > computeSqrt(ScalarField3D<T>& A, Box3D domain) 00735 { 00736 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00737 computeSqrt(A, *result, domain); 00738 return result; 00739 } 00740 00741 template<typename T> 00742 std::auto_ptr<ScalarField3D<T> > computeSqrt(ScalarField3D<T>& A) 00743 { 00744 return computeSqrt(A, A.getBoundingBox()); 00745 } 00746 00747 00748 00749 template<typename T> 00750 void computeAbsoluteValue(ScalarField3D<T>& A, ScalarField3D<T>& result, Box3D domain) 00751 { 00752 applyProcessingFunctional ( 00753 new ComputeAbsoluteValueFunctional3D<T>, domain, A, result ); 00754 } 00755 00756 template<typename T> 00757 std::auto_ptr<ScalarField3D<T> > computeAbsoluteValue(ScalarField3D<T>& A, Box3D domain) 00758 { 00759 ScalarField3D<T>* result = new ScalarField3D<T>(A.getNx(), A.getNy(), A.getNz()); 00760 computeAbsoluteValue(A, *result, domain); 00761 return result; 00762 } 00763 00764 template<typename T> 00765 std::auto_ptr<ScalarField3D<T> > computeAbsoluteValue(ScalarField3D<T>& A) 00766 { 00767 return computeAbsoluteValue(A, A.getBoundingBox()); 00768 } 00769 00770 00771 /* *************** ScalarField - ScalarField inplace operations *************** */ 00772 00773 template<typename T> 00774 void addInPlace(ScalarField3D<T>& A, ScalarField3D<T>& B) { 00775 applyProcessingFunctional ( 00776 new A_plus_B_inplace_functional3D<T>, A.getBoundingBox(), A, B ); 00777 } 00778 00779 template<typename T> 00780 void subtractInPlace(ScalarField3D<T>& A, ScalarField3D<T>& B) { 00781 applyProcessingFunctional ( 00782 new A_minus_B_inplace_functional3D<T>, A.getBoundingBox(), A, B ); 00783 } 00784 00785 template<typename T> 00786 void multiplyInPlace(ScalarField3D<T>& A, ScalarField3D<T>& B) { 00787 applyProcessingFunctional ( 00788 new A_times_B_inplace_functional3D<T>, A.getBoundingBox(), A, B ); 00789 } 00790 00791 template<typename T> 00792 void divideInPlace(ScalarField3D<T>& A, ScalarField3D<T>& B) { 00793 applyProcessingFunctional ( 00794 new A_dividedBy_B_inplace_functional3D<T>, A.getBoundingBox(), A, B ); 00795 } 00796 00797 00798 00799 /* ******************************************************************* */ 00800 /* *************** PART III. Atomic-block wrappers: Tensor-Field ***** */ 00801 /* ******************************************************************* */ 00802 00803 /* *************** Reductive functions ******************************* */ 00804 00805 template<typename T, plint nDim, class BoolMask> 00806 plint count(TensorField3D<T,nDim>& field, Box3D domain, BoolMask boolMask) 00807 { 00808 CountTensorElementsFunctional3D<T,nDim,BoolMask> functional(boolMask); 00809 applyProcessingFunctional(functional, domain, field); 00810 return functional.getCount(); 00811 } 00812 00813 template<typename T, plint nDim, class BoolMask> 00814 plint count(TensorField3D<T,nDim>& field, BoolMask boolMask) 00815 { 00816 return count(field, field.getBoundingBox(), boolMask); 00817 } 00818 00819 /* *************** Component (scalar-field) out of a tensor-field ****** */ 00820 00821 template<typename T, int nDim> 00822 void extractComponent(TensorField3D<T,nDim>& tensorField, ScalarField3D<T>& component, int iComponent) 00823 { 00824 applyProcessingFunctional ( 00825 new ExtractTensorComponentFunctional3D<T,nDim>(iComponent), tensorField.getBoundingBox(), component, tensorField ); 00826 } 00827 00828 template<typename T, int nDim> 00829 std::auto_ptr<ScalarField3D<T> > extractComponent(TensorField3D<T,nDim>& tensorField, int iComponent) 00830 { 00831 ScalarField3D<T>* component = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00832 extractComponent(tensorField, *component, iComponent); 00833 return std::auto_ptr<ScalarField3D<T> >(component); 00834 } 00835 00836 00837 /* *************** Vector-norm of each cell in the field *************** */ 00838 00839 template<typename T, int nDim> 00840 void computeNorm(TensorField3D<T,nDim>& tensorField, ScalarField3D<T>& component) 00841 { 00842 applyProcessingFunctional ( 00843 new ComputeNormFunctional3D<T,nDim>, tensorField.getBoundingBox(), component, tensorField ); 00844 } 00845 00846 template<typename T, int nDim> 00847 std::auto_ptr<ScalarField3D<T> > computeNorm(TensorField3D<T,nDim>& tensorField) 00848 { 00849 ScalarField3D<T>* component = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00850 computeNorm(tensorField, *component); 00851 return std::auto_ptr<ScalarField3D<T> >(component); 00852 } 00853 00854 /* *************** Sqrt operation on each component of each cell *************** */ 00855 00856 template<typename T, int nDim> 00857 void computeSqrt(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& result, Box3D domain) 00858 { 00859 applyProcessingFunctional ( 00860 new ComputeTensorSqrtFunctional3D<T, nDim>, domain, A, result ); 00861 } 00862 00863 template<typename T, int nDim> 00864 std::auto_ptr<TensorField3D<T,nDim> > computeSqrt(TensorField3D<T,nDim>& A, Box3D domain) 00865 { 00866 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(A.getNx(), A.getNy(), A.getNz()); 00867 computeSqrt(A, *result, domain); 00868 return result; 00869 } 00870 00871 template<typename T, int nDim> 00872 std::auto_ptr<TensorField3D<T,nDim> > computeSqrt(TensorField3D<T,nDim>& A) 00873 { 00874 return computeSqrt(A, A.getBoundingBox()); 00875 } 00876 00877 00878 /* *************** Squared vector-norm of each cell in the field ******** */ 00879 00880 template<typename T, int nDim> 00881 void computeNormSqr(TensorField3D<T,nDim>& tensorField, ScalarField3D<T>& component) 00882 { 00883 applyProcessingFunctional ( 00884 new ComputeNormSqrFunctional3D<T,nDim>, tensorField.getBoundingBox(), component, tensorField ); 00885 } 00886 00887 template<typename T, int nDim> 00888 std::auto_ptr<ScalarField3D<T> > computeNormSqr(TensorField3D<T,nDim>& tensorField) 00889 { 00890 ScalarField3D<T>* component = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00891 computeNormSqr(tensorField, *component); 00892 return std::auto_ptr<ScalarField3D<T> >(component); 00893 } 00894 00895 00896 /* *************** Tensor-norm of each symmetric tensor of a field ***** */ 00897 00898 template<typename T> 00899 void computeSymmetricTensorNorm(TensorField3D<T,6>& tensorField, ScalarField3D<T>& norm) 00900 { 00901 applyProcessingFunctional ( 00902 new ComputeSymmetricTensorNormFunctional3D<T>, tensorField.getBoundingBox(), norm, tensorField ); 00903 } 00904 00905 template<typename T> 00906 std::auto_ptr<ScalarField3D<T> > computeSymmetricTensorNorm(TensorField3D<T,6>& tensorField) 00907 { 00908 ScalarField3D<T>* norm = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00909 computeSymmetricTensorNorm(tensorField, *norm); 00910 return std::auto_ptr<ScalarField3D<T> >(norm); 00911 } 00912 00913 00914 /* *************** Squared Tensor-norm of each symmetric tensor of a field*/ 00915 00916 template<typename T> 00917 void computeSymmetricTensorNormSqr(TensorField3D<T,6>& tensorField, ScalarField3D<T>& normSqr) 00918 { 00919 applyProcessingFunctional ( 00920 new ComputeSymmetricTensorNormSqrFunctional3D<T>, tensorField.getBoundingBox(), normSqr, tensorField ); 00921 } 00922 00923 template<typename T> 00924 std::auto_ptr<ScalarField3D<T> > computeSymmetricTensorNormSqr(TensorField3D<T,6>& tensorField) 00925 { 00926 ScalarField3D<T>* normSqr = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00927 computeSymmetricTensorNormSqr(tensorField, *normSqr); 00928 return std::auto_ptr<ScalarField3D<T> >(normSqr); 00929 } 00930 00931 00932 /* *************** Trace of each symmetric tensor of a field ************ */ 00933 00934 template<typename T> 00935 void computeSymmetricTensorTrace(TensorField3D<T,6>& tensorField, ScalarField3D<T>& trace) 00936 { 00937 applyProcessingFunctional ( 00938 new ComputeSymmetricTensorTraceFunctional3D<T>, tensorField.getBoundingBox(), trace, tensorField ); 00939 } 00940 00941 template<typename T> 00942 std::auto_ptr<ScalarField3D<T> > computeSymmetricTensorTrace(TensorField3D<T,6>& tensorField) 00943 { 00944 ScalarField3D<T>* trace = new ScalarField3D<T>(tensorField.getNx(), tensorField.getNy(), tensorField.getNz()); 00945 computeSymmetricTensorTrace(tensorField, *trace); 00946 return std::auto_ptr<ScalarField3D<T> >(trace); 00947 } 00948 00949 00950 00951 00952 /* *************** Vorticity from Velocity field *********************** */ 00953 00954 template<typename T> 00955 void computeVorticity(TensorField3D<T,3>& velocity, TensorField3D<T,3>& vorticity) 00956 { 00957 plint envelopeWidth=1; 00958 applyProcessingFunctional ( 00959 new BoxVorticityFunctional3D<T,3>, velocity.getBoundingBox(), velocity, vorticity, envelopeWidth ); 00960 } 00961 00962 template<typename T> 00963 std::auto_ptr<TensorField3D<T,3> > computeVorticity(TensorField3D<T,3>& velocity) 00964 { 00965 TensorField3D<T,3>* vorticity = new TensorField3D<T,3>(velocity.getNx(), velocity.getNy(), velocity.getNz()); 00966 computeVorticity(velocity, *vorticity); 00967 return std::auto_ptr<TensorField3D<T,3> >(vorticity); 00968 } 00969 00970 00971 /* *************** Vorticity, witout boundary treatment, from Velocity field */ 00972 00973 template<typename T> 00974 void computeBulkVorticity(TensorField3D<T,3>& velocity, TensorField3D<T,3>& vorticity) 00975 { 00976 applyProcessingFunctional ( 00977 new BoxBulkVorticityFunctional3D<T,3>, velocity.getBoundingBox(), velocity, vorticity ); 00978 } 00979 00980 template<typename T> 00981 std::auto_ptr<TensorField3D<T,3> > computeBulkVorticity(TensorField3D<T,3>& velocity) 00982 { 00983 TensorField3D<T,3>* vorticity = new TensorField3D<T,3>(velocity.getNx(), velocity.getNy(), velocity.getNz()); 00984 computeBulkVorticity(velocity, *vorticity); 00985 return std::auto_ptr<TensorField3D<T,3> >(vorticity); 00986 } 00987 00988 00989 /* *************** Divergence, witout boundary treatment, from Velocity field */ 00990 00991 template<typename T> 00992 void computeBulkDivergence(TensorField3D<T,3>& velocity, ScalarField3D<T>& divergence) 00993 { 00994 applyProcessingFunctional ( 00995 new BoxBulkDivergenceFunctional3D<T,3>, velocity.getBoundingBox(), divergence, velocity ); 00996 } 00997 00998 template<typename T> 00999 std::auto_ptr<ScalarField3D<T> > computeBulkDivergence(TensorField3D<T,3>& velocity) 01000 { 01001 ScalarField3D<T>* divergence = new ScalarField3D<T>(velocity.getNx(), velocity.getNy(), velocity.getNz()); 01002 computeBulkDivergence(velocity, *divergence); 01003 return std::auto_ptr<ScalarField3D<T> >(divergence); 01004 } 01005 01006 01007 /* *************** Strain rate from Velocity field ********************* */ 01008 01009 template<typename T> 01010 void computeStrainRate(TensorField3D<T,3>& velocity, TensorField3D<T,6>& S) 01011 { 01012 plint envelopeWidth=1; 01013 applyProcessingFunctional ( 01014 new BoxStrainRateFunctional3D<T,3>, velocity.getBoundingBox(), velocity, S, envelopeWidth ); 01015 } 01016 01017 template<typename T> 01018 std::auto_ptr<TensorField3D<T,3> > computeStrainRate(TensorField3D<T,3>& velocity) 01019 { 01020 TensorField3D<T,6>* S = new TensorField3D<T,6>(velocity.getNx(), velocity.getNy(), velocity.getNz()); 01021 computeStrainRate(velocity, *S); 01022 return std::auto_ptr<TensorField3D<T,6> >(S); 01023 } 01024 01025 01026 /* *************** Str. rate, witout boundary treatment, from Velocity field */ 01027 01028 template<typename T> 01029 void computeBulkStrainRate(TensorField3D<T,3>& velocity, TensorField3D<T,6>& S) 01030 { 01031 plint envelopeWidth=1; 01032 applyProcessingFunctional ( 01033 new BoxBulkStrainRateFunctional3D<T,3>, velocity.getBoundingBox(), velocity, S ); 01034 } 01035 01036 template<typename T> 01037 std::auto_ptr<TensorField3D<T,6> > computeBulkStrainRate(TensorField3D<T,3>& velocity) 01038 { 01039 TensorField3D<T,6>* S = new TensorField3D<T,6>(velocity.getNx(), velocity.getNy(), velocity.getNz()); 01040 computeBulkStrainRate(velocity, *S); 01041 return std::auto_ptr<TensorField3D<T,6> >(S); 01042 } 01043 01044 01045 /* *************** TensorField - TensorField operations *************** */ 01046 01047 template<typename T1, typename T2, int nDim> 01048 void copy(TensorField3D<T1,nDim>& field, TensorField3D<T2,nDim>& convertedField) 01049 { 01050 applyProcessingFunctional ( 01051 new CopyConvertTensorFunctional3D<T1,T2,nDim>, field.getBoundingBox(), field, convertedField ); 01052 } 01053 01054 template<typename T1, typename T2, int nDim> 01055 std::auto_ptr<TensorField3D<T2,nDim> > copyConvert(TensorField3D<T1,nDim>& field) 01056 { 01057 TensorField3D<T2,nDim>* convertedField 01058 = new TensorField3D<T2,nDim>(field.getNx(), field.getNy(), field.getNz()); 01059 plb::copy(field, *convertedField); 01060 return std::auto_ptr<TensorField3D<T2,nDim> >(convertedField); 01061 } 01062 01063 template<typename T, int nDim> 01064 void add(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B, TensorField3D<T,nDim>& result) 01065 { 01066 std::vector<TensorField3D<T,nDim>* > fields; 01067 fields.push_back(&A); 01068 fields.push_back(&B); 01069 fields.push_back(&result); 01070 applyProcessingFunctional ( 01071 new Tensor_A_plus_B_functional3D<T,nDim>, A.getBoundingBox(), fields ); 01072 } 01073 01074 template<typename T, int nDim> 01075 std::auto_ptr<TensorField3D<T,nDim> > add(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 01076 { 01077 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(A.getNx(), A.getNy(), A.getNz()); 01078 add(A, B, *result); 01079 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01080 } 01081 01082 01083 template<typename T, int nDim> 01084 void subtract(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B, TensorField3D<T,nDim>& result) 01085 { 01086 std::vector<TensorField3D<T,nDim>* > fields; 01087 fields.push_back(&A); 01088 fields.push_back(&B); 01089 fields.push_back(&result); 01090 applyProcessingFunctional ( 01091 new Tensor_A_minus_B_functional3D<T,nDim>, A.getBoundingBox(), fields ); 01092 } 01093 01094 template<typename T, int nDim> 01095 std::auto_ptr<TensorField3D<T,nDim> > subtract(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 01096 { 01097 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(A.getNx(), A.getNy(), A.getNz()); 01098 subtract(A, B, *result); 01099 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01100 } 01101 01102 01103 template<typename T, int nDim> 01104 void multiply(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B, TensorField3D<T,nDim>& result) 01105 { 01106 std::vector<TensorField3D<T,nDim>* > fields; 01107 fields.push_back(&A); 01108 fields.push_back(&B); 01109 fields.push_back(&result); 01110 applyProcessingFunctional ( 01111 new Tensor_A_times_B_functional3D<T,nDim>, A.getBoundingBox(), fields ); 01112 } 01113 01114 template<typename T, int nDim> 01115 std::auto_ptr<TensorField3D<T,nDim> > multiply(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 01116 { 01117 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(A.getNx(), A.getNy(), A.getNz()); 01118 multiply(A, B, *result); 01119 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01120 } 01121 01122 01123 template<typename T, int nDim> 01124 void multiply(TensorField3D<T,nDim>& field, T scalar, TensorField3D<T,nDim>& result, Box3D domain) 01125 { 01126 applyProcessingFunctional ( 01127 new Tensor_A_times_alpha_functional3D<T,nDim>(scalar), domain, field, result ); 01128 } 01129 01130 template<typename T, int nDim> 01131 std::auto_ptr<TensorField3D<T,nDim> > multiply(TensorField3D<T,nDim>& field, T scalar) 01132 { 01133 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(field.getNx(), field.getNy(), field.getNz()); 01134 multiply(field, scalar, *result); 01135 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01136 } 01137 01138 01139 template<typename T, int nDim> 01140 void multiply(T scalar, TensorField3D<T,nDim>& field, TensorField3D<T,nDim>& result, Box3D domain) 01141 { 01142 applyProcessingFunctional ( 01143 new Tensor_A_times_alpha_functional3D<T,nDim>(scalar), domain, field, result ); 01144 } 01145 01146 template<typename T, int nDim> 01147 std::auto_ptr<TensorField3D<T,nDim> > multiply(T scalar, TensorField3D<T,nDim>& field) 01148 { 01149 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(field.getNx(), field.getNy(), field.getNz()); 01150 multiply(scalar, field, *result); 01151 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01152 } 01153 01154 01155 template<typename T, int nDim> 01156 void divide(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B, TensorField3D<T,nDim>& result) 01157 { 01158 std::vector<TensorField3D<T,nDim>* > fields; 01159 fields.push_back(&A); 01160 fields.push_back(&B); 01161 fields.push_back(&result); 01162 applyProcessingFunctional ( 01163 new Tensor_A_dividedBy_B_functional3D<T,nDim>, A.getBoundingBox(), fields ); 01164 } 01165 01166 template<typename T, int nDim> 01167 std::auto_ptr<TensorField3D<T,nDim> > divide(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) 01168 { 01169 TensorField3D<T,nDim>* result = new TensorField3D<T,nDim>(A.getNx(), A.getNy(), A.getNz()); 01170 divide(A, B, *result); 01171 return std::auto_ptr<TensorField3D<T,nDim> >(result); 01172 } 01173 01174 01175 /* *************** TensorField - TensorField inplace operations *************** */ 01176 01177 template<typename T, int nDim> 01178 void addInPlace(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) { 01179 applyProcessingFunctional ( 01180 new Tensor_A_plus_B_inplace_functional3D<T,nDim>, A.getBoundingBox(), A, B ); 01181 } 01182 01183 template<typename T, int nDim> 01184 void subtractInPlace(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) { 01185 applyProcessingFunctional ( 01186 new Tensor_A_minus_B_inplace_functional3D<T,nDim>, A.getBoundingBox(), A, B ); 01187 } 01188 01189 template<typename T, int nDim> 01190 void multiplyInPlace(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) { 01191 applyProcessingFunctional ( 01192 new Tensor_A_times_B_inplace_functional3D<T,nDim>, A.getBoundingBox(), A, B ); 01193 } 01194 01195 template<typename T, int nDim> 01196 void multiplyInPlace(TensorField3D<T,nDim>& A, T alpha) 01197 { 01198 applyProcessingFunctional ( 01199 new Tensor_A_times_alpha_inplace_functional3D<T,nDim>(alpha), A.getBoundingBox(), A); 01200 } 01201 01202 template<typename T, int nDim> 01203 void divideInPlace(TensorField3D<T,nDim>& A, TensorField3D<T,nDim>& B) { 01204 applyProcessingFunctional ( 01205 new Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>, A.getBoundingBox(), A, B ); 01206 } 01207 01208 01209 /* ******************************************************************* */ 01210 /* *************** PART IV. Multi-block wrappers: Block-Lattice ****** */ 01211 /* ******************************************************************* */ 01212 01213 /* *************** Reductive functions ******************************* */ 01214 01215 template<typename T, template<typename U> class Descriptor> 01216 T computeAverageDensity(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) { 01217 BoxSumRhoBarFunctional3D<T,Descriptor> functional; 01218 applyProcessingFunctional(functional, domain, lattice); 01219 return Descriptor<T>::fullRho( functional.getSumRhoBar() / (T) domain.nCells() ); 01220 } 01221 01222 template<typename T, template<typename U> class Descriptor> 01223 T computeAverageDensity(MultiBlockLattice3D<T,Descriptor>& lattice) { 01224 return computeAverageDensity(lattice, lattice.getBoundingBox()); 01225 } 01226 01227 01228 template<typename T, template<typename U> class Descriptor> 01229 T computeAverageRhoBar(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) { 01230 BoxSumRhoBarFunctional3D<T,Descriptor> functional; 01231 applyProcessingFunctional(functional, domain, lattice); 01232 return functional.getSumRhoBar() / (T) domain.nCells(); 01233 } 01234 01235 template<typename T, template<typename U> class Descriptor> 01236 T computeAverageRhoBar(MultiBlockLattice3D<T,Descriptor>& lattice) { 01237 return computeAverageRhoBar(lattice, lattice.getBoundingBox()); 01238 } 01239 01240 01241 template<typename T, template<typename U> class Descriptor> 01242 T computeAverageEnergy(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01243 { 01244 BoxSumEnergyFunctional3D<T,Descriptor> functional; 01245 applyProcessingFunctional(functional, domain, lattice); 01246 return functional.getSumEnergy() / (T) domain.nCells();; 01247 } 01248 01249 template<typename T, template<typename U> class Descriptor> 01250 T computeAverageEnergy(MultiBlockLattice3D<T,Descriptor>& lattice) { 01251 return computeAverageEnergy(lattice, lattice.getBoundingBox()); 01252 } 01253 01254 template<typename T, template<typename U> class Descriptor, class BoolMask> 01255 plint count(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain, BoolMask boolMask) 01256 { 01257 CountLatticeElementsFunctional3D<T,Descriptor,BoolMask> functional(boolMask); 01258 applyProcessingFunctional(functional, domain, lattice); 01259 return functional.getCount(); 01260 } 01261 01262 template<typename T, template<typename U> class Descriptor, class BoolMask> 01263 plint count(MultiBlockLattice3D<T,Descriptor>& lattice, BoolMask boolMask) 01264 { 01265 return count(lattice, lattice.getBoundingBox(), boolMask); 01266 } 01267 01268 template<typename T, template<typename U> class Descriptor> 01269 std::vector<T> densitySingleProbes ( 01270 MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain, 01271 std::vector<Array<T,3> > const& positions ) 01272 { 01273 DensitySingleProbe3D<T,Descriptor> functional(positions); 01274 applyProcessingFunctional(functional, domain, lattice); 01275 return functional.getDensities(); 01276 } 01277 01278 template<typename T, template<typename U> class Descriptor> 01279 std::vector<T> densitySingleProbes ( 01280 MultiBlockLattice3D<T,Descriptor>& lattice, 01281 std::vector<Array<T,3> > const& positions ) 01282 { 01283 return densitySingleProbes(lattice, lattice.getBoundingBox(), positions); 01284 } 01285 01286 template<typename T, template<typename U> class Descriptor> 01287 std::vector<Array<T,3> > velocitySingleProbes ( 01288 MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain, 01289 std::vector<Array<T,3> > const& positions ) 01290 { 01291 VelocitySingleProbe3D<T,Descriptor> functional(positions);; 01292 applyProcessingFunctional(functional, domain, lattice); 01293 return functional.getVelocities(); 01294 } 01295 01296 template<typename T, template<typename U> class Descriptor> 01297 std::vector<Array<T,3> > velocitySingleProbes ( 01298 MultiBlockLattice3D<T,Descriptor>& lattice, 01299 std::vector<Array<T,3> > const& positions ) 01300 { 01301 return velocitySingleProbes(lattice, lattice.getBoundingBox(), positions); 01302 } 01303 01304 template<typename T, template<typename U> class Descriptor> 01305 std::vector<Array<T,3> > vorticitySingleProbes ( 01306 MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain, 01307 std::vector<Array<T,3> > const& positions ) 01308 { 01309 VorticitySingleProbe3D<T,Descriptor> functional(positions);; 01310 applyProcessingFunctional(functional, domain, lattice); 01311 return functional.getVorticities(); 01312 } 01313 01314 template<typename T, template<typename U> class Descriptor> 01315 std::vector<Array<T,3> > vorticitySingleProbes ( 01316 MultiBlockLattice3D<T,Descriptor>& lattice, 01317 std::vector<Array<T,3> > const& positions ) 01318 { 01319 return vorticitySingleProbes(lattice, lattice.getBoundingBox(), positions); 01320 } 01321 01322 /* *************** Extract Sub-Lattice ******************************* */ 01323 01324 template<typename T, template<typename U> class Descriptor> 01325 void extractSubDomain( MultiBlockLattice3D<T,Descriptor>& lattice, 01326 MultiBlockLattice3D<T,Descriptor>& extractedLattice, 01327 Box3D domain) 01328 { 01329 applyProcessingFunctional ( 01330 new LatticeRegenerateFunctional3D<T,Descriptor>, domain, lattice, extractedLattice ); 01331 } 01332 01333 template<typename T, template<typename U> class Descriptor> 01334 std::auto_ptr<MultiBlockLattice3D<T,Descriptor> > extractSubDomain(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01335 { 01336 std::auto_ptr<MultiBlockLattice3D<T,Descriptor> > extractedLattice = 01337 generateMultiBlockLattice<T,Descriptor>(lattice, domain); 01338 extractSubDomain(lattice, *extractedLattice, domain); 01339 return extractedLattice; 01340 } 01341 01342 01343 /* *************** Density ******************************************* */ 01344 01345 template<typename T, template<typename U> class Descriptor> 01346 void computeDensity(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& density, Box3D domain) 01347 { 01348 applyProcessingFunctional ( 01349 new BoxDensityFunctional3D<T,Descriptor>, domain, lattice, density ); 01350 } 01351 01352 template<typename T, template<typename U> class Descriptor> 01353 std::auto_ptr<MultiScalarField3D<T> > computeDensity(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01354 { 01355 std::auto_ptr<MultiScalarField3D<T> > density = 01356 generateMultiScalarField<T>(lattice, domain); 01357 computeDensity(lattice, *density, domain); 01358 return density; 01359 } 01360 01361 template<typename T, template<typename U> class Descriptor> 01362 std::auto_ptr<MultiScalarField3D<T> > computeDensity(MultiBlockLattice3D<T,Descriptor>& lattice) { 01363 return computeDensity(lattice, lattice.getBoundingBox()); 01364 } 01365 01366 01367 /* *************** RhoBar ******************************************* */ 01368 01369 template<typename T, template<typename U> class Descriptor> 01370 void computeRhoBar(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& rhoBar, Box3D domain) 01371 { 01372 applyProcessingFunctional ( 01373 new BoxRhoBarFunctional3D<T,Descriptor>, domain, lattice, rhoBar ); 01374 } 01375 01376 template<typename T, template<typename U> class Descriptor> 01377 std::auto_ptr<MultiScalarField3D<T> > computeRhoBar(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01378 { 01379 std::auto_ptr<MultiScalarField3D<T> > rhoBar = 01380 generateMultiScalarField<T>(lattice, domain); 01381 computeRhoBar(lattice, *rhoBar, domain); 01382 return rhoBar; 01383 } 01384 01385 template<typename T, template<typename U> class Descriptor> 01386 std::auto_ptr<MultiScalarField3D<T> > computeRhoBar(MultiBlockLattice3D<T,Descriptor>& lattice) { 01387 return computeRhoBar(lattice, lattice.getBoundingBox()); 01388 } 01389 01390 01391 template<typename T, template<typename U> class Descriptor> 01392 void computeRhoBarJ( MultiBlockLattice3D<T,Descriptor>& lattice, 01393 MultiScalarField3D<T>& rhoBar, MultiTensorField3D<T,3>& j, Box3D domain ) 01394 { 01395 std::vector<MultiBlock3D*> fields; 01396 fields.push_back(&lattice); 01397 fields.push_back(&rhoBar); 01398 fields.push_back(&j); 01399 applyProcessingFunctional ( 01400 new BoxRhoBarJfunctional3D<T,Descriptor>, domain, fields ); 01401 } 01402 01403 /* *************** Kinetic Energy ************************************ */ 01404 01405 template<typename T, template<typename U> class Descriptor> 01406 void computeKineticEnergy(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& energy, Box3D domain) 01407 { 01408 applyProcessingFunctional ( 01409 new BoxKineticEnergyFunctional3D<T,Descriptor>, domain, lattice, energy ); 01410 } 01411 01412 template<typename T, template<typename U> class Descriptor> 01413 std::auto_ptr<MultiScalarField3D<T> > computeKineticEnergy(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01414 { 01415 std::auto_ptr<MultiScalarField3D<T> > energy = 01416 generateMultiScalarField<T>(lattice, domain); 01417 computeKineticEnergy(lattice, *energy, domain); 01418 return energy; 01419 } 01420 01421 template<typename T, template<typename U> class Descriptor> 01422 std::auto_ptr<MultiScalarField3D<T> > computeKineticEnergy(MultiBlockLattice3D<T,Descriptor>& lattice) { 01423 return computeKineticEnergy(lattice, lattice.getBoundingBox()); 01424 } 01425 01426 01427 /* *************** Packed RhoBar J *********************************** */ 01428 01429 template<typename T, template<typename U> class Descriptor> 01430 void computePackedRhoBarJ(MultiBlockLattice3D<T,Descriptor>& lattice, MultiNTensorField3D<T>& rhoBarJ, Box3D domain) 01431 { 01432 applyProcessingFunctional ( 01433 new PackedRhoBarJfunctional3D<T,Descriptor>, domain, lattice, rhoBarJ ); 01434 } 01435 01436 template<typename T, template<typename U> class Descriptor> 01437 std::auto_ptr<MultiNTensorField3D<T> > computePackedRhoBarJ(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01438 { 01439 std::auto_ptr<MultiNTensorField3D<T> > rhoBarJ = 01440 generateMultiNTensorField<T>(lattice, domain); 01441 computePackedRhoBarJ(lattice, *rhoBarJ, domain); 01442 return rhoBarJ; 01443 } 01444 01445 template<typename T, template<typename U> class Descriptor> 01446 std::auto_ptr<MultiScalarField3D<T> > computePackedRhoBarJ(MultiBlockLattice3D<T,Descriptor>& lattice) { 01447 return computePackedRhoBarJ(lattice, lattice.getBoundingBox()); 01448 } 01449 01450 01451 /* *************** Velocity Norm ************************************* */ 01452 01453 template<typename T, template<typename U> class Descriptor> 01454 void computeVelocityNorm(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& velocityNorm, Box3D domain) 01455 { 01456 applyProcessingFunctional ( 01457 new BoxVelocityNormFunctional3D<T,Descriptor>, domain, lattice, velocityNorm ); 01458 } 01459 01460 template<typename T, template<typename U> class Descriptor> 01461 std::auto_ptr<MultiScalarField3D<T> > computeVelocityNorm(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01462 { 01463 std::auto_ptr<MultiScalarField3D<T> > velocityNorm = 01464 generateMultiScalarField<T>(lattice, domain); 01465 computeVelocityNorm(lattice, *velocityNorm, domain); 01466 return velocityNorm; 01467 } 01468 01469 template<typename T, template<typename U> class Descriptor> 01470 std::auto_ptr<MultiScalarField3D<T> > computeVelocityNorm(MultiBlockLattice3D<T,Descriptor>& lattice) { 01471 return computeVelocityNorm(lattice, lattice.getBoundingBox()); 01472 } 01473 01474 01475 /* *************** Velocity Component ******************************** */ 01476 01477 template<typename T, template<typename U> class Descriptor> 01478 void computeVelocityComponent(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& velocityComponent, 01479 Box3D domain, plint iComponent) 01480 { 01481 applyProcessingFunctional ( 01482 new BoxVelocityComponentFunctional3D<T,Descriptor>(iComponent), domain, lattice, velocityComponent ); 01483 } 01484 01485 template<typename T, template<typename U> class Descriptor> 01486 std::auto_ptr<MultiScalarField3D<T> > computeVelocityComponent(MultiBlockLattice3D<T,Descriptor>& lattice, 01487 Box3D domain, plint iComponent) 01488 { 01489 std::auto_ptr<MultiScalarField3D<T> > velocityComponent = 01490 generateMultiScalarField<T>(lattice, domain); 01491 computeVelocityComponent(lattice, *velocityComponent, domain, iComponent); 01492 return velocityComponent; 01493 } 01494 01495 template<typename T, template<typename U> class Descriptor> 01496 std::auto_ptr<MultiScalarField3D<T> > computeVelocityComponent(MultiBlockLattice3D<T,Descriptor>& lattice, plint iComponent) 01497 { 01498 return computeVelocityComponent(lattice, lattice.getBoundingBox(), iComponent); 01499 } 01500 01501 01502 /* *************** Velocity ****************************************** */ 01503 01504 template<typename T, template<typename U> class Descriptor> 01505 void computeVelocity(MultiBlockLattice3D<T,Descriptor>& lattice, 01506 MultiTensorField3D<T,Descriptor<T>::d>& velocity, Box3D domain) 01507 { 01508 applyProcessingFunctional ( 01509 new BoxVelocityFunctional3D<T,Descriptor>, domain, lattice, velocity ); 01510 } 01511 01512 template<typename T, template<typename U> class Descriptor> 01513 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::d> > computeVelocity(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01514 { 01515 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::d> > velocity 01516 = generateMultiTensorField<T,Descriptor<T>::d>(lattice, domain); 01517 computeVelocity(lattice, *velocity, domain); 01518 return velocity; 01519 } 01520 01521 template<typename T, template<typename U> class Descriptor> 01522 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::d> > 01523 computeVelocity(MultiBlockLattice3D<T,Descriptor>& lattice) 01524 { 01525 return computeVelocity(lattice, lattice.getBoundingBox()); 01526 } 01527 01528 /* *************** Temperature ******************************************* */ 01529 01530 template<typename T, template<typename U> class Descriptor> 01531 void computeTemperature(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& temperature, Box3D domain) 01532 { 01533 applyProcessingFunctional ( 01534 new BoxTemperatureFunctional3D<T,Descriptor>, domain, lattice, temperature ); 01535 } 01536 01537 template<typename T, template<typename U> class Descriptor> 01538 std::auto_ptr<MultiScalarField3D<T> > computeTemperature(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01539 { 01540 std::auto_ptr<MultiScalarField3D<T> > temperature = 01541 generateMultiScalarField<T>(lattice, domain); 01542 computeTemperature(lattice, *temperature, domain); 01543 return temperature; 01544 } 01545 01546 template<typename T, template<typename U> class Descriptor> 01547 std::auto_ptr<MultiScalarField3D<T> > computeTemperature(MultiBlockLattice3D<T,Descriptor>& lattice) { 01548 return computeTemperature(lattice, lattice.getBoundingBox()); 01549 } 01550 01551 01552 /* *************** Deviatoric Stress ********************************* */ 01553 01554 template<typename T, template<typename U> class Descriptor> 01555 void computeDeviatoricStress( MultiBlockLattice3D<T,Descriptor>& lattice, 01556 MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n>& PiNeq, 01557 Box3D domain ) 01558 { 01559 applyProcessingFunctional ( 01560 new BoxDeviatoricStressFunctional3D<T,Descriptor>, domain, lattice, PiNeq ); 01561 } 01562 01563 template<typename T, template<typename U> class Descriptor> 01564 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > 01565 computeDeviatoricStress(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01566 { 01567 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > PiNeq 01568 = generateMultiTensorField<T,SymmetricTensor<T,Descriptor>::n>(lattice, domain); 01569 computeDeviatoricStress(lattice, *PiNeq, domain); 01570 return PiNeq; 01571 } 01572 01573 template<typename T, template<typename U> class Descriptor> 01574 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > 01575 computeDeviatoricStress(MultiBlockLattice3D<T,Descriptor>& lattice) 01576 { 01577 return computeDeviatoricStress(lattice, lattice.getBoundingBox()); 01578 } 01579 01580 01581 /* *************** Strain Rate from Stress *************************** */ 01582 01583 template<typename T, template<typename U> class Descriptor> 01584 void computeStrainRateFromStress( MultiBlockLattice3D<T,Descriptor>& lattice, 01585 MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n>& S, 01586 Box3D domain ) 01587 { 01588 applyProcessingFunctional ( 01589 new BoxStrainRateFromStressFunctional3D<T,Descriptor>, domain, lattice, S ); 01590 } 01591 01592 template<typename T, template<typename U> class Descriptor> 01593 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > 01594 computeStrainRateFromStress(MultiBlockLattice3D<T,Descriptor>& lattice, Box3D domain) 01595 { 01596 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > S 01597 = generateMultiTensorField<T,SymmetricTensor<T,Descriptor>::n>(lattice, domain); 01598 computeStrainRateFromStress(lattice, *S, domain); 01599 return S; 01600 } 01601 01602 template<typename T, template<typename U> class Descriptor> 01603 std::auto_ptr<MultiTensorField3D<T,SymmetricTensor<T,Descriptor>::n> > 01604 computeStrainRateFromStress(MultiBlockLattice3D<T,Descriptor>& lattice) 01605 { 01606 return computeStrainRateFromStress(lattice, lattice.getBoundingBox()); 01607 } 01608 01609 01610 /* *************** Population **************************************** */ 01611 01612 template<typename T, template<typename U> class Descriptor> 01613 void computePopulation(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& population, 01614 Box3D domain, plint iPop) 01615 { 01616 applyProcessingFunctional ( 01617 new BoxPopulationFunctional3D<T,Descriptor>(iPop), domain, lattice, population ); 01618 } 01619 01620 template<typename T, template<typename U> class Descriptor> 01621 std::auto_ptr<MultiScalarField3D<T> > computePopulation(MultiBlockLattice3D<T,Descriptor>& lattice, 01622 Box3D domain, plint iPop) 01623 { 01624 std::auto_ptr<MultiScalarField3D<T> > population = generateMultiScalarField<T>(lattice, domain); 01625 computePopulation(lattice, *population, domain, iPop); 01626 return population; 01627 } 01628 01629 template<typename T, template<typename U> class Descriptor> 01630 std::auto_ptr<MultiScalarField3D<T> > computePopulation(MultiBlockLattice3D<T,Descriptor>& lattice, plint iPop) 01631 { 01632 return computePopulation(lattice, lattice.getBoundingBox(), iPop); 01633 } 01634 01635 01636 template<typename T, template<typename U> class Descriptor> 01637 void computeEquilibrium(MultiBlockLattice3D<T,Descriptor>& lattice, MultiScalarField3D<T>& equilibrium, 01638 Box3D domain, plint iPop) 01639 { 01640 applyProcessingFunctional ( 01641 new BoxEquilibriumFunctional3D<T,Descriptor>(iPop), domain, lattice, equilibrium ); 01642 } 01643 01644 template<typename T, template<typename U> class Descriptor> 01645 std::auto_ptr<MultiScalarField3D<T> > computeEquilibrium(MultiBlockLattice3D<T,Descriptor>& lattice, 01646 Box3D domain, plint iPop) 01647 { 01648 std::auto_ptr<MultiScalarField3D<T> > equilibrium = generateMultiScalarField<T>(lattice, domain); 01649 computeEquilibrium(lattice, *equilibrium, domain, iPop); 01650 return equilibrium; 01651 } 01652 01653 template<typename T, template<typename U> class Descriptor> 01654 std::auto_ptr<MultiScalarField3D<T> > computeEquilibrium(MultiBlockLattice3D<T,Descriptor>& lattice, plint iPop) 01655 { 01656 return computeEquilibrium(lattice, lattice.getBoundingBox(), iPop); 01657 } 01658 01659 template<typename T, template<typename U> class Descriptor> 01660 void computeAllPopulations(MultiBlockLattice3D<T,Descriptor>& lattice, 01661 MultiTensorField3D<T,Descriptor<T>::q>& populations, 01662 Box3D domain) 01663 { 01664 applyProcessingFunctional ( 01665 new BoxAllPopulationsFunctional3D<T,Descriptor>(), domain, lattice, populations ); 01666 } 01667 01668 template<typename T, template<typename U> class Descriptor> 01669 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > computeAllPopulations(MultiBlockLattice3D<T,Descriptor>& lattice, 01670 Box3D domain) 01671 { 01672 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > populations = 01673 generateMultiTensorField<T,Descriptor<T>::q>(lattice, domain); 01674 computeAllPopulations(lattice, *populations, domain); 01675 return populations; 01676 } 01677 01678 template<typename T, template<typename U> class Descriptor> 01679 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > computeAllPopulations(MultiBlockLattice3D<T,Descriptor>& lattice) 01680 { 01681 return computeAllPopulations(lattice, lattice.getBoundingBox()); 01682 } 01683 01684 template<typename T, template<typename U> class Descriptor> 01685 void computeAllPopulationsFromTensorField(MultiBlockLattice3D<T,Descriptor>& lattice, 01686 MultiTensorField3D<T,Descriptor<T>::q>& populations, 01687 Box3D domain) 01688 { 01689 applyProcessingFunctional ( 01690 new BoxAllPopulationsToLatticeFunctional3D<T,Descriptor>(), domain, lattice, populations ); 01691 } 01692 01693 template<typename T, template<typename U> class Descriptor> 01694 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > computeAllPopulationsFromTensorField(MultiBlockLattice3D<T,Descriptor>& lattice, 01695 Box3D domain) 01696 { 01697 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > populations = 01698 generateMultiTensorField<T,Descriptor<T>::q>(lattice, domain); 01699 computeAllPopulationsFromTensorField(lattice, *populations, domain); 01700 return populations; 01701 } 01702 01703 template<typename T, template<typename U> class Descriptor> 01704 std::auto_ptr<MultiTensorField3D<T,Descriptor<T>::q> > computeAllPopulationsFromTensorField(MultiBlockLattice3D<T,Descriptor>& lattice) 01705 { 01706 return computeAllPopulationsFromTensorField(lattice, lattice.getBoundingBox()); 01707 } 01708 01709 template<typename T, template<typename U> class Descriptor> 01710 void copyPopulations(MultiBlockLattice3D<T,Descriptor>& latticeFrom, MultiBlockLattice3D<T,Descriptor>& latticeTo, 01711 Box3D domain) 01712 { 01713 applyProcessingFunctional ( 01714 new CopyPopulationsFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 01715 } 01716 01717 template<typename T, template<typename U> class Descriptor> 01718 void copyAll(MultiBlockLattice3D<T,Descriptor>& latticeFrom, 01719 MultiBlockLattice3D<T,Descriptor>& latticeTo, Box3D domain) 01720 { 01721 applyProcessingFunctional ( 01722 new LatticeCopyAllFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 01723 } 01724 01725 template<typename T, template<typename U> class Descriptor> 01726 void copyRegenerate(MultiBlockLattice3D<T,Descriptor>& latticeFrom, 01727 MultiBlockLattice3D<T,Descriptor>& latticeTo, Box3D domain) 01728 { 01729 applyProcessingFunctional ( 01730 new LatticeRegenerateFunctional3D<T,Descriptor>(), domain, latticeFrom, latticeTo ); 01731 } 01732 01733 01734 /* ******************************************************************* */ 01735 /* *************** PART V. Multi-block wrappers: Scalar-Field ******** */ 01736 /* ******************************************************************* */ 01737 01738 /* *************** Reductive functions ******************************* */ 01739 template<typename T> 01740 T computeSum(MultiScalarField3D<T>& scalarField, Box3D domain) { 01741 BoxScalarSumFunctional3D<T> functional; 01742 applyProcessingFunctional(functional, domain, scalarField); 01743 return functional.getSumScalar(); 01744 } 01745 01746 template<typename T> 01747 T computeSum(MultiScalarField3D<T>& scalarField) { 01748 return computeSum(scalarField, scalarField.getBoundingBox()); 01749 } 01750 01751 template<typename T> 01752 T computeBoundedSum(MultiScalarField3D<T>& scalarField, Box3D domain) { 01753 BoundedBoxScalarSumFunctional3D<T> functional; 01754 plint envelopeWidth=1; 01755 applyProcessingFunctional(functional, domain, scalarField, envelopeWidth); 01756 return functional.getSumScalar(); 01757 } 01758 01759 template<typename T> 01760 T computeBoundedSum(MultiScalarField3D<T>& scalarField) { 01761 return computeBoundedSum(scalarField, scalarField.getBoundingBox()); 01762 } 01763 01764 template<typename T> 01765 T computeAverage(MultiScalarField3D<T>& scalarField, Box3D domain) { 01766 BoxScalarSumFunctional3D<T> functional; 01767 applyProcessingFunctional(functional, domain, scalarField); 01768 return functional.getSumScalar() / (T) domain.nCells(); 01769 } 01770 01771 template<typename T> 01772 T computeAverage(MultiScalarField3D<T>& scalarField) { 01773 return computeAverage(scalarField, scalarField.getBoundingBox()); 01774 } 01775 01776 01777 template<typename T> 01778 T computeAverage(MultiScalarField3D<T>& scalarField, MultiScalarField3D<int>& mask, int flag, Box3D domain) 01779 { 01780 MaskedBoxScalarAverageFunctional3D<T> functional(flag); 01781 applyProcessingFunctional(functional, domain, scalarField, mask); 01782 return functional.getAverageScalar(); 01783 } 01784 01785 template<typename T> 01786 T computeAverage(MultiScalarField3D<T>& scalarField, MultiScalarField3D<int>& mask, int flag) { 01787 return computeAverage(scalarField, mask, flag, scalarField.getBoundingBox()); 01788 } 01789 01790 01791 template<typename T> 01792 T computeMin(MultiScalarField3D<T>& scalarField, Box3D domain) { 01793 BoxScalarMinFunctional3D<T> functional; 01794 applyProcessingFunctional(functional, domain, scalarField); 01795 return functional.getMinScalar(); 01796 } 01797 01798 template<typename T> 01799 T computeMin(MultiScalarField3D<T>& scalarField) { 01800 return computeMin(scalarField, scalarField.getBoundingBox()); 01801 } 01802 01803 01804 template<typename T> 01805 T computeMax(MultiScalarField3D<T>& scalarField, Box3D domain) { 01806 BoxScalarMaxFunctional3D<T> functional; 01807 applyProcessingFunctional(functional, domain, scalarField); 01808 return functional.getMaxScalar(); 01809 } 01810 01811 template<typename T> 01812 T computeMax(MultiScalarField3D<T>& scalarField) { 01813 return computeMax(scalarField, scalarField.getBoundingBox()); 01814 } 01815 01816 01817 template<typename T> 01818 T computeBoundedAverage(MultiScalarField3D<T>& scalarField, Box3D domain) { 01819 BoundedBoxScalarSumFunctional3D<T> functional; 01820 plint envelopeWidth=1; 01821 applyProcessingFunctional(functional, domain, scalarField, envelopeWidth); 01822 return functional.getSumScalar() / 01823 (T) ( (domain.getNx()-1)*(domain.getNy()-1)*(domain.getNz()-1) ); 01824 } 01825 01826 template<typename T> 01827 T computeBoundedAverage(MultiScalarField3D<T>& scalarField) { 01828 return computeBoundedAverage(scalarField, scalarField.getBoundingBox()); 01829 } 01830 01831 01832 template<typename T, class BoolMask> 01833 plint count(MultiScalarField3D<T>& field, Box3D domain, BoolMask boolMask) 01834 { 01835 CountScalarElementsFunctional3D<T,BoolMask> functional(boolMask); 01836 applyProcessingFunctional(functional, domain, field); 01837 return functional.getCount(); 01838 } 01839 01840 template<typename T, class BoolMask> 01841 plint count(MultiScalarField3D<T>& field, BoolMask boolMask) 01842 { 01843 return count(field, field.getBoundingBox(), boolMask); 01844 } 01845 01846 /* *************** Extract Sub-ScalarField *************************** */ 01847 01848 template<typename T> 01849 void extractSubDomain( MultiScalarField3D<T>& field, 01850 MultiScalarField3D<T>& extractedField, 01851 Box3D domain) 01852 { 01853 applyProcessingFunctional ( 01854 new ExtractScalarSubDomainFunctional3D<T>, domain, field, extractedField ); 01855 } 01856 01857 template<typename T> 01858 std::auto_ptr<MultiScalarField3D<T> > extractSubDomain(MultiScalarField3D<T>& field, Box3D domain) 01859 { 01860 std::auto_ptr<MultiScalarField3D<T> > extractedField = 01861 generateMultiScalarField<T>(field, domain); 01862 extractSubDomain(field, *extractedField, domain); 01863 return extractedField; 01864 } 01865 01866 /* *************** MultiScalarField - Scalar operations *************** */ 01867 01868 01869 template<typename T> 01870 void lessThan(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<int>& result, Box3D domain) 01871 { 01872 applyProcessingFunctional ( 01873 new A_lt_alpha_functional3D<T>(scalar), domain, field, result ); 01874 } 01875 01876 template<typename T> 01877 std::auto_ptr<MultiScalarField3D<int> > lessThan(MultiScalarField3D<T>& field, T scalar, Box3D domain) 01878 { 01879 std::auto_ptr<MultiScalarField3D<int> > result = 01880 generateMultiScalarField<int>(field, domain); 01881 lessThan(field, scalar, *result, domain); 01882 return result; 01883 } 01884 01885 template<typename T> 01886 std::auto_ptr<MultiScalarField3D<int> > lessThan(MultiScalarField3D<T>& field, T scalar) 01887 { 01888 return lessThan(field, scalar, field.getBoundingBox()); 01889 } 01890 01891 01892 template<typename T> 01893 void greaterThan(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<int>& result, Box3D domain) 01894 { 01895 applyProcessingFunctional ( 01896 new A_gt_alpha_functional3D<T>(scalar), domain, field, result ); 01897 } 01898 01899 template<typename T> 01900 std::auto_ptr<MultiScalarField3D<int> > greaterThan(MultiScalarField3D<T>& field, T scalar, Box3D domain) 01901 { 01902 std::auto_ptr<MultiScalarField3D<int> > result = 01903 generateMultiScalarField<int>(field, domain); 01904 greaterThan(field, scalar, *result, domain); 01905 return result; 01906 } 01907 01908 template<typename T> 01909 std::auto_ptr<MultiScalarField3D<int> > greaterThan(MultiScalarField3D<T>& field, T scalar) 01910 { 01911 return greaterThan(field, scalar, field.getBoundingBox()); 01912 } 01913 01914 template<typename T> 01915 void add(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<T>& result, Box3D domain) 01916 { 01917 applyProcessingFunctional ( 01918 new A_plus_alpha_functional3D<T>(scalar), domain, field, result ); 01919 } 01920 01921 template<typename T> 01922 std::auto_ptr<MultiScalarField3D<T> > add(MultiScalarField3D<T>& field, T scalar, Box3D domain) 01923 { 01924 std::auto_ptr<MultiScalarField3D<T> > result = 01925 generateMultiScalarField<T>(field, domain); 01926 add(field, scalar, *result, domain); 01927 return result; 01928 } 01929 01930 template<typename T> 01931 std::auto_ptr<MultiScalarField3D<T> > add(MultiScalarField3D<T>& field, T scalar) 01932 { 01933 return add(field, scalar, field.getBoundingBox()); 01934 } 01935 01936 01937 template<typename T> 01938 void add(T scalar, MultiScalarField3D<T>& field, MultiScalarField3D<T>& result, Box3D domain) 01939 { 01940 applyProcessingFunctional ( 01941 new A_plus_alpha_functional3D<T>(scalar), domain, field, result ); 01942 } 01943 01944 template<typename T> 01945 std::auto_ptr<MultiScalarField3D<T> > add(T scalar, MultiScalarField3D<T>& field, Box3D domain) 01946 { 01947 std::auto_ptr<MultiScalarField3D<T> > result = 01948 generateMultiScalarField<T>(field, domain); 01949 add(scalar, field, *result, domain); 01950 return result; 01951 } 01952 01953 template<typename T> 01954 std::auto_ptr<MultiScalarField3D<T> > add(T scalar, MultiScalarField3D<T>& field) 01955 { 01956 return add(scalar, field, field.getBoundingBox()); 01957 } 01958 01959 01960 template<typename T> 01961 void subtract(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<T>& result, Box3D domain) 01962 { 01963 applyProcessingFunctional ( 01964 new A_minus_alpha_functional3D<T>(scalar), domain, field, result ); 01965 } 01966 01967 template<typename T> 01968 std::auto_ptr<MultiScalarField3D<T> > subtract(MultiScalarField3D<T>& field, T scalar, Box3D domain) 01969 { 01970 std::auto_ptr<MultiScalarField3D<T> > result = 01971 generateMultiScalarField<T>(field, domain); 01972 subtract(field, scalar, *result, domain); 01973 return result; 01974 } 01975 01976 template<typename T> 01977 std::auto_ptr<MultiScalarField3D<T> > subtract(MultiScalarField3D<T>& field, T scalar) 01978 { 01979 return subtract(field, scalar, field.getBoundingBox()); 01980 } 01981 01982 01983 template<typename T> 01984 void subtract(T scalar, MultiScalarField3D<T>& field, MultiScalarField3D<T>& result, Box3D domain) 01985 { 01986 applyProcessingFunctional ( 01987 new Alpha_minus_A_functional3D<T>(scalar), domain, field, result ); 01988 } 01989 01990 template<typename T> 01991 std::auto_ptr<MultiScalarField3D<T> > subtract(T scalar, MultiScalarField3D<T>& field, Box3D domain) 01992 { 01993 std::auto_ptr<MultiScalarField3D<T> > result = 01994 generateMultiScalarField<T>(field, domain); 01995 subtract(scalar, field, *result, domain); 01996 return result; 01997 } 01998 01999 template<typename T> 02000 std::auto_ptr<MultiScalarField3D<T> > subtract(T scalar, MultiScalarField3D<T>& field) 02001 { 02002 return subtract(scalar, field, field.getBoundingBox()); 02003 } 02004 02005 02006 template<typename T> 02007 void multiply(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<T>& result, Box3D domain) 02008 { 02009 applyProcessingFunctional ( 02010 new A_times_alpha_functional3D<T>(scalar), domain, field, result ); 02011 } 02012 02013 template<typename T> 02014 std::auto_ptr<MultiScalarField3D<T> > multiply(MultiScalarField3D<T>& field, T scalar, Box3D domain) 02015 { 02016 std::auto_ptr<MultiScalarField3D<T> > result = 02017 generateMultiScalarField<T>(field, domain); 02018 multiply(field, scalar, *result, domain); 02019 return result; 02020 } 02021 02022 template<typename T> 02023 std::auto_ptr<MultiScalarField3D<T> > multiply(MultiScalarField3D<T>& field, T scalar) 02024 { 02025 return multiply(field, scalar, field.getBoundingBox()); 02026 } 02027 02028 02029 template<typename T> 02030 void multiply(T scalar, MultiScalarField3D<T>& field, MultiScalarField3D<T>& result, Box3D domain) 02031 { 02032 applyProcessingFunctional ( 02033 new A_times_alpha_functional3D<T>(scalar), domain, field, result ); 02034 } 02035 02036 template<typename T> 02037 std::auto_ptr<MultiScalarField3D<T> > multiply(T scalar, MultiScalarField3D<T>& field, Box3D domain) 02038 { 02039 std::auto_ptr<MultiScalarField3D<T> > result = 02040 generateMultiScalarField<T>(field, domain); 02041 multiply(scalar, field, *result, domain); 02042 return result; 02043 } 02044 02045 template<typename T> 02046 std::auto_ptr<MultiScalarField3D<T> > multiply(T scalar, MultiScalarField3D<T>& field) 02047 { 02048 return multiply(scalar, field, field.getBoundingBox()); 02049 } 02050 02051 02052 template<typename T> 02053 void divide(MultiScalarField3D<T>& field, T scalar, MultiScalarField3D<T>& result, Box3D domain) 02054 { 02055 applyProcessingFunctional ( 02056 new A_dividedBy_alpha_functional3D<T>(scalar), domain, field, result ); 02057 } 02058 02059 template<typename T> 02060 std::auto_ptr<MultiScalarField3D<T> > divide(MultiScalarField3D<T>& field, T scalar, Box3D domain) 02061 { 02062 std::auto_ptr<MultiScalarField3D<T> > result = 02063 generateMultiScalarField<T>(field, domain); 02064 divide(field, scalar, *result, domain); 02065 return result; 02066 } 02067 02068 template<typename T> 02069 std::auto_ptr<MultiScalarField3D<T> > divide(MultiScalarField3D<T>& field, T scalar) 02070 { 02071 return divide(field, scalar, field.getBoundingBox()); 02072 } 02073 02074 02075 template<typename T> 02076 void divide(T scalar, MultiScalarField3D<T>& field, MultiScalarField3D<T>& result, Box3D domain) 02077 { 02078 applyProcessingFunctional ( 02079 new Alpha_dividedBy_A_functional3D<T>(scalar), domain, field, result ); 02080 } 02081 02082 template<typename T> 02083 std::auto_ptr<MultiScalarField3D<T> > divide(T scalar, MultiScalarField3D<T>& field, Box3D domain) 02084 { 02085 std::auto_ptr<MultiScalarField3D<T> > result = 02086 generateMultiScalarField<T>(field, domain); 02087 divide(scalar, field, *result, domain); 02088 return result; 02089 } 02090 02091 template<typename T> 02092 std::auto_ptr<MultiScalarField3D<T> > divide(T scalar, MultiScalarField3D<T>& field) 02093 { 02094 return divide(scalar, field, field.getBoundingBox()); 02095 } 02096 02097 02098 /* *************** MultiScalarField - Scalar inplace operations *************** */ 02099 02100 template<typename T> 02101 void addInPlace(MultiScalarField3D<T>& field, T scalar, Box3D domain) { 02102 applyProcessingFunctional ( 02103 new A_plus_alpha_inplace_functional3D<T>(scalar), domain, field); 02104 } 02105 02106 template<typename T> 02107 void addInPlace(MultiScalarField3D<T>& field, T scalar) { 02108 addInPlace(field, scalar, field.getBoundingBox()); 02109 } 02110 02111 02112 template<typename T> 02113 void subtractInPlace(MultiScalarField3D<T>& field, T scalar, Box3D domain) { 02114 applyProcessingFunctional ( 02115 new A_minus_alpha_inplace_functional3D<T>(scalar), domain, field); 02116 } 02117 02118 template<typename T> 02119 void subtractInPlace(MultiScalarField3D<T>& field, T scalar) { 02120 subtractInPlace(field, scalar, field.getBoundingBox()); 02121 } 02122 02123 02124 template<typename T> 02125 void multiplyInPlace(MultiScalarField3D<T>& field, T scalar, Box3D domain) { 02126 applyProcessingFunctional ( 02127 new A_times_alpha_inplace_functional3D<T>(scalar), domain, field); 02128 } 02129 02130 template<typename T> 02131 void multiplyInPlace(MultiScalarField3D<T>& field, T scalar) { 02132 multiplyInPlace(field, scalar, field.getBoundingBox()); 02133 } 02134 02135 02136 template<typename T> 02137 void divideInPlace(MultiScalarField3D<T>& field, T scalar, Box3D domain) { 02138 applyProcessingFunctional ( 02139 new A_dividedBy_alpha_inplace_functional3D<T>(scalar), domain, field); 02140 } 02141 02142 template<typename T> 02143 void divideInPlace(MultiScalarField3D<T>& field, T scalar) { 02144 divideInPlace(field, scalar, field.getBoundingBox()); 02145 } 02146 02147 02148 /* *************** MultiScalarField - MultiScalarField operations *************** */ 02149 02150 template<typename T1, typename T2> 02151 void copy(MultiScalarField3D<T1>& field, MultiScalarField3D<T2>& convertedField, Box3D domain) 02152 { 02153 applyProcessingFunctional ( 02154 new CopyConvertScalarFunctional3D<T1,T2>, domain, field, convertedField ); 02155 } 02156 02157 template<typename T1, typename T2> 02158 std::auto_ptr<MultiScalarField3D<T2> > copyConvert(MultiScalarField3D<T1>& field, Box3D domain) 02159 { 02160 std::auto_ptr<MultiScalarField3D<T2> > convertedField = 02161 generateMultiScalarField<T2>(field, domain); 02162 plb::copy(field, *convertedField, domain); 02163 return convertedField; 02164 } 02165 02166 template<typename T1, typename T2> 02167 std::auto_ptr<MultiScalarField3D<T2> > copyConvert(MultiScalarField3D<T1>& field) 02168 { 02169 return copyConvert<T1,T2>(field, field.getBoundingBox()); 02170 } 02171 02172 02173 template<typename T> 02174 void lessThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<int>& result, Box3D domain) 02175 { 02176 std::vector<MultiBlock3D* > fields; 02177 fields.push_back(&A); 02178 fields.push_back(&B); 02179 fields.push_back(&result); 02180 applyProcessingFunctional ( 02181 new A_lt_B_functional3D<T>, domain, fields ); 02182 } 02183 02184 template<typename T> 02185 std::auto_ptr<MultiScalarField3D<int> > lessThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02186 { 02187 std::auto_ptr<MultiScalarField3D<int> > result = 02188 generateIntersectMultiScalarField<int>(A,B, domain); 02189 lessThan(A, B, *result, domain); 02190 return result; 02191 } 02192 02193 02194 template<typename T> 02195 std::auto_ptr<MultiScalarField3D<int> > lessThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02196 { 02197 return lessThan(A, B, A.getBoundingBox()); 02198 } 02199 02200 02201 template<typename T> 02202 void greaterThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<int>& result, Box3D domain) 02203 { 02204 std::vector<MultiBlock3D* > fields; 02205 fields.push_back(&A); 02206 fields.push_back(&B); 02207 fields.push_back(&result); 02208 applyProcessingFunctional ( 02209 new A_gt_B_functional3D<T>, domain, fields ); 02210 } 02211 02212 template<typename T> 02213 std::auto_ptr<MultiScalarField3D<int> > greaterThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02214 { 02215 std::auto_ptr<MultiScalarField3D<int> > result = 02216 generateIntersectMultiScalarField<int>(A,B, domain); 02217 greaterThan(A, B, *result, domain); 02218 return result; 02219 } 02220 02221 02222 template<typename T> 02223 std::auto_ptr<MultiScalarField3D<int> > greaterThan(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02224 { 02225 return greaterThan(A, B, A.getBoundingBox()); 02226 } 02227 02228 02229 02230 template<typename T> 02231 void add(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<T>& result, Box3D domain) 02232 { 02233 std::vector<MultiScalarField3D<T>* > fields; 02234 fields.push_back(&A); 02235 fields.push_back(&B); 02236 fields.push_back(&result); 02237 applyProcessingFunctional ( 02238 new A_plus_B_functional3D<T>, domain, fields ); 02239 } 02240 02241 template<typename T> 02242 std::auto_ptr<MultiScalarField3D<T> > add(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02243 { 02244 std::auto_ptr<MultiScalarField3D<T> > result = 02245 generateIntersectMultiScalarField<T>(A,B, domain); 02246 add(A, B, *result, domain); 02247 return result; 02248 } 02249 02250 template<typename T> 02251 std::auto_ptr<MultiScalarField3D<T> > add(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02252 { 02253 return add(A, B, A.getBoundingBox()); 02254 } 02255 02256 02257 template<typename T> 02258 void subtract(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<T>& result, Box3D domain) 02259 { 02260 std::vector<MultiScalarField3D<T>* > fields; 02261 fields.push_back(&A); 02262 fields.push_back(&B); 02263 fields.push_back(&result); 02264 applyProcessingFunctional ( 02265 new A_minus_B_functional3D<T>, domain, fields ); 02266 } 02267 02268 template<typename T> 02269 std::auto_ptr<MultiScalarField3D<T> > subtract(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02270 { 02271 std::auto_ptr<MultiScalarField3D<T> > result = 02272 generateIntersectMultiScalarField<T>(A,B, domain); 02273 subtract(A, B, *result, domain); 02274 return result; 02275 } 02276 02277 template<typename T> 02278 std::auto_ptr<MultiScalarField3D<T> > subtract(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02279 { 02280 return subtract(A, B, A.getBoundingBox()); 02281 } 02282 02283 02284 template<typename T> 02285 void multiply(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<T>& result, Box3D domain) 02286 { 02287 std::vector<MultiScalarField3D<T>* > fields; 02288 fields.push_back(&A); 02289 fields.push_back(&B); 02290 fields.push_back(&result); 02291 applyProcessingFunctional ( 02292 new A_times_B_functional3D<T>, domain, fields ); 02293 } 02294 02295 template<typename T> 02296 std::auto_ptr<MultiScalarField3D<T> > multiply(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02297 { 02298 std::auto_ptr<MultiScalarField3D<T> > result = 02299 generateIntersectMultiScalarField<T>(A,B, domain); 02300 multiply(A, B, *result, domain); 02301 return result; 02302 } 02303 02304 template<typename T> 02305 std::auto_ptr<MultiScalarField3D<T> > multiply(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02306 { 02307 return multiply(A, B, A.getBoundingBox()); 02308 } 02309 02310 template<typename T> 02311 void divide(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, MultiScalarField3D<T>& result, Box3D domain) 02312 { 02313 std::vector<MultiScalarField3D<T>* > fields; 02314 fields.push_back(&A); 02315 fields.push_back(&B); 02316 fields.push_back(&result); 02317 applyProcessingFunctional ( 02318 new A_dividedBy_B_functional3D<T>, domain, fields ); 02319 } 02320 02321 template<typename T> 02322 std::auto_ptr<MultiScalarField3D<T> > divide(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) 02323 { 02324 std::auto_ptr<MultiScalarField3D<T> > result = 02325 generateIntersectMultiScalarField<T>(A,B, domain); 02326 divide(A, B, *result, domain); 02327 return result; 02328 } 02329 02330 template<typename T> 02331 std::auto_ptr<MultiScalarField3D<T> > divide(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) 02332 { 02333 return divide(A, B, A.getBoundingBox()); 02334 } 02335 02336 02337 /* *************** ScalarField - ScalarField inplace operations *************** */ 02338 02339 template<typename T> 02340 void addInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) { 02341 applyProcessingFunctional ( 02342 new A_plus_B_inplace_functional3D<T>, domain, A, B ); 02343 } 02344 02345 template<typename T> 02346 void addInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) { 02347 addInPlace(A, B, A.getBoundingBox()); 02348 } 02349 02350 02351 template<typename T> 02352 void subtractInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) { 02353 applyProcessingFunctional ( 02354 new A_minus_B_inplace_functional3D<T>, domain, A, B ); 02355 } 02356 02357 template<typename T> 02358 void subtractInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) { 02359 subtractInPlace(A, B, A.getBoundingBox()); 02360 } 02361 02362 02363 template<typename T> 02364 void multiplyInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) { 02365 applyProcessingFunctional ( 02366 new A_times_B_inplace_functional3D<T>, domain, A, B ); 02367 } 02368 02369 template<typename T> 02370 void multiplyInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) { 02371 multiplyInPlace(A,B, A.getBoundingBox()); 02372 } 02373 02374 02375 template<typename T> 02376 void divideInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B, Box3D domain) { 02377 applyProcessingFunctional ( 02378 new A_dividedBy_B_inplace_functional3D<T>, domain, A, B ); 02379 } 02380 02381 template<typename T> 02382 void divideInPlace(MultiScalarField3D<T>& A, MultiScalarField3D<T>& B) { 02383 divideInPlace(A, B, A.getBoundingBox()); 02384 } 02385 02386 /* *************** MultiScalarField operations *************** */ 02387 02388 template<typename T> 02389 void computeSqrt(MultiScalarField3D<T>& A, MultiScalarField3D<T>& result, Box3D domain) 02390 { 02391 applyProcessingFunctional ( 02392 new ComputeScalarSqrtFunctional3D<T>, domain, A, result ); 02393 } 02394 02395 template<typename T> 02396 std::auto_ptr<MultiScalarField3D<T> > computeSqrt(MultiScalarField3D<T>& A, Box3D domain) 02397 { 02398 std::auto_ptr<MultiScalarField3D<T> > result = 02399 generateMultiScalarField<T>(A, domain); 02400 computeSqrt(A, *result, domain); 02401 return result; 02402 } 02403 02404 template<typename T> 02405 std::auto_ptr<MultiScalarField3D<T> > computeSqrt(MultiScalarField3D<T>& A) 02406 { 02407 return computeSqrt(A, A.getBoundingBox()); 02408 } 02409 02410 02411 template<typename T> 02412 void computeAbsoluteValue(MultiScalarField3D<T>& A, MultiScalarField3D<T>& result, Box3D domain) 02413 { 02414 applyProcessingFunctional ( 02415 new ComputeAbsoluteValueFunctional3D<T>, domain, A, result ); 02416 } 02417 02418 template<typename T> 02419 std::auto_ptr<MultiScalarField3D<T> > computeAbsoluteValue(MultiScalarField3D<T>& A, Box3D domain) 02420 { 02421 std::auto_ptr<MultiScalarField3D<T> > result = 02422 generateMultiScalarField<T>(A, domain); 02423 computeAbsoluteValue(A, *result, domain); 02424 return result; 02425 } 02426 02427 template<typename T> 02428 std::auto_ptr<MultiScalarField3D<T> > computeAbsoluteValue(MultiScalarField3D<T>& A) 02429 { 02430 return computeAbsoluteValue(A, A.getBoundingBox()); 02431 } 02432 02433 02434 /* ******************************************************************* */ 02435 /* *************** PART VI. Multi-block wrappers: Tensor-field ******* */ 02436 /* ******************************************************************* */ 02437 02438 /* *************** Reductive functions ******************************* */ 02439 02440 template<typename T, plint nDim, class BoolMask> 02441 plint count(MultiTensorField3D<T,nDim>& field, Box3D domain, BoolMask boolMask) 02442 { 02443 CountTensorElementsFunctional3D<T,nDim,BoolMask> functional(boolMask); 02444 applyProcessingFunctional(functional, domain, field); 02445 return functional.getCount(); 02446 } 02447 02448 template<typename T, plint nDim, class BoolMask> 02449 plint count(MultiTensorField3D<T,nDim>& field, BoolMask boolMask) 02450 { 02451 return count(field, field.getBoundingBox(), boolMask); 02452 } 02453 02454 /* *************** Extract Sub-TensorField *************************** */ 02455 02456 template<typename T, int nDim> 02457 void extractSubDomain( MultiTensorField3D<T,nDim>& field, 02458 MultiTensorField3D<T,nDim>& extractedField, 02459 Box3D domain) 02460 { 02461 applyProcessingFunctional ( 02462 new ExtractTensorSubDomainFunctional3D<T,nDim>, domain, field, extractedField ); 02463 } 02464 02465 template<typename T, int nDim> 02466 std::auto_ptr<MultiTensorField3D<T,nDim> > extractSubDomain(MultiTensorField3D<T,nDim>& field, Box3D domain) 02467 { 02468 std::auto_ptr<MultiTensorField3D<T,nDim> > extractedField = 02469 generateMultiTensorField<T,nDim>(field, domain); 02470 extractSubDomain(field, *extractedField, domain); 02471 return extractedField; 02472 } 02473 02474 02475 /* *************** Component (scalar-field) out of a tensor-field ****** */ 02476 02477 template<typename T, int nDim> 02478 void extractComponent(MultiTensorField3D<T,nDim>& tensorField, MultiScalarField3D<T>& component, Box3D domain, int iComponent) 02479 { 02480 applyProcessingFunctional ( 02481 new ExtractTensorComponentFunctional3D<T,nDim>(iComponent), domain, component, tensorField ); 02482 } 02483 02484 template<typename T, int nDim> 02485 std::auto_ptr<MultiScalarField3D<T> > extractComponent(MultiTensorField3D<T,nDim>& tensorField, Box3D domain, int iComponent) 02486 { 02487 std::auto_ptr<MultiScalarField3D<T> > component = 02488 generateMultiScalarField<T>(tensorField, domain); 02489 extractComponent(tensorField, *component, domain, iComponent); 02490 return component; 02491 } 02492 02493 template<typename T, int nDim> 02494 std::auto_ptr<MultiScalarField3D<T> > extractComponent(MultiTensorField3D<T,nDim>& tensorField, int iComponent) 02495 { 02496 return extractComponent(tensorField, tensorField.getBoundingBox(), iComponent); 02497 } 02498 02499 02500 /* *************** Vector-norm of each cell in the field *************** */ 02501 02502 template<typename T, int nDim> 02503 void computeNorm(MultiTensorField3D<T,nDim>& tensorField, MultiScalarField3D<T>& norm, Box3D domain) 02504 { 02505 applyProcessingFunctional ( 02506 new ComputeNormFunctional3D<T,nDim>, domain, norm, tensorField ); 02507 } 02508 02509 template<typename T, int nDim> 02510 std::auto_ptr<MultiScalarField3D<T> > computeNorm(MultiTensorField3D<T,nDim>& tensorField, Box3D domain) 02511 { 02512 std::auto_ptr<MultiScalarField3D<T> > norm = generateMultiScalarField<T>(tensorField, domain); 02513 computeNorm(tensorField, *norm, domain); 02514 return norm; 02515 } 02516 02517 template<typename T, int nDim> 02518 std::auto_ptr<MultiScalarField3D<T> > computeNorm(MultiTensorField3D<T,nDim>& tensorField) 02519 { 02520 return computeNorm(tensorField, tensorField.getBoundingBox()); 02521 } 02522 02523 /* *************** Sqrt operation on each component of each cell *************** */ 02524 02525 template<typename T, int nDim> 02526 void computeSqrt(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& result, Box3D domain) 02527 { 02528 applyProcessingFunctional ( 02529 new ComputeTensorSqrtFunctional3D<T, nDim>, domain, A, result); 02530 } 02531 02532 template<typename T, int nDim> 02533 std::auto_ptr<MultiTensorField3D<T,nDim> > computeSqrt(MultiTensorField3D<T,nDim>& A, Box3D domain) 02534 { 02535 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02536 generateMultiTensorField<T,nDim>(A, domain); 02537 computeSqrt(A, *result, domain); 02538 return result; 02539 } 02540 02541 template<typename T, int nDim> 02542 std::auto_ptr<MultiTensorField3D<T,nDim> > computeSqrt(MultiTensorField3D<T,nDim>& A) 02543 { 02544 return computeSqrt(A, A.getBoundingBox()); 02545 } 02546 02547 02548 /* *************** Squared vector-norm of each cell in the field ******** */ 02549 02550 template<typename T, int nDim> 02551 void computeNormSqr(MultiTensorField3D<T,nDim>& tensorField, MultiScalarField3D<T>& normSqr, Box3D domain) 02552 { 02553 applyProcessingFunctional ( 02554 new ComputeNormSqrFunctional3D<T,nDim>, domain, normSqr, tensorField ); 02555 } 02556 02557 template<typename T, int nDim> 02558 std::auto_ptr<MultiScalarField3D<T> > computeNormSqr(MultiTensorField3D<T,nDim>& tensorField, Box3D domain) 02559 { 02560 std::auto_ptr<MultiScalarField3D<T> > normSqr = 02561 generateMultiScalarField<T>(tensorField, domain); 02562 computeNormSqr(tensorField, *normSqr, domain); 02563 return normSqr; 02564 } 02565 02566 template<typename T, int nDim> 02567 std::auto_ptr<MultiScalarField3D<T> > computeNormSqr(MultiTensorField3D<T,nDim>& tensorField) 02568 { 02569 return computeNormSqr(tensorField, tensorField.getBoundingBox()); 02570 } 02571 02572 02573 /* *************** Tensor-norm of each symmetric tensor of a field ***** */ 02574 02575 template<typename T> 02576 void computeSymmetricTensorNorm(MultiTensorField3D<T,6>& tensorField, MultiScalarField3D<T>& norm, Box3D domain) 02577 { 02578 applyProcessingFunctional ( 02579 new ComputeSymmetricTensorNormFunctional3D<T>, domain, norm, tensorField ); 02580 } 02581 02582 template<typename T> 02583 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorNorm(MultiTensorField3D<T,6>& tensorField, Box3D domain) 02584 { 02585 std::auto_ptr<MultiScalarField3D<T> > norm = 02586 generateMultiScalarField<T>(tensorField, domain); 02587 computeSymmetricTensorNorm(tensorField, *norm, domain); 02588 return norm; 02589 } 02590 02591 template<typename T> 02592 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorNorm(MultiTensorField3D<T,6>& tensorField) 02593 { 02594 return computeSymmetricTensorNorm(tensorField, tensorField.getBoundingBox()); 02595 } 02596 02597 02598 /* *************** Squared Tensor-norm of each symmetric tensor of a field*/ 02599 02600 template<typename T> 02601 void computeSymmetricTensorNormSqr(MultiTensorField3D<T,6>& tensorField, MultiScalarField3D<T>& normSqr, Box3D domain) 02602 { 02603 applyProcessingFunctional ( 02604 new ComputeSymmetricTensorNormSqrFunctional3D<T>, domain, normSqr, tensorField ); 02605 } 02606 02607 template<typename T> 02608 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorNormSqr(MultiTensorField3D<T,6>& tensorField, Box3D domain) 02609 { 02610 std::auto_ptr<MultiScalarField3D<T> > normSqr = 02611 generateMultiScalarField<T>(tensorField, domain); 02612 computeSymmetricTensorNormSqr(tensorField, *normSqr, domain); 02613 return normSqr; 02614 } 02615 02616 template<typename T> 02617 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorNormSqr(MultiTensorField3D<T,6>& tensorField) 02618 { 02619 return computeSymmetricTensorNormSqr(tensorField, tensorField.getBoundingBox()); 02620 } 02621 02622 02623 /* *************** Trace of each symmetric tensor of a field ************ */ 02624 02625 template<typename T> 02626 void computeSymmetricTensorTrace(MultiTensorField3D<T,6>& tensorField, MultiScalarField3D<T>& trace, Box3D domain) 02627 { 02628 applyProcessingFunctional ( 02629 new ComputeSymmetricTensorTraceFunctional3D<T>, domain, trace, tensorField ); 02630 } 02631 02632 template<typename T> 02633 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorTrace(MultiTensorField3D<T,6>& tensorField, Box3D domain) 02634 { 02635 std::auto_ptr<MultiScalarField3D<T> > trace = 02636 generateMultiScalarField<T>(tensorField, domain); 02637 computeSymmetricTensorTrace(tensorField, *trace, domain); 02638 return trace; 02639 } 02640 02641 template<typename T> 02642 std::auto_ptr<MultiScalarField3D<T> > computeSymmetricTensorTrace(MultiTensorField3D<T,6>& tensorField) 02643 { 02644 return computeSymmetricTensorTrace(tensorField, tensorField.getBoundingBox()); 02645 } 02646 02647 02648 /* *************** Gradient from scalar field *********************** */ 02649 02650 template<typename T> 02651 void computeGradient(MultiScalarField3D<T>& phi, MultiTensorField3D<T,3>& gradient, Box3D domain) 02652 { 02653 plint envelopeWidth=1; 02654 applyProcessingFunctional ( 02655 new BoxGradientFunctional3D<T>, domain, phi, gradient, envelopeWidth ); 02656 } 02657 02658 template<typename T> 02659 std::auto_ptr<MultiTensorField3D<T,3> > computeGradient(MultiScalarField3D<T>& phi, Box3D domain) 02660 { 02661 std::auto_ptr<MultiTensorField3D<T,3> > gradient = 02662 generateMultiTensorField<T,3>(phi, domain); 02663 computeGradient(phi, *gradient, domain); 02664 return gradient; 02665 } 02666 02667 template<typename T> 02668 std::auto_ptr<MultiTensorField3D<T,3> > computeGradient(MultiScalarField3D<T>& phi) 02669 { 02670 return computeGradient(phi, phi.getBoundingBox()); 02671 } 02672 02673 02674 /* *************** Gradient, without boundary treatment, from scalar field */ 02675 02676 template<typename T> 02677 void computeBulkGradient(MultiScalarField3D<T>& phi, MultiTensorField3D<T,3>& gradient, Box3D domain) 02678 { 02679 applyProcessingFunctional ( 02680 new BoxBulkGradientFunctional3D<T>, domain, phi, gradient ); 02681 } 02682 02683 template<typename T> 02684 std::auto_ptr<MultiTensorField3D<T,3> > computeBulkGradient(MultiScalarField3D<T>& phi, Box3D domain) 02685 { 02686 std::auto_ptr<MultiTensorField3D<T,3> > gradient = 02687 generateMultiTensorField<T,3>(phi, domain); 02688 computeBulkGradient(phi, *gradient, domain); 02689 return gradient; 02690 } 02691 02692 template<typename T> 02693 std::auto_ptr<MultiTensorField3D<T,3> > computeBulkGradient(MultiScalarField3D<T>& phi) 02694 { 02695 return computeBulkGradient(phi, phi.getBoundingBox()); 02696 } 02697 02698 02699 02700 /* *************** Vorticity from Velocity field *********************** */ 02701 02702 template<typename T> 02703 void computeVorticity(MultiTensorField3D<T,3>& velocity, MultiTensorField3D<T,3>& vorticity, Box3D domain) 02704 { 02705 plint envelopeWidth=1; 02706 applyProcessingFunctional ( 02707 new BoxVorticityFunctional3D<T,3>, domain, velocity, vorticity, envelopeWidth ); 02708 } 02709 02710 template<typename T> 02711 std::auto_ptr<MultiTensorField3D<T,3> > computeVorticity(MultiTensorField3D<T,3>& velocity, Box3D domain) 02712 { 02713 std::auto_ptr<MultiTensorField3D<T,3> > vorticity = 02714 generateMultiTensorField<T,3>(velocity, domain); 02715 computeVorticity(velocity, *vorticity, domain); 02716 return vorticity; 02717 } 02718 02719 template<typename T> 02720 std::auto_ptr<MultiTensorField3D<T,3> > computeVorticity(MultiTensorField3D<T,3>& velocity) 02721 { 02722 return computeVorticity(velocity, velocity.getBoundingBox()); 02723 } 02724 02725 02726 /* *************** Vorticity, without boundary treatment, from Velocity field */ 02727 02728 template<typename T> 02729 void computeBulkVorticity(MultiTensorField3D<T,3>& velocity, MultiTensorField3D<T,3>& vorticity, Box3D domain) 02730 { 02731 applyProcessingFunctional ( 02732 new BoxBulkVorticityFunctional3D<T,3>, domain, velocity, vorticity ); 02733 } 02734 02735 template<typename T> 02736 std::auto_ptr<MultiTensorField3D<T,3> > computeBulkVorticity(MultiTensorField3D<T,3>& velocity, Box3D domain) 02737 { 02738 std::auto_ptr<MultiTensorField3D<T,3> > vorticity = 02739 generateMultiTensorField<T,3>(velocity, domain); 02740 computeBulkVorticity(velocity, *vorticity, domain); 02741 return vorticity; 02742 } 02743 02744 template<typename T> 02745 std::auto_ptr<MultiTensorField3D<T,3> > computeBulkVorticity(MultiTensorField3D<T,3>& velocity) 02746 { 02747 return computeBulkVorticity(velocity, velocity.getBoundingBox()); 02748 } 02749 02750 02751 02752 /* *************** Divergence, without boundary treatment, from Velocity field */ 02753 02754 template<typename T> 02755 void computeBulkDivergence(MultiTensorField3D<T,3>& velocity, MultiScalarField3D<T>& divergence, Box3D domain) 02756 { 02757 applyProcessingFunctional ( 02758 new BoxBulkDivergenceFunctional3D<T,3>, domain, divergence, velocity ); 02759 } 02760 02761 template<typename T> 02762 std::auto_ptr<MultiScalarField3D<T> > computeBulkDivergence(MultiTensorField3D<T,3>& velocity, Box3D domain) 02763 { 02764 std::auto_ptr<MultiScalarField3D<T> > divergence = 02765 generateMultiScalarField<T>(velocity, domain); 02766 computeBulkDivergence(velocity, *divergence, domain); 02767 return divergence; 02768 } 02769 02770 template<typename T> 02771 std::auto_ptr<MultiScalarField3D<T> > computeBulkDivergence(MultiTensorField3D<T,3>& velocity) 02772 { 02773 return computeBulkDivergence(velocity, velocity.getBoundingBox()); 02774 } 02775 02776 02777 02778 /* *************** Strain rate from Velocity field ********************* */ 02779 02780 template<typename T> 02781 void computeStrainRate(MultiTensorField3D<T,3>& velocity, MultiTensorField3D<T,6>& S, Box3D domain) 02782 { 02783 plint envelopeWidth=1; 02784 applyProcessingFunctional ( 02785 new BoxStrainRateFunctional3D<T,3>, domain, velocity, S, envelopeWidth ); 02786 } 02787 02788 template<typename T> 02789 std::auto_ptr<MultiTensorField3D<T,6> > computeStrainRate(MultiTensorField3D<T,3>& velocity, Box3D domain) 02790 { 02791 std::auto_ptr<MultiTensorField3D<T,6> > S = 02792 generateMultiTensorField<T,6>(velocity, domain); 02793 computeStrainRate(velocity, *S, domain); 02794 return S; 02795 } 02796 02797 template<typename T> 02798 std::auto_ptr<MultiTensorField3D<T,6> > computeStrainRate(MultiTensorField3D<T,3>& velocity) 02799 { 02800 return computeStrainRate(velocity, velocity.getBoundingBox()); 02801 } 02802 02803 02804 /* *************** Str. rate, without boundary treatment, from Velocity field */ 02805 02806 template<typename T> 02807 void computeBulkStrainRate(MultiTensorField3D<T,3>& velocity, MultiTensorField3D<T,6>& S, Box3D domain) 02808 { 02809 applyProcessingFunctional ( 02810 new BoxBulkStrainRateFunctional3D<T,3>, domain, velocity, S ); 02811 } 02812 02813 template<typename T> 02814 std::auto_ptr<MultiTensorField3D<T,6> > computeBulkStrainRate(MultiTensorField3D<T,3>& velocity, Box3D domain) 02815 { 02816 std::auto_ptr<MultiTensorField3D<T,6> > S = 02817 generateMultiTensorField<T,6>(velocity, domain); 02818 computeBulkStrainRate(velocity, *S, domain); 02819 return S; 02820 } 02821 02822 template<typename T> 02823 std::auto_ptr<MultiTensorField3D<T,6> > computeBulkStrainRate(MultiTensorField3D<T,3>& velocity) 02824 { 02825 return computeBulkStrainRate(velocity, velocity.getBoundingBox()); 02826 } 02827 02828 /* *************** Q-criterion from vorticity and strain rate fields */ 02829 02830 template<typename T> 02831 void computeQcriterion(MultiTensorField3D<T,3>& vorticity, MultiTensorField3D<T,6>& S, MultiScalarField3D<T>& qCriterion, Box3D domain) 02832 { 02833 std::vector<MultiBlock3D* > fields; 02834 fields.push_back(&vorticity); 02835 fields.push_back(&S); 02836 fields.push_back(&qCriterion); 02837 02838 applyProcessingFunctional ( 02839 new BoxQcriterionFunctional3D<T>, domain, fields ); 02840 } 02841 02842 template<typename T> 02843 std::auto_ptr<MultiScalarField3D<T> > computeQcriterion(MultiTensorField3D<T,3>& vorticity, MultiTensorField3D<T,6>& S, Box3D domain) 02844 { 02845 std::auto_ptr<MultiScalarField3D<T> > qCriterion = generateMultiScalarField<T>(vorticity, domain); 02846 computeQcriterion(vorticity, S, *qCriterion, domain); 02847 return qCriterion; 02848 } 02849 02850 template<typename T> 02851 std::auto_ptr<MultiScalarField3D<T> > computeQcriterion(MultiTensorField3D<T,3>& vorticity, MultiTensorField3D<T,6>& S) 02852 { 02853 return computeQcriterion(vorticity, S, vorticity.getBoundingBox()); 02854 } 02855 02856 02857 /* *************** MultiTensorField - MultiTensorField operations *************** */ 02858 02859 template<typename T1, typename T2, int nDim> 02860 void copy(MultiTensorField3D<T1,nDim>& field, MultiTensorField3D<T2,nDim>& convertedField, Box3D domain) 02861 { 02862 applyProcessingFunctional ( 02863 new CopyConvertTensorFunctional3D<T1,T2,nDim>, domain, field, convertedField ); 02864 } 02865 02866 template<typename T1, typename T2, int nDim> 02867 std::auto_ptr<MultiTensorField3D<T2,nDim> > copyConvert(MultiTensorField3D<T1,nDim>& field, Box3D domain) 02868 { 02869 std::auto_ptr<MultiTensorField3D<T2,nDim> > convertedField = 02870 generateMultiTensorField<T2,nDim>(field, domain); 02871 plb::copy<T1,T2,nDim>(field, *convertedField, domain); 02872 return convertedField; 02873 } 02874 02875 template<typename T1, typename T2, int nDim> 02876 std::auto_ptr<MultiTensorField3D<T2,nDim> > copyConvert(MultiTensorField3D<T1,nDim>& field) 02877 { 02878 return copyConvert<T1,T2,nDim>(field, field.getBoundingBox()); 02879 } 02880 02881 template<typename T, int nDim> 02882 void add(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, MultiTensorField3D<T,nDim>& result, Box3D domain) 02883 { 02884 std::vector<MultiTensorField3D<T,nDim>* > fields; 02885 fields.push_back(&A); 02886 fields.push_back(&B); 02887 fields.push_back(&result); 02888 applyProcessingFunctional ( 02889 new Tensor_A_plus_B_functional3D<T,nDim>, domain, fields ); 02890 } 02891 02892 template<typename T, int nDim> 02893 std::auto_ptr<MultiTensorField3D<T,nDim> > add(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) 02894 { 02895 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02896 generateIntersectMultiTensorField<T,nDim>(A,B, domain); 02897 add(A, B, *result, domain); 02898 return result; 02899 } 02900 02901 template<typename T, int nDim> 02902 std::auto_ptr<MultiTensorField3D<T,nDim> > add(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) 02903 { 02904 return add(A, B, A.getBoundingBox()); 02905 } 02906 02907 02908 template<typename T, int nDim> 02909 void subtract(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, MultiTensorField3D<T,nDim>& result, Box3D domain) 02910 { 02911 std::vector<MultiTensorField3D<T,nDim>* > fields; 02912 fields.push_back(&A); 02913 fields.push_back(&B); 02914 fields.push_back(&result); 02915 applyProcessingFunctional ( 02916 new Tensor_A_minus_B_functional3D<T,nDim>, domain, fields ); 02917 } 02918 02919 template<typename T, int nDim> 02920 std::auto_ptr<MultiTensorField3D<T,nDim> > subtract(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) 02921 { 02922 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02923 generateIntersectMultiTensorField<T,nDim>(A,B, domain); 02924 subtract(A, B, *result, domain); 02925 return result; 02926 } 02927 02928 template<typename T, int nDim> 02929 std::auto_ptr<MultiTensorField3D<T,nDim> > subtract(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) 02930 { 02931 return subtract(A, B, A.getBoundingBox()); 02932 } 02933 02934 02935 template<typename T, int nDim> 02936 void multiply(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, MultiTensorField3D<T,nDim>& result, Box3D domain) 02937 { 02938 std::vector<MultiTensorField3D<T,nDim>* > fields; 02939 fields.push_back(&A); 02940 fields.push_back(&B); 02941 fields.push_back(&result); 02942 applyProcessingFunctional ( 02943 new Tensor_A_times_B_functional3D<T,nDim>, domain, fields ); 02944 } 02945 02946 template<typename T, int nDim> 02947 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) 02948 { 02949 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02950 generateIntersectMultiTensorField<T,nDim>(A,B, domain); 02951 multiply(A, B, *result, domain); 02952 return result; 02953 } 02954 02955 template<typename T, int nDim> 02956 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) 02957 { 02958 return multiply(A, B, A.getBoundingBox()); 02959 } 02960 02961 template<typename T, int nDim> 02962 void multiply(MultiTensorField3D<T,nDim>& field, T scalar, MultiTensorField3D<T,nDim>& result, Box3D domain) 02963 { 02964 applyProcessingFunctional ( 02965 new Tensor_A_times_alpha_functional3D<T,nDim>(scalar), domain, field, result ); 02966 } 02967 02968 template<typename T, int nDim> 02969 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(MultiTensorField3D<T,nDim>& field, T scalar, Box3D domain) 02970 { 02971 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02972 generateMultiTensorField<T,nDim>(field, domain); 02973 multiply(field, scalar, *result, domain); 02974 return result; 02975 } 02976 02977 template<typename T, int nDim> 02978 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(MultiTensorField3D<T,nDim>& field, T scalar) 02979 { 02980 return multiply(field, scalar, field.getBoundingBox()); 02981 } 02982 02983 02984 template<typename T, int nDim> 02985 void multiply(T scalar, MultiTensorField3D<T,nDim>& field, MultiTensorField3D<T,nDim>& result, Box3D domain) 02986 { 02987 applyProcessingFunctional ( 02988 new Tensor_A_times_alpha_functional3D<T,nDim>(scalar), domain, field, result ); 02989 } 02990 02991 template<typename T, int nDim> 02992 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(T scalar, MultiTensorField3D<T,nDim>& field, Box3D domain) 02993 { 02994 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 02995 generateMultiTensorField<T,nDim>(field, domain); 02996 multiply(scalar, field, *result, domain); 02997 return result; 02998 } 02999 03000 template<typename T, int nDim> 03001 std::auto_ptr<MultiTensorField3D<T,nDim> > multiply(T scalar, MultiTensorField3D<T,nDim>& field) 03002 { 03003 return multiply(scalar, field, field.getBoundingBox()); 03004 } 03005 03006 03007 template<typename T, int nDim> 03008 void divide(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, MultiTensorField3D<T,nDim>& result, Box3D domain) 03009 { 03010 std::vector<MultiTensorField3D<T,nDim>* > fields; 03011 fields.push_back(&A); 03012 fields.push_back(&B); 03013 fields.push_back(&result); 03014 applyProcessingFunctional ( 03015 new Tensor_A_dividedBy_B_functional3D<T,nDim>, domain, fields ); 03016 } 03017 03018 template<typename T, int nDim> 03019 std::auto_ptr<MultiTensorField3D<T,nDim> > divide(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) 03020 { 03021 std::auto_ptr<MultiTensorField3D<T,nDim> > result = 03022 generateIntersectMultiTensorField<T,nDim>(A,B, domain); 03023 divide(A, B, *result, domain); 03024 return result; 03025 } 03026 03027 template<typename T, int nDim> 03028 std::auto_ptr<MultiTensorField3D<T,nDim> > divide(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) 03029 { 03030 return divide(A, B, A.getBoundingBox()); 03031 } 03032 03033 03034 /* *************** TensorField - TensorField inplace operations *************** */ 03035 03036 template<typename T, int nDim> 03037 void addInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) { 03038 applyProcessingFunctional ( 03039 new Tensor_A_plus_B_inplace_functional3D<T,nDim>, domain, A, B ); 03040 } 03041 03042 template<typename T, int nDim> 03043 void addInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) { 03044 addInPlace(A, B, A.getBoundingBox()); 03045 } 03046 03047 03048 template<typename T, int nDim> 03049 void subtractInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) { 03050 applyProcessingFunctional ( 03051 new Tensor_A_minus_B_inplace_functional3D<T,nDim>, domain, A, B ); 03052 } 03053 03054 template<typename T, int nDim> 03055 void subtractInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) { 03056 subtractInPlace(A, B, A.getBoundingBox()); 03057 } 03058 03059 03060 template<typename T, int nDim> 03061 void multiplyInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) { 03062 applyProcessingFunctional ( 03063 new Tensor_A_times_B_inplace_functional3D<T,nDim>, domain, A, B ); 03064 } 03065 03066 template<typename T, int nDim> 03067 void multiplyInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) { 03068 multiplyInPlace(A,B, A.getBoundingBox()); 03069 } 03070 03071 03072 template<typename T, int nDim> 03073 void multiplyInPlace(MultiTensorField3D<T,nDim>& A, T alpha, Box3D domain) { 03074 applyProcessingFunctional ( 03075 new Tensor_A_times_alpha_inplace_functional3D<T,nDim>(alpha), domain, A); 03076 } 03077 03078 template<typename T, int nDim> 03079 void multiplyInPlace(MultiTensorField3D<T,nDim>& A, T alpha) 03080 { 03081 multiplyInPlace(A,alpha, A.getBoundingBox()); 03082 } 03083 03084 03085 template<typename T, int nDim> 03086 void divideInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B, Box3D domain) { 03087 applyProcessingFunctional ( 03088 new Tensor_A_dividedBy_B_inplace_functional3D<T,nDim>, domain, A, B ); 03089 } 03090 03091 template<typename T, int nDim> 03092 void divideInPlace(MultiTensorField3D<T,nDim>& A, MultiTensorField3D<T,nDim>& B) { 03093 divideInPlace(A, B, A.getBoundingBox()); 03094 } 03095 03096 /* *************** LBMsmoothen3D ******************************************* */ 03097 03098 template<typename T, template<typename U> class Descriptor> 03099 void lbmSmoothen(MultiScalarField3D<T>& data, MultiScalarField3D<T>& result, Box3D domain) 03100 { 03101 applyProcessingFunctional ( 03102 new LBMsmoothen3D<T,Descriptor>, domain, data, result ); 03103 } 03104 03105 template<typename T, template<typename U> class Descriptor> 03106 std::auto_ptr<MultiScalarField3D<T> > lbmSmoothen(MultiScalarField3D<T>& data, Box3D domain) 03107 { 03108 std::auto_ptr<MultiScalarField3D<T> > result = 03109 generateMultiScalarField<T>(data, domain); 03110 lbmSmoothen<T,Descriptor>(data, *result, domain); 03111 return result; 03112 } 03113 03114 template<typename T, template<typename U> class Descriptor> 03115 std::auto_ptr<MultiScalarField3D<T> > lbmSmoothen(MultiScalarField3D<T>& data) { 03116 return lbmSmoothen<T,Descriptor>(data, data.getBoundingBox()); 03117 } 03118 03119 03120 } // namespace plb 03121 03122 #endif // DATA_ANALYSIS_WRAPPER_3D_HH 03123
1.6.3
1.6.3