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 _MESHREFINE_H_ 00012 #define _MESHREFINE_H_ 00013 00014 #include <climits> 00015 00016 #include "Vector.H" 00017 #include "Box.H" 00018 #include "IntVectSet.H" 00019 #include "REAL.H" 00020 #include "ProblemDomain.H" 00021 #include "NamespaceHeader.H" 00022 00023 // Constants: 00024 00025 /// Class which manages grid generation 00026 class MeshRefine 00027 /** 00028 This class manages grid generation from sets of tagged cells. It is 00029 designed to be a pure virtual base class from which another class 00030 may be derived with a specific grid-generation algorithm (for example, 00031 the BRMeshRefine class). 00032 00033 There are two ways grids can be defined based on tagged cells. 00034 one takes a single IntVectSet of tags defined on the BaseLevel 00035 mesh and uses that set of tags for every level to be refined; 00036 the other takes a Vector<IntVectSet> of tags defined on all the 00037 mesh levels to be refined and uses those. 00038 00039 <b> Long Description: </b> 00040 00041 Create new meshes based on tagged cells on a range of levels of a mesh 00042 hierarchy. Each level of tagged cells is used to generate a new mesh at 00043 the next finer level. The finest level in the output mesh will be one 00044 level higher than the top of the range of levels given as input. As a 00045 special case, use the same tags (appropriately refined) for all levels. 00046 00047 \b Usage: 00048 00049 Call the regrid functions after computing error estimates and tagging cells. 00050 To add a new mesh level, set TopLevel to the index of the finest level 00051 in the existing mesh and define tags on the finest level. To keep the 00052 existing number of mesh levels, set TopLevel to one less than the 00053 index of the finest level and don't define any tags on the finest level. 00054 If a single IntVectSet of tags is passed (instead of a 00055 Vector<IntVectSet>) then the same tags (properly refined) will be used 00056 for all the new meshes up to level TopLevel+1. In any case, the 00057 meshes at levels BaseLevel and below are not modified. The output 00058 argument newmeshes will be reallocated to the necessary size before 00059 being used. When this function returns, the elements of the 00060 newmeshes vector corresponding to the unchanged levels will be 00061 filled in with copies of the levels from the old mesh vector. The 00062 variable tags is modified in an undefined way, so its contents 00063 should not be relied upon. The variable BlockFactor specifies the 00064 amount by which each box will be coarsenable. Every grid box will 00065 have an integral multiple of BlockFactor cells in each dimension and 00066 also lower index values that are integral multiples. As a side effect, 00067 the minimum box size will be BlockFactor. 00068 00069 Expensive validations are done only when debugging is enabled 00070 (i.e. the DEBUG make variable is "TRUE"). 00071 00072 <b> Usage Notes: </b> 00073 00074 All the input vectors should be defined with max index >= TopLevel. 00075 They should have values for indices [BaseLevel:TopLevel]. 00076 (except for OldMeshes, which must be defined for all indices). The 00077 new mesh vector newmeshes will be redefined up to index 00078 TopLevel+1. RefRatios should be defined such that 00079 RefRatios[L] is the value to use to refine the level L mesh to 00080 produce the level L+1 mesh. The tags vector is modified in an 00081 undefined manner. The output variable newmeshes may not be 00082 completely defined if an exception occurs. 00083 The BlockFactor can be used to force a minimum box size. 00084 */ 00085 { 00086 public: 00087 /// default constructor -- leaves object in an unusable state 00088 MeshRefine(); 00089 00090 /// full constructor -- leaves object in usable state 00091 MeshRefine(/// level 0 domain 00092 const Box& a_baseDomain, 00093 /// refinement ratios -- refRatio[0] is btwn levels 0 and 1 00094 const Vector<int>& a_refRatios, 00095 /// measure of how efficiently tagged cells will be covered 00096 const Real a_fillRatio, 00097 /// amount by which grids are guaranteed to be coarsenable 00098 const int a_blockFactor, 00099 /// proper nesting buffer amount 00100 const int a_bufferSize, 00101 /// maximum grid length in any direction -- 0 means no limit. 00102 const int a_maxSize); 00103 00104 /// full constructor -- leaves object in usable state 00105 MeshRefine(/// level 0 domain 00106 const ProblemDomain& a_baseDomain, 00107 /// refinement ratios -- refRatio[0] is btwn levels 0 and 1 00108 const Vector<int>& a_refRatios, 00109 /// measure of how efficiently tagged cells will be covered 00110 const Real a_fillRatio, 00111 /// amount by which grids are guaranteed to be coarsenable 00112 const int a_blockFactor, 00113 /// proper nesting buffer amount 00114 const int a_bufferSize, 00115 /// maximum grid length in any direction -- 0 means no limit. 00116 const int a_maxSize); 00117 00118 /// destructor 00119 virtual ~MeshRefine(); 00120 00121 /// define function -- size of RefRatios will define maximum number of levels 00122 void define(/// level 0 domain 00123 const Box& a_baseDomain, 00124 /// refinement ratios -- refRatio[0] is btwn levels 0 and 1 00125 const Vector<int>& a_refRatios, 00126 /// measure of how efficiently tagged cells will be covered 00127 const Real a_fillRatio, 00128 /// amount by which grids are guaranteed to be coarsenable 00129 const int a_blockFactor, 00130 /// proper nesting buffer amount 00131 const int a_bufferSize, 00132 /// maximum grid length in any direction -- 0 means no limit 00133 const int a_maxSize); 00134 00135 /// define function -- size of RefRatios will define maximum number of levels 00136 virtual void define(/// level 0 domain 00137 const ProblemDomain& a_baseDomain, 00138 /// refinement ratios -- refRatio[0] is btwn levels 0 and 1 00139 const Vector<int>& a_refRatios, 00140 /// measure of how efficiently tagged cells will be covered 00141 const Real a_fillRatio, 00142 /// amount by which grids are guaranteed to be coarsenable 00143 const int a_blockFactor, 00144 /// proper nesting buffer amount 00145 const int a_bufferSize, 00146 /// maximum grid length in any direction -- 0 means no limit 00147 const int a_maxSize); 00148 00149 ///create hierarchy of grids from a single level of tags 00150 /** This function creates a hierarchy of grids from a single level of 00151 tags on BaseLevel. If tags exist, then all levels will have grids. 00152 Returns the new finest level of grids. 00153 00154 If m_refineDirs != IntVect::Unit, then a_tags and a_oldMeshes must have 00155 ranges restricted to 0 in all dimensions d with m_refineDirs[d] == 0, 00156 and the output a_newmeshes will have this same restriction. 00157 */ 00158 virtual int regrid(/// new set of grids at every level 00159 Vector<Vector<Box> >& a_newmeshes, 00160 /// tagged cells on baseLevel 00161 const IntVectSet& a_tags, 00162 /// index of base mesh level (finest unchanged level) 00163 const int a_baseLevel, 00164 /// top level to refine (one less than finest possible level) 00165 const int a_topLevel, 00166 /// existing grids (if no previous grids, set to domains) 00167 const Vector<Vector<Box> >& a_oldMeshes); 00168 00169 /// create hierarchy of grids from tags at all levels 00170 /** This function creates a hierarchy of grids from tags at all 00171 refinement levels. It is possible that not all levels will 00172 return with grids, since there may not be tags at all levels. 00173 Returns the new finest level of grids. 00174 00175 If m_refineDirs != IntVect::Unit, then a_tags and a_oldMeshes must have 00176 ranges restricted to 0 in all dimensions d with m_refineDirs[d] == 0, 00177 and the output a_newmeshes will have this same restriction. 00178 */ 00179 virtual int regrid(/// new set of grids at every level 00180 Vector<Vector<Box> >& a_newmeshes, 00181 /// tagged cells on each existing level 00182 Vector<IntVectSet>& a_tags, 00183 /// index of base mesh level (finest unchanged level) 00184 const int a_baseLevel, 00185 /// top level to refine (one less than finest possible level) 00186 const int a_topLevel, 00187 /// existing grids (if no previous grids, set to domains) 00188 const Vector<Vector<Box> >& a_oldMeshes); 00189 00190 // Access functions 00191 00192 /// returns vector of refinement ratios 00193 const Vector<int>& refRatios() const; 00194 00195 /// returns fillRatio 00196 Real fillRatio() const; 00197 00198 /// returns blocking factor 00199 int blockFactor() const; 00200 00201 /// returns proper nesting buffer size 00202 int bufferSize() const; 00203 00204 /// returns maximum box size in any dimension -- 0 means no limit 00205 int maxSize() const; 00206 00207 /// sets vector of refinement ratios 00208 void refRatios(const Vector<int>& a_nRefVect); 00209 00210 /// sets fillRatio 00211 virtual void fillRatio(const Real a_fill_ratio); 00212 00213 /// sets blocking factor 00214 virtual void blockFactor(const int a_block_factor); 00215 00216 /// sets proper nesting buffer size 00217 virtual void bufferSize(const int a_buffer_size); 00218 00219 /// sets maximum box size in any dimension -- 0 means no limit 00220 virtual void maxSize(const int a_max_size); 00221 00222 /// has this object been defined properly? 00223 bool isDefined() const; 00224 00225 /// sets proper nesting region granularity. 00226 void granularity(int a_granularity); 00227 00228 /// constructs a set of boxes which covers a set of tagged cells 00229 /** constructs a set of boxes which covers a set of tagged cells 00230 by using the algorithm of choice. Everything should 00231 be on the same level, and blocking factor is not applied. 00232 Boxes will be on the same refinement level as the tags. 00233 This would normally be a protected function, but it can be useful 00234 to call it on its own, so it has been left public. 00235 */ 00236 virtual void 00237 makeBoxes(/// output: refined boxes at each new level 00238 Vector<Box>& a_mesh, 00239 /// input: set of tagged cells to cover 00240 const IntVectSet& a_tags, 00241 /// input: proper nesting domain in which mesh boxes must live 00242 const IntVectSet& a_pnd, 00243 /// input: physical domain 00244 const ProblemDomain& a_domain, 00245 ///input: largest number of cells in any dimension for any box 00246 const int a_maxSize, 00247 const int a_totalBufferSize) const = 0; 00248 00249 void setPNDMode(int a_mode); 00250 00251 /// set each component to 1 or 0 according to whether or not we refine in that direction. Default IntVect::Unit. 00252 void setRefineDirs(const IntVect& a_refineDirs); 00253 00254 /// returns IntVect with component d set to a_val if m_refineDirs[d] == 1; else 1. 00255 IntVect inRefineDirs(int a_val) const; 00256 00257 // intersects the Box with the hyperplane of 0 in dimensions where m_refineDirs == 0 00258 void restrictUnrefined(Box& a_box) const; 00259 00260 // intersects the IntVectSet with the hyperplane of 0 in dimensions where m_refineDirs == 0 00261 void restrictUnrefined(IntVectSet& a_ivs) const; 00262 00263 protected: 00264 00265 /// computes local blockFactors used internally to enforce the BlockFactor 00266 /** This function computes values for m_local_blockfactors array, which 00267 is the amount that tags on a level are coarsened in order to guarantee 00268 that the grids on the next finer level are coarsenable by the 00269 BlockFactor. */ 00270 virtual void 00271 computeLocalBlockFactors(); 00272 00273 virtual bool properlyNested(const Box& a_box, 00274 const ProblemDomain& a_domain, 00275 const IntVectSet& a_pnd, 00276 int a_totalBuffer) const; 00277 00278 /// Computes proper nesting domains. 00279 /** 00280 This should only be 00281 called by refine. it assumes that everything has already been 00282 coarsened by the local blocking factor 00283 */ 00284 virtual void 00285 makePNDs(///output: proper nesting domains at each level 00286 Vector<IntVectSet>& a_pnds, 00287 Vector<int>& a_totalBufferSize, 00288 /// input: index of highest AMR level not to be refined 00289 const int a_baseLevel, 00290 /// input: index of highest AMR level in output 00291 const int a_topLevel, 00292 /// input: (same as in \em meshRefine) 00293 const Vector<ProblemDomain>& a_domains, 00294 /// input: boxes at mesh level \em BaseLevel 00295 const IntVectSet& a_baseMesh, 00296 ///input: (similar to \em meshRefine; but with level-dependent coarsening factors) 00297 const Vector<int>& a_bufferSize ) const; 00298 00299 virtual void 00300 makePNDs(///output: proper nesting domains at each level 00301 Vector<IntVectSet>& a_pnds, 00302 Vector<int>& a_totalBufferSize, 00303 /// input: index of highest AMR level not to be refined 00304 const int a_baseLevel, 00305 /// input: index of highest AMR level in output 00306 const int a_topLevel, 00307 /// input: (same as in \em meshRefine) 00308 const Vector<ProblemDomain>& a_domains, 00309 /// input: boxes at mesh level \em BaseLevel 00310 const Vector<Box>& a_baseMesh, 00311 ///input: (similar to \em meshRefine; but with level-dependent coarsening factors) 00312 const Vector<int>& a_bufferSize ) const; 00313 00314 virtual void buildSupport(const ProblemDomain& lvldomain, Vector<Box>& lvlboxes, IntVectSet& modifiedTags); 00315 00316 virtual void clipBox(Box& a_box, const ProblemDomain& a_domain) const ; 00317 // local data members 00318 00319 bool m_isDefined; 00320 00321 Vector<ProblemDomain> m_vectDomains; 00322 00323 Vector<IntVectSet> m_pnds; 00324 int m_lastBase; 00325 int m_lastTop; 00326 int m_lastBuffer; 00327 00328 Vector<int> m_nRefVect; 00329 00330 Real m_fillRatio; 00331 00332 int m_blockFactor; 00333 00334 Vector<int> m_level_blockfactors; 00335 00336 int m_bufferSize; 00337 00338 int m_maxSize; 00339 00340 int m_granularity; 00341 00342 int m_PNDMode; 00343 00344 // component 1 if refining in this dimension, 0 if not. Default IntVect::Unit. 00345 IntVect m_refineDirs; 00346 00347 // Lowest d such that m_refineDirs[d] == 1. Default 0. 00348 int m_lowestRefineDir; 00349 }; 00350 00351 #include "NamespaceFooter.H" 00352 #endif