$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 00025 /* Main author: Daniel Lagrava 00026 **/ 00027 00031 #ifndef GRID_REFINEMENT_PROCESSORS_3D_HH 00032 #define GRID_REFINEMENT_PROCESSORS_3D_HH 00033 00034 #include "multiGrid/gridRefinementProcessors3D.h" 00035 #include "multiBlock/multiDataProcessorWrapper3D.h" 00036 #include "finiteDifference/fdStencils1D.h" 00037 #include "core/geometry3D.h" 00038 00039 namespace plb { 00040 00041 00042 template<typename T, template<typename U> class Descriptor> 00043 void InterpolateOverLineAndExcess ( 00044 Box3D domain, 00045 BlockLattice3D<T,Descriptor>& coarseLattice, 00046 BlockLattice3D<T,Descriptor>& fineLattice, 00047 InterpolationEngine2D<T,Descriptor>* interpolationEngine, 00048 RescaleEngine<T,Descriptor>* rescaleEngine, 00049 std::vector<Dot3D>& delta ) 00050 { 00051 const plint x0 = domain.x0; 00052 const plint y0 = domain.y0; 00053 const plint z0 = domain.z0; 00054 const plint x1 = domain.x1; 00055 const plint y1 = domain.y1; 00056 const plint z1 = domain.z1; 00057 00058 plint whichTime = 1; 00059 CoarseToFineConverter3D<T,Descriptor> converter(coarseLattice, fineLattice); 00060 00061 // delta[0] especifies the direction of the interpolation 00062 // delta[1] especifies the direction perpendicular to the interpolation 00063 // delta[2] is the sum of the other two deltas 00064 delta.push_back(Dot3D(delta[0].x+delta[1].x,delta[0].y+delta[1].y,delta[0].z+delta[1].z)); 00065 00066 // Check if the extended domain (over which the interpolation is executed) exceeds either 00067 // the coarse or the fine lattice, in which case interpolation is not executed. 00068 Dot3D coarseExcess ( x0 + delta[1].x, y0 + delta[1].y, z0 + delta[1].z ); 00069 Dot3D fineExcess ( converter.fineX(x0) + delta[1].x, 00070 converter.fineY(y0) + delta[1].y, 00071 converter.fineZ(z0) + delta[1].z ); 00072 bool outOfRange = ( !contained(coarseExcess, coarseLattice.getBoundingBox()) || 00073 !contained(fineExcess, fineLattice.getBoundingBox()) ); 00074 00075 Dot3D startExcess ( x0 - delta[0].x, y0 - delta[0].y, z0 - delta[0].z ); 00076 Dot3D startFineExcess ( converter.fineX(x0) - delta[0].x, 00077 converter.fineY(y0) - delta[0].y, 00078 converter.fineZ(z0) - delta[0].z ); 00079 bool startOutOfRange = ( !contained(startExcess, coarseLattice.getBoundingBox()) || 00080 !contained(startFineExcess, fineLattice.getBoundingBox()) ); 00081 Dot3D endExcess ( x1 + delta[0].x, y1 + delta[0].y, z1 + delta[0].z ); 00082 Dot3D endFineExcess ( converter.fineX(x1) + delta[0].x, 00083 converter.fineY(y1) + delta[0].y, 00084 converter.fineZ(z1) + delta[0].z ); 00085 bool endOutOfRange = ( !contained(endExcess, coarseLattice.getBoundingBox()) || 00086 !contained(endFineExcess, fineLattice.getBoundingBox()) ); 00087 00088 if (!startOutOfRange){ 00089 interpolationEngine->pushToCouple ( 00090 Array<Cell<T,Descriptor>,2>(coarseLattice.get(x0-delta[0].x, 00091 y0-delta[0].y, 00092 z0-delta[0].z), 00093 coarseLattice.get(x0,y0,z0)), 00094 *rescaleEngine ); 00095 } 00096 00097 if (outOfRange && !startOutOfRange){ 00098 interpolationEngine->pushToCouple(); 00099 } 00100 else { 00101 if (!startOutOfRange && !outOfRange){ 00102 interpolationEngine->pushToCouple ( 00103 Array<Cell<T,Descriptor>,2>(coarseLattice.get( x0-delta[0].x+delta[1].x, 00104 y0-delta[0].y+delta[1].y, 00105 z0-delta[0].z+delta[1].z ), 00106 coarseLattice.get( x0+delta[1].x, 00107 y0+delta[1].y, 00108 z0+delta[1].z)), 00109 *rescaleEngine ); 00110 00111 if (startOutOfRange){ 00112 interpolationEngine->pushToCouple(); 00113 } 00114 } 00115 } 00116 00117 if (!startOutOfRange){ 00118 interpolationEngine->copyFrom ( 00119 converter.fineDynamics(x0,y0,z0, 0,0,0).getDecomposedValues(whichTime), 0 ); 00120 interpolationEngine->interpolateFromCouple ( 00121 converter.fineDynamics( x0,y0,z0, 00122 -delta[0].x, -delta[0].y,-delta[0].z).getDecomposedValues(whichTime), 0,1 ); 00123 } 00124 00125 if (!outOfRange){ 00126 if (!startOutOfRange){ 00127 interpolationEngine->interpolateFromCouple ( 00128 converter.fineDynamics( x0,y0,z0, 00129 -delta[0].x+delta[1].x, 00130 -delta[0].y+delta[1].y, 00131 -delta[0].z+delta[1].z ).getDecomposedValues(whichTime), 0,2 ); 00132 interpolationEngine->interpolateFromAll( 00133 converter.fineDynamics( x0,y0,z0, 00134 delta[1].x,delta[1].y,delta[1].z ).getDecomposedValues(whichTime) ); 00135 } 00136 else { 00137 interpolationEngine->interpolateFromCouple ( 00138 converter.fineDynamics( x0,y0,z0, 00139 delta[1].x, 00140 delta[1].y, 00141 delta[1].z ).getDecomposedValues(whichTime), 0,1 ); 00142 } 00143 } 00144 00145 00146 for (plint iX=x0; iX<=x1-delta[0].x; ++iX) { 00147 for (plint iY=y0; iY<=y1-delta[0].y; ++iY){ 00148 for (plint iZ=z0; iZ<=z1-delta[0].z; ++iZ){ 00149 interpolationEngine->pushToCouple ( 00150 Array<Cell<T,Descriptor>,2>(coarseLattice.get(iX, iY, iZ), 00151 coarseLattice.get(iX+delta[0].x, 00152 iY+delta[0].y, 00153 iZ+delta[0].z)), 00154 *rescaleEngine ); 00155 00156 if (outOfRange){ 00157 interpolationEngine->pushToCouple(); 00158 } 00159 else { 00160 interpolationEngine->pushToCouple ( 00161 Array<Cell<T,Descriptor>,2>(coarseLattice.get( iX+delta[1].x, 00162 iY+delta[1].y, 00163 iZ+delta[1].z), 00164 coarseLattice.get( iX+delta[2].x, 00165 iY+delta[2].y, 00166 iZ+delta[2].z)), 00167 *rescaleEngine ); 00168 } 00169 00170 interpolationEngine->copyFrom ( 00171 converter.fineDynamics(iX,iY,iZ, 0,0,0).getDecomposedValues(whichTime), 0 ); 00172 interpolationEngine->copyFrom ( 00173 converter.fineDynamics(iX,iY,iZ, 00174 2*delta[0].x,2*delta[0].y,2*delta[0].z).getDecomposedValues(whichTime), 1 ); 00175 interpolationEngine->interpolateFromCouple ( 00176 converter.fineDynamics(iX,iY,iZ, 00177 delta[0].x, delta[0].y,delta[0].z).getDecomposedValues(whichTime), 0,1 ); 00178 if (!outOfRange){ 00179 interpolationEngine->interpolateFromCouple ( 00180 converter.fineDynamics( iX,iY,iZ, 00181 delta[1].x, delta[1].y, delta[1].z ).getDecomposedValues(whichTime), 0,2 ); 00182 interpolationEngine->interpolateFromAll( 00183 converter.fineDynamics( iX,iY,iZ, 00184 delta[2].x,delta[2].y,delta[2].z ).getDecomposedValues(whichTime) ); 00185 } 00186 } 00187 } 00188 } 00189 00190 00191 if (!endOutOfRange){ 00192 interpolationEngine->pushToCouple ( 00193 Array<Cell<T,Descriptor>,2>(coarseLattice.get(x1,y1,z1), 00194 coarseLattice.get(x1+delta[0].x, 00195 y1+delta[0].y, 00196 z1+delta[0].z)), 00197 *rescaleEngine ); 00198 } 00199 00200 if (outOfRange && !endOutOfRange){ 00201 interpolationEngine->pushToCouple(); 00202 } 00203 else { 00204 if (!endOutOfRange && !outOfRange){ 00205 interpolationEngine->pushToCouple ( 00206 Array<Cell<T,Descriptor>,2>(coarseLattice.get( x1+delta[1].x, 00207 y1+delta[1].y, 00208 z1+delta[1].z), 00209 coarseLattice.get( x1+delta[0].x+delta[1].x, 00210 y1+delta[0].y+delta[1].y, 00211 z1+delta[0].z+delta[1].z ) 00212 ), 00213 *rescaleEngine ); 00214 00215 if (endOutOfRange){ 00216 interpolationEngine->pushToCouple(); 00217 } 00218 } 00219 } 00220 00221 if (!endOutOfRange){ 00222 interpolationEngine->copyFrom ( 00223 converter.fineDynamics(x1,y1,z1, 0,0,0).getDecomposedValues(whichTime), 0 ); 00224 interpolationEngine->interpolateFromCouple ( 00225 converter.fineDynamics( x1,y1,z1, 00226 delta[0].x, delta[0].y,delta[0].z).getDecomposedValues(whichTime), 0,1 ); 00227 } 00228 00229 if (!outOfRange){ 00230 if (!endOutOfRange){ 00231 interpolationEngine->interpolateFromCouple ( 00232 converter.fineDynamics( x1,y1,z1, 00233 delta[1].x, 00234 delta[1].y, 00235 delta[1].z ).getDecomposedValues(whichTime), 0,2 ); 00236 interpolationEngine->interpolateFromAll( 00237 converter.fineDynamics( x1,y1,z1, 00238 delta[2].x,delta[2].y,delta[2].z ).getDecomposedValues(whichTime) ); 00239 } 00240 else { 00241 interpolationEngine->interpolateFromCouple ( 00242 converter.fineDynamics( x1,y1,z1, 00243 delta[1].x, 00244 delta[1].y, 00245 delta[1].z ).getDecomposedValues(whichTime), 0,1 ); 00246 } 00247 } 00248 00249 delete rescaleEngine; 00250 delete interpolationEngine; 00251 00252 } 00253 00254 00255 std::vector<Box3D> createCorners(Box3D domain, plint direction){ 00256 std::vector<Box3D> result; 00257 if (direction == 0){ // the YZ plane 00258 result.push_back(Box3D(domain.x0,domain.x1,domain.y0,domain.y0,domain.z1,domain.z1)); // CUL 00259 result.push_back(Box3D(domain.x0,domain.x1,domain.y0,domain.y0,domain.z0,domain.z0)); // CLL 00260 result.push_back(Box3D(domain.x0,domain.x1,domain.y1,domain.y1,domain.z0,domain.z0)); // CLR 00261 result.push_back(Box3D(domain.x0,domain.x1,domain.y1,domain.y1,domain.z1,domain.z1)); // CUR 00262 } 00263 if (direction == 1){ // the XZ plane 00264 result.push_back(Box3D(domain.x0,domain.x0,domain.y0,domain.y1,domain.z1,domain.z1)); 00265 result.push_back(Box3D(domain.x0,domain.x0,domain.y0,domain.y1,domain.z0,domain.z0)); 00266 result.push_back(Box3D(domain.x1,domain.x1,domain.y0,domain.y1,domain.z0,domain.z0)); 00267 result.push_back(Box3D(domain.x1,domain.x1,domain.y0,domain.y1,domain.z1,domain.z1)); 00268 } 00269 if (direction == 2){ // the XY plane 00270 result.push_back(Box3D(domain.x0,domain.x0,domain.y1,domain.y1,domain.z0,domain.z1)); 00271 result.push_back(Box3D(domain.x0,domain.x0,domain.y0,domain.y0,domain.z0,domain.z1)); 00272 result.push_back(Box3D(domain.x1,domain.x1,domain.y0,domain.y0,domain.z0,domain.z1)); 00273 result.push_back(Box3D(domain.x1,domain.x1,domain.y1,domain.y1,domain.z0,domain.z1)); 00274 } 00275 00276 return result; 00277 } 00278 00279 Box3D createLeftDomain(Box3D originalDomain, plint direction){ 00280 Box3D result; 00281 if (direction == 0){ // the YZ plane 00282 result = Box3D(originalDomain.x0,originalDomain.x1, 00283 originalDomain.y0,originalDomain.y0, 00284 originalDomain.z0,originalDomain.z1); 00285 } 00286 if (direction == 1){ // the XZ plane 00287 result = Box3D(originalDomain.x0,originalDomain.x0, 00288 originalDomain.y0,originalDomain.y1, 00289 originalDomain.z0,originalDomain.z1); 00290 } 00291 if (direction == 2){ // the XY plane 00292 result = Box3D(originalDomain.x0,originalDomain.x0, 00293 originalDomain.y0,originalDomain.y1, 00294 originalDomain.z0,originalDomain.z1); 00295 } 00296 return result; 00297 } 00298 00299 Box3D createRightDomain(Box3D originalDomain, plint direction){ 00300 Box3D result; 00301 if (direction == 0){ // the YZ plane 00302 result = Box3D(originalDomain.x0,originalDomain.x1, 00303 originalDomain.y1,originalDomain.y1, 00304 originalDomain.z0,originalDomain.z1); 00305 } 00306 if (direction == 1){ // the XZ plane 00307 result = Box3D(originalDomain.x1,originalDomain.x1, 00308 originalDomain.y0,originalDomain.y1, 00309 originalDomain.z0,originalDomain.z1); 00310 } 00311 if (direction == 2){ // the XY plane 00312 result = Box3D(originalDomain.x1,originalDomain.x1, 00313 originalDomain.y0,originalDomain.y1, 00314 originalDomain.z0,originalDomain.z1); 00315 } 00316 return result; 00317 } 00318 00319 Box3D createBottomDomain(Box3D originalDomain, plint direction){ 00320 Box3D result; 00321 if (direction == 0){ // the YZ plane 00322 result = Box3D(originalDomain.x0,originalDomain.x1, 00323 originalDomain.y0,originalDomain.y1, 00324 originalDomain.z0,originalDomain.z0); 00325 } 00326 if (direction == 1){ // the XZ plane 00327 result = Box3D(originalDomain.x0,originalDomain.x1, 00328 originalDomain.y0,originalDomain.y1, 00329 originalDomain.z0,originalDomain.z0); 00330 } 00331 if (direction == 2){ // the XY plane 00332 result = Box3D(originalDomain.x0,originalDomain.x1, 00333 originalDomain.y0,originalDomain.y0, 00334 originalDomain.z0,originalDomain.z1); 00335 } 00336 return result; 00337 } 00338 00339 Box3D createTopDomain(Box3D originalDomain, plint direction){ 00340 Box3D result; 00341 if (direction == 0){ // the YZ plane 00342 result = Box3D(originalDomain.x0,originalDomain.x1, 00343 originalDomain.y0,originalDomain.y1, 00344 originalDomain.z1,originalDomain.z1); 00345 } 00346 if (direction == 1){ // the XZ plane 00347 result = Box3D(originalDomain.x0,originalDomain.x1, 00348 originalDomain.y0,originalDomain.y1, 00349 originalDomain.z1,originalDomain.z1); 00350 } 00351 if (direction == 2){ // the XY plane 00352 result = Box3D(originalDomain.x0,originalDomain.x1, 00353 originalDomain.y1,originalDomain.y1, 00354 originalDomain.z0,originalDomain.z1); 00355 } 00356 return result; 00357 } 00358 00359 00360 00361 00362 /* *************** Class InterpolateCoarseToFineDynamics3D ****************** */ 00363 00364 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00365 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineDynamics3D ( 00366 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00367 InterpolationEngine2D<T,Descriptor1>* interpolationEngine_, 00368 plint direction_, const Dot3D delta_[2] ) 00369 : rescaleEngine(rescaleEngine_), 00370 interpolationEngine(interpolationEngine_), 00371 direction(direction_) 00372 { 00373 delta.push_back(delta_[0]); 00374 delta.push_back(delta_[1]); 00375 } 00376 00377 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00378 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::~InterpolateCoarseToFineDynamics3D() { 00379 delete rescaleEngine; 00380 delete interpolationEngine; 00381 } 00382 00383 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00384 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineDynamics3D ( 00385 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00386 : rescaleEngine(rhs.rescaleEngine->clone()), 00387 interpolationEngine(rhs.interpolationEngine->clone()), 00388 direction(rhs.direction), delta(rhs.delta) 00389 { } 00390 00391 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00392 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>& 00393 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::operator= ( 00394 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00395 { 00396 delete rescaleEngine; 00397 rescaleEngine = rhs.rescaleEngine->clone(); 00398 delete interpolationEngine; 00399 interpolationEngine = rhs.interpolationEngine->clone(); 00400 direction = rhs.direction; 00401 delta.assign(rhs.delta.begin(),rhs.delta.end()); 00402 } 00403 00404 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00405 void InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::process ( 00406 Box3D coarseDomain, 00407 BlockLattice3D<T,Descriptor1>& coarseLattice, 00408 BlockLattice3D<T,Descriptor2>& fineLattice ) 00409 { 00410 const plint x0 = coarseDomain.x0; 00411 const plint y0 = coarseDomain.y0; 00412 const plint z0 = coarseDomain.z0; 00413 const plint x1 = coarseDomain.x1; 00414 const plint y1 = coarseDomain.y1; 00415 const plint z1 = coarseDomain.z1; 00416 00417 PLB_PRECONDITION ( x0==x1 || y0==y1 || z0==z1 ); 00418 PLB_PRECONDITION ( delta[0].x+delta[0].y+delta[0].z==1 && delta[1].x+delta[1].y+delta[1].z==1 ); 00419 // creation of delta[2] 00420 delta.push_back(Dot3D(delta[0].x+delta[1].x,delta[0].y+delta[1].y,delta[0].z+delta[1].z)); 00421 00422 CoarseToFineConverter3D<T,Descriptor1> converter(coarseLattice, fineLattice); 00423 plint whichTime=1; 00424 00425 // Check if the extended domain (over which the interpolation is executed) exceeds either 00426 // the coarse or the fine lattice, in which case interpolation is not executed in these 00427 // areas. 00428 Dot3D coarseLeftExcess ( x0 - delta[0].x, y0 - delta[0].y, z0 - delta[0].z ); 00429 Dot3D fineLeftExcess ( converter.fineX(x0) - delta[0].x, 00430 converter.fineY(y0) - delta[0].y, 00431 converter.fineZ(z0) - delta[0].z ); 00432 Dot3D coarseRightExcess( x1 + delta[0].x, y1 + delta[0].y, z1 + delta[0].z ); 00433 Dot3D fineRightExcess ( converter.fineX(x1) + delta[0].x, 00434 converter.fineY(y1) + delta[0].y, 00435 converter.fineZ(z1) + delta[0].z ); 00436 Dot3D coarseBottomExcess ( x0 - delta[1].x, y0 - delta[1].y, z0 - delta[1].z ); 00437 Dot3D fineBottomExcess ( converter.fineX(x0) - delta[1].x, 00438 converter.fineY(y0) - delta[1].y, 00439 converter.fineZ(z0) - delta[1].z ); 00440 Dot3D coarseTopExcess( x1 + delta[1].x, y1 + delta[1].y, z1 + delta[1].z ); 00441 Dot3D fineTopExcess ( converter.fineX(x1) + delta[1].x, 00442 converter.fineY(y1) + delta[1].y, 00443 converter.fineZ(z1) + delta[1].z ); 00444 00445 // leftOutOfRange is true if interpolations are out-of-range on the left side of the domain. 00446 bool leftOutOfRange = ( !contained(coarseLeftExcess, coarseLattice.getBoundingBox()) || 00447 !contained(fineLeftExcess , fineLattice.getBoundingBox() ) ); 00448 // rightOutOfRange is true if interpolations are out-of-range on the right side of the domain. 00449 bool rightOutOfRange = ( !contained(coarseRightExcess, coarseLattice.getBoundingBox()) || 00450 !contained(fineRightExcess , fineLattice.getBoundingBox() ) ); 00451 // bottomOutOfRange is true if interpolations are out-of-range on the bottom of the domain. 00452 bool bottomOutOfRange = ( !contained(coarseBottomExcess, coarseLattice.getBoundingBox()) || 00453 !contained(fineBottomExcess , fineLattice.getBoundingBox()) ); 00454 // topOutOfRange is true if interpolations are out-of-range on the top of the domain. 00455 bool topOutOfRange = ( !contained(coarseTopExcess, coarseLattice.getBoundingBox()) || 00456 !contained(fineTopExcess , fineLattice.getBoundingBox() ) ); 00457 00458 // STEP 1: We take 4 sites of the coarse grid and we interpolate all the fine values inside 00459 for (plint iX=x0; iX<=x1-delta[2].x; ++iX) { 00460 for (plint iY=y0; iY<=y1-delta[2].y; ++iY){ 00461 for (plint iZ=z0; iZ<=z1-delta[2].z; ++iZ){ 00462 // inserting the corresponding coarse values inside the 2D 00463 // interpolation engine 00464 interpolationEngine->pushToCouple ( 00465 Array<Cell<T,Descriptor1>,2>( coarseLattice.get(iX, iY, iZ), 00466 coarseLattice.get(iX+delta[0].x, 00467 iY+delta[0].y, 00468 iZ+delta[0].z)), 00469 *rescaleEngine ); 00470 interpolationEngine->pushToCouple ( 00471 Array<Cell<T,Descriptor1>,2>(coarseLattice.get( iX+delta[1].x, 00472 iY+delta[1].y, 00473 iZ+delta[1].z), 00474 coarseLattice.get( iX+delta[2].x, 00475 iY+delta[2].y, 00476 iZ+delta[2].z)), 00477 *rescaleEngine ); 00478 00479 00480 // copy of the values from the coarse to the fine 00481 interpolationEngine->copyFrom ( 00482 converter.fineDynamics(iX,iY,iZ, 0,0,0).getDecomposedValues(whichTime), 0 ); 00483 interpolationEngine->copyFrom ( 00484 converter.fineDynamics(iX+delta[0].x,iY+delta[0].y,iZ+delta[0].z, 00485 0,0,0).getDecomposedValues(whichTime), 1 ); 00486 interpolationEngine->copyFrom ( 00487 converter.fineDynamics(iX+delta[1].x,iY+delta[1].y,iZ+delta[1].z, 00488 0,0,0).getDecomposedValues(whichTime), 2 ); 00489 interpolationEngine->copyFrom ( 00490 converter.fineDynamics(iX+delta[2].x,iY+delta[2].y,iZ+delta[2].z, 00491 0,0,0).getDecomposedValues(whichTime), 3 ); 00492 00493 // interpolate the 5 missing values 00494 interpolationEngine->interpolateFromCouple ( 00495 converter.fineDynamics(iX,iY,iZ, 00496 delta[0].x, delta[0].y,delta[0].z).getDecomposedValues(whichTime), 0,1 ); 00497 interpolationEngine->interpolateFromCouple ( 00498 converter.fineDynamics(iX,iY,iZ, 00499 delta[1].x, delta[1].y,delta[1].z).getDecomposedValues(whichTime), 0,2 ); 00500 interpolationEngine->interpolateFromCouple ( 00501 converter.fineDynamics(iX+delta[0].x,iY+delta[0].y,iZ+delta[0].z, 00502 delta[1].x, delta[1].y,delta[1].z).getDecomposedValues(whichTime), 1,3 ); 00503 interpolationEngine->interpolateFromCouple ( 00504 converter.fineDynamics(iX+delta[1].x,iY+delta[1].y,iZ+delta[1].z, 00505 delta[0].x, delta[0].y,delta[0].z).getDecomposedValues(whichTime), 2,3 ); 00506 // this interpolation uses the four coarse values stored 00507 interpolationEngine->interpolateFromAll( 00508 converter.fineDynamics( iX,iY,iZ, 00509 delta[2].x,delta[2].y,delta[2].z ).getDecomposedValues(whichTime) ); 00510 00511 } 00512 } 00513 } 00514 00515 00516 // STEP 2: We perform interpolations over the excedent regions of the grid if needed 00517 if (!leftOutOfRange){ 00518 std::vector<Dot3D> deltas; 00519 deltas.push_back(Dot3D(delta[1].x,delta[1].y,delta[1].z)); 00520 deltas.push_back(Dot3D(-delta[0].x,-delta[0].y,-delta[0].z)); 00521 InterpolateOverLineAndExcess<T,Descriptor1>( createLeftDomain(coarseDomain,direction), 00522 coarseLattice, fineLattice, 00523 interpolationEngine->clone(), rescaleEngine->clone(), 00524 deltas ); 00525 00526 } 00527 00528 if (!bottomOutOfRange){ 00529 std::vector<Dot3D> deltas; 00530 deltas.push_back(Dot3D(delta[0].x,delta[0].y,delta[0].z)); 00531 deltas.push_back(Dot3D(-delta[1].x,-delta[1].y,-delta[1].z)); 00532 InterpolateOverLineAndExcess<T,Descriptor1>( createBottomDomain(coarseDomain,direction), 00533 coarseLattice, fineLattice, 00534 interpolationEngine->clone(), rescaleEngine->clone(), 00535 deltas ); 00536 } 00537 00538 if (!topOutOfRange){ 00539 std::vector<Dot3D> deltas; 00540 deltas.push_back(Dot3D(delta[0].x,delta[0].y,delta[0].z)); 00541 deltas.push_back(Dot3D(delta[1].x,delta[1].y,delta[1].z)); 00542 InterpolateOverLineAndExcess<T,Descriptor1>( createTopDomain(coarseDomain,direction), 00543 coarseLattice, fineLattice, 00544 interpolationEngine->clone(), rescaleEngine->clone(), 00545 deltas ); 00546 } 00547 00548 if (!rightOutOfRange){ 00549 std::vector<Dot3D> deltas; 00550 deltas.push_back(Dot3D(delta[1].x,delta[1].y,delta[1].z)); 00551 deltas.push_back(Dot3D(delta[0].x,delta[0].y,delta[0].z)); 00552 InterpolateOverLineAndExcess<T,Descriptor1>( createRightDomain(coarseDomain,direction), 00553 coarseLattice, fineLattice, 00554 interpolationEngine->clone(), rescaleEngine->clone(), 00555 deltas ); 00556 } 00557 00558 // STEP 3: We perform interpolations over the excedent corners if needed 00559 std::vector<Box3D> corners = createCorners(coarseDomain,direction); 00560 00561 if (!leftOutOfRange && !topOutOfRange){ 00562 const Dot3D deltas[2] = {Dot3D(delta[1].x,delta[1].y,delta[1].z),Dot3D(-delta[0].x,-delta[0].y,-delta[0].z)}; 00563 applyProcessingFunctional( 00564 new InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>( 00565 rescaleEngine->clone(), interpolationEngine->clone(), 00566 deltas 00567 ), 00568 corners[0], 00569 coarseLattice, fineLattice 00570 ); 00571 } 00572 00573 if (!leftOutOfRange && !bottomOutOfRange){ 00574 const Dot3D deltas[2] = {Dot3D(-delta[1].x,-delta[1].y,-delta[1].z),Dot3D(-delta[0].x,-delta[0].y,-delta[0].z)}; 00575 applyProcessingFunctional( 00576 new InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>( 00577 rescaleEngine->clone(), interpolationEngine->clone(), 00578 deltas 00579 ), 00580 corners[1], 00581 coarseLattice, fineLattice 00582 ); 00583 } 00584 if (!rightOutOfRange && !bottomOutOfRange){ 00585 const Dot3D deltas[2] = {Dot3D(-delta[1].x,-delta[1].y,-delta[1].z),Dot3D(delta[0].x,delta[0].y,delta[0].z)}; 00586 applyProcessingFunctional( 00587 new InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>( 00588 rescaleEngine->clone(), interpolationEngine->clone(), 00589 deltas 00590 ), 00591 corners[2], 00592 coarseLattice, fineLattice 00593 ); 00594 } 00595 if (!rightOutOfRange && !topOutOfRange){ 00596 const Dot3D deltas[2] = {Dot3D(delta[1].x,delta[1].y,delta[1].z),Dot3D(delta[0].x,delta[0].y,delta[0].z)}; 00597 applyProcessingFunctional( 00598 new InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>( 00599 rescaleEngine->clone(), interpolationEngine->clone(), 00600 deltas 00601 ), 00602 corners[3], 00603 coarseLattice, fineLattice 00604 ); 00605 } 00606 } 00607 00608 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00609 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>* 00610 InterpolateCoarseToFineDynamics3D<T,Descriptor1,Descriptor2>::clone() const 00611 { 00612 return new InterpolateCoarseToFineDynamics3D(*this); 00613 } 00614 00615 00616 00617 /* *************** Class InterpolateCoarseToFineBoundaryDynamics3D ********** */ 00618 00619 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00620 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineBoundaryDynamics3D ( 00621 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00622 InterpolationEngine2D<T,Descriptor1>* interpolationEngine_, 00623 const Dot3D delta_[2] ) 00624 : rescaleEngine(rescaleEngine_), 00625 interpolationEngine(interpolationEngine_) 00626 00627 { 00628 delta.push_back(delta_[0]); 00629 delta.push_back(delta_[1]); 00630 } 00631 00632 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00633 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineBoundaryDynamics3D ( 00634 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00635 : rescaleEngine(rhs.rescaleEngine->clone()), 00636 interpolationEngine(rhs.interpolationEngine->clone()), delta(rhs.delta) 00637 00638 { } 00639 00640 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00641 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>& 00642 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::operator= ( 00643 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00644 { 00645 delete rescaleEngine; 00646 rescaleEngine = rhs.rescaleEngine->clone(); 00647 delete interpolationEngine; 00648 interpolationEngine = rhs.interpolationEngine->clone(); 00649 delta.resize(0); 00650 delta.push_back(rhs.delta[0]); 00651 delta.push_back(rhs.delta[1]); 00652 00653 } 00654 00655 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00656 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::~InterpolateCoarseToFineBoundaryDynamics3D() 00657 { 00658 delete rescaleEngine; 00659 delete interpolationEngine; 00660 } 00661 00662 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00663 void InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::process ( 00664 Box3D domain, 00665 BlockLattice3D<T,Descriptor1>& coarseLattice, 00666 BlockLattice3D<T,Descriptor2>& fineLattice ) 00667 { 00668 InterpolateOverLineAndExcess<T,Descriptor1>(domain, coarseLattice, fineLattice, 00669 interpolationEngine->clone(), rescaleEngine->clone(), 00670 delta); 00671 00672 } 00673 00674 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00675 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>* 00676 InterpolateCoarseToFineBoundaryDynamics3D<T,Descriptor1,Descriptor2>::clone() const 00677 { 00678 return new InterpolateCoarseToFineBoundaryDynamics3D(*this); 00679 } 00680 00681 /* *************** Class InterpolateCoarseToFineCornerDynamics3D ********** */ 00682 00683 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00684 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineCornerDynamics3D ( 00685 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00686 InterpolationEngine2D<T,Descriptor1>* interpolationEngine_, 00687 const Dot3D delta_[2]) 00688 : rescaleEngine(rescaleEngine_), 00689 interpolationEngine(interpolationEngine_) 00690 { 00691 delta.push_back(delta_[0]); 00692 delta.push_back(delta_[1]); 00693 } 00694 00695 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00696 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::InterpolateCoarseToFineCornerDynamics3D ( 00697 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00698 : rescaleEngine(rhs.rescaleEngine->clone()), 00699 interpolationEngine(rhs.interpolationEngine->clone()), delta(rhs.delta) 00700 {} 00701 00702 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00703 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>& 00704 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::operator= ( 00705 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2> const& rhs ) 00706 { 00707 delete rescaleEngine; 00708 rescaleEngine = rhs.rescaleEngine->clone(); 00709 delete interpolationEngine; 00710 interpolationEngine = rhs.interpolationEngine->clone(); 00711 delta.resize(0); 00712 delta.push_back(rhs.delta[0]); 00713 delta.push_back(rhs.delta[1]); 00714 } 00715 00716 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00717 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::~InterpolateCoarseToFineCornerDynamics3D() 00718 { 00719 delete rescaleEngine; 00720 delete interpolationEngine; 00721 } 00722 00723 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00724 void InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::process ( 00725 Box3D domain, 00726 BlockLattice3D<T,Descriptor1>& coarseLattice, 00727 BlockLattice3D<T,Descriptor2>& fineLattice ) 00728 { 00729 PLB_PRECONDITION( domain.x0 == domain.x1 ); 00730 PLB_PRECONDITION( domain.y0 == domain.y1 ); 00731 PLB_PRECONDITION( domain.z0 == domain.z1 ); 00732 00733 plint x0 = domain.x0; 00734 plint y0 = domain.y0; 00735 plint z0 = domain.z0; 00736 00737 plint whichTime = 1; 00738 CoarseToFineConverter3D<T,Descriptor1> converter(coarseLattice, fineLattice); 00739 00740 // Check if the extended domain (over which the interpolation is executed) exceeds either 00741 // the coarse or the fine lattice, in which case interpolation is not executed. 00742 Dot3D coarseExcess1 ( x0 + delta[0].x, y0 + delta[0].y, z0 + delta[0].z ); 00743 Dot3D fineExcess1 ( converter.fineX(x0) + delta[0].x, 00744 converter.fineY(y0) + delta[0].y, 00745 converter.fineZ(z0) + delta[0].z ); 00746 Dot3D coarseExcess2 ( x0 + delta[1].x, y0 + delta[1].y, z0 + delta[1].z ); 00747 Dot3D fineExcess2 ( converter.fineX(x0) + delta[1].x, 00748 converter.fineY(y0) + delta[1].y, 00749 converter.fineZ(z0) + delta[1].z ); 00750 00751 bool outOfRange1 = ( !contained( coarseExcess1, coarseLattice.getBoundingBox()) || 00752 !contained( fineExcess1 , fineLattice.getBoundingBox()) ); 00753 bool outOfRange2 = ( !contained( coarseExcess2, coarseLattice.getBoundingBox()) || 00754 !contained( fineExcess2 , fineLattice.getBoundingBox()) ); 00755 00756 // Copy coarse->left on the chosen cell, and execute interpolation, unless the 00757 // interpolation is out-of-range. 00758 if (!outOfRange1){ 00759 interpolationEngine->pushToCouple ( 00760 Array<Cell<T,Descriptor1>,2>(coarseLattice.get(x0, y0, z0), 00761 coarseLattice.get(x0+delta[0].x, 00762 y0+delta[0].y, 00763 z0+delta[0].z)), 00764 *rescaleEngine ); 00765 } 00766 00767 if (outOfRange2){ 00768 interpolationEngine->pushToCouple(); 00769 } 00770 else { 00771 interpolationEngine->pushToCouple ( 00772 Array<Cell<T,Descriptor1>,2>(coarseLattice.get(x0+delta[1].x, y0+delta[1].y, z0+delta[1].z), 00773 coarseLattice.get(x0+delta[0].x+delta[1].x, 00774 y0+delta[0].y+delta[1].y, 00775 z0+delta[0].z+delta[1].z)), 00776 *rescaleEngine ); 00777 } 00778 00779 00780 interpolationEngine->copyFrom ( 00781 converter.fineDynamics(x0,y0,z0, 0,0,0).getDecomposedValues(whichTime), 0 ); 00782 00783 if (!outOfRange1) { 00784 interpolationEngine->interpolateFromCouple ( 00785 converter.fineDynamics(x0,y0,z0, delta[0].x, delta[0].y, delta[0].z).getDecomposedValues(whichTime), 0,1 ); 00786 } 00787 00788 if (!outOfRange2) { 00789 interpolationEngine->interpolateFromCouple ( 00790 converter.fineDynamics(x0,y0,z0, delta[1].x, delta[1].y, delta[1].z).getDecomposedValues(whichTime), 0,2 ); 00791 } 00792 00793 if (!outOfRange1 && !outOfRange2){ 00794 interpolationEngine->interpolateFromAll( 00795 converter.fineDynamics(x0,y0,z0, 00796 delta[1].x+delta[0].x, 00797 delta[1].y+delta[0].y, 00798 delta[1].z+delta[0].z).getDecomposedValues(whichTime) ); 00799 } 00800 00801 } 00802 00803 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00804 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>* 00805 InterpolateCoarseToFineCornerDynamics3D<T,Descriptor1,Descriptor2>::clone() const 00806 { 00807 return new InterpolateCoarseToFineCornerDynamics3D(*this); 00808 } 00809 00810 00811 00812 00813 /* *************** Class Copy_t1_to_t0_3D *********************************** */ 00814 00815 template<typename T, template<typename U> class Descriptor> 00816 Copy_t1_to_t0_3D<T,Descriptor>::Copy_t1_to_t0_3D(plint numTimeSteps_, plint executionTime_) 00817 : numTimeSteps(numTimeSteps_), 00818 executionTime(executionTime_) 00819 { } 00820 00821 template<typename T, template<typename U> class Descriptor> 00822 void Copy_t1_to_t0_3D<T,Descriptor>::process(Box3D domain, BlockLattice3D<T,Descriptor>& fineLattice) 00823 { 00824 // Determine current relative value of time steps. 00825 size_t relativeTime = fineLattice.getTimeCounter().getTime()%numTimeSteps; 00826 // Execute data processor only if one is at the end of a cycle. 00827 if ((plint)relativeTime==executionTime) { 00828 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00829 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00830 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00831 FineGridBoundaryDynamics<T,Descriptor>& fineDynamics = 00832 dynamic_cast<FineGridBoundaryDynamics<T,Descriptor>&> 00833 ( fineLattice.get(iX,iY,iZ).getDynamics() ); 00834 std::vector<T>& t0 = fineDynamics.getDecomposedValues(0); 00835 std::vector<T>& t1 = fineDynamics.getDecomposedValues(1); 00836 t0.assign(t1.begin(), t1.end()); 00837 } 00838 } 00839 } 00840 } 00841 } 00842 00843 template<typename T, template<typename U> class Descriptor> 00844 Copy_t1_to_t0_3D<T,Descriptor>* Copy_t1_to_t0_3D<T,Descriptor>::clone() const { 00845 return new Copy_t1_to_t0_3D(*this); 00846 } 00847 00848 00849 /* *************** Class CopyFineToCoarse3D ********************************* */ 00850 00851 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00852 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::CopyFineToCoarse3D ( 00853 RescaleEngine<T,Descriptor1>* rescaleEngine_, plint numTimeSteps_, plint executionTime_ ) 00854 : rescaleEngine(rescaleEngine_), 00855 numTimeSteps(numTimeSteps_), 00856 executionTime(executionTime_) 00857 { } 00858 00859 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00860 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::~CopyFineToCoarse3D() { 00861 delete rescaleEngine; 00862 } 00863 00864 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00865 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::CopyFineToCoarse3D(CopyFineToCoarse3D<T,Descriptor1,Descriptor2> const& 00866 rhs) 00867 : rescaleEngine(rhs.rescaleEngine->clone()), 00868 numTimeSteps(rhs.numTimeSteps), 00869 executionTime(rhs.executionTime) 00870 { } 00871 00872 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00873 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>& CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::operator= ( 00874 CopyFineToCoarse3D<T,Descriptor1,Descriptor2> const& rhs ) 00875 { 00876 delete rescaleEngine; 00877 rescaleEngine = rhs.rescaleEngine->clone(); 00878 numTimeSteps = rhs.numTimeSteps; 00879 executionTime = rhs.executionTime; 00880 } 00881 00882 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00883 void CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::process ( 00884 Box3D fineDomain, 00885 BlockLattice3D<T,Descriptor1>& fineLattice, 00886 BlockLattice3D<T,Descriptor2>& coarseLattice ) 00887 { 00888 PLB_PRECONDITION( fineDomain.x0==fineDomain.x1 || 00889 fineDomain.y0==fineDomain.y1 || 00890 fineDomain.z0==fineDomain.z1); 00891 00892 // Determine current relative value of time steps 00893 size_t relativeTime = fineLattice.getTimeCounter().getTime()%numTimeSteps; 00894 // Execute data processor only if one is at the end of a cycle (iT=1) 00895 if ((plint)relativeTime==executionTime) { 00896 Dot3D posFine = fineLattice.getLocation(); // Position of fine grid in multi block. 00897 Dot3D posCoarse = coarseLattice.getLocation(); // Position of coarse grid in multi block. 00898 Box3D coarseDomain ( 00899 fineDomain.shift(posFine.x,posFine.y,posFine.z). // Convert to absolute fine coordinates. 00900 divideAndFitSmaller(2). // Rescale, but don't exceed original domain. 00901 shift(-posCoarse.x,-posCoarse.y,-posCoarse.z) ); // Convert to relative coarse coordinates. 00902 std::vector<T> decomposedCoarseValues; 00903 // Loop over coarse lattice 00904 for (plint iX=coarseDomain.x0; iX<=coarseDomain.x1; ++iX) { 00905 for (plint iY=coarseDomain.y0; iY<=coarseDomain.y1; ++iY) { 00906 for (plint iZ=coarseDomain.z0; iZ<=coarseDomain.z1; ++iZ) { 00907 // Determine corresonding coordinates on fine lattice 00908 plint fineX = (iX+posCoarse.x)*2 - posFine.x; 00909 plint fineY = (iY+posCoarse.y)*2 - posFine.y; 00910 plint fineZ = (iZ+posCoarse.z)*2 - posFine.z; 00911 00912 Cell<T,Descriptor1>& coarseCell = coarseLattice.get(iX,iY,iZ); 00913 Cell<T,Descriptor2> const& fineCell = fineLattice.get(fineX,fineY,fineZ); 00914 00915 rescaleEngine->scaleFineCoarse(fineCell, decomposedCoarseValues); 00916 rescaleEngine->recompose(coarseCell, decomposedCoarseValues); 00917 } 00918 } 00919 } 00920 } 00921 } 00922 00923 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00924 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>* 00925 CopyFineToCoarse3D<T,Descriptor1,Descriptor2>::clone() const 00926 { 00927 return new CopyFineToCoarse3D(*this); 00928 } 00929 00930 } // namespace plb 00931 00932 #endif // GRID_REFINEMENT_PROCESSORS_3D_HH
1.6.3
1.6.3