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