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 _LEVELGRIDMETRICS_H_ 00012 #define _LEVELGRIDMETRICS_H_ 00013 00014 00015 /******************************************************************************/ 00016 /** 00017 * \file 00018 * 00019 * \brief Grid metrics on and between levels. 00020 * 00021 *//*+*************************************************************************/ 00022 00023 #include "AMRLevel.H" 00024 #include "CodimBox.H" 00025 #include "CoarseAverageFace.H" 00026 #include "CoarseAverageCodim.H" 00027 #include "MultiBlockCoordSys.H" 00028 #include "NewFourthOrderCoordSys.H" 00029 #include "FourthOrderMappedFineInterp.H" 00030 #include "MultiBlockLevelGeom.H" 00031 #include "MultiBlockLevelExchangeAverage.H" 00032 #include "MultiBlockFaceRegister.H" 00033 00034 #include "NamespaceHeader.H" 00035 00036 //--Forward declarations 00037 00038 class TimeInterpolatorRK4; // (part of timeIntermediate hack) 00039 00040 // //--Debug support 00041 00042 // extern int LGMDebug; 00043 00044 00045 /******************************************************************************* 00046 */ 00047 /// Average from fine intersections 00048 /** 00049 * The objective of this class is to average down information from A^(l+1) 00050 * to C^(l) but only on the intersection of A^(l+1) and B^(l+1). This class 00051 * is designed to support class 'LevelGridMetrics' where A is the snapback 00052 * flux on the old fine mesh, B is the new mesh, and C (= A^l) is the snapback 00053 * flux on the old coarse mesh. These are the steps (Cr is coarsen operator): 00054 * <ol> 00055 * <li> Average A^(l+1) to D^(l) on boxes of Cr(A^(l+1)). This step is 00056 * performed at level 'l+1'. D and the coarsened box layout of A are 00057 * saved. 00058 * <li> Now at level 'l', copy to E^(l) on boxes of C^(l). These first two 00059 * steps are done in the averager 00060 * <li> Compute mask for each box of C^(l). The mask is the 00061 * intersection of Cr(A^(l+1)), Cr(B^(l+1)), and C^(l) 00062 * <li> Copy from E^(1) to C^(1) using the mask. 00063 * </ol> 00064 * 00065 ******************************************************************************/ 00066 00067 class IntersectionAverageFace 00068 { 00069 public: 00070 00071 /// Constructor 00072 IntersectionAverageFace(const LevelData<FluxBox>& a_A, 00073 const int a_nRef); 00074 00075 // Use synthesized destructor 00076 00077 /// Copy the average using a mask 00078 void copyTo(LevelData<FluxBox>& a_C, 00079 const DisjointBoxLayout& a_dblB); 00080 00081 private: 00082 00083 // Copy and assignment not allowed 00084 IntersectionAverageFace(const IntersectionAverageFace&); 00085 IntersectionAverageFace& operator=(const IntersectionAverageFace&); 00086 00087 protected: 00088 00089 const int m_nComp; ///< Number of components in A (same as C) 00090 const int m_nRef; ///< Refinement between A & C 00091 DisjointBoxLayout m_crDblA; ///< Coarsened layout for A 00092 CoarseAverageFace m_averager; ///< The averager itself stores the 00093 ///< averaged data between averaging and 00094 ///< copying 00095 }; 00096 00097 00098 /******************************************************************************* 00099 */ 00100 /// Grid metrics for a level 00101 /** 00102 * This class adds infrastructure for mapped grids to the fourth-order 00103 * Cartesian AMRLevel class. The interface closely follows that of 00104 * AMRLevel. Typically this class is a member of the user's derived 00105 * AMRLevel and the member functions of LevelGridData should be called 00106 * from member functions of the derived AMRLevel that have the same name. 00107 * 00108 * <p> This class provides m_N, the metric terms \f$\mathbf(N)\f$ on each 00109 * face, and m_J, the determinant (physical cell volume divided by 00110 * computational cell volume). These quantities are appropriately maintained 00111 * during all aspects of an AMR solution. 00112 * 00113 * <p> GHOSTS --- The determinants, (J), are defined on all ghost cells at 00114 * the domain interior and 1 layer of ghost cells outside a non-periodic 00115 * domain. Hence, gradients of J are available everywhere an application may 00116 * store data. To achieve this, it is assumed that the metrics can be 00117 * evaluated everywhere in \f$\mathcal(G)(\Gamma,2)\f$. 00118 * HOWEVER, metrics that are consistent between levels are only maintained in 00119 * the valid region of the finer level. A valid cell on a coarse level will 00120 * have metrics computed separately from any overlapping ghost cells from a 00121 * finer level (i.e., the volumes of the fine ghost cells may not sum to the 00122 * volume of the valid coarse cell). Consistency between levels everywhere 00123 * could be achieved by treating all ghost cells as part of the valid region 00124 * --- this would simply (probably simply) require some modifications to the 00125 * "averagers". However we do not do this because: 00126 * <ul> 00127 * <li> it breaks a consistent definition of valid/invalid 00128 * <li> there is no requirement for conservation in ghost cells since they 00129 * are only used for gradient reconstruction, limiting, etc. 00130 * </ul> 00131 * Any ghost cell that is covered by a valid cell on that level is consistent 00132 * with the metrics from any finer level by means of the copiers (used in 00133 * the averagers) copying to both the invalid and valid regions of a 00134 * destination. 00135 * <p> 00136 * Transverse terms in N are determined only on the faces of grow(N.box(), -1) 00137 * if obtained by averaging, i.e., on one less layer than where the normal 00138 * components are known. If obtained by analytic methods, they are available 00139 * everywhere. 00140 * 00141 * <p> Normally, N is calculated using script N to ensure freestream 00142 * preservation. But in some cases, e.g., a 2-D solution on the surface of 00143 * a sphere, there is no definition of script N. In those cases, 00144 * m_useScriptN should be set to false and N will be calculated and averaged 00145 * directly. The averaging ensures conservation but freestream-preservation 00146 * is sacrificed. The value of m_useScriptN is obtained from the 00147 * MultiBlockCoordSys and should be set to 'false' in the constructor of 00148 * coordinate systems derived from class MultiBlockCoordSys. Otherwise, by 00149 * default, it is set to true. 00150 * 00151 * <p> 00152 * The following routines should be called from the corresponding routines 00153 * with the same name derived AMRLevel: 00154 * <ul> 00155 * <li> initialGrid 00156 * <li> postInitialGrid 00157 * <li> postTimeStep 00158 * <li> preRegrid 00159 * <li> regrid 00160 * </ul> 00161 * 00162 * <p> Setup for the class is as follows: 00163 * <ol> 00164 * <li> Call define to setup the class members -- metrics are still 00165 * undefined. 00166 * <li> Optionally call initialGrid to set the new box layout on a level. 00167 * This can be deferred until postInitialGrid if desired. 00168 * <li> Call postInitialGrid to set the new box layout (if not done in 00169 * previous step) and define the metrics. 00170 * </ol> 00171 * 00172 * <p> During a run, be sure to: 00173 * <ol> 00174 * <li> Call postTimeStep to average down the metric terms from finer 00175 * levels. This only has an effect if they changed on the finer 00176 * level 00177 * </ol> 00178 * 00179 * <p> For a regrid do the following: 00180 * <ol> 00181 * <li> Call preRegrid to compute the new metrics and correct the solution 00182 * on the old mesh to the metrics of the new mesh (snapback). 00183 * <li> Optionally call regrid to interpolate from the coarse mesh to 00184 * the new fine mesh. This can be done is user code but must 00185 * use FourthOrderMappedFineInterp to ensure a conservative and 00186 * free-stream preserving interpolation on the mapped grid. 00187 * </ol> 00188 * 00189 * \note 00190 * <ul> 00191 * <li> To facilitate products that involve gradients, the metrics (N) are 00192 * determined on the faces of boxes with size ghostBox+2. This is 00193 * labeled an 'NReqGhostBox' herein. At domain boundaries, the boxes 00194 * for 'N' extend by 2 cells outside the physical domain and it is 00195 * assumed that the mappings exist there. The determinants (J) are 00196 * determined on the cells of boxes with size ghostBox+1. This is 00197 * labeled a 'JReqGhostBox' herein. At domain boundaries, the boxes 00198 * for 'J' extends by 1 cell outside the physical domain 00199 * <li> Averages of fluxes. Most of the fluxes, <F>\ are stored as average 00200 * quantities to be applied to a face and do not include area 00201 * information. I.e., the actual flux across a 2-D face is 00202 * \f$\langle F\rangle h^2\f$ Hence when correcting from fine to 00203 * coarse, you want to average the fine <F> and then muliply by the 00204 * area of the coarse face (although in most equations, the area 00205 * cancels out with another term). However, the \f$\mathcal(N)^s\f$, 00206 * which are a type of flux, are stored differently in that they have 00207 * already been multiplied by the length term (equivalent to 00208 * \f$\langle F\rangle h^2\f$ in the example above). Hence, these 00209 * fluxes needed to be summed when correcting from coarse to fine. 00210 * <li> WARNING! If transverse components of <N> are computed analytically, 00211 * they are only averaged down when finer levels have changed before 00212 * entering a postTimeStep (along with normal components). 00213 * Consequently, it is currently difficult to know if they have been 00214 * computed or averaged from a finer level at any given point. But 00215 * note that if transverse components of <N> are computed by averaging 00216 * from normal components, then they should always be consistent. 00217 * **FIXME -- probably the best fix is to only average the normal 00218 * components if transverse are computed analytically. 00219 * </ul> 00220 * 00221 *//*+*************************************************************************/ 00222 00223 class LevelGridMetrics 00224 { 00225 00226 public: 00227 00228 /// Age of metric terms during a regrid 00229 enum AgeType 00230 { 00231 AgeOld = 0, 00232 AgeNew = 1, 00233 AgeNum = 2 00234 }; 00235 00236 /// Type of operation for computing transverse terms in N 00237 enum TransverseNOpType 00238 { 00239 TransverseNOpNone, 00240 TransverseNOpAnalytic, // Analytic calculation 00241 TransverseNOpAverage // Average from normals on nearby 00242 // transverse faces 00243 }; 00244 00245 00246 /*============================================================================== 00247 * Constructors and destructors 00248 *============================================================================*/ 00249 00250 public: 00251 00252 /// Constructor 00253 LevelGridMetrics(const int a_nComp, 00254 const int a_spaceOrder); 00255 00256 /// Destructor 00257 ~LevelGridMetrics(); 00258 00259 private: 00260 00261 // Copy and assignment not allowed 00262 LevelGridMetrics(const LevelGridMetrics&); 00263 LevelGridMetrics& operator=(const LevelGridMetrics&); 00264 00265 00266 /*============================================================================== 00267 * Member functions 00268 *============================================================================*/ 00269 00270 public: 00271 00272 /// Free memory 00273 void clear(); 00274 00275 /// Does a finer level exist? 00276 bool hasFiner() const; 00277 00278 /// Does a coarser level exist? 00279 bool hasCoarser() const; 00280 00281 /// Define the class. No metrics terms are yet available. 00282 void define( 00283 AMRLevel *const a_AMRLevel, 00284 MultiBlockCoordSysFactory *const a_coordSysFact, 00285 LevelGridMetrics *const a_coarserLevelGridMetrics, 00286 const RealVect& a_dxVect, 00287 const IntVect& a_ghostVect, 00288 const TransverseNOpType a_transverseNOpType = TransverseNOpNone, 00289 const bool a_haveMultiBlockVectorData = true, 00290 //**FIXME do we need this? 00291 const int a_numBlocks = 1); 00292 00293 /// Are the metrics defined on this level? 00294 bool metricsDefined() const; 00295 00296 /// Did the metrics change on the finer mesh? 00297 bool didFinerChange() const; 00298 00299 /// Retrieve the multi-block coordinate system. 00300 const MultiBlockCoordSys& getCoordSys() const; 00301 00302 /// Get the coordinate system 00303 /* Are we ever going to use a second-order system? If so, I assume the 00304 * CoordSys routines will be virtualized such that getCoordSys2 can be 00305 * changed to getCoordSys and the cast will be unnecessary. 00306 */ 00307 const NewCoordSys* getCoordSys2(const Box& box) const; 00308 00309 /// 00310 const NewFourthOrderCoordSys* getCoordSys(const Box& box) const; 00311 00312 /// Get the block index 00313 int getBlock(const Box& a_box) const; 00314 00315 /// Get a problem domain representing a block 00316 const ProblemDomain& blockDomain(const Box& a_box, const int a_numGhost = 0); 00317 00318 /// Get the computational mesh spacing 00319 const RealVect& dxVect() const; 00320 00321 //--AMRLevel extensions 00322 00323 /// After a time step, average down \f$N\f$ and \f$J\f$ 00324 void postTimeStep(); 00325 00326 /// Set up initial grid 00327 virtual void initialGrid(const DisjointBoxLayout *const a_newGrid); 00328 00329 /// Set up the initial metric terms. 00330 void postInitialGrid(const DisjointBoxLayout *const a_newGrid); 00331 00332 /// Compute new metrics and correct the solution on the coarser meshes 00333 void preRegrid(const int a_baseLevel, 00334 const DisjointBoxLayout& a_newGrid, 00335 const LevelData<FArrayBox> *const a_coarseUOldPtr, 00336 LevelData<FArrayBox>& a_UOld, 00337 LevelData<FArrayBox>& a_JUOld); 00338 00339 /// Regrid operations -- performs a coarse to fine interpolation 00340 virtual void regrid(LevelData<FArrayBox>& a_JU, 00341 const LevelData<FArrayBox>& a_CrU, 00342 const LevelData<FArrayBox>& a_CrJU, 00343 const Interval& a_vectorIntv); 00344 00345 // /// Post regrid operations -- currently unused. 00346 // void postRegrid(int a_base_level); 00347 00348 //--Convenience 00349 00350 /// Fill invalid fine ghost cells (with preset CrFnU) 00351 virtual void fillFineGhostCells(LevelData<FArrayBox>& a_U, 00352 LevelData<FArrayBox>& a_JU, 00353 Real a_time = -1); 00354 00355 /// Computes <U> in valid cells 00356 void computeValidU(LevelData<FArrayBox>& a_U, 00357 const LevelData<FArrayBox>& a_JU); 00358 00359 /// Compute the minimum grid buffer size for a fourth-order interpolation 00360 static int bufferSize4thO(const std::vector<int>& a_refRatio, 00361 const int a_maxLevel, 00362 const int a_numGhost); 00363 00364 /// Exchange <U> across multiblock boundaries 00365 void multiblockExchangeU(LevelData<FArrayBox>& a_U, 00366 const Interval& a_vectorIntv) const; 00367 00368 /// Supports a call to TimeInterpolatorRK4::intermediate for multi-block grids 00369 void timeIntermediate(const TimeInterpolatorRK4& a_timeInterpolator, 00370 const Real& a_timeInterpCoeff, 00371 const int& a_stage, 00372 const Interval& a_vectorIntv); 00373 00374 //--Consistent access to structural boxes 00375 00376 /// Get the boxes 00377 const DisjointBoxLayout& getBoxes() const; 00378 00379 /// Get a level iterator 00380 DataIterator getDataIterator() const; 00381 00382 /// Resize a box to include the ghost cells 00383 Box resizeWithGhosts(const Box& box) const; 00384 00385 /// Determine the ghost vector required for \f$J\f$. 00386 virtual IntVect getJReqGhostVect() const; 00387 00388 /// Determine the ghost vector required for \f$N\f$. 00389 virtual IntVect getNReqGhostVect() const; 00390 00391 /// Resize a box to the size required for \f$J\f$ 00392 Box resizeWithJReqGhosts(const Box& box) const; 00393 00394 /// Resize a box to the size required for \f$N\f$ 00395 Box resizeWithNReqGhosts(const Box& box) const; 00396 00397 //--Access to the interpolator's temporary structures 00398 00399 /* 00400 * The following return a coarsened representation of 'this' level, i.e., 00401 * 'this' is the fine level. 00402 */ 00403 00404 /// Set the coarsened-fine <U> used by the interpolator (CrFn access) 00405 LevelData<FArrayBox>& presetCr2ThisInterpolatorCrFnLevU(); 00406 00407 /// Set the coarsened-fine <JU> used by the interpolator (CrFn access) 00408 LevelData<FArrayBox>& presetCr2ThisInterpolatorCrFnLevJU(); 00409 00410 // Obsolete 00411 // /// Get the coarsened-fine <U> used by the interpolator 00412 // const LevelData<FArrayBox>& getCr2ThisInterpolatorCrFnLevU() const; 00413 00414 // /// Get the coarsened-fine <JU> used by the interpolator 00415 // const LevelData<FArrayBox>& getCr2ThisInterpolatorCrFnLevJU() const; 00416 00417 /* 00418 * The following make use of the coarse data on 'this' level, i.e., 'this' is 00419 * the coarse level. 00420 */ 00421 00422 /// Set the coarsened-fine <U> used by the interpolator 00423 void presetThis2FnInterpolatorCrFnLevU( 00424 const LevelData<FArrayBox>& a_CrLevU, 00425 const Interval& a_vectorIntv); 00426 00427 // Should not be used 00428 // /// Set the coarsened-fine <JU> used by the interpolator 00429 // void presetThis2FnInterpolatorCrFnLevJU( 00430 // const LevelData<FArrayBox>& a_CrLevJU); 00431 00432 /// Invalidate the CrFn data, both <U> and <JU>\, used by the interpolator 00433 void invalidateCr2ThisInterpolatorCrFnLevData(); 00434 00435 /// Invalidate the CrFn data, both <U> and <JU>\, used by the interpolator 00436 void invalidateThis2FnInterpolatorCrFnLevData(); 00437 00438 /// Number of ghosts used to build the coarsened-fine data in the interpolator 00439 const IntVect& interpolatorCrFnNumGhost(const bool a_force = false) const; 00440 00441 /// Is this a multiblock grid 00442 bool isMultiblock() const; 00443 00444 /// 00445 const ProblemDomain& problemDomain() const; 00446 00447 protected: 00448 00449 //--Easier access to AMRLevel data (these are also defined in AMRLevel.H). 00450 00451 /// 00452 int level() const; 00453 00454 /// 00455 int refRatio() const; 00456 00457 /// 00458 static int verbosity(); 00459 00460 //--Internal 00461 00462 /// Completely define the metrics for this level 00463 void defineMetrics(); 00464 00465 /// Label this and all finer levels as having undefined metrics 00466 void undefineMetrics(); 00467 00468 /// Compute \f$N\f$ on the hyperfaces from \f$\mathcal{N}^s\f$ 00469 // Only used if m_useScriptN == true 00470 void faceNormalN(LevelData<FluxBox>& a_N, 00471 const LevelData<CodimBox <FArrayBox> >& a_scrN); 00472 00473 /// Compute \f$N\f$ on the hyperfaces from \f$\mathcal{N}^s\f$ 00474 // Only used if m_useScriptN == false 00475 void getN(LevelData<FluxBox>& a_N); 00476 00477 /// Add transverse components to \f$N\f$ 00478 void faceTransverseN(LevelData<FluxBox>& a_N); 00479 00480 /// Integrate \f$\mathcal{N}^s\f$ on each hyperedge 00481 void getScriptN(LevelData<CodimBox<FArrayBox> >& a_scrN); 00482 00483 /// Average \f$\mathcal{N}^s\f$ 00484 // Only used if m_useScriptN == true 00485 void averageScriptN(const bool a_isBase, 00486 LevelData<CodimBox<FArrayBox> >& a_scrN); 00487 00488 /// Average \f$N\f$ directly if \f$\mathcal{N}^s\f$ doesn't exist. 00489 // Only used if m_useScriptN == false 00490 void averageN(const bool a_isBase, 00491 LevelData<FluxBox>& a_N); 00492 00493 /// Compute the volume flux 00494 void getVolFlux(LevelData<FluxBox>& a_NtX, 00495 const LevelData<FluxBox>& a_N); 00496 00497 /// Take divergence of \f$N^T X\f$ to set m_J. 00498 virtual void setAvgJfromNtX(LevelData<FluxBox>& a_NtX); 00499 00500 /// Average the volume flux \f$N^T X\f$. 00501 void averageVolFlux(const bool a_isBase, 00502 LevelData<FluxBox>& a_NtX, 00503 const AgeType a_age); 00504 00505 /// Compute \f$N^T X\f$ on all finer levels and average down 00506 void volFluxCascade(); 00507 00508 /// Average the snapback solution flux, \f$N^T F\f$. 00509 void averageSnapbackSolFlux(const bool a_isBase, 00510 LevelData<FluxBox>& a_NtFDiff); 00511 00512 /// Store the DisjointBoxLayout and define multiblock structures 00513 virtual void defineGrids(const DisjointBoxLayout& a_grids); 00514 00515 /// Create a non-periodic DisjointBoxLayout 00516 void defineGridsNP(const DisjointBoxLayout& a_grids); 00517 00518 00519 /*============================================================================== 00520 * Data members 00521 *============================================================================*/ 00522 00523 public: 00524 00525 LevelData<FluxBox> m_N; ///< \f$\mathbf(N)\f$ on each face 00526 LevelData<FArrayBox> m_J; ///< Physical cell volume divided by 00527 ///< computational cell volume 00528 00529 protected: 00530 00531 //--Single-block 00532 00533 // The following averagers are not defined on the finest level 00534 CoarseAverageCodim* m_scrNAverager; ///< Averager for \f$\mathcal(N)^s\f$. 00535 ///< Only used if m_useScriptN == true 00536 CoarseAverageFace* m_NAverager; ///< Averager for \f$N\f$ 00537 ///< Only used if m_useScriptN == false 00538 CoarseAverageFace* m_NtXAverager[AgeNum]; 00539 ///< This averages the volume flux from a 00540 ///< finer level. Averagers exist for old 00541 ///< "AgeOld" and new "AgeNew" meshes 00542 ///< during a regrid 00543 IntersectionAverageFace* m_NtFDiffAverager; 00544 ///< Averager for the snapback solution 00545 ///< flux. This averager only operates 00546 ///< on the intersections of three 00547 ///< layouts. 00548 00549 MultiBlockCoordSys* m_coordSys; ///< The multi-block coordinate system. 00550 00551 LevelGridMetrics* m_finerLevelGridMetrics; 00552 ///< Grid metrics on the next finer level 00553 LevelGridMetrics* m_coarserLevelGridMetrics; 00554 ///< Grid metrics on the next coarser 00555 ///< level 00556 00557 AMRLevel* m_parentAMRLevel; ///< The AMR level we are attached to 00558 00559 IntVect m_ghostVect; ///< Ghost cell vector 00560 DisjointBoxLayout m_grids; ///< Grid layout 00561 DisjointBoxLayout m_gridsNP; ///< Non-periodic grid layout. This is a 00562 ///< shallow copy of m_grids, with a non- 00563 ///< periodic problem domain and a new 00564 ///< neighbor iterator if problemDomain() 00565 ///< is periodic. 00566 RealVect m_dxVect; ///< Mesh spacing in each direction 00567 const int m_spaceOrder; ///< Spatial-order of accuracy - must be 4 00568 00569 //--AMR tools 00570 00571 FourthOrderMappedFineInterp* m_interpolator; 00572 ///< Constrained least-squares 00573 ///< interpolator for interpolating <JU> 00574 ///< from coarse to fine meshes. 'This' 00575 ///< mesh is the coarse mesh. 00576 00577 //--Multiblock tools 00578 00579 ProblemDomain m_cachedBlockDomain; ///< Representing only the block (it is 00580 ///< assumed periodic boundaries are not 00581 ///< used for multiblock) 00582 int m_cachedBlockIdx; ///< Index of the cached block 00583 int m_cachedBlockNG; ///< Number of ghosts that the cached 00584 ///< block was grown by. 00585 MultiBlockLevelGeom m_mbgeo; ///< Topology of the multiblock layout 00586 MultiBlockLevelExchangeAverage m_mbex; 00587 ///< To exchange information across 00588 ///< multiblock boundaries 00589 MultiBlockFaceRegister* m_Nmbreg; ///< Flux-like register for resolving 00590 ///< \f$\mathbf{N}\f$ on faces at coarse- 00591 ///< fine interfaces that overlap 00592 ///< multiblock boundaries 00593 MultiBlockFaceRegister* m_NtXmbreg[AgeNum]; 00594 ///< Flux-like register for resolving 00595 ///< \f$\mathbf{N}^T\mathbf{X}\f$ on faces 00596 ///< at coarse-fine interfaces that 00597 ///< overlap multiblock boundaries 00598 00599 //--Miscellaneous/flags 00600 00601 TransverseNOpType m_transverseNOpType; 00602 ///< Type of operatation for computing 00603 ///< transverse terms in N 00604 bool m_metricsChanged; ///< T - The metrics on this level have 00605 ///< changed 00606 bool m_metricsDefined; ///< T - The metrics have been defined for 00607 ///< this level 00608 bool m_useScriptN; ///< For some mappings, it is not possible 00609 ///< to define scriptN. In those cases, 00610 ///< N is calculated and averaged 00611 ///< directly. The solution is 00612 ///< conservative but freestream- 00613 ///< preservation is lost across coarse- 00614 ///< fine interfaces. 00615 ///< T - Script N is used (default). 00616 ///< F - Script N is not used. N is 00617 ///< calculated directly and 00618 ///< freestream preservation is lost 00619 bool m_isMultiblock; ///< T - A multiblock coordinates system 00620 bool m_haveMultiBlockVectorData; ///< T - Space vector data will be 00621 ///< exchanged across multiblock 00622 ///< boundaries 00623 00624 static int s_verbosity; 00625 }; 00626 00627 00628 /******************************************************************************* 00629 * 00630 * Class LevelGridMetrics: inline member definitions 00631 * 00632 ******************************************************************************/ 00633 00634 /*--------------------------------------------------------------------*/ 00635 // Are the metrics defined on this level? 00636 /** After preRegrid, this also indicates if a level is used. 00637 * \return T - yes. 00638 *//*-----------------------------------------------------------------*/ 00639 00640 inline bool 00641 LevelGridMetrics::metricsDefined() const 00642 { 00643 return m_metricsDefined; 00644 } 00645 00646 /*--------------------------------------------------------------------*/ 00647 // Did the metrics change on the finer mesh? 00648 /** \return T - yes. 00649 *//*-----------------------------------------------------------------*/ 00650 00651 inline bool 00652 LevelGridMetrics::didFinerChange() const 00653 { 00654 return m_finerLevelGridMetrics->m_metricsChanged; 00655 } 00656 00657 /*--------------------------------------------------------------------*/ 00658 // Get the coordinate system 00659 /** \param[in] box Assigned to this box 00660 *//*-----------------------------------------------------------------*/ 00661 00662 inline const NewCoordSys* 00663 LevelGridMetrics::getCoordSys2(const Box& box) const 00664 { 00665 return m_coordSys->getCoordSys(box); 00666 } 00667 00668 inline const MultiBlockCoordSys& 00669 LevelGridMetrics::getCoordSys() const 00670 { 00671 return *m_coordSys; 00672 } 00673 00674 #if 0 00675 /*--------------------------------------------------------------------*/ 00676 // Get the coordinate system 00677 /** \param[in] dit Assigned to this data iterator 00678 *//*-----------------------------------------------------------------*/ 00679 00680 inline const NewCoordSys* 00681 LevelGridMetrics::getCoordSys2(const DataIterator& dit) const 00682 { 00683 return m_coordSys->getCoordSys(m_grids[dit()]); 00684 } 00685 #endif 00686 00687 /*--------------------------------------------------------------------*/ 00688 // Get the "fourth-order" coordinate system 00689 /** \param[in] box Assigned to this box 00690 *//*-----------------------------------------------------------------*/ 00691 00692 inline const NewFourthOrderCoordSys* 00693 LevelGridMetrics::getCoordSys(const Box& box) const 00694 { 00695 return static_cast<const NewFourthOrderCoordSys*>(m_coordSys->getCoordSys(box)); 00696 } 00697 00698 #if 0 00699 /*--------------------------------------------------------------------*/ 00700 // Get the "fourth-order" coordinate system 00701 /** \param[in] dit Assigned to this data iterator 00702 *//*-----------------------------------------------------------------*/ 00703 00704 inline const NewFourthOrderCoordSys* 00705 LevelGridMetrics::getCoordSys(const DataIterator& dit) const 00706 { 00707 return static_cast<const NewFourthOrderCoordSys*>(m_coordSys->getCoordSys(m_grids[dit()])); 00708 } 00709 #endif 00710 00711 /*--------------------------------------------------------------------*/ 00712 // Get the block index 00713 /** \param[in] a_box Assigned to this interior box 00714 * \return Block index 00715 *//*-----------------------------------------------------------------*/ 00716 00717 inline int 00718 LevelGridMetrics::getBlock(const Box& a_box) const 00719 { 00720 return m_coordSys->whichBlock(a_box); 00721 } 00722 00723 /*--------------------------------------------------------------------*/ 00724 // Get a problem domain representing a block 00725 /** \param[in] a_box Assigned to this interior box 00726 * \param[in] a_numGhost 00727 * The number of ghosts that the box representing 00728 * the block should be grown by before cropping. 00729 * Cropping *only* occurs at boundaries defined 00730 * by the physical domain 00731 * \return If singleblock, the problem domain. If 00732 * multiblock, non-periodic problem domain 00733 * representing the block 00734 * \note 00735 * <ul> 00736 * <li> If single block, the problem domain must be cached when 00737 * the coordSys is defined 00738 * </ul> 00739 *//*-----------------------------------------------------------------*/ 00740 00741 inline const ProblemDomain& 00742 LevelGridMetrics::blockDomain(const Box& a_box, const int a_numGhost) 00743 { 00744 if (isMultiblock()) 00745 { 00746 CH_assert(a_numGhost >= 0); 00747 const int iBlock = getBlock(a_box); 00748 CH_assert(iBlock >= 0); 00749 if (iBlock != m_cachedBlockIdx || a_numGhost != m_cachedBlockNG) 00750 { 00751 m_cachedBlockIdx = iBlock; 00752 m_cachedBlockNG = a_numGhost; 00753 // Find the problem domain representing the block 00754 Box grownBlock = 00755 grow(m_coordSys->mappingBlocks()[iBlock], a_numGhost); 00756 if (a_numGhost > 0) 00757 { 00758 m_coordSys->keepInDomain(grownBlock, iBlock); 00759 } 00760 m_cachedBlockDomain.define(grownBlock); 00761 } 00762 } 00763 return m_cachedBlockDomain; 00764 } 00765 00766 /*--------------------------------------------------------------------*/ 00767 // Get the computational mesh spacing 00768 /** \return Mesh spacing in each direction 00769 *//*-----------------------------------------------------------------*/ 00770 00771 inline const RealVect& 00772 LevelGridMetrics::dxVect() const 00773 { 00774 return m_dxVect; 00775 } 00776 00777 00778 /*====================================================================*/ 00779 /** \name Consistent access to structural boxes 00780 * 00781 * There are several places to get the boxes and interators from but 00782 * all should be the same. These functions provide consistent 00783 * access with sizes relevant to the metrics. 00784 *//*=================================================================*/ 00785 //@{ 00786 00787 // Get the boxes 00788 inline const DisjointBoxLayout& 00789 LevelGridMetrics::getBoxes() const 00790 { 00791 return m_grids; 00792 } 00793 00794 // Get a level iterator 00795 inline DataIterator 00796 LevelGridMetrics::getDataIterator() const 00797 { 00798 return getBoxes().dataIterator(); 00799 } 00800 00801 // Resize a box to include the ghost cells (defines J) 00802 inline Box 00803 LevelGridMetrics::resizeWithGhosts(const Box& box) const 00804 { 00805 return grow(box, m_ghostVect); 00806 } 00807 00808 // Determine the ghost vector required for \f$J\f$. 00809 /** This is +1 over the ghost box to allow for derivatives needed 00810 * to manipulate products 00811 */ 00812 inline IntVect 00813 LevelGridMetrics::getJReqGhostVect() const 00814 { 00815 return IntVect::Unit; 00816 } 00817 00818 // Determine the ghost vector required for \f$N\f$. 00819 /** This is +2 over the ghost box to allow for tangential derivatives needed 00820 * to compute the volume flux 00821 */ 00822 inline IntVect 00823 LevelGridMetrics::getNReqGhostVect() const 00824 { 00825 return 2*IntVect::Unit; 00826 } 00827 00828 // Resize a box to the size required for \f$J\f$ 00829 inline Box 00830 LevelGridMetrics::resizeWithJReqGhosts(const Box& box) const 00831 { 00832 return grow(box, getJReqGhostVect()); 00833 } 00834 00835 // Resize a box to the size required for \f$N\f$ 00836 inline Box 00837 LevelGridMetrics::resizeWithNReqGhosts(const Box& box) const 00838 { 00839 return grow(box, getNReqGhostVect()); 00840 } 00841 //@} 00842 00843 00844 /*====================================================================*/ 00845 /** \name Easier access to AMRLevel data 00846 *//*=================================================================*/ 00847 //@{ 00848 00849 inline int 00850 LevelGridMetrics::level() const 00851 { 00852 return m_parentAMRLevel->level(); 00853 } 00854 00855 inline int 00856 LevelGridMetrics::refRatio() const 00857 { 00858 return m_parentAMRLevel->refRatio(); 00859 } 00860 00861 inline const ProblemDomain& 00862 LevelGridMetrics::problemDomain() const 00863 { 00864 return m_parentAMRLevel->problemDomain(); 00865 } 00866 //@} 00867 00868 /*--------------------------------------------------------------------*/ 00869 // Set the coarsened-fine <U> used by the interpolator (CrFn access) 00870 /** Grids must have been defined for the interpolator. Returns a 00871 * coarsening of 'this' level to be filled externally using a copyTo. 00872 * 'this' is the fine level. I.e., 'this' is the fine level. 00873 *//*-----------------------------------------------------------------*/ 00874 00875 inline LevelData<FArrayBox>& 00876 LevelGridMetrics::presetCr2ThisInterpolatorCrFnLevU() 00877 { 00878 CH_assert(hasCoarser()); 00879 return m_coarserLevelGridMetrics->m_interpolator->presetCrFnLevU(); 00880 } 00881 00882 /*--------------------------------------------------------------------*/ 00883 // Set the coarsened-fine <JU> used by the interpolator (CrFn access) 00884 /** Grids must have been defined for the interpolator. Returns a 00885 * coarsening of 'this' level to be filled externally using a copyTo. 00886 * 'this' is the fine level. I.e., 'this' is the fine level. 00887 *//*-----------------------------------------------------------------*/ 00888 00889 inline LevelData<FArrayBox>& 00890 LevelGridMetrics::presetCr2ThisInterpolatorCrFnLevJU() 00891 { 00892 CH_assert(hasCoarser()); 00893 return m_coarserLevelGridMetrics->m_interpolator->presetCrFnLevJU(); 00894 } 00895 00896 // Obsolete 00897 // /*--------------------------------------------------------------------*/ 00898 // // Get the coarsened-fine <U> used by the interpolator 00899 // /** Grids must have been defined for the interpolator. Returns a 00900 // * coarsening of 'this' level. I.e., 'this' is the fine level. 00901 // *//*-----------------------------------------------------------------*/ 00902 00903 // inline const LevelData<FArrayBox>& 00904 // LevelGridMetrics::getCr2ThisInterpolatorCrFnLevU() const 00905 // { 00906 // CH_assert(hasCoarser()); 00907 // return m_coarserLevelGridMetrics->m_interpolator.getCrFnLevU(); 00908 // } 00909 00910 // /*--------------------------------------------------------------------*/ 00911 // // Get the coarsened-fine <JU> used by the interpolator 00912 // /** Grids must have been defined for the interpolator. Returns a 00913 // * coarsening of 'this' level. I.e., 'this' is the fine level. 00914 // *//*-----------------------------------------------------------------*/ 00915 00916 // inline const LevelData<FArrayBox>& 00917 // LevelGridMetrics::getCr2ThisInterpolatorCrFnLevJU() const 00918 // { 00919 // CH_assert(hasCoarser()); 00920 // return m_coarserLevelGridMetrics->m_interpolator.getCrFnLevJU(); 00921 // } 00922 00923 /*--------------------------------------------------------------------*/ 00924 // Set the coarsened-fine <U> used by the interpolator 00925 /** Grids must have been defined for the interpolator. Copies the 00926 * coarse data from 'this' level to the coarsened-fine representation 00927 * in the interpolator. 'this' is the coarse level. 00928 * \param[in] a_CrU <U> on the coarse level 00929 * \param[in] a_vectorIntv 00930 * An interval in components of U consisting of 00931 * vector data 00932 *//*-----------------------------------------------------------------*/ 00933 00934 inline void 00935 LevelGridMetrics::presetThis2FnInterpolatorCrFnLevU( 00936 const LevelData<FArrayBox>& a_CrLevU, 00937 const Interval& a_vectorIntv) 00938 { 00939 CH_assert(hasFiner()); 00940 m_interpolator->presetCrFnLevU(a_CrLevU, a_vectorIntv); 00941 } 00942 00943 // Should not be used 00944 // /*--------------------------------------------------------------------*/ 00945 // // Set the coarsened-fine <JU> used by the interpolator 00946 // /** Grids must have been defined for the interpolator. Copies the 00947 // * coarse data from 'this' level to the coarsened-fine representation 00948 // * in the interpolator. 'this' is the coarse level. 00949 // *//*-----------------------------------------------------------------*/ 00950 00951 // inline void 00952 // LevelGridMetrics::presetThis2FnInterpolatorCrFnLevJU( 00953 // const LevelData<FArrayBox>& a_CrLevJU) 00954 // { 00955 // CH_assert(hasFiner()); 00956 // m_interpolator.presetCrFnLevJU(a_CrLevJU); 00957 // } 00958 00959 /*--------------------------------------------------------------------*/ 00960 // Invalidate the CrFn data, both <U> and <JU>, used by the 00961 // interpolator 00962 /** 'this' is the fine level. If data goes out-of-date on the coarser 00963 * level, then the interpolator, for interpolating to 'this' level, 00964 * has out-of-date coarsened-fine data. There must be a coarser 00965 * level 00966 *//*-----------------------------------------------------------------*/ 00967 00968 inline void 00969 LevelGridMetrics::invalidateCr2ThisInterpolatorCrFnLevData() 00970 { 00971 CH_assert(hasCoarser()); 00972 m_coarserLevelGridMetrics->m_interpolator->invalidateCrFnLevData(); 00973 } 00974 00975 /*--------------------------------------------------------------------*/ 00976 // Invalidate the CrFn data, both <U> and <JU>, used by the 00977 // interpolator 00978 /** 'this' is the coarse level. If data goes out-of-date on 'this' 00979 * level, then the interpolator, for interpolating to the next finer 00980 * level, has out-of-date coarsened-fine data. You can invalidate 00981 * even if there is no finer level. 00982 *//*-----------------------------------------------------------------*/ 00983 00984 inline void 00985 LevelGridMetrics::invalidateThis2FnInterpolatorCrFnLevData() 00986 { 00987 m_interpolator->invalidateCrFnLevData(); 00988 } 00989 00990 /*--------------------------------------------------------------------*/ 00991 // Number of ghosts used to build the coarsened-fine data in the 00992 // interpolator 00993 /** \param[in] a_force T - avoid assertion checking. 00994 * F - (default) 00995 * \note 00996 * <ul> 00997 * <li> The caller should ensure that a finer level exists if the 00998 * assertion is disabled. Commonly, the return value is 00999 * required inbetween initialGrid() and postInitialGrid() 01000 * where the metrics have not yet been defined (so the 01001 * assertion would fail) but the grid has been defined (so 01002 * this value is known). 01003 * </ul> 01004 *//*-----------------------------------------------------------------*/ 01005 01006 inline const IntVect& 01007 LevelGridMetrics::interpolatorCrFnNumGhost(const bool a_force) const 01008 { 01009 if (!a_force) 01010 { 01011 CH_assert(hasFiner()); 01012 } 01013 return m_interpolator->CrFnNumGhost(); 01014 } 01015 01016 /*--------------------------------------------------------------------*/ 01017 // Is this a multiblock grid? 01018 /** \return T - Yes 01019 *//*-----------------------------------------------------------------*/ 01020 01021 inline bool 01022 LevelGridMetrics::isMultiblock() const 01023 { 01024 return m_isMultiblock; 01025 } 01026 01027 #include "NamespaceFooter.H" 01028 #endif
1.5.5