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 _BRMESHREFINE_H_ 00012 #define _BRMESHREFINE_H_ 00013 00014 #include <climits> 00015 00016 #include "Vector.H" 00017 #include "Box.H" 00018 #include "IntVectSet.H" 00019 #include "REAL.H" 00020 #include "MeshRefine.H" 00021 #include "Interval.H" 00022 #include <list> 00023 #include "NamespaceHeader.H" 00024 00025 // Constants: 00026 00027 // Minimum acceptable ratio of tagged cells to total cells for 00028 // the Berger-Rigoutsos algorithm in \func{makeBoxes}. 00029 // Used as default for \var{FillRatio} optional argument. 00030 #ifndef _BR_MIN_BOX_FILL_RATIO_ 00031 #define _BR_MIN_BOX_FILL_RATIO_ ( 0.75 ) 00032 #endif 00033 00034 /// Class which manages Berger-Rigoutsos grid generation 00035 /** 00036 This class manages grid generation from sets of tagged cells using the 00037 Berger-Rigoutsos algorithm in the context of the MeshRefine class 00038 from which it is derived 00039 00040 There are two ways grids can be defined based on tagged cells. 00041 one takes a single IntVectSet of tags defined on the BaseLevel 00042 mesh and uses that set of tags for every level to be refined; 00043 the other takes a Vector<IntVectSet> of tags defined on all the 00044 mesh levels to be refined and uses those. 00045 00046 <b> Long Description: </b> 00047 00048 Create new meshes based on tagged cells on a range of levels of a mesh 00049 hierarchy. Each level of tagged cells is used to generate a new mesh at 00050 the next finer level. The finest level in the output mesh will be one 00051 level higher than the top of the range of levels given as input. As a 00052 special case, use the same tags (appropriately refined) for all levels. 00053 00054 \b Usage: 00055 00056 Call the regrid functions after computing error estimates and tagging cells. 00057 To add a new mesh level, set TopLevel to the index of the finest level 00058 in the existing mesh and define tags on the finest level. To keep the 00059 existing number of mesh levels, set TopLevel to one less than the 00060 index of the finest level and don't define any tags on the finest level. 00061 If a single IntVectSet of tags is passed (instead of a 00062 Vector<IntVectSet>) then the same tags (properly refined) will be used 00063 for all the new meshes up to level TopLevel+1. In any case, the 00064 meshes at levels BaseLevel and below are not modified. The output 00065 argument newmeshes will be reallocated to the necessary size before 00066 being used. When this function returns, the elements of the 00067 newmeshes vector corresponding to the unchanged levels will be 00068 filled in with copies of the levels from the old mesh vector. The 00069 variable tags is modified in an undefined way, so its contents 00070 should not be relied upon. The variable BlockFactor specifies the 00071 amount by which each box will be coarsenable. Every grid box will 00072 have an integral multiple of BlockFactor cells in each dimension and 00073 also lower index values that are integral multiples. As a side effect, 00074 the minimum box size will be BlockFactor. 00075 00076 Expensive validations are done only when debugging is enabled 00077 (i.e. the DEBUG make variable is "TRUE"). 00078 00079 <b> Usage Notes: </b> 00080 00081 All the input vectors should be defined with max index >= TopLevel. 00082 They should have values for indices [BaseLevel:TopLevel]. 00083 (except for OldMeshes, which must be defined for all indices). The 00084 new mesh vector newmeshes will be redefined up to index 00085 TopLevel+1. RefRatios should be defined such that 00086 RefRatios[L] is the value to use to refine the level L mesh to 00087 produce the level L+1 mesh. The tags vector is modified in an 00088 undefined manner. The output variable newmeshes may not be 00089 completely defined if an exception occurs. 00090 The BlockFactor can be used to force a minimum box size. 00091 */ 00092 class BRMeshRefine : public MeshRefine 00093 { 00094 public: 00095 /// Default constructor -- leaves object in an unusable state 00096 BRMeshRefine(); 00097 00098 /// Full constructor -- leaves object in usable state 00099 BRMeshRefine(/// Level 0 domain 00100 const Box& a_baseDomain, 00101 /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1 00102 const Vector<int>& a_refRatios, 00103 /// Measure of how efficiently tagged cells will be covered 00104 const Real a_fillRatio, 00105 /// Amount by which grids are guaranteed to be coarsenable 00106 const int a_blockFactor, 00107 /// Proper nesting buffer amount 00108 const int a_bufferSize, 00109 /// Maximum grid length in any direction -- 0 means no limit. 00110 const int a_maxSize); 00111 00112 /// Full constructor -- leaves object in usable state 00113 BRMeshRefine(/// Level 0 domain 00114 const ProblemDomain& a_baseDomain, 00115 /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1 00116 const Vector<int>& a_refRatios, 00117 /// Measure of how efficiently tagged cells will be covered 00118 const Real a_fillRatio, 00119 /// Amount by which grids are guaranteed to be coarsenable 00120 const int a_blockFactor, 00121 /// Proper nesting buffer amount 00122 const int a_bufferSize, 00123 /// Maximum grid length in any direction -- 0 means no limit. 00124 const int a_maxSize); 00125 00126 /// Destructor 00127 virtual ~BRMeshRefine(); 00128 00129 /// Define function -- size of RefRatios will define maximum number of levels 00130 void define(/// Level 0 domain 00131 const Box& a_baseDomain, 00132 /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1 00133 const Vector<int>& a_refRatios, 00134 /// Measure of how efficiently tagged cells will be covered 00135 const Real a_fillRatio, 00136 /// Amount by which grids are guaranteed to be coarsenable 00137 const int a_blockFactor, 00138 /// Proper nesting buffer amount 00139 const int a_bufferSize, 00140 /// Maximum grid length in any direction -- 0 means no limit 00141 const int a_maxSize); 00142 00143 /// Define function -- size of RefRatios will define maximum number of levels 00144 void define(/// :evel 0 domain 00145 const ProblemDomain& a_baseDomain, 00146 /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1 00147 const Vector<int>& a_refRatios, 00148 /// Measure of how efficiently tagged cells will be covered 00149 const Real a_fillRatio, 00150 /// Amount by which grids are guaranteed to be coarsenable 00151 const int a_blockFactor, 00152 /// Proper nesting buffer amount 00153 const int a_bufferSize, 00154 /// Maximum grid length in any direction -- 0 means no limit 00155 const int a_maxSize); 00156 00157 /// Constructs a set of boxes which covers a set of tagged cells 00158 /** Constructs a set of boxes which covers a set of tagged cells 00159 by using the Berger-Rigoutsos algorithm. Everything should 00160 be on the same level, and blocking factor is not applied. 00161 Boxes will be on the same refinement level as the tags. 00162 This would normally be a protected function, but it can be useful 00163 to call it on it's own, so it has been left public. 00164 */ 00165 void 00166 makeBoxes(/// Putput: refined boxes at each new level 00167 Vector<Box>& a_mesh, 00168 /// Input: set of tagged cells to cover 00169 const IntVectSet& a_tags, 00170 /// Input: proper nesting domain in which mesh boxes must live 00171 const IntVectSet& a_pnd, 00172 /// Input: physical domain 00173 const ProblemDomain& a_domain, 00174 /// Input: largest number of cells in any dimension for any box 00175 const int a_maxSize, 00176 const int a_totalBufferSize) const; 00177 00178 00179 00180 /** 00181 Function which actually implement Berger-Rigoutsos chopping. 00182 */ 00183 void 00184 makeBoxes(/// Output: refined boxes at each new level 00185 std::list<Box>& a_mesh, 00186 /// Input: set of tagged cells to cover 00187 IntVectSet& a_tags, 00188 /// Input: proper nesting domain in which mesh boxes must live 00189 const IntVectSet& a_pnd, 00190 /// Input: physical domain 00191 const ProblemDomain& a_domain, 00192 /// Input: largest number of cells in any dimension for any box 00193 const int a_maxSize, 00194 /// Input: depth of this recursion in the algorithm 00195 const int a_depth, 00196 const int a_totalBufferSize 00197 ) const; 00198 00199 protected: 00200 00201 /** 00202 */ 00203 void 00204 splitBox(std::list<Box> & a_boxes , 00205 const std::list<Box>::iterator& a_boxindex, 00206 const int a_dimension ,const int a_maxboxsize ) const; 00207 00208 void 00209 splitBox(std::list<Box> & a_boxes , 00210 const std::list<Box>::iterator& a_boxindex, 00211 const int a_maxboxsize ) const; 00212 00213 /// 00214 Vector<int> 00215 makeTrace( const IntVectSet& a_Ivs ,int a_dir ) const; 00216 00217 /// 00218 void 00219 makeTraces( const IntVectSet& a_Ivs ,Vector<int>* a_traces ) const; 00220 /// 00221 int 00222 findSplit( const Vector<int>& a_trace ) const; 00223 00224 int 00225 findSplit( const Vector<int>& a_trace, const int a_maxSize ) const; 00226 00227 /// 00228 int 00229 findMaxInflectionPoint( const Vector<int>& a_trace ,int& a_maxVal ) const; 00230 int 00231 findMaxInflectionPoint( const Vector<int>& a_trace ,int& a_maxVal, const int a_maxSize ) const; 00232 00233 /// 00234 void 00235 splitTags( const IntVectSet& a_tags, 00236 const int a_split_dir ,const int a_split_indx, 00237 IntVectSet& a_tags_lo ,IntVectSet& a_tags_hi ) const; 00238 00239 void splitTagsInPlace(const int a_split_dir, const int a_split_indx, 00240 IntVectSet& a_tags_inout_lo, 00241 IntVectSet& a_tags_hi) const; 00242 00243 void splitTagsInBestDimension(IntVectSet& a_tags_inout_lo, 00244 IntVectSet& a_tags_hi, 00245 const int a_maxSize) const; 00246 /// 00247 void 00248 breakBoxes(Vector<Box>& a_vboxin, const int& a_maxSize, 00249 const int& a_idir) const; 00250 00251 /// 00252 int 00253 maxloc( const int* a_V ,const int a_Size ) const; 00254 00255 void makeBoxesParallel(std::list<Box>& a_mesh, 00256 IntVectSet& a_tags, 00257 const IntVectSet& a_pnd, 00258 const ProblemDomain& a_domain, 00259 const int a_maxSize, 00260 const int a_depth, 00261 const int a_totalBufferSize, 00262 const int a_minSize, 00263 const Interval& a_procInterval 00264 ) const; 00265 00266 void sendBoxesParallel( const std::list<Box>& a_mesh, 00267 int tag) const; 00268 00269 void receiveBoxesParallel(const Interval& a_from, 00270 const Interval& a_to, 00271 std::list<Box>& a_mesh, 00272 int tag) const; 00273 00274 int longsideRefineDirs(const Box& a_bx, int& a_dir) const; 00275 00276 mutable Vector<int> m_messageBuffer; // used for messaging in parallel 00277 }; 00278 00279 /// Splits domain into vector of disjoint boxes with max size maxsize 00280 /** 00281 Blocking factor is default to one. 00282 If you make minimum size > 1, then domain must 00283 be coarsenable and refineable by blockfactor 00284 (refine(coarsen(domain,blockfactor), minsize) == domain) 00285 or an error is thrown. This would be defined in 00286 MeshRefine.H, except that it needs to use a BRMeshRefine object. 00287 Here a_refineDirs[d] is 1 if refining in dimension d, and 0 if not. 00288 */ 00289 extern void domainSplit(const ProblemDomain& a_domain, Vector<Box>& a_vbox, 00290 int a_maxSize, int a_blockfactor=1, 00291 IntVect a_refineDirs=IntVect::Unit); 00292 00293 /// 00294 /** 00295 Splits domain into a vector of disjoint boxes with 00296 maximum size maxsize. 00297 blocking factor is default to one. 00298 If you make minimum size > 1, then domain must 00299 be coarsenable and refineable by blockfactor 00300 (refine(coarsen(domain,blockfactor), minsize) == domain) 00301 or an error is thrown. This would be defined in 00302 MeshRefine.H, except that it needs to use a BRMeshRefine object. 00303 Here a_refineDirs[d] is 1 if refining in dimension d, and 0 if not. 00304 */ 00305 extern void domainSplit(const Box& a_domain, Vector<Box>& a_vbox, 00306 int a_maxSize, int a_blockfactor=1, 00307 IntVect a_refineDirs=IntVect::Unit); 00308 00309 /// 00310 /** 00311 Recursive function to enforce max size of boxes in a given direction. 00312 Does not call Meshrefine. 00313 */ 00314 extern void 00315 breakBoxes(Vector<Box>& a_vboxin, const int& a_maxSize, const int& a_idir); 00316 00317 #include "NamespaceFooter.H" 00318 #endif