00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 #ifndef _PIECEWISELINEARFILLPATCH_H_ 00012 #define _PIECEWISELINEARFILLPATCH_H_ 00013 00014 #include <iostream> 00015 #include <fstream> 00016 #include "REAL.H" 00017 #include "Box.H" 00018 #include "FArrayBox.H" 00019 #include "LevelData.H" 00020 #include "IntVectSet.H" 00021 #include "ProblemDomain.H" 00022 #include "NamespaceHeader.H" 00023 00024 /// Fills ghost cells by linear interpolation in space and time 00025 00026 /** 00027 Fills some fine level ghost cells by piecewise linear interpolation 00028 from the coarse level. 00029 00030 This class also presents an interface for performing piecewise 00031 constant interpolation in space. If this is all that is required, 00032 define with 'a_pwconst_interp_only = true' to save memory and 00033 expense. 00034 00035 This class fills the first a_interp_radius layers of fine level 00036 ghost cells that are not part of other fine level grids. It uses 00037 piecewise linear interpolation from the coarse level. The slopes 00038 are computed using van leer limiting if there is enough room for 00039 the stencil. It drops order and uses first-order one-sided 00040 differences otherwise. 00041 00042 Below is a picture of a fine level, with a_interp_radius = 1. The 00043 ghost cells of grid 1 are shown. Cells marked X are interpolated 00044 to from the coarse level. Cells marked ^ are not interpolated to 00045 because they are in the valid domain of another fine grid. Cells 00046 marked . are not interpolated to because they are outside the 00047 problem domain. All of this changes in the presence of periodic 00048 boundary conditions -- in periodic directions, all cells are considered 00049 to be within the domain. 00050 00051 <PRE> 00052 +=======================================+ 00053 | | 00054 | | 00055 | | 00056 | | 00057 | + - - - - - - - - - - - - - - | + 00058 | X X X X X X X X X X X X X X X|. 00059 | | +===========================+ | 00060 | X| |. 00061 | | | | | 00062 | X| grid 1 |. 00063 | | | | | 00064 | X| |. 00065 | | | | | 00066 | X| |. 00067 | +=======+===+===============+=======+ | 00068 | | ^ ^ ^|X X X X X X X X|^ ^ ^ ^|. 00069 | | + - - | - - - - - - - | - - - | + 00070 | | | |grid 2 | 00071 | | grid 0 | +=======+ 00072 | | | | 00073 | | | | 00074 | | | | 00075 | +===========+ | 00076 | | 00077 | | 00078 | problem domain | 00079 +=======================================+ 00080 </PRE> 00081 00082 the picture below shows the locations of the types of slopes. The 00083 coarse grid is shown, and the projection of the fine grid onto the 00084 coarse index space (on which slopes are computed). Coarse cells 00085 marked ^ and . do not need slopes. Van Leer slopes in both 00086 directions are used at coarse cells marked X. Coarse cells marked 00087 V and < have one-sided differencing: cells marked V have low-sided 00088 differencing in the y-direction (in this example, because the 00089 coarse grid doesn't exist on the high side of these cells), and 00090 cells marked < have low-sided differencing in the x-direction 00091 (because the problem domain doesn't exist on the high side of 00092 these cells). There can also be cells that have one-sided 00093 differences in both directions. 00094 00095 <PRE> 00096 +-----------------------+===============+ 00097 | | coarse grid 1 | 00098 | | | 00099 | | | 00100 +=======================+ - - - - - - - | - + 00101 | \ / \ / \ / \ /|\ / \ / \ / \ /| 00102 | | V V V V | X X X < | . | 00103 | / \ / \ / \ / \|/ \ / \ / \ / \| 00104 | | +---------------------------+ | 00105 | \ /| | | 00106 | | X | | | . | 00107 | / \| | | 00108 | | | | | | 00109 | \ /| | | 00110 | | X | | | . | 00111 | / \| | | 00112 | +-------+---+---------------+-------+ | 00113 | | |\ / \ /|\ / \ /| | 00114 | | | ^ ^ | X X | X X | ^ ^ | . | 00115 | | |/ \ / \|/ \ / \| | 00116 | | + - - - | - - - - - - - +-------+ - + 00117 | | | | | 00118 | | | | | 00119 | | | | | 00120 | +-----------+ +===============+ 00121 | | | 00122 | | | 00123 | coarse grid 0 | | 00124 +=======================+---------------+ 00125 </PRE> 00126 */ 00127 00128 class PiecewiseLinearFillPatch 00129 { 00130 public: 00131 /// 00132 /** 00133 Default constructor. User must subsequently call define(). 00134 */ 00135 PiecewiseLinearFillPatch(); 00136 00137 /// 00138 /** 00139 Destructor. 00140 */ 00141 virtual ~PiecewiseLinearFillPatch(); 00142 00143 /// 00144 /** 00145 Defining constructor. 00146 00147 {\bf Arguments:}\\ 00148 a_fine_domain (not modified): domain of fine level. \\ 00149 a_coarse_domain (not modified): domain of coarse level. \\ 00150 a_num_comps (not modified): number of components of state vector. \\ 00151 a_problem_domain (not modified): problem domain on the coarse level. \\ 00152 a_ref_ratio (not modified): refinement ratio. \\ 00153 a_interp_radius (not modified): number of layers of fine ghost cells to fill by interpolation. \\ 00154 a_constInterpOnly (not modified): if true, only set up for piecewise-constant interpolation in space. \\ 00155 */ 00156 PiecewiseLinearFillPatch(const DisjointBoxLayout& a_fine_domain, 00157 const DisjointBoxLayout& a_coarse_domain, 00158 int a_num_comps, 00159 const Box& a_crse_problem_domain, 00160 int a_ref_ratio, 00161 int a_interp_radius, 00162 bool a_pwconst_interp_only = false 00163 ); 00164 00165 /// 00166 /** 00167 Defining constructor. 00168 00169 {\bf Arguments:}\\ 00170 a_fine_domain (not modified): domain of fine level. \\ 00171 a_coarse_domain (not modified): domain of coarse level. \\ 00172 a_num_comps (not modified): number of components of state vector. \\ 00173 a_problem_domain (not modified): problem domain on the coarse level. \\ 00174 a_ref_ratio (not modified): refinement ratio. \\ 00175 a_interp_radius (not modified): number of layers of fine ghost cells to fill by interpolation. \\ 00176 a_constInterpOnly (not modified): if true, only set up for piecewise-constant interpolation in space. \\ 00177 */ 00178 PiecewiseLinearFillPatch(const DisjointBoxLayout& a_fine_domain, 00179 const DisjointBoxLayout& a_coarse_domain, 00180 int a_num_comps, 00181 const ProblemDomain& a_crse_problem_domain, 00182 int a_ref_ratio, 00183 int a_interp_radius, 00184 bool a_pwconst_interp_only = false 00185 ); 00186 00187 /// 00188 /** 00189 Defines this object. The user may call define() once and call 00190 fillInterp() multiple times with different valid data sets. 00191 00192 {\bf Arguments:}\\ 00193 a_fine_domain (not modified): domain of fine level. \\ 00194 a_coarse_domain (not modified): domain of coarse level. \\ 00195 a_num_comps (not modified): number of components of state vector. \\ 00196 a_problem_domain (not modified): problem domain on the coarse level. \\ 00197 a_ref_ratio (not modified): refinement ratio. \\ 00198 a_interp_radius (not modified): number of layers of fine ghost cells to fill by interpolation. \\ 00199 a_constInterpOnly (not modified): if true, only set up for piecewise-constant interpolation in space. \\ 00200 00201 {\bf This:}\\ 00202 ---This object is modified.--- 00203 00204 */ 00205 void 00206 define(const DisjointBoxLayout& a_fine_domain, 00207 const DisjointBoxLayout& a_coarse_domain, 00208 int a_num_comps, 00209 const Box& a_crse_problem_domain, 00210 int a_ref_ratio, 00211 int a_interp_radius, 00212 bool a_pwconst_interp_only = false 00213 ); 00214 00215 /// 00216 /** 00217 Defines this object. The user may call define() once and call 00218 fillInterp() multiple times with different valid data sets. 00219 00220 {\bf Arguments:}\\ 00221 a_fine_domain (not modified): domain of fine level. \\ 00222 a_coarse_domain (not modified): domain of coarse level. \\ 00223 a_num_comps (not modified): number of components of state vector. \\ 00224 a_problem_domain (not modified): problem domain on the coarse level. \\ 00225 a_ref_ratio (not modified): refinement ratio. \\ 00226 a_interp_radius (not modified): number of layers of fine ghost cells to fill by interpolation. \\ 00227 a_constInterpOnly (not modified): if true, only set up for piecewise-constant interpolation in space. \\ 00228 00229 {\bf This:}\\ 00230 ---This object is modified.--- 00231 00232 */ 00233 void 00234 define(const DisjointBoxLayout& a_fine_domain, 00235 const DisjointBoxLayout& a_coarse_domain, 00236 int a_num_comps, 00237 const ProblemDomain& a_crse_problem_domain, 00238 int a_ref_ratio, 00239 int a_interp_radius, 00240 bool a_pwconst_interp_only = false 00241 ); 00242 00243 /// 00244 /** 00245 Returns true if this object was created with the defining 00246 constructor or if define() has been called. 00247 00248 {\bf This:}\\ 00249 This object is not modified. 00250 */ 00251 bool 00252 isDefined() const; 00253 00254 /// 00255 /** 00256 Fills the first m_interp_radius layers of fine ghost cells by 00257 interpolation from the coarse level. It is an error to call if not 00258 this->isDefined(). The range components to interpolate must be 00259 specified. The corresponding components on the coarse and fine 00260 levels may be different. It is required that a_fine_data's domain 00261 is the same as was specified in the most recent call to define(). 00262 It is expected that the coarse and fine level's domains are 00263 properly nested. 00264 00265 {\bf Arguments:}\\ 00266 a_fine_data (modified): fine-level data being interpolated to.\\ 00267 a_old_coarse_data (not modified): coarse level source data at the old time.\\ 00268 a_new_coarse_data (not modified): coarse level source data at the new time.\\ 00269 a_time_interp_coef (not modified): time interpolation coefficient, in the range [0:1]. 0=old time, 1=new time.\\ 00270 a_src_comp (not modifed): starting coarse data component.\\ 00271 a_dest_comp (not modifed): starting fine data component.\\ 00272 a_num_comp (not modified): number of data components to be 00273 interpolated. 00274 00275 {\bf This:}\\ 00276 Well, it's complicated. As far as the user is concerned, this object 00277 is not modified. See the design document if you care for details. 00278 00279 */ 00280 void 00281 fillInterp(LevelData<FArrayBox>& a_fine_data, 00282 const LevelData<FArrayBox>& a_old_coarse_data, 00283 const LevelData<FArrayBox>& a_new_coarse_data, 00284 Real a_time_interp_coef, 00285 int a_src_comp, 00286 int a_dest_comp, 00287 int a_num_comp 00288 ); 00289 00290 /// 00291 /** 00292 Fills the first m_interp_radius layers of fine ghost cells by 00293 piece-wise constant interpolation (only in space) from a coarse level 00294 {\bf Arguments:}\\ 00295 a_fine_data (modified): fine-level data being interpolated to.\\ 00296 a_coarse_data (not modified): coarse level source data.\\ 00297 a_src_comp (not modifed): starting coarse data component.\\ 00298 a_dest_comp (not modifed): starting fine data component.\\ 00299 a_num_comp (not modified): number of data components to be 00300 */ 00301 void 00302 fillInterpPWConstSpace(LevelData<FArrayBox>& a_fine_data, 00303 const LevelData<FArrayBox>& a_coarse_data, 00304 int a_src_comp, 00305 int a_dest_comp, 00306 int a_num_comp 00307 ); 00308 00309 // debugging utilities 00310 void 00311 printIntVectSets() const; 00312 00313 00314 protected: 00315 // copy coarse data to coarsened fine work array and interpolate to 00316 // fine time level 00317 void 00318 timeInterp(const LevelData<FArrayBox>& a_old_coarse_data, 00319 const LevelData<FArrayBox>& a_new_coarse_data, 00320 Real a_time_interp_coef, 00321 int a_src_comp, 00322 int a_dest_comp, 00323 int a_num_comp 00324 ); 00325 00326 // fill the fine interpolation sites piecewise-constantly 00327 virtual void 00328 fillConstantInterp(LevelData<FArrayBox>& a_fine_data, 00329 int a_src_comp, 00330 int a_dest_comp, 00331 int a_num_comp 00332 ) 00333 const; 00334 00335 // compute slopes in specified direction 00336 virtual void computeSlopes(int a_src_comp, 00337 int a_num_comp); 00338 00339 void computeSimpleSlopesFab(FArrayBox & a_slopeFab, 00340 const int & a_src_comp, 00341 const int & a_num_comp, 00342 const int & a_dir, 00343 const FArrayBox & a_dataFab, 00344 const IntVectSet& a_local_centered_interp, 00345 const IntVectSet& a_local_lo_interp, 00346 const IntVectSet& a_local_hi_interp); 00347 00348 void computeMultiDimSlopes(FArrayBox & a_slopes0, 00349 FArrayBox & a_slopes1, 00350 FArrayBox & a_slopes2, 00351 const FArrayBox& a_dataFab, 00352 const int & a_src_comp, 00353 const int & a_num_comp, 00354 const Box & a_slopeBox); 00355 00356 // increment the fine interpolation sites with linear term for the 00357 // specified coordinate direction 00358 virtual void 00359 incrementLinearInterp(LevelData<FArrayBox>& a_fine_data, 00360 int a_src_comp, 00361 int a_dest_comp, 00362 int a_num_comp) 00363 const; 00364 00365 00366 protected: 00367 bool m_is_defined; 00368 // the radius of the interpolation stencil. e.g. a stencil using 00369 // (i-1,j), (i,j) and (i+1,j) has a radius of 1. 00370 static const int s_stencil_radius; 00371 // refinement ratio 00372 int m_ref_ratio; 00373 // number of layers of fine ghost cells to fill by interpolation. 00374 int m_interp_radius; 00375 // work array for coarse data in grids shaped like the fine level. 00376 LevelData<FArrayBox> m_coarsened_fine_data; 00377 // work array for slopes 00378 LevelData<FArrayBox> m_slopes[3]; 00379 // problem domain on the coarse level. 00380 ProblemDomain m_crse_problem_domain; 00381 // per-grid fine locations that you interpolate to. 00382 LayoutData<IntVectSet> m_fine_interp; 00383 // per-grid coarse locations that you interpolate from, by type of 00384 // interpolation in the specified coordinate direction. 00385 LayoutData<IntVectSet> m_coarse_centered_interp[SpaceDim]; 00386 LayoutData<IntVectSet> m_coarse_lo_interp[SpaceDim]; 00387 LayoutData<IntVectSet> m_coarse_hi_interp[SpaceDim]; 00388 // cached Copier 00389 Copier m_coarsenCopier; 00390 }; 00391 00392 extern bool getNearPeriodic(const Box & a_box, 00393 const ProblemDomain& a_pdom, 00394 const int & a_rad); 00395 00396 #include "NamespaceFooter.H" 00397 #endif