|
AFEPack
|
00001 00012 #ifndef __MPI_UMemoryReclaimer_h__ 00013 #define __MPI_UMemoryReclaimer_h__ 00014 00015 #include "MPI_HGeometry.h" 00016 00030 namespace MPI { 00031 template <class FOREST> 00032 class MemoryReclaimer { 00033 public: 00034 enum { dim = FOREST::dim, dow = FOREST::dow }; 00035 typedef FOREST tree_t; 00036 typedef BirdView<tree_t> ir_mesh_t; 00037 private: 00038 tree_t * h_tree; 00039 std::list<ir_mesh_t *> ir_mesh; 00040 00041 public: 00042 MemoryReclaimer() : h_tree(NULL) {} 00043 MemoryReclaimer(tree_t& _h_tree) : h_tree(&_h_tree) {} 00044 virtual ~MemoryReclaimer() {} 00045 00046 public: 00051 void setGeometryTree(tree_t& _h_tree) { 00052 h_tree = &_h_tree; 00053 } 00058 void addIrregularMesh(ir_mesh_t& _ir_mesh) { 00059 if (&(_ir_mesh.getForest()) != h_tree) { 00060 std::cout << "warning: the irregular mesh added is not based on the geometry tree used." 00061 << std::endl; 00062 } 00063 ir_mesh.push_back(&_ir_mesh); 00064 } 00065 void clear() { 00066 h_tree = NULL; 00067 ir_mesh.clear(); 00068 } 00069 void reclaim() { 00071 typename std::list<ir_mesh_t *>::iterator 00072 the_ir_mesh = ir_mesh.begin(), 00073 end_ir_mesh = ir_mesh.end(); 00074 for (;the_ir_mesh != end_ir_mesh;++ the_ir_mesh) { 00075 reclaimIrregularMesh(**the_ir_mesh); 00076 } 00077 00079 initialTreeLabel(); 00080 00082 the_ir_mesh = ir_mesh.begin(); 00083 for (;the_ir_mesh != end_ir_mesh;++ the_ir_mesh) { 00084 labelIrregularMesh(**the_ir_mesh); 00085 } 00086 00088 reclaimTreeMemory(); 00089 } 00090 00091 private: 00092 void reclaimIrregularMesh(ir_mesh_t& m) { 00093 ActiveElementIterator<dim,dow> 00094 the_ele = m.beginActiveElement(), 00095 end_ele = m.endActiveElement(); 00096 for (;the_ele != end_ele;++ the_ele) { 00097 if (the_ele->isRefined()) { 00098 for (int i = 0;i < the_ele->n_child;++ i) { 00099 m.deleteTree(the_ele->child[i]); 00100 the_ele->child[i] = NULL; 00101 } 00102 } 00103 } 00104 } 00105 00106 void initialTreeLabel() { 00107 typename HGeometryTree<dim,dow>::RootIterator 00108 the_ele = h_tree->beginRootElement(), 00109 end_ele = h_tree->endRootElement(); 00110 for (;the_ele != end_ele;++ the_ele) { 00111 labelHGeometryRecursively(*the_ele, -1); 00112 } 00113 } 00114 00115 void labelIrregularMesh(ir_mesh_t& m) { 00116 RootFirstElementIterator<dim,dow> 00117 the_ele = m.beginRootFirstElement(), 00118 end_ele = m.endRootFirstElement(); 00119 for (;the_ele != end_ele;++ the_ele) { 00120 labelHGeometry(*(the_ele->h_element), 1); 00121 } 00122 } 00123 00124 void reclaimTreeMemory() { 00125 typename HGeometryTree<dim,dow>::RootIterator 00126 the_ele = h_tree->beginRootElement(), 00127 end_ele = h_tree->endRootElement(); 00128 for (;the_ele != end_ele;++ the_ele) { 00129 relabelHGeometryRecursively(*the_ele); 00130 } 00131 00132 the_ele = h_tree->beginRootElement(); 00133 for (;the_ele != end_ele;++ the_ele) { 00134 reclaimHGeometryRecursively(*the_ele); 00135 } 00136 } 00137 00138 private: 00139 template <class GEO> bool 00140 is_shared_geometry(const GEO& g) const { 00141 return (h_tree->get_shared_info(g) != NULL); 00142 } 00143 00144 template <int D> void 00145 labelHGeometry(HGeometry<D,dow>& g, int lab) const { 00146 for (int i = 0;i < g.n_vertex;++ i) { 00147 labelHGeometry(*(g.vertex[i]), lab); 00148 } 00149 for (int i = 0;i < g.n_boundary;++ i) { 00150 labelHGeometry(*(g.boundary[i]), lab); 00151 } 00152 g.index = lab; 00153 } 00154 00155 template <int D> void 00156 labelHGeometryRecursively(HGeometry<D,dow>& g, int lab) const { 00157 if (g.isRefined()) { 00158 for (int i = 0;i < g.n_child;++ i) { 00159 labelHGeometryRecursively(*(g.child[i]), lab); 00160 } 00161 } 00162 00163 labelHGeometry(g, lab); 00164 } 00165 00166 template <int D> int 00167 relabelHGeometryRecursively(HGeometry<D,dow>& g) const { 00168 if (is_shared_geometry(g)) g.index = 1; 00169 00170 for (int i = 0;i < g.n_vertex;++ i) { 00171 if (g.vertex[i] == NULL) continue; 00172 if (relabelHGeometryRecursively(*(g.vertex[i])) == -2) { 00173 g.vertex[i] = NULL; 00174 } 00175 } 00176 for (int i = 0;i < g.n_boundary;++ i) { 00177 if (g.boundary[i] == NULL) continue; 00178 if (relabelHGeometryRecursively(*(g.boundary[i])) == -2) { 00179 g.boundary[i] = NULL; 00180 } 00181 } 00182 if (g.isRefined()) { 00183 for (int i = 0;i < g.n_child;++ i) { 00184 if (g.child[i] == NULL) continue; 00185 if (relabelHGeometryRecursively(*(g.child[i])) == -2) { 00186 g.child[i] = NULL; 00187 } 00188 } 00189 } 00190 if (g.index == -1) { 00191 g.index = -2; 00192 return -1; 00193 } else { 00194 return g.index; 00195 } 00196 } 00197 00198 template <int D> int 00199 reclaimHGeometryRecursively(HGeometry<D,dow>& g) const { 00200 if (is_shared_geometry(g)) return 1; 00201 00202 for (int i = 0;i < g.n_vertex;++ i) { 00203 if (g.vertex[i] != NULL) { 00204 if (reclaimHGeometryRecursively(*(g.vertex[i])) == -1) { 00205 g.vertex[i] = NULL; 00206 } 00207 } 00208 } 00209 for (int i = 0;i < g.n_boundary;++ i) { 00210 if (g.boundary[i] != NULL) { 00211 if (reclaimHGeometryRecursively(*(g.boundary[i])) == -1) { 00212 g.boundary[i] = NULL; 00213 } 00214 } 00215 } 00216 for (int i = 0;i < g.n_child;++ i) { 00217 if (g.child[i] == NULL) continue; 00218 if (reclaimHGeometryRecursively(*(g.child[i])) == -1) { 00219 g.child[i] = NULL; 00220 } 00221 } 00222 Assert (((g.index == 1) || 00223 (g.index == -1) || 00224 (g.index == -2)), ExcInternalError()); 00225 if (g.index == -2) { 00226 this->reclaimHGeometry(&g); 00227 return -1; 00228 } else { 00229 return 1; 00230 } 00231 } 00232 00233 template <int D> void 00234 reclaimHGeometry(HGeometry<D,dow> * p_geo) const { 00235 delete p_geo; 00236 } 00237 }; 00238 00239 } 00240 #endif // __MPI_UMemoryReclaimer_h__ 00241
1.7.4