$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

dataAnalysisWrapper2D.hh

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00028 #ifndef DATA_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