$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 FINITE_DIFFERENCE_FUNCTIONAL_3D_HH 00029 #define FINITE_DIFFERENCE_FUNCTIONAL_3D_HH 00030 00031 #include "finiteDifference/fdFunctional3D.h" 00032 #include "core/blockStatistics.h" 00033 #include "core/plbDebug.h" 00034 #include "finiteDifference/fdStencils1D.h" 00035 #include "atomicBlock/atomicBlock3D.h" 00036 #include "atomicBlock/blockLattice3D.h" 00037 #include "atomicBlock/dataField3D.h" 00038 #include "dataProcessors/dataAnalysisFunctional3D.hh" 00039 #include <cmath> 00040 00041 namespace plb { 00042 00043 /* ******** BoxXderivativeFunctional3D *********************************** */ 00044 00045 template<typename T> 00046 void BoxXderivativeFunctional3D<T>::processBulk ( 00047 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00048 { 00049 Dot3D offset = computeRelativeDisplacement(value, derivative); 00050 00051 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00052 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00053 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00054 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = fdDataField::bulkXderiv(value, iX, iY, iZ ); 00055 } 00056 } 00057 } 00058 } 00059 00060 template<typename T> 00061 void BoxXderivativeFunctional3D<T>::processPlane ( 00062 int direction, int orientation, Box3D domain, 00063 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00064 { 00065 Dot3D offset = computeRelativeDisplacement(value, derivative); 00066 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00067 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00068 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00069 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00070 fdDataField::planeXderiv(value, direction, orientation, iX, iY, iZ ); 00071 } 00072 } 00073 } 00074 } 00075 00076 template<typename T> 00077 void BoxXderivativeFunctional3D<T>::processEdge( int plane, int normal1, int normal2, Box3D domain, 00078 ScalarField3D<T>& value, ScalarField3D<T>& derivative) 00079 { 00080 Dot3D offset = computeRelativeDisplacement(value, derivative); 00081 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00082 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00083 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00084 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00085 fdDataField::edgeXderiv (value,plane, normal1, normal2, iX, iY, iZ ); 00086 } 00087 } 00088 } 00089 } 00090 00091 template<typename T> 00092 void BoxXderivativeFunctional3D<T>::processCorner ( 00093 int normalX, int normalY, int normalZ, Box3D domain, 00094 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00095 { 00096 Dot3D offset = computeRelativeDisplacement(value, derivative); 00097 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00098 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00099 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00100 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00101 fdDataField::cornerXderiv (value,normalX, normalY, normalZ, iX, iY, iZ ); 00102 } 00103 } 00104 } 00105 } 00106 00107 template<typename T> 00108 BoxXderivativeFunctional3D<T>* BoxXderivativeFunctional3D<T>::clone() const 00109 { 00110 return new BoxXderivativeFunctional3D<T>(*this); 00111 } 00112 00113 template<typename T> 00114 void BoxXderivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00115 modified[0] = modif::nothing; 00116 modified[1] = modif::staticVariables; 00117 } 00118 00119 template<typename T> 00120 BlockDomain::DomainT BoxXderivativeFunctional3D<T>::appliesTo() const { 00121 // Don't apply to envelope, because nearest neighbors need to be accessed. 00122 return BlockDomain::bulk; 00123 } 00124 00125 00126 /* ******** BoxYderivativeFunctional3D *********************************** */ 00127 00128 template<typename T> 00129 void BoxYderivativeFunctional3D<T>::processBulk ( 00130 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00131 { 00132 Dot3D offset = computeRelativeDisplacement(value, derivative); 00133 00134 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00135 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00136 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00137 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = fdDataField::bulkYderiv(value, iX, iY, iZ ); 00138 } 00139 } 00140 } 00141 } 00142 00143 template<typename T> 00144 void BoxYderivativeFunctional3D<T>::processPlane ( 00145 int direction, int orientation, Box3D domain, 00146 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00147 { 00148 Dot3D offset = computeRelativeDisplacement(value, derivative); 00149 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00150 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00151 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00152 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00153 fdDataField::planeYderiv(value, direction, orientation, iX, iY, iZ ); 00154 } 00155 } 00156 } 00157 } 00158 00159 template<typename T> 00160 void BoxYderivativeFunctional3D<T>::processEdge( 00161 int plane, int normal1, int normal2, Box3D domain, 00162 ScalarField3D<T>& value, ScalarField3D<T>& derivative) 00163 { 00164 Dot3D offset = computeRelativeDisplacement(value, derivative); 00165 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00166 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00167 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00168 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00169 fdDataField::edgeYderiv (value,plane, normal1, normal2, iX, iY, iZ ); 00170 } 00171 } 00172 } 00173 } 00174 00175 template<typename T> 00176 void BoxYderivativeFunctional3D<T>::processCorner ( 00177 int normalX, int normalY, int normalZ, Box3D domain, 00178 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00179 { 00180 Dot3D offset = computeRelativeDisplacement(value, derivative); 00181 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00182 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00183 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00184 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00185 fdDataField::cornerYderiv (value,normalX, normalY, normalZ, iX, iY, iZ ); 00186 } 00187 } 00188 } 00189 } 00190 00191 template<typename T> 00192 BoxYderivativeFunctional3D<T>* BoxYderivativeFunctional3D<T>::clone() const 00193 { 00194 return new BoxYderivativeFunctional3D<T>(*this); 00195 } 00196 00197 template<typename T> 00198 void BoxYderivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00199 modified[0] = modif::nothing; 00200 modified[1] = modif::staticVariables; 00201 } 00202 00203 template<typename T> 00204 BlockDomain::DomainT BoxYderivativeFunctional3D<T>::appliesTo() const { 00205 // Don't apply to envelope, because nearest neighbors need to be accessed. 00206 return BlockDomain::bulk; 00207 } 00208 00209 /* ******** BoxZderivativeFunctional3D *********************************** */ 00210 00211 template<typename T> 00212 void BoxZderivativeFunctional3D<T>::processBulk ( 00213 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00214 { 00215 Dot3D offset = computeRelativeDisplacement(value, derivative); 00216 00217 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00218 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00219 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00220 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00221 fdDataField::bulkZderiv (value,iX, iY, iZ ); 00222 } 00223 } 00224 } 00225 } 00226 00227 template<typename T> 00228 void BoxZderivativeFunctional3D<T>::processPlane ( 00229 int direction, int orientation, Box3D domain, 00230 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00231 { 00232 Dot3D offset = computeRelativeDisplacement(value, derivative); 00233 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00234 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00235 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00236 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00237 fdDataField::planeZderiv(value, direction, orientation, iX, iY, iZ ); 00238 } 00239 } 00240 } 00241 } 00242 00243 template<typename T> 00244 void BoxZderivativeFunctional3D<T>::processEdge( 00245 int plane, int normal1, int normal2, Box3D domain, 00246 ScalarField3D<T>& value, ScalarField3D<T>& derivative) 00247 { 00248 Dot3D offset = computeRelativeDisplacement(value, derivative); 00249 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00250 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00251 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00252 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00253 fdDataField::edgeZderiv(value, plane, normal1, normal2, iX, iY, iZ ); 00254 } 00255 } 00256 } 00257 } 00258 00259 template<typename T> 00260 void BoxZderivativeFunctional3D<T>::processCorner ( 00261 int normalX, int normalY, int normalZ, Box3D domain, 00262 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00263 { 00264 Dot3D offset = computeRelativeDisplacement(value, derivative); 00265 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00266 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00267 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00268 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00269 fdDataField::cornerZderiv(value, normalX, normalY, normalZ, iX, iY, iZ ); 00270 } 00271 } 00272 } 00273 } 00274 00275 template<typename T> 00276 BoxZderivativeFunctional3D<T>* BoxZderivativeFunctional3D<T>::clone() const 00277 { 00278 return new BoxZderivativeFunctional3D<T>(*this); 00279 } 00280 00281 template<typename T> 00282 void BoxZderivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00283 modified[0] = modif::nothing; 00284 modified[1] = modif::staticVariables; 00285 } 00286 00287 template<typename T> 00288 BlockDomain::DomainT BoxZderivativeFunctional3D<T>::appliesTo() const { 00289 // Don't apply to envelope, because nearest neighbors need to be accessed. 00290 return BlockDomain::bulk; 00291 } 00292 00293 00294 /* ******** BoxGradientNormFunctional3D *********************************** */ 00295 00296 template<typename T> 00297 void BoxGradientNormFunctional3D<T>::processBulk ( 00298 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00299 { 00300 Dot3D offset = computeRelativeDisplacement(value, derivative); 00301 00302 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00303 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00304 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00305 T xDeriv = fdDataField::bulkXderiv (value,iX, iY, iZ ); 00306 T yDeriv = fdDataField::bulkYderiv (value,iX, iY, iZ ); 00307 T zDeriv = fdDataField::bulkZderiv (value,iX, iY, iZ ); 00308 T gradientNorm = sqrt(util::sqr(xDeriv)+util::sqr(yDeriv)+util::sqr(zDeriv)); 00309 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = gradientNorm; 00310 } 00311 } 00312 } 00313 } 00314 00315 template<typename T> 00316 void BoxGradientNormFunctional3D<T>::processPlane ( 00317 int direction, int orientation, Box3D domain, 00318 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00319 { 00320 Dot3D offset = computeRelativeDisplacement(value, derivative); 00321 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00322 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00323 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00324 T xDeriv = fdDataField::planeXderiv (value, direction, orientation, iX, iY, iZ ); 00325 T yDeriv = fdDataField::planeYderiv (value, direction, orientation, iX, iY, iZ ); 00326 T zDeriv = fdDataField::planeZderiv (value, direction, orientation, iX, iY, iZ ); 00327 T gradientNorm = sqrt(util::sqr(xDeriv)+util::sqr(yDeriv)+util::sqr(zDeriv)); 00328 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = gradientNorm; 00329 } 00330 } 00331 } 00332 } 00333 00334 template<typename T> 00335 void BoxGradientNormFunctional3D<T>::processEdge( 00336 int plane, int normal1, int normal2, Box3D domain, 00337 ScalarField3D<T>& value, ScalarField3D<T>& derivative) 00338 { 00339 Dot3D offset = computeRelativeDisplacement(value, derivative); 00340 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00341 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00342 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00343 T xDeriv = fdDataField::edgeXderiv (value,plane, normal1, normal2, iX, iY, iZ ); 00344 T yDeriv = fdDataField::edgeYderiv (value,plane, normal1, normal2, iX, iY, iZ ); 00345 T zDeriv = fdDataField::edgeZderiv (value,plane, normal1, normal2, iX, iY, iZ ); 00346 T gradientNorm = sqrt(util::sqr(xDeriv)+util::sqr(yDeriv)+util::sqr(zDeriv)); 00347 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = gradientNorm; 00348 } 00349 } 00350 } 00351 } 00352 00353 template<typename T> 00354 void BoxGradientNormFunctional3D<T>::processCorner ( 00355 int normalX, int normalY, int normalZ, Box3D domain, 00356 ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00357 { 00358 Dot3D offset = computeRelativeDisplacement(value, derivative); 00359 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00360 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00361 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00362 T xDeriv = fdDataField::cornerXderiv (value, normalX, normalY, normalZ, iX, iY, iZ ); 00363 T yDeriv = fdDataField::cornerYderiv (value, normalX, normalY, normalZ, iX, iY, iZ ); 00364 T zDeriv = fdDataField::cornerZderiv (value, normalX, normalY, normalZ, iX, iY, iZ ); 00365 T gradientNorm = sqrt(util::sqr(xDeriv)+util::sqr(yDeriv)+util::sqr(zDeriv)); 00366 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = gradientNorm; 00367 } 00368 } 00369 } 00370 } 00371 00372 template<typename T> 00373 BoxGradientNormFunctional3D<T>* BoxGradientNormFunctional3D<T>::clone() const 00374 { 00375 return new BoxGradientNormFunctional3D<T>(*this); 00376 } 00377 00378 template<typename T> 00379 void BoxGradientNormFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00380 modified[0] = modif::nothing; 00381 modified[1] = modif::staticVariables; 00382 } 00383 00384 template<typename T> 00385 BlockDomain::DomainT BoxGradientNormFunctional3D<T>::appliesTo() const { 00386 // Don't apply to envelope, because nearest neighbors need to be accessed. 00387 return BlockDomain::bulk; 00388 } 00389 00390 /* *************** BoxPoissonResidueFunctional3D ********************* */ 00391 00392 template<typename T> 00393 BoxPoissonResidueFunctional3D<T>::BoxPoissonResidueFunctional3D() 00394 : maxResidueId(this->getStatistics().subscribeMax()) 00395 { } 00396 00397 template<typename T> 00398 void BoxPoissonResidueFunctional3D<T>::process ( 00399 Box3D domain, ScalarField3D<T>& pressure, ScalarField3D<T>& rhs ) 00400 { 00401 Dot3D offset = computeRelativeDisplacement(pressure, rhs); 00402 BlockStatistics& statistics = this->getStatistics(); 00403 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00404 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00405 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00406 T sumPressure = 00407 pressure.get(iX+1,iY,iZ) + 00408 pressure.get(iX,iY+1,iZ) + 00409 pressure.get(iX,iY,iZ+1) + 00410 pressure.get(iX-1,iY,iZ) + 00411 pressure.get(iX,iY-1,iZ) + 00412 pressure.get(iX,iY,iZ-1); 00413 T residue = fabs( sumPressure -(T)6*pressure.get(iX,iY,iZ) 00414 + rhs.get(iX+offset.x,iY+offset.y,iZ+offset.z) ); 00415 statistics.gatherMax(maxResidueId, residue); 00416 } 00417 } 00418 } 00419 } 00420 00421 template<typename T> 00422 BoxPoissonResidueFunctional3D<T>* BoxPoissonResidueFunctional3D<T>::clone() const 00423 { 00424 return new BoxPoissonResidueFunctional3D<T>(*this); 00425 } 00426 00427 template<typename T> 00428 T BoxPoissonResidueFunctional3D<T>::getMaxResidue() const { 00429 return this->getStatistics().getMax(maxResidueId); 00430 } 00431 00432 00433 /* ******** BoxPoissonIteration3D ************************************* */ 00434 00435 template<typename T> 00436 BoxPoissonIteration3D<T>::BoxPoissonIteration3D(T beta_) 00437 : beta(beta_) 00438 { } 00439 00440 template<typename T> 00441 void BoxPoissonIteration3D<T>::processBulk ( 00442 Box3D domain, std::vector<ScalarField3D<T>*> scalarFields ) 00443 { 00444 ScalarField3D<T> const& u_h = *scalarFields[0]; 00445 ScalarField3D<T>& new_u_h = *scalarFields[1]; 00446 ScalarField3D<T> const& rhs = *scalarFields[2]; 00447 Dot3D offset1 = computeRelativeDisplacement(u_h, new_u_h); 00448 Dot3D offset2 = computeRelativeDisplacement(u_h, rhs); 00449 00450 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00451 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00452 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00453 T sumPressure = 00454 u_h.get(iX+1,iY,iZ) + 00455 u_h.get(iX,iY+1,iZ) + 00456 u_h.get(iX,iY,iZ+1) + 00457 u_h.get(iX-1,iY,iZ) + 00458 u_h.get(iX,iY-1,iZ) + 00459 u_h.get(iX,iY,iZ-1); 00460 00461 new_u_h.get(iX+offset1.x,iY+offset1.y,iZ+offset1.z) = 00462 ((T)1-beta) * u_h.get(iX,iY,iZ) + 00463 (beta/(T)6) * (sumPressure + rhs.get(iX+offset2.x,iY+offset2.y,iZ+offset2.z) ); 00464 } 00465 } 00466 } 00467 } 00468 00469 template<typename T> 00470 void BoxPoissonIteration3D<T>::processPlane ( 00471 int direction, int orientation, Box3D domain, 00472 std::vector<ScalarField3D<T>*> scalarFields ) 00473 { 00474 ScalarField3D<T> const& u_h = *scalarFields[0]; 00475 ScalarField3D<T>& new_u_h = *scalarFields[1]; 00476 ScalarField3D<T> const& rhs = *scalarFields[2]; 00477 Dot3D offset1 = computeRelativeDisplacement(u_h, new_u_h); 00478 Dot3D offset2 = computeRelativeDisplacement(u_h, rhs); 00479 00480 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00481 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00482 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00483 T sumPressure = T(); 00484 if (direction==0 && orientation==1) 00485 sumPressure += u_h.get(iX,iY,iZ); 00486 else 00487 sumPressure += u_h.get(iX+1,iY,iZ); 00488 00489 if (direction==1 && orientation==1) 00490 sumPressure += u_h.get(iX,iY,iZ); 00491 else 00492 sumPressure += u_h.get(iX,iY+1,iZ); 00493 00494 if (direction==2 && orientation==1) 00495 sumPressure += u_h.get(iX,iY,iZ); 00496 else 00497 sumPressure += u_h.get(iX,iY,iZ+1); 00498 00499 if (direction==0 && orientation==-1) 00500 sumPressure += u_h.get(iX,iY,iZ); 00501 else 00502 sumPressure += u_h.get(iX-1,iY,iZ); 00503 00504 if (direction==1 && orientation==-1) 00505 sumPressure += u_h.get(iX,iY,iZ); 00506 else 00507 sumPressure += u_h.get(iX,iY-1,iZ); 00508 00509 if (direction==2 && orientation==-1) 00510 sumPressure += u_h.get(iX,iY,iZ); 00511 else 00512 sumPressure += u_h.get(iX,iY,iZ-1); 00513 00514 new_u_h.get(iX+offset1.x,iY+offset1.y,iZ+offset1.z) = 00515 ((T)1-beta) * u_h.get(iX,iY,iZ) + 00516 (beta/(T)6) * (sumPressure + rhs.get(iX+offset2.x,iY+offset2.y,iZ+offset2.z) ); 00517 } 00518 } 00519 } 00520 } 00521 00522 template<typename T> 00523 void BoxPoissonIteration3D<T>::processEdge ( 00524 int plane, int normal1, int normal2, Box3D domain, 00525 std::vector<ScalarField3D<T>*> scalarFields ) 00526 { 00527 ScalarField3D<T> const& u_h = *scalarFields[0]; 00528 ScalarField3D<T>& new_u_h = *scalarFields[1]; 00529 ScalarField3D<T> const& rhs = *scalarFields[2]; 00530 Dot3D offset1 = computeRelativeDisplacement(u_h, new_u_h); 00531 Dot3D offset2 = computeRelativeDisplacement(u_h, rhs); 00532 00533 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00534 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00535 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00536 T sumPressure = T(); 00537 if (plane == 0) { 00538 sumPressure += u_h.get(iX+1,iY,iZ); 00539 sumPressure += u_h.get(iX-1,iY,iZ); 00540 if (normal1 == 1) { 00541 sumPressure += u_h.get(iX,iY-1, iZ); 00542 } 00543 else { 00544 sumPressure += u_h.get(iX,iY, iZ); 00545 } 00546 00547 if (normal1 == -1) { 00548 sumPressure += u_h.get(iX,iY+1, iZ); 00549 } 00550 else { 00551 sumPressure += u_h.get(iX,iY, iZ); 00552 } 00553 00554 if (normal2 == 1) { 00555 sumPressure += u_h.get(iX,iY, iZ-1); 00556 } 00557 else { 00558 sumPressure += u_h.get(iX,iY, iZ); 00559 } 00560 00561 if (normal2 == -1) { 00562 sumPressure += u_h.get(iX,iY, iZ+1); 00563 } 00564 else { 00565 sumPressure += u_h.get(iX,iY, iZ); 00566 } 00567 } 00568 else if (plane == 1) { 00569 sumPressure += u_h.get(iX,iY+1,iZ); 00570 sumPressure += u_h.get(iX,iY-1,iZ); 00571 if (normal1 == 1) { 00572 sumPressure += u_h.get(iX,iY, iZ-1); 00573 } 00574 else { 00575 sumPressure += u_h.get(iX,iY, iZ); 00576 } 00577 00578 if (normal1 == -1) { 00579 sumPressure += u_h.get(iX,iY, iZ+1); 00580 } 00581 else { 00582 sumPressure += u_h.get(iX,iY, iZ); 00583 } 00584 00585 if (normal2 == 1) { 00586 sumPressure += u_h.get(iX-1,iY, iZ); 00587 } 00588 else { 00589 sumPressure += u_h.get(iX,iY, iZ); 00590 } 00591 00592 if (normal2 == -1) { 00593 sumPressure += u_h.get(iX+1,iY, iZ); 00594 } 00595 else { 00596 sumPressure += u_h.get(iX,iY, iZ); 00597 } 00598 } 00599 else if (plane == 2) { 00600 sumPressure += u_h.get(iX,iY,iZ+1); 00601 sumPressure += u_h.get(iX,iY,iZ-1); 00602 if (normal1 == 1) { 00603 sumPressure += u_h.get(iX-1,iY, iZ); 00604 } 00605 else { 00606 sumPressure += u_h.get(iX,iY, iZ); 00607 } 00608 00609 if (normal1 == -1) { 00610 sumPressure += u_h.get(iX+1,iY, iZ); 00611 } 00612 else { 00613 sumPressure += u_h.get(iX,iY, iZ); 00614 } 00615 00616 if (normal2 == 1) { 00617 sumPressure += u_h.get(iX,iY, iZ-1); 00618 } 00619 else { 00620 sumPressure += u_h.get(iX,iY, iZ); 00621 } 00622 00623 if (normal2 == -1) { 00624 sumPressure += u_h.get(iX,iY, iZ+1); 00625 } 00626 else { 00627 sumPressure += u_h.get(iX,iY, iZ); 00628 } 00629 } 00630 00631 new_u_h.get(iX+offset1.x,iY+offset1.y,iZ+offset1.z) = 00632 ((T)1-beta) * u_h.get(iX,iY,iZ) + 00633 (beta/(T)6) * (sumPressure + rhs.get(iX+offset2.x,iY+offset2.y,iZ+offset2.z) ); 00634 } 00635 } 00636 } 00637 } 00638 00639 template<typename T> 00640 void BoxPoissonIteration3D<T>::processCorner ( 00641 int normalX, int normalY, int normalZ, Box3D domain, 00642 std::vector<ScalarField3D<T>*> scalarFields ) 00643 { 00644 ScalarField3D<T> const& u_h = *scalarFields[0]; 00645 ScalarField3D<T>& new_u_h = *scalarFields[1]; 00646 ScalarField3D<T> const& rhs = *scalarFields[2]; 00647 Dot3D offset1 = computeRelativeDisplacement(u_h, new_u_h); 00648 Dot3D offset2 = computeRelativeDisplacement(u_h, rhs); 00649 00650 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00651 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00652 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00653 T sumPressure = T(); 00654 if (normalX==1) 00655 sumPressure += u_h.get(iX,iY,iZ); 00656 else 00657 sumPressure += u_h.get(iX+1,iY,iZ); 00658 00659 if (normalY==1) 00660 sumPressure += u_h.get(iX,iY,iZ); 00661 else 00662 sumPressure += u_h.get(iX,iY+1,iZ); 00663 00664 if (normalZ==1) 00665 sumPressure += u_h.get(iX,iY,iZ); 00666 else 00667 sumPressure += u_h.get(iX,iY,iZ+1); 00668 00669 if (normalX==-1) 00670 sumPressure += u_h.get(iX,iY,iZ); 00671 else 00672 sumPressure += u_h.get(iX-1,iY,iZ); 00673 00674 if (normalY==-1) 00675 sumPressure += u_h.get(iX,iY,iZ); 00676 else 00677 sumPressure += u_h.get(iX,iY-1,iZ); 00678 00679 if (normalZ==-1) 00680 sumPressure += u_h.get(iX,iY,iZ); 00681 else 00682 sumPressure += u_h.get(iX,iY,iZ-1); 00683 00684 new_u_h.get(iX+offset1.x,iY+offset1.y,iZ+offset1.z) = 00685 ((T)1-beta) * u_h.get(iX,iY,iZ) + 00686 (beta/(T)6) * (sumPressure + rhs.get(iX+offset2.x,iY+offset2.y,iZ+offset2.z) ); 00687 } 00688 } 00689 } 00690 } 00691 00692 template<typename T> 00693 BoxPoissonIteration3D<T>* BoxPoissonIteration3D<T>::clone() const 00694 { 00695 return new BoxPoissonIteration3D<T>(*this); 00696 } 00697 00698 template<typename T> 00699 void BoxPoissonIteration3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00700 modified[0] = modif::nothing; 00701 modified[1] = modif::staticVariables; 00702 modified[2] = modif::nothing; 00703 } 00704 00705 template<typename T> 00706 BlockDomain::DomainT BoxPoissonIteration3D<T>::appliesTo() const { 00707 // Don't apply to envelope, because nearest neighbors need to be accessed. 00708 return BlockDomain::bulk; 00709 } 00710 00711 00712 // ========================================================================= // 00713 // PERIODIC VERSIONS OF THE DERIVATIVES AND POISSON SCHEMES // 00714 // ========================================================================= // 00715 00716 00717 /* ******** BoxXperiodicDerivativeFunctional3D *********************************** */ 00718 00719 template<typename T> 00720 void BoxXperiodicDerivativeFunctional3D<T>::process( 00721 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00722 { 00723 Dot3D offset = computeRelativeDisplacement(value, derivative); 00724 00725 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00726 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00727 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00728 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = fdDataField::bulkXderiv(value, iX, iY, iZ ); 00729 } 00730 } 00731 } 00732 } 00733 00734 template<typename T> 00735 BoxXperiodicDerivativeFunctional3D<T>* BoxXperiodicDerivativeFunctional3D<T>::clone() const 00736 { 00737 return new BoxXperiodicDerivativeFunctional3D<T>(*this); 00738 } 00739 00740 template<typename T> 00741 void BoxXperiodicDerivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00742 modified[0] = modif::nothing; 00743 modified[1] = modif::staticVariables; 00744 } 00745 00746 template<typename T> 00747 BlockDomain::DomainT BoxXperiodicDerivativeFunctional3D<T>::appliesTo() const { 00748 // Don't apply to envelope, because nearest neighbors need to be accessed. 00749 return BlockDomain::bulk; 00750 } 00751 00752 00753 /* ******** BoxYperiodicDerivativeFunctional3D *********************************** */ 00754 00755 template<typename T> 00756 void BoxYperiodicDerivativeFunctional3D<T>::process( 00757 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00758 { 00759 Dot3D offset = computeRelativeDisplacement(value, derivative); 00760 00761 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00762 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00763 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00764 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = fdDataField::bulkYderiv(value, iX, iY, iZ ); 00765 } 00766 } 00767 } 00768 } 00769 00770 template<typename T> 00771 BoxYperiodicDerivativeFunctional3D<T>* BoxYperiodicDerivativeFunctional3D<T>::clone() const 00772 { 00773 return new BoxYperiodicDerivativeFunctional3D<T>(*this); 00774 } 00775 00776 template<typename T> 00777 void BoxYperiodicDerivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00778 modified[0] = modif::nothing; 00779 modified[1] = modif::staticVariables; 00780 } 00781 00782 template<typename T> 00783 BlockDomain::DomainT BoxYperiodicDerivativeFunctional3D<T>::appliesTo() const { 00784 // Don't apply to envelope, because nearest neighbors need to be accessed. 00785 return BlockDomain::bulk; 00786 } 00787 00788 /* ******** BoxZperiodicDerivativeFunctional3D *********************************** */ 00789 00790 template<typename T> 00791 void BoxZperiodicDerivativeFunctional3D<T>::process( 00792 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00793 { 00794 Dot3D offset = computeRelativeDisplacement(value, derivative); 00795 00796 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00797 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00798 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00799 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = 00800 fdDataField::bulkZderiv (value,iX, iY, iZ ); 00801 } 00802 } 00803 } 00804 } 00805 00806 template<typename T> 00807 BoxZperiodicDerivativeFunctional3D<T>* BoxZperiodicDerivativeFunctional3D<T>::clone() const 00808 { 00809 return new BoxZperiodicDerivativeFunctional3D<T>(*this); 00810 } 00811 00812 template<typename T> 00813 void BoxZperiodicDerivativeFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00814 modified[0] = modif::nothing; 00815 modified[1] = modif::staticVariables; 00816 } 00817 00818 template<typename T> 00819 BlockDomain::DomainT BoxZperiodicDerivativeFunctional3D<T>::appliesTo() const { 00820 // Don't apply to envelope, because nearest neighbors need to be accessed. 00821 return BlockDomain::bulk; 00822 } 00823 00824 00825 /* ******** BoxGradientNormFunctional3D *********************************** */ 00826 00827 template<typename T> 00828 void BoxPeriodicGradientNormFunctional3D<T>::process( 00829 Box3D domain, ScalarField3D<T>& value, ScalarField3D<T>& derivative ) 00830 { 00831 Dot3D offset = computeRelativeDisplacement(value, derivative); 00832 00833 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00834 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00835 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00836 T xDeriv = fdDataField::bulkXderiv (value,iX, iY, iZ ); 00837 T yDeriv = fdDataField::bulkYderiv (value,iX, iY, iZ ); 00838 T zDeriv = fdDataField::bulkZderiv (value,iX, iY, iZ ); 00839 T gradientNorm = sqrt(util::sqr(xDeriv)+util::sqr(yDeriv)+util::sqr(zDeriv)); 00840 derivative.get(iX+offset.x, iY+offset.y, iZ+offset.z) = gradientNorm; 00841 } 00842 } 00843 } 00844 } 00845 00846 template<typename T> 00847 BoxPeriodicGradientNormFunctional3D<T>* BoxPeriodicGradientNormFunctional3D<T>::clone() const 00848 { 00849 return new BoxPeriodicGradientNormFunctional3D<T>(*this); 00850 } 00851 00852 template<typename T> 00853 void BoxPeriodicGradientNormFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00854 modified[0] = modif::nothing; 00855 modified[1] = modif::staticVariables; 00856 } 00857 00858 template<typename T> 00859 BlockDomain::DomainT BoxPeriodicGradientNormFunctional3D<T>::appliesTo() const { 00860 // Don't apply to envelope, because nearest neighbors need to be accessed. 00861 return BlockDomain::bulk; 00862 } 00863 00864 /* ******** BoxPeriodicPoissonIteration3D ************************************* */ 00865 00866 template<typename T> 00867 BoxPeriodicPoissonIteration3D<T>::BoxPeriodicPoissonIteration3D(T beta_) 00868 : beta(beta_) 00869 { } 00870 00871 template<typename T> 00872 void BoxPeriodicPoissonIteration3D<T>::process ( 00873 Box3D domain, std::vector<ScalarField3D<T>*> scalarFields ) 00874 { 00875 ScalarField3D<T> const& u_h = *scalarFields[0]; 00876 ScalarField3D<T>& new_u_h = *scalarFields[1]; 00877 ScalarField3D<T> const& rhs = *scalarFields[2]; 00878 Dot3D offset1 = computeRelativeDisplacement(u_h, new_u_h); 00879 Dot3D offset2 = computeRelativeDisplacement(u_h, rhs); 00880 00881 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00882 plint oX1 = iX + offset1.x; 00883 plint oX2 = iX + offset2.x; 00884 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00885 plint oY1 = iY + offset1.y; 00886 plint oY2 = iY + offset2.y; 00887 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00888 T sumPressure = 00889 u_h.get(iX+1,iY,iZ) + 00890 u_h.get(iX,iY+1,iZ) + 00891 u_h.get(iX,iY,iZ+1) + 00892 u_h.get(iX-1,iY,iZ) + 00893 u_h.get(iX,iY-1,iZ) + 00894 u_h.get(iX,iY,iZ-1); 00895 00896 new_u_h.get(oX1,oY1,iZ+offset1.z) = 00897 ((T)1-beta) * u_h.get(iX,iY,iZ) + 00898 (beta/(T)6) * (sumPressure + rhs.get(oX2,oY2,iZ+offset2.z) ); 00899 } 00900 } 00901 } 00902 } 00903 00904 template<typename T> 00905 BoxPeriodicPoissonIteration3D<T>* BoxPeriodicPoissonIteration3D<T>::clone() const 00906 { 00907 return new BoxPeriodicPoissonIteration3D<T>(*this); 00908 } 00909 00910 template<typename T> 00911 void BoxPeriodicPoissonIteration3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00912 modified[0] = modif::nothing; 00913 modified[1] = modif::staticVariables; 00914 modified[2] = modif::nothing; 00915 } 00916 00917 } // namespace plb 00918 00919 #endif // FINITE_DIFFERENCE_FUNCTIONAL_3D_HH 00920
1.6.3
1.6.3