AFEPack
|
00001 00012 #ifndef __MPI_MemoryReclaimer_h__ 00013 #define __MPI_MemoryReclaimer_h__ 00014 00015 #include "MPI_HGeometry.h" 00016 00045 namespace MPI { 00046 template <class FOREST> 00047 class MemoryReclaimer { 00048 public: 00049 enum { dim = FOREST::dim, dow = FOREST::dow }; 00050 typedef FOREST tree_t; 00051 typedef BirdView<tree_t> ir_mesh_t; 00052 private: 00053 tree_t * h_tree; 00054 std::list<ir_mesh_t *> ir_mesh; 00055 00056 public: 00057 MemoryReclaimer() : h_tree(NULL) {} 00058 MemoryReclaimer(tree_t& _h_tree) : h_tree(&_h_tree) {} 00059 virtual ~MemoryReclaimer() {} 00060 00061 public: 00066 void setGeometryTree(tree_t& _h_tree) { 00067 h_tree = &_h_tree; 00068 } 00073 void addIrregularMesh(ir_mesh_t& _ir_mesh) { 00074 if (&(_ir_mesh.getForest()) != h_tree) { 00075 std::cout << "warning: the irregular mesh added is not based on the geometry tree used." 00076 << std::endl; 00077 } 00078 ir_mesh.push_back(&_ir_mesh); 00079 } 00080 void clear() { 00081 h_tree = NULL; 00082 ir_mesh.clear(); 00083 } 00084 void reclaim() { 00086 typename std::list<ir_mesh_t *>::iterator 00087 the_ir_mesh = ir_mesh.begin(), 00088 end_ir_mesh = ir_mesh.end(); 00089 for (;the_ir_mesh != end_ir_mesh;++ the_ir_mesh) { 00090 reclaimIrregularMesh(**the_ir_mesh); 00091 } 00092 00094 new_property_id(_pid_is_shared); 00095 markSharedObject(); 00096 00098 initialTreeLabel(); 00099 00101 the_ir_mesh = ir_mesh.begin(); 00102 for (;the_ir_mesh != end_ir_mesh;++ the_ir_mesh) { 00103 labelIrregularMesh(**the_ir_mesh); 00104 } 00105 00107 reclaimTreeMemory(); 00108 free_property_id(_pid_is_shared); 00109 } 00110 00111 private: 00112 void markSharedObject() { 00113 typename HGeometryTree<dim,dow>::RootIterator 00114 the_ele = h_tree->beginRootElement(), 00115 end_ele = h_tree->endRootElement(); 00116 for (;the_ele != end_ele;++ the_ele) { 00117 HGeometry<dim,dow> * p_geo = &(*the_ele); 00118 do { 00119 if (p_geo->parent != NULL) { 00120 p_geo = p_geo->parent; 00121 } else break; 00122 } while (true); 00123 markSharedElement(*p_geo); 00124 } 00125 00126 the_ele = h_tree->beginRootElement(); 00127 for (;the_ele != end_ele;++ the_ele) { 00128 HGeometry<dim,dow> * p_geo = &(*the_ele); 00129 do { 00130 if (p_geo->parent != NULL) { 00131 p_geo = p_geo->parent; 00132 } else break; 00133 } while (true); 00134 markSharedGeometry(*p_geo); 00135 } 00136 } 00137 00138 void reclaimIrregularMesh(ir_mesh_t& m) { 00139 ActiveElementIterator<dim,dow> 00140 the_ele = m.beginActiveElement(), 00141 end_ele = m.endActiveElement(); 00142 for (;the_ele != end_ele;++ the_ele) { 00143 if (the_ele->isRefined()) { 00144 for (int i = 0;i < the_ele->n_child;++ i) { 00145 m.deleteTree(the_ele->child[i]); 00146 the_ele->child[i] = NULL; 00147 } 00148 } 00149 } 00150 } 00151 00152 void initialTreeLabel() { 00153 typename HGeometryTree<dim,dow>::RootIterator 00154 the_ele = h_tree->beginRootElement(), 00155 end_ele = h_tree->endRootElement(); 00156 for (;the_ele != end_ele;++ the_ele) { 00157 labelHGeometryRecursively(*the_ele, -1); 00158 } 00159 } 00160 00161 void labelIrregularMesh(ir_mesh_t& m) { 00162 RootFirstElementIterator<dim,dow> 00163 the_ele = m.beginRootFirstElement(), 00164 end_ele = m.endRootFirstElement(); 00165 for (;the_ele != end_ele;++ the_ele) { 00166 labelHGeometry(*(the_ele->h_element), 1); 00167 } 00168 00169 typename ir_mesh_t::mesh_t& mesh = m.regularMesh(); 00170 #define LABEL_USED_HGEOMETRY(D) \ 00171 if (dim >= D) { \ 00172 int n_geo = mesh.h_geometry()[D].size(); \ 00173 for (int i = 0;i < n_geo;++ i) { \ 00174 HGeometry<D,dow> * p_geo = mesh.template h_geometry<D>(i); \ 00175 labelHGeometry(*p_geo, 1); \ 00176 } \ 00177 } 00178 00179 LABEL_USED_HGEOMETRY(0); 00180 LABEL_USED_HGEOMETRY(1); 00181 LABEL_USED_HGEOMETRY(2); 00182 LABEL_USED_HGEOMETRY(3); 00183 00184 #undef LABEL_USED_HGEOMETRY 00185 } 00186 00187 void reclaimTreeMemory() { 00188 typename HGeometryTree<dim,dow>::RootIterator 00189 the_ele = h_tree->beginRootElement(), 00190 end_ele = h_tree->endRootElement(); 00191 for (;the_ele != end_ele;++ the_ele) { 00192 relabelHGeometryRecursively(*the_ele); 00193 } 00194 00195 the_ele = h_tree->beginRootElement(); 00196 for (;the_ele != end_ele;++ the_ele) { 00197 reclaimHGeometryRecursively(*the_ele); 00198 } 00199 } 00200 00201 private: 00202 property_id_t<> _pid_is_shared; 00203 00207 template <class GEO> bool 00208 is_shared_geometry(const GEO& g) const { 00209 bool result = false; 00210 result |= (h_tree->get_shared_info(g) != NULL); 00211 if (! result) { 00212 for (int i = 0;i < g.n_vertex;++ i) { 00213 result |= is_shared_geometry(*(g.vertex[i])); 00214 } 00215 } 00216 if (result) { 00217 return result; 00218 } else { 00219 for (int i = 0;i < g.n_boundary;++ i) { 00220 result |= is_shared_geometry(*(g.boundary[i])); 00221 } 00222 } 00223 return result; 00224 } 00225 00230 void markSharedElement(HGeometry<dim,dow>& ele) const { 00231 if ((ele.get_property(_pid_is_shared) == NULL) && 00232 (is_shared_geometry(ele))) { 00233 ele.new_property(_pid_is_shared); 00234 00235 if (ele.parent != NULL) { 00236 for (int i = 0;i < ele.parent->n_child;++ i) { 00237 HGeometry<dim,dow> * p_sibling = ele.parent->child[i]; 00238 if (p_sibling == &ele) continue; 00239 if (p_sibling->get_property(_pid_is_shared) == NULL) { 00240 p_sibling->new_property(_pid_is_shared); 00241 } 00242 } 00243 } 00244 } 00245 00246 if (ele.isRefined()) { 00247 for (int i = 0;i < ele.n_child;++ i) { 00248 markSharedElement(*ele.child[i]); 00249 } 00250 } 00251 } 00252 00257 template <class GEO> void 00258 markSharedGeometry(GEO& g) const { 00259 if (g.get_property(_pid_is_shared) != NULL) { 00260 for (int i = 0;i < g.n_vertex;++ i) { 00261 if (g.vertex[i]->get_property(_pid_is_shared) == NULL) { 00262 g.vertex[i]->new_property(_pid_is_shared); 00263 } 00264 } 00265 for (int i = 0;i < g.n_boundary;++ i) { 00266 if (g.boundary[i]->get_property(_pid_is_shared) == NULL) { 00267 g.boundary[i]->new_property(_pid_is_shared); 00268 } 00269 markSharedGeometry(*g.boundary[i]); 00270 } 00271 } 00272 if (g.isRefined()) { 00273 for (int i = 0;i < g.n_child;++ i) { 00274 markSharedGeometry(*g.child[i]); 00275 } 00276 } 00277 } 00278 00279 template <class GEO> void 00280 labelHGeometry(GEO& g, int lab) const { 00281 for (int i = 0;i < g.n_vertex;++ i) { 00282 labelHGeometry(*(g.vertex[i]), lab); 00283 } 00284 for (int i = 0;i < g.n_boundary;++ i) { 00285 labelHGeometry(*(g.boundary[i]), lab); 00286 } 00287 g.index = lab; 00288 } 00289 00290 template <class GEO> void 00291 labelHGeometryRecursively(GEO& g, int lab) const { 00292 labelHGeometry(g, lab); 00293 00294 if (g.isRefined()) { 00295 for (int i = 0;i < g.n_child;++ i) { 00296 labelHGeometryRecursively(*(g.child[i]), lab); 00297 } 00298 } 00299 } 00300 00301 template <class GEO> int 00302 relabelHGeometryRecursively(GEO& g) const { 00303 if (g.get_property(_pid_is_shared) != NULL) { 00304 g.index = 1; 00305 } 00306 00307 for (int i = 0;i < g.n_vertex;++ i) { 00308 if (g.vertex[i] == NULL) continue; 00309 if (relabelHGeometryRecursively(*(g.vertex[i])) == -2) { 00310 g.vertex[i] = NULL; 00311 } 00312 } 00313 for (int i = 0;i < g.n_boundary;++ i) { 00314 if (g.boundary[i] == NULL) continue; 00315 if (relabelHGeometryRecursively(*(g.boundary[i])) == -2) { 00316 g.boundary[i] = NULL; 00317 } 00318 } 00319 if (g.isRefined()) { 00320 for (int i = 0;i < g.n_child;++ i) { 00321 if (g.child[i] == NULL) continue; 00322 if (relabelHGeometryRecursively(*(g.child[i])) == -2) { 00323 g.child[i] = NULL; 00324 } 00325 } 00326 } 00327 if (g.index == -1) { 00328 g.index = -2; 00329 return -1; 00330 } else { 00331 return g.index; 00332 } 00333 } 00334 00335 template <class GEO> int 00336 reclaimHGeometryRecursively(GEO& g) const { 00337 for (int i = 0;i < g.n_vertex;++ i) { 00338 if (g.vertex[i] != NULL) { 00339 if (reclaimHGeometryRecursively(*(g.vertex[i])) == -1) { 00340 g.vertex[i] = NULL; 00341 } 00342 } 00343 } 00344 for (int i = 0;i < g.n_boundary;++ i) { 00345 if (g.boundary[i] != NULL) { 00346 if (reclaimHGeometryRecursively(*(g.boundary[i])) == -1) { 00347 g.boundary[i] = NULL; 00348 } 00349 } 00350 } 00351 for (int i = 0;i < g.n_child;++ i) { 00352 if (g.child[i] == NULL) continue; 00353 if (reclaimHGeometryRecursively(*(g.child[i])) == -1) { 00354 g.child[i] = NULL; 00355 } 00356 } 00357 00358 if ((g.index == -2) && 00359 (g.get_property(_pid_is_shared) == NULL)) { 00360 this->reclaimHGeometry(&g); 00361 return -1; 00362 } else { 00363 return 1; 00364 } 00365 } 00366 00367 template <class GEO> void 00368 reclaimHGeometry(GEO * p_geo) const { 00369 assert ((p_geo->get_property(_pid_is_shared) == NULL)); 00370 delete p_geo; 00371 } 00372 }; 00373 00374 } 00375 #endif // __MPI_MemoryReclaimer_h__ 00376