$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 FINE_GRID_PROCESSORS_2D_HH 00032 #define FINE_GRID_PROCESSORS_2D_HH 00033 00034 #include <iomanip> 00035 00036 #include "multiGrid/fineGridProcessors2D.h" 00037 #include "multiBlock/multiDataProcessorWrapper2D.h" 00038 #include "finiteDifference/fdStencils1D.h" 00039 #include "core/geometry2D.h" 00040 00041 namespace plb { 00042 00043 /* *************** Class CopyCoarseToFineLinearInterp2D ****************** */ 00044 00045 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00046 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineLinearInterp2D ( 00047 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00048 plint direction_, plint orientation_ ) 00049 : rescaleEngine(rescaleEngine_), 00050 direction(direction_), orientation(orientation_) 00051 { } 00052 00053 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00054 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::~CopyCoarseToFineLinearInterp2D() { 00055 delete rescaleEngine; 00056 } 00057 00058 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00059 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineLinearInterp2D ( 00060 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00061 : rescaleEngine(rhs.rescaleEngine->clone()), 00062 direction(rhs.direction), orientation(rhs.orientation) 00063 { } 00064 00065 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00066 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>& 00067 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::operator= ( 00068 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00069 { 00070 delete rescaleEngine; 00071 rescaleEngine = rhs.rescaleEngine->clone(); 00072 direction = rhs.direction; 00073 orientation = rhs.orientation; 00074 } 00075 00076 00077 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00078 void CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::process ( 00079 Box2D coarseDomain, 00080 BlockLattice2D<T,Descriptor1>& coarseLattice, 00081 BlockLattice2D<T,Descriptor2>& fineLattice ) 00082 { 00083 const plint x0 = coarseDomain.x0; 00084 const plint y0 = coarseDomain.y0; 00085 const plint x1 = coarseDomain.x1; 00086 const plint y1 = coarseDomain.y1; 00087 00088 PLB_PRECONDITION ( x0==x1 || y0==y1 ); 00089 00090 Array<plint,Descriptor1<T>::d> delta; 00091 delta.resetToZero(); 00092 if (direction == 0) delta[1]=1; else delta[0]=1; 00093 plint whichTime = 1; 00094 00095 std::vector<T> pop1; 00096 std::vector<T> pop2; 00097 00098 CoarseToFineConverter2D<T,Descriptor1,Descriptor2> converter(coarseLattice, fineLattice); 00099 00100 // Check if the extended domain (over which the interpolation is executed) exceeds either 00101 // the coarse or the fine lattice, in which case interpolation is not executed in these 00102 // areas. 00103 Dot2D coarseLeftExcess ( x0 - delta[0], y0 - delta[1] ); 00104 Dot2D fineLeftExcess ( converter.fineX(x0) - delta[0], 00105 converter.fineY(y0) - delta[1] ); 00106 Dot2D coarseRightExcess( x1 + delta[0], y1 + delta[1] ); 00107 Dot2D fineRightExcess ( converter.fineX(x1) + delta[0], 00108 converter.fineY(y1) + delta[1] ); 00109 // leftOutOfRange is true if interpolations are out-of-range on the left side of the domain. 00110 bool leftOutOfRange = ( !contained(coarseLeftExcess, coarseLattice.getBoundingBox()) || 00111 !contained(fineLeftExcess, fineLattice.getBoundingBox()) ); 00112 // rightOutOfRange is true if interpolations are out-of-range on the right side of the domain. 00113 bool rightOutOfRange = ( !contained(coarseRightExcess, coarseLattice.getBoundingBox()) || 00114 !contained(fineRightExcess, fineLattice.getBoundingBox()) ); 00115 00116 // STEP 1: Add left-most cell to the interpolation engine, and perform left-most interpolation 00117 // unless interpolations are out-of-range on the left side of the domain. 00118 00119 if (!leftOutOfRange) { 00120 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0-delta[0],y0-delta[1]) , pop1 ); 00121 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0,y0) , pop2 ); 00122 linearInterpolation(pop1,pop2, 00123 converter.fineDynamics(x0, y0, -delta[0],-delta[1]).getDecomposedValues(whichTime)); 00124 } 00125 00126 // STEP 2: Perform copies and right-directed interpolations on each cell, except the last one 00127 // (which must be treated individually to avoid out-of-range problems). 00128 00129 for (plint iX=x0; iX<=x1-delta[0]; ++iX) { 00130 for (plint iY=y0; iY<=y1-delta[1]; ++iY) { 00131 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX,iY) , pop1 ); 00132 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+delta[0],iY+delta[1]) , pop2 ); 00133 converter.fineDynamics(iX,iY, 00134 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00135 00136 // linearInterpolation the unknown population 00137 linearInterpolation(pop1,pop2, 00138 converter.fineDynamics(iX,iY, delta[0],delta[1]).getDecomposedValues(whichTime)); 00139 } 00140 } 00141 00142 // STEP 3: Copy from the last cell, and perform right-most interpolation unless interpolations 00143 // are out-of-range on the right side of the domain. 00144 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1) , pop1 ); 00145 converter.fineDynamics(x1,y1, 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00146 00147 if (!rightOutOfRange) { 00148 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1) , pop1 ); 00149 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1+delta[0],y1+delta[1]) , pop2 ); 00150 linearInterpolation(pop1,pop2, 00151 converter.fineDynamics(x1,y1, delta[0],delta[1]).getDecomposedValues(whichTime)); 00152 } 00153 } 00154 00155 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00156 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>* 00157 CopyCoarseToFineLinearInterp2D<T,Descriptor1,Descriptor2>::clone() const 00158 { 00159 return new CopyCoarseToFineLinearInterp2D(*this); 00160 } 00161 00162 00163 /* *************** Class CopyCoarseToFineBoundaryLinearInterp2D ********** */ 00164 00165 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00166 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineBoundaryLinearInterp2D ( 00167 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00168 plint direction_, plint orientation_, plint whereToInterpolate_) 00169 : rescaleEngine(rescaleEngine_), 00170 direction(direction_),orientation(orientation_), 00171 whereToInterpolate(whereToInterpolate_) 00172 { } 00173 00174 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00175 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineBoundaryLinearInterp2D ( 00176 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00177 : rescaleEngine(rhs.rescaleEngine->clone()), 00178 direction(rhs.direction),orientation(rhs.orientation), 00179 whereToInterpolate(rhs.whereToInterpolate) 00180 { } 00181 00182 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00183 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>& 00184 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::operator= ( 00185 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00186 { 00187 delete rescaleEngine; 00188 rescaleEngine = rhs.rescaleEngine->clone(); 00189 direction = rhs.direction; 00190 orientation = rhs.orientation; 00191 whereToInterpolate = rhs.whereToInterpolate; 00192 } 00193 00194 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00195 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::~CopyCoarseToFineBoundaryLinearInterp2D() 00196 { 00197 delete rescaleEngine; 00198 } 00199 00200 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00201 void CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::process ( 00202 Box2D domain, 00203 BlockLattice2D<T,Descriptor1>& coarseLattice, 00204 BlockLattice2D<T,Descriptor2>& fineLattice ) 00205 { 00206 PLB_PRECONDITION( domain.x0 == domain.x1 ); 00207 PLB_PRECONDITION( domain.y0 == domain.y1 ); 00208 PLB_PRECONDITION( whereToInterpolate==1 || whereToInterpolate==-1 ); 00209 00210 plint iX = domain.x0; 00211 plint iY = domain.y0; 00212 00213 Array<plint,Descriptor1<T>::d> delta; 00214 delta.resetToZero(); 00215 if (direction == 0) delta[1]=whereToInterpolate; else delta[0]=whereToInterpolate; 00216 plint whichTime = 1; 00217 00218 std::vector<T> pop1; 00219 std::vector<T> pop2; 00220 CoarseToFineConverter2D<T,Descriptor1,Descriptor2> converter(coarseLattice, fineLattice); 00221 00222 // Check if the extended domain (over which the interpolation is executed) exceeds either 00223 // the coarse or the fine lattice, in which case interpolation is not executed. 00224 Dot2D coarseExcess ( iX + delta[0], iY + delta[1] ); 00225 Dot2D fineExcess ( converter.fineX(iX) + delta[0], 00226 converter.fineY(iY) + delta[1] ); 00227 bool outOfRange = ( !contained(coarseExcess, coarseLattice.getBoundingBox()) || 00228 !contained(fineExcess, fineLattice.getBoundingBox()) ); 00229 00230 // retrieve the values at x0,y0 00231 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX,iY), pop1 ); 00232 // copy them to the corresponding fine site 00233 converter.fineDynamics(iX,iY, 00234 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00235 00236 // check if we are not out of range 00237 if (!outOfRange) { 00238 // if it is not the case, linearInterpolation 00239 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+delta[0],iY+delta[1]) , pop2 ); 00240 linearInterpolation(pop1,pop2, 00241 converter.fineDynamics(iX,iY, delta[0],delta[1]).getDecomposedValues(whichTime)); 00242 } 00243 } 00244 00245 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00246 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>* 00247 CopyCoarseToFineBoundaryLinearInterp2D<T,Descriptor1,Descriptor2>::clone() const 00248 { 00249 return new CopyCoarseToFineBoundaryLinearInterp2D(*this); 00250 } 00251 00252 00253 /* *************** Class CopyCoarseToFineCubicInterp2D ****************** */ 00254 00255 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00256 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineCubicInterp2D ( 00257 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00258 plint direction_, plint orientation_ ) 00259 : rescaleEngine(rescaleEngine_), 00260 direction(direction_), orientation(orientation_) 00261 { } 00262 00263 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00264 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::~CopyCoarseToFineCubicInterp2D() { 00265 delete rescaleEngine; 00266 } 00267 00268 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00269 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineCubicInterp2D ( 00270 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00271 : rescaleEngine(rhs.rescaleEngine->clone()), 00272 direction(rhs.direction), orientation(rhs.orientation) 00273 { } 00274 00275 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00276 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>& 00277 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::operator= ( 00278 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00279 { 00280 delete rescaleEngine; 00281 rescaleEngine = rhs.rescaleEngine->clone(); 00282 direction = rhs.direction; 00283 orientation = rhs.orientation; 00284 } 00285 00286 00287 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00288 void CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::process ( 00289 Box2D coarseDomain, 00290 BlockLattice2D<T,Descriptor1>& coarseLattice, 00291 BlockLattice2D<T,Descriptor2>& fineLattice ) 00292 { 00293 const plint x0 = coarseDomain.x0; 00294 const plint y0 = coarseDomain.y0; 00295 const plint x1 = coarseDomain.x1; 00296 const plint y1 = coarseDomain.y1; 00297 00298 CoarseToFineConverter2D<T,Descriptor1,Descriptor2> converter(coarseLattice, fineLattice); 00299 00300 // prepare the delta, keep in mind that it has Palabos BC conventiion 00301 PLB_PRECONDITION ( x0==x1 || y0==y1 ); 00302 Array<plint,Descriptor1<T>::d> delta; 00303 delta.resetToZero(); 00304 // recomputing the correct delta in the direction of refinement 00305 if (direction == 0) delta[1]=1; else delta[0]=1; 00306 plint whichTime = 1; 00307 00308 std::vector<T> pop1;// the leftmost 00309 std::vector<T> pop2;// the current 00310 std::vector<T> pop3;// the next 00311 std::vector<T> pop4;// the rightmost 00312 00313 // Check if the extended domain (over which the interpolation is executed) exceeds either 00314 // the coarse or the fine lattice, in which case interpolation is not executed in these 00315 // areas. 00316 Dot2D coarseLeftExcess ( x0 - 2*delta[0], y0 - 2*delta[1] ); // 2 neighbors for the coarse 00317 Dot2D fineLeftExcess ( converter.fineX(x0) - 2*delta[0], 00318 converter.fineY(y0) - 2*delta[1] ); // only one for the fine 00319 00320 Dot2D coarseRightExcess( x1 + 2*delta[0], y1 + 2*delta[1] ); 00321 Dot2D fineRightExcess ( converter.fineX(x1) + 2*delta[0], 00322 converter.fineY(y1) + 2*delta[1] ); 00323 00324 // leftOutOfRange is true if interpolations are out-of-range on the left side of the domain. 00325 bool leftOutOfRange = ( !contained(coarseLeftExcess, coarseLattice.getBoundingBox()) || 00326 !contained(fineLeftExcess, fineLattice.getBoundingBox()) ); 00327 // rightOutOfRange is true if interpolations are out-of-range on the right side of the domain. 00328 bool rightOutOfRange = ( !contained(coarseRightExcess, coarseLattice.getBoundingBox()) || 00329 !contained(fineRightExcess, fineLattice.getBoundingBox()) ); 00330 00331 // STEP 1: Check if we need to interpolate left of x0 00332 if (!leftOutOfRange){ 00333 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0-2*delta[0],y0-2*delta[1]) , pop1 ); 00334 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0-delta[0],y0-delta[1]) , pop2 ); 00335 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0,y0) , pop3 ); 00336 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0+delta[0],y0+delta[1]) , pop4 ); 00337 00338 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00339 converter.fineDynamics(x0,y0, -delta[0],-delta[1]).getDecomposedValues(whichTime)); 00340 } 00341 00342 // STEP 2: Perform copies and right-directed interpolations on each cell, except the last one 00343 // (which must be treated individually to avoid out-of-range problems). 00344 for (plint iX=x0; iX<=x1-delta[0]; ++iX) { 00345 for (plint iY=y0; iY<=y1-delta[1]; ++iY) { 00346 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX-delta[0],iY-delta[1]) , pop1 ); 00347 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX,iY) , pop2 ); 00348 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+delta[0],iY+delta[1]) , pop3 ); 00349 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+2*delta[0],iY+2*delta[1]) , pop4 ); 00350 // copy the known value over iX,iY in fine coordinates 00351 converter.fineDynamics(iX,iY, 00352 0,0).getDecomposedValues(whichTime).assign(pop2.begin(),pop2.end()); 00353 // linearInterpolation the unknown population 00354 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00355 converter.fineDynamics(iX,iY, delta[0],delta[1]).getDecomposedValues(whichTime)); 00356 } 00357 } 00358 // copy over the last site 00359 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1), pop1 ); 00360 converter.fineDynamics(x1,y1, 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00361 00362 // STEP 3: Check if we need to interpolate at the rightmost cells 00363 if (!rightOutOfRange){ 00364 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1-delta[0],y1-delta[1]), pop1 ); 00365 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1) , pop2 ); 00366 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1+delta[0],y1+delta[1]) , pop3 ); 00367 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1+2*delta[0],y1+2*delta[1]), pop4 ); 00368 00369 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00370 converter.fineDynamics(x1,y1,delta[0],delta[1]).getDecomposedValues(whichTime)); 00371 } 00372 } 00373 00374 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00375 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>* 00376 CopyCoarseToFineCubicInterp2D<T,Descriptor1,Descriptor2>::clone() const 00377 { 00378 return new CopyCoarseToFineCubicInterp2D(*this); 00379 } 00380 00381 /* *************** Class CopyCoarseToFineCubicInterpWithDeconvolution2D ****************** */ 00382 00383 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00384 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineCubicInterpWithDeconvolution2D ( 00385 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00386 plint direction_, plint orientation_ ) 00387 : rescaleEngine(rescaleEngine_), 00388 direction(direction_), orientation(orientation_) 00389 { } 00390 00391 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00392 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::~CopyCoarseToFineCubicInterpWithDeconvolution2D() { 00393 delete rescaleEngine; 00394 } 00395 00396 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00397 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineCubicInterpWithDeconvolution2D ( 00398 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2> const& rhs ) 00399 : rescaleEngine(rhs.rescaleEngine->clone()), 00400 direction(rhs.direction), orientation(rhs.orientation) 00401 { } 00402 00403 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00404 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>& 00405 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::operator= ( 00406 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2> const& rhs ) 00407 { 00408 delete rescaleEngine; 00409 rescaleEngine = rhs.rescaleEngine->clone(); 00410 direction = rhs.direction; 00411 orientation = rhs.orientation; 00412 } 00413 00414 00415 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00416 void CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::process ( 00417 Box2D coarseDomain, 00418 BlockLattice2D<T,Descriptor1>& coarseLattice, 00419 BlockLattice2D<T,Descriptor2>& fineLattice ) 00420 { 00421 const plint x0 = coarseDomain.x0; 00422 const plint y0 = coarseDomain.y0; 00423 const plint x1 = coarseDomain.x1; 00424 const plint y1 = coarseDomain.y1; 00425 00426 00427 CoarseToFineConverter2D<T,Descriptor1,Descriptor2> converter(coarseLattice, fineLattice); 00428 00429 // prepare the delta, keep in mind that it has Palabos BC conventiion 00430 PLB_PRECONDITION ( x0==x1 || y0==y1 ); 00431 Array<plint,Descriptor1<T>::d> delta; 00432 delta.resetToZero(); 00433 // recomputing the correct delta in the direction of refinement 00434 if (direction == 0) delta[1]=1; else delta[0]=1; 00435 plint whichTime = 1; 00436 00437 std::vector<T> pop1;// the leftmost 00438 std::vector<T> pop2;// the current 00439 std::vector<T> pop3;// the next 00440 std::vector<T> pop4;// the rightmost 00441 00442 // Check if the extended domain (over which the interpolation is executed) exceeds either 00443 // the coarse or the fine lattice, in which case interpolation is not executed in these 00444 // areas. 00445 Dot2D coarseLeftExcess ( x0 - 2*delta[0], y0 - 2*delta[1] ); // 2 neighbors for the coarse 00446 Dot2D fineLeftExcess ( converter.fineX(x0) - 2*delta[0], 00447 converter.fineY(y0) - 2*delta[1] ); // only one for the fine 00448 00449 Dot2D coarseRightExcess( x1 + 2*delta[0], y1 + 2*delta[1] ); 00450 Dot2D fineRightExcess ( converter.fineX(x1) + 2*delta[0], 00451 converter.fineY(y1) + 2*delta[1] ); 00452 00453 // leftOutOfRange is true if interpolations are out-of-range on the left side of the domain. 00454 bool leftOutOfRange = ( !contained(coarseLeftExcess, coarseLattice.getBoundingBox()) || 00455 !contained(fineLeftExcess, fineLattice.getBoundingBox()) ); 00456 // rightOutOfRange is true if interpolations are out-of-range on the right side of the domain. 00457 bool rightOutOfRange = ( !contained(coarseRightExcess, coarseLattice.getBoundingBox()) || 00458 !contained(fineRightExcess, fineLattice.getBoundingBox()) ); 00459 00460 // STEP 1: Check if we need to interpolate left of x0 00461 if (!leftOutOfRange){ 00462 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0-2*delta[0],y0-2*delta[1]) , pop1 ); 00463 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0-delta[0],y0-delta[1]) , pop2 ); 00464 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0,y0) , pop3 ); 00465 rescaleEngine->scaleCoarseFine( coarseLattice.get(x0+delta[0],y0+delta[1]) , pop4 ); 00466 00467 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00468 converter.fineDynamics(x0,y0, -delta[0],-delta[1]).getDecomposedValues(whichTime)); 00469 00470 // plint fX = converter.fineX(x0) - delta[0] - orientation*(1-delta[0]); 00471 // plint fY = converter.fineY(y0) - delta[1] - orientation*(1-delta[1]); 00472 // std::vector<T> correction = computeDeconvolutionExtrapolation(fineLattice, fX, fY, delta[0], delta[1]); 00473 // std::vector<T> original = converter.fineDynamics(x0,y0,-delta[0],-delta[1]).getDecomposedValues(whichTime); 00474 // 00475 // for (pluint iA = 0; iA < original.size(); ++iA) { 00476 // original[iA] -= correction[iA]; 00477 // } 00478 // 00479 // converter.fineDynamics(x0,y0,-delta[0],-delta[1]).getDecomposedValues(whichTime).assign(original.begin(),original.end()); 00480 } 00481 00482 // STEP 2: Perform copies and right-directed interpolations on each cell, except the last one 00483 // (which must be treated individually to avoid out-of-range problems). 00484 for (plint iX=x0; iX<=x1-delta[0]; ++iX) { 00485 for (plint iY=y0; iY<=y1-delta[1]; ++iY) { 00486 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX-delta[0],iY-delta[1]) , pop1 ); 00487 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX,iY) , pop2 ); 00488 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+delta[0],iY+delta[1]) , pop3 ); 00489 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+2*delta[0],iY+2*delta[1]) , pop4 ); 00490 // copy the known value over iX,iY in fine coordinates 00491 converter.fineDynamics(iX,iY, 00492 0, 0 ).getDecomposedValues(whichTime).assign(pop2.begin(),pop2.end()); 00493 00494 // plint fX = converter.fineX(iX) - orientation*(1-delta[0]); 00495 // plint fY = converter.fineY(iY) - orientation*(1-delta[1]); 00496 // 00497 // std::vector<T> correction = computeDeconvolutionExtrapolation(fineLattice, fX, fY, delta[0], delta[1]); 00498 // std::vector<T> original = converter.fineDynamics(iX,iY,0,0).getDecomposedValues(whichTime); 00499 // 00500 // for (pluint iA = 0; iA < original.size(); ++iA) { 00501 // original[iA] -= correction[iA]; 00502 // } 00503 // converter.fineDynamics(iX,iY,0,0).getDecomposedValues(whichTime).assign(original.begin(),original.end()); 00504 00505 // linearInterpolation the unknown population 00506 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00507 converter.fineDynamics(iX,iY, delta[0],delta[1]).getDecomposedValues(whichTime)); 00508 00509 // fX += delta[0]; fY += delta[1]; 00510 // correction = computeDeconvolutionExtrapolation(fineLattice, fX, fY, delta[0], delta[1]); 00511 // original = converter.fineDynamics(iX,iY,delta[0],delta[1]).getDecomposedValues(whichTime); 00512 // 00513 // for (pluint iA = 0; iA < original.size(); ++iA) { 00514 // original[iA] -= correction[iA]; 00515 // } 00516 // converter.fineDynamics(iX,iY,delta[0],delta[1]).getDecomposedValues(whichTime).assign(original.begin(),original.end()); 00517 } 00518 } 00519 // copy over the last site 00520 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1), pop1 ); 00521 converter.fineDynamics(x1,y1, 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00522 00523 // plint fX = converter.fineX(x1) - orientation*(1-delta[0]); 00524 // plint fY = converter.fineY(y1) - orientation*(1-delta[1]); 00525 // 00526 // std::vector<T> correction = computeDeconvolutionExtrapolation(fineLattice, fX, fY, delta[0], delta[1]); 00527 // std::vector<T> original = converter.fineDynamics(x1,y1,0,0).getDecomposedValues(whichTime); 00528 // 00529 // for (pluint iA = 0; iA < original.size(); ++iA) { 00530 // original[iA] -= correction[iA]; 00531 // } 00532 // 00533 // converter.fineDynamics(x1,y1,0,0).getDecomposedValues(whichTime).assign(original.begin(),original.end()); 00534 00535 // STEP 3: Check if we need to interpolate at the rightmost cells 00536 if (!rightOutOfRange){ 00537 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1-delta[0],y1-delta[1]), pop1 ); 00538 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1,y1) , pop2 ); 00539 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1+delta[0],y1+delta[1]) , pop3 ); 00540 rescaleEngine->scaleCoarseFine( coarseLattice.get(x1+2*delta[0],y1+2*delta[1]), pop4 ); 00541 00542 cubicCenteredInterpolation(pop1,pop2,pop3,pop4, 00543 converter.fineDynamics(x1,y1,delta[0],delta[1]).getDecomposedValues(whichTime)); 00544 00545 // plint fX = converter.fineX(x1) - orientation*(1-delta[0]); 00546 // plint fY = converter.fineY(y1) - orientation*(1-delta[1]); 00547 // std::vector<T> correction = computeDeconvolutionExtrapolation(fineLattice, fX, fY, delta[0], delta[1]); 00548 // std::vector<T> original = converter.fineDynamics(x1,y1,delta[0],delta[1]).getDecomposedValues(whichTime); 00549 // 00550 // for (pluint iA = 0; iA < original.size(); ++iA) { 00551 // original[iA] -= correction[iA]; 00552 // } 00553 // converter.fineDynamics(x1,y1,delta[0],delta[1]).getDecomposedValues(whichTime).assign(original.begin(),original.end()); 00554 } 00555 } 00556 00557 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00558 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>* 00559 CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>::clone() const 00560 { 00561 return new CopyCoarseToFineCubicInterpWithDeconvolution2D(*this); 00562 } 00563 00564 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00565 std::vector<T> CopyCoarseToFineCubicInterpWithDeconvolution2D<T,Descriptor1,Descriptor2>:: 00566 computeDeconvolutionExtrapolation(BlockLattice2D<T,Descriptor2> &fineLattice, plint iX, plint iY, plint dx, plint dy) const 00567 { 00568 std::vector<T> currentDecomp; 00569 std::vector<std::vector<T> > filteredDecomp; 00570 00571 fineLattice.get(iX+dx,iY+dy).getDynamics().decompose(fineLattice.get(iX+dx,iY+dy), currentDecomp, rescaleEngine->getDecompositionOrder()); 00572 filteredDecomp.push_back(currentDecomp); 00573 fineLattice.get(iX-dx,iY-dy).getDynamics().decompose(fineLattice.get(iX-dx,iY-dy), currentDecomp, rescaleEngine->getDecompositionOrder()); 00574 filteredDecomp.push_back(currentDecomp); 00575 00576 fineLattice.get(iX,iY).getDynamics().decompose(fineLattice.get(iX,iY), currentDecomp, rescaleEngine->getDecompositionOrder()); 00577 00578 std::vector<T> refDecomp = currentDecomp; 00579 00580 for (pluint iA = 0; iA < filteredDecomp.size(); ++iA) { 00581 for (pluint iB = 0; iB < filteredDecomp[iA].size(); ++iB) { 00582 currentDecomp[iB] += filteredDecomp[iA][iB]; 00583 } 00584 } 00585 00586 for (pluint iA = 0; iA < refDecomp.size(); ++iA) { 00587 currentDecomp[iA] /= ((T)filteredDecomp.size()+(T)1); 00588 00589 refDecomp[iA] -= currentDecomp[iA]; 00590 refDecomp[iA] *= (T)0.8; 00591 } 00592 00593 return refDecomp; 00594 } 00595 00596 00597 /* *************** Class CopyCoarseToFineBoundaryCubicInterp2D ************* */ 00598 00599 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00600 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineBoundaryCubicInterp2D ( 00601 RescaleEngine<T,Descriptor1>* rescaleEngine_, 00602 plint direction_, plint orientation_, plint whereToInterpolate_) 00603 : rescaleEngine(rescaleEngine_), 00604 direction(direction_),orientation(orientation_), 00605 whereToInterpolate(whereToInterpolate_) 00606 { } 00607 00608 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00609 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::CopyCoarseToFineBoundaryCubicInterp2D ( 00610 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00611 : rescaleEngine(rhs.rescaleEngine->clone()), 00612 direction(rhs.direction),orientation(rhs.orientation), 00613 whereToInterpolate(rhs.whereToInterpolate) 00614 { } 00615 00616 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00617 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>& 00618 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::operator= ( 00619 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2> const& rhs ) 00620 { 00621 delete rescaleEngine; 00622 rescaleEngine = rhs.rescaleEngine->clone(); 00623 direction = rhs.direction; 00624 orientation = rhs.orientation; 00625 whereToInterpolate = rhs.whereToInterpolate; 00626 } 00627 00628 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00629 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::~CopyCoarseToFineBoundaryCubicInterp2D() 00630 { 00631 delete rescaleEngine; 00632 } 00633 00634 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00635 void CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::process ( 00636 Box2D domain, 00637 BlockLattice2D<T,Descriptor1>& coarseLattice, 00638 BlockLattice2D<T,Descriptor2>& fineLattice ) 00639 { 00640 PLB_PRECONDITION( domain.x0 == domain.x1 || domain.y0 == domain.y1 ); 00641 PLB_PRECONDITION( whereToInterpolate==1 || whereToInterpolate==-1 ); 00642 00643 plint iX = domain.x0; 00644 plint iY = domain.y0; 00645 00646 Array<plint,Descriptor1<T>::d> delta; 00647 delta.resetToZero(); 00648 if (direction == 0) delta[1]=whereToInterpolate; else delta[0]=whereToInterpolate; 00649 plint whichTime = 1; 00650 00651 std::vector<T> pop1; 00652 std::vector<T> pop2; 00653 std::vector<T> pop3; 00654 00655 CoarseToFineConverter2D<T,Descriptor1,Descriptor2> converter(coarseLattice, fineLattice); 00656 00657 // retrieve the values at x0,y0 and neighbors 00658 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX,iY), pop1 ); 00659 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+delta[0],iY+delta[1]), pop2 ); 00660 rescaleEngine->scaleCoarseFine( coarseLattice.get(iX+2*delta[0],iY+2*delta[1]), pop3 ); 00661 00662 // copy (x0,y0) values from coarse to the corresponding fine site 00663 converter.fineDynamics(iX,iY, 00664 0,0).getDecomposedValues(whichTime).assign(pop1.begin(),pop1.end()); 00665 // cubic decentered interpolation for the fine site next to (x0,y0) 00666 quadraticNonCenteredInterpolation(pop1,pop2,pop3, 00667 converter.fineDynamics(iX,iY,delta[0],delta[1]).getDecomposedValues(whichTime)); 00668 00669 } 00670 00671 template<typename T, template<typename U> class Descriptor1, template<typename U> class Descriptor2> 00672 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>* 00673 CopyCoarseToFineBoundaryCubicInterp2D<T,Descriptor1,Descriptor2>::clone() const 00674 { 00675 return new CopyCoarseToFineBoundaryCubicInterp2D(*this); 00676 } 00677 00678 00679 00680 /* *************** Class Copy_t1_to_t0_2D *********************************** */ 00681 template<typename T, template<typename U> class Descriptor> 00682 Copy_t1_to_t0_2D<T,Descriptor>::Copy_t1_to_t0_2D(plint numTimeSteps_, plint executionTime_) 00683 : numTimeSteps(numTimeSteps_), 00684 executionTime(executionTime_) 00685 { } 00686 00687 template<typename T, template<typename U> class Descriptor> 00688 void Copy_t1_to_t0_2D<T,Descriptor>::process(Box2D domain, BlockLattice2D<T,Descriptor>& fineLattice) 00689 { 00690 // Determine current relative value of time steps. 00691 size_t relativeTime = fineLattice.getTimeCounter().getTime()%numTimeSteps; 00692 // Execute data processor only if one is at the end of a cycle. 00693 if ((plint)relativeTime==executionTime) { 00694 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00695 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00696 FineGridBoundaryDynamics<T,Descriptor>& fineDynamics = 00697 dynamic_cast<FineGridBoundaryDynamics<T,Descriptor>&> 00698 ( fineLattice.get(iX,iY).getDynamics() ); 00699 std::vector<T>& t0 = fineDynamics.getDecomposedValues(0); 00700 std::vector<T>& t1 = fineDynamics.getDecomposedValues(1); 00701 t0.assign(t1.begin(), t1.end()); 00702 // complete populations 00703 //TODO: erase this and create a data processor that executes this only when needed 00704 fineDynamics.completePopulations(fineLattice.get(iX,iY)); 00705 } 00706 } 00707 } 00708 } 00709 00710 template<typename T, template<typename U> class Descriptor> 00711 Copy_t1_to_t0_2D<T,Descriptor>* Copy_t1_to_t0_2D<T,Descriptor>::clone() const { 00712 return new Copy_t1_to_t0_2D(*this); 00713 } 00714 00715 } // namespace plb 00716 00717 #endif // FINE_GRID_PROCESSORS_2D_HH 00718
1.6.3
1.6.3