AFEPack
MPI_UMemoryReclaimer.h
浏览该文件的文档。
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