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