AFEPack
HGeometry.templates.h
浏览该文件的文档。
00001 
00012 #ifndef _HGeometry_templates_h_
00013 #define _HGeometry_templates_h_
00014 
00015 #include "HGeometry.h"
00016 
00017 #define TEMPLATE template <int DIM, int DOW>
00018 #define THIS HGeometry<DIM,DOW>
00019 
00020 TEMPLATE
00021 THIS::HGeometry() : HBuffer()
00022 {
00023   index = 0;
00024   for (int i = 0;i < THIS::n_vertex;i ++)
00025     vertex[i] = NULL;
00026   for (int i = 0;i < THIS::n_boundary;i ++)
00027     boundary[i] = NULL;
00028   parent = NULL;
00029   for (int i = 0;i < THIS::n_child;i ++)
00030     child[i] = NULL;
00031   bmark = 0;
00032 }
00033 
00034 TEMPLATE
00035 bool THIS::isRefined() const
00036 {
00037   return (child[0] != NULL);
00038 }
00039 
00040 TEMPLATE
00041 void THIS::refine()
00042 {}
00043 
00044 TEMPLATE
00045 void THIS::checkIntegrity() const
00046 {
00051   int k;
00052   for (int i = 0;i < THIS::n_boundary;i ++) {
00053     const bound_t * b = boundary[i];
00054     for (int j = 0;j < bound_t::n_vertex;j ++) {
00055       for (k = 0;k < THIS::n_vertex;k ++) {
00056         if (b->vertex[j] == vertex[k]) {
00057           break;
00058         }
00059       }
00060       Assert(k < THIS::n_vertex, ExcInternalError());
00061     }
00062   }
00068   if (isRefined()) {
00069     for (int i = 0;i < THIS::n_child;i ++) {
00070       child[i]->checkIntegrity();
00071     }
00072   }
00073 }
00074 
00075 TEMPLATE
00076 bool THIS::isIncludePoint(const Point<DOW>& p) const
00077 {
00078   return true;
00079 }
00080 
00081 #undef THIS /// HGeometry<DIM,DOW>
00082 
00084 
00085 #define THIS HGeometryTree<DIM,DOW>
00086 
00087 TEMPLATE
00088 void THIS::checkIntegrity()
00089 {
00090   RootIterator the_ele = beginRootElement();
00091   RootIterator end_ele = endRootElement();
00092   for (;the_ele != end_ele;++ the_ele) {
00093     the_ele->checkIntegrity();
00094   }
00095 }
00096 
00097 TEMPLATE
00098 void THIS::clear()
00099 {
00100   Tools tools;
00101   RootIterator 
00102     the_ele = beginRootElement(),
00103     end_ele = endRootElement();
00104   for (;the_ele != end_ele;++ the_ele) {
00105     tools.clearIndex(*the_ele);
00106   }
00107 
00108   the_ele = beginRootElement();
00109   for (;the_ele != end_ele;++ the_ele) {
00110     tools.incrIndex(*the_ele);
00111   }
00112 
00113   the_ele = beginRootElement();
00114   for (;the_ele != end_ele;++ the_ele) {
00115     tools.decrIndex(*the_ele);
00116   }
00117 
00118   root_element.clear();
00119 }
00120 
00121 TEMPLATE
00122 void THIS::readEasyMesh(const std::string& filename)
00123 {
00124   std::cerr << "THIS::readEasyMesh is only avaiable for 2-dimensional case."
00125             << std::endl;
00126   abort();
00127 }
00128         
00129 TEMPLATE
00130 void THIS::readMesh(const std::string& filename)
00131 {
00132   std::cerr << "Reading in mesh data file " 
00133             << filename 
00134             << " as geometry tree root ..." 
00135             << std::endl;
00136   std::ifstream is(filename.c_str());
00137 
00139   u_int n_point;
00140   is >> n_point;
00141   std::cerr << "\t# points: " << n_point << std::endl;
00142   std::vector<Point<DOW> > point(n_point);
00143   for (u_int i = 0;i < n_point;i ++) is >> point[i];
00144   is >> n_point;
00145   std::vector<HGeometry<0,DOW> *> geo_0d(n_point, (HGeometry<0,DOW> *)NULL);
00146   for (u_int i = 0;i < n_point;i ++) {
00147     u_int j, k;
00148     is >> j; geo_0d[j] = new HGeometry<0,DOW>();
00149     is >> k >> k; *dynamic_cast<Point<DOW> *>(geo_0d[j]) = point[k];
00150     is >> k >> k >> geo_0d[j]->bmark;
00151   }
00152   point.clear();
00153         
00154 #define GDIM 1
00155   u_int n_geo_1d;
00156   std::vector<HGeometry<GDIM,DOW>*> geo_1d;
00157   if (DIM >= 1) {
00158     is >> n_geo_1d;
00159     std::cerr << "\t# 1D-geometry: " << n_geo_1d << std::endl;
00160     geo_1d.resize(n_geo_1d, NULL);
00161     for (u_int i = 0;i < n_geo_1d;i ++) {
00162       u_int j, k, l;
00163       is >> j >> k; geo_1d[j] = new HGeometry<GDIM,DOW>();
00164       for (k = 0;k < GDIM + 1;k ++) {
00165         is >> l; geo_1d[j]->vertex[k] = geo_0d[l];
00166       }
00167       is >> k;
00168       for (k = 0;k < GDIM + 1;k ++) {
00169         is >> l;
00170       }
00171       is >> geo_1d[j]->bmark;
00172     }
00173   }
00174 #undef GDIM
00175 
00176 #define GDIM 2
00177   u_int n_geo_2d;
00178   std::vector<HGeometry<GDIM,DOW>*> geo_2d;
00179   if (DIM >= 2) {
00180     is >> n_geo_2d;
00181     std::cerr << "\t# 2D-geometry: " << n_geo_2d << std::endl;
00182     geo_2d.resize(n_geo_2d, NULL);
00183     for (u_int i = 0;i < n_geo_2d;i ++) {
00184       u_int j, k, l;
00185       is >> j >> k; geo_2d[j] = new HGeometry<GDIM,DOW>();
00186       for (k = 0;k < GDIM + 1;k ++) {
00187         is >> l; geo_2d[j]->vertex[k] = geo_0d[l];
00188       }
00189       is >> k;
00190       for (k = 0;k < GDIM + 1;k ++) {
00191         is >> l; geo_2d[j]->boundary[k] = geo_1d[l];
00192       }
00193       is >> geo_2d[j]->bmark;
00194     }
00195   }
00196 #undef GDIM
00197 
00198 #define GDIM 3
00199   u_int n_geo_3d;
00200   std::vector<HGeometry<GDIM,DOW>*> geo_3d;
00201   if (DIM >= 3) { 
00202     is >> n_geo_3d;
00203     std::cerr << "\t# 3D-geometry: " << n_geo_3d << std::endl;
00204     geo_3d.resize(n_geo_3d, NULL);
00205     for (u_int i = 0;i < n_geo_3d;i ++) {
00206       u_int j, k, l;
00207       is >> j >> k; geo_3d[j] = new HGeometry<GDIM,DOW>();
00208       for (k = 0;k < GDIM + 1;k ++) {
00209         is >> l; geo_3d[j]->vertex[k] = geo_0d[l];
00210       }
00211       is >> k;
00212       for (k = 0;k < GDIM + 1;k ++) {
00213         is >> l; geo_3d[j]->boundary[k] = geo_2d[l];
00214       }
00215       is >> geo_3d[j]->bmark;
00216     }
00217 #undef GDIM
00218   }
00219   is.close();
00220 
00221   if (DIM == 1) {
00222     for (u_int i = 0;i < n_geo_1d;++ i) {
00223       this->rootElement().push_back((HGeometry<DIM,DOW> *)geo_1d[i]);
00224     }
00225   } else if (DIM == 2) {
00226     for (u_int i = 0;i < n_geo_2d;++ i) {
00227       this->rootElement().push_back((HGeometry<DIM,DOW> *)geo_2d[i]);
00228     }
00229   } else if (DIM == 3) {
00230     for (u_int i = 0;i < n_geo_3d;++ i) {
00231       this->rootElement().push_back((HGeometry<DIM,DOW> *)geo_3d[i]);
00232     }
00233   }
00234 }
00235 
00236 #undef THIS /// HGeometryTree<DIM,DOW>
00237 
00239 
00240 #define THIS HElement<DIM,DOW>
00241 
00242 TEMPLATE
00243 THIS::HElement() 
00244 : value(-1), parent(NULL), child(THIS::n_child, NULL) {}
00245 
00246 TEMPLATE
00247 THIS::HElement(const element_t& ele) :
00248 index(ele.index), value(ele.value), 
00249   indicator(ele.indicator),
00250   h_element(ele.h_element) {}
00251 
00252 TEMPLATE
00253 THIS::~HElement()
00254 {}
00255 
00256 TEMPLATE
00257 typename THIS::element_t& THIS::operator=(const element_t& ele) {
00258   index = ele.index;
00259   value = ele.value;
00260   indicator = ele.indicator;
00261   h_element = ele.h_element;
00262   return *this;
00263 }
00264 
00265   TEMPLATE
00266   void THIS::refine()
00267   {}
00268 
00269 TEMPLATE
00270 bool THIS::isRefined() const
00271 {
00272   return (child.size() > 0 && child[0] != NULL);
00273 }
00274 
00275 TEMPLATE
00276 void THIS::checkIntegrity() const
00277 {
00278   if (!isRefined()) return;
00279   for (int i = 0;i < THIS::n_child;i ++) {
00280     child[i]->checkIntegrity();
00281   }
00282 }
00283 
00284 TEMPLATE
00285 bool THIS::isIncludePoint(const Point<DOW>& p) const
00286 {
00287   return h_element->isIncludePoint(p);
00288 }
00289 
00290 #undef THIS /// HElement<DIM,DOW>
00291 
00293 
00294 #define THIS IrregularMesh<DIM,DOW>
00295 
00296 TEMPLATE
00297 void THIS::semiregularize()
00298 {
00299   if (! geometry_tree->lock()) { // 对几何遗传树进行加锁
00300     std::cerr << "The hierarchy geometry tree is locked, aborting ...";
00301     abort();
00302   }
00303 
00304   std::cerr << "Semiregularizing the mesh ...  " << std::flush;
00305   int round = 0;
00306   const char * timer = "-/|\\";
00307   bool flag;
00308   int n_element_refined = 0;
00309   prepareSemiregularize();
00310   do {
00311     std::cerr << "\b" << timer[round] << std::flush;
00312     round = (round + 1)%4;
00313     flag = false;
00314     semiregularizeHelper(flag, n_element_refined);
00315   } while (flag);
00316   std::cerr << "\bOK!\n"
00317             << "\t" << n_element_refined 
00318             << " elements refined in semiregularization."
00319             << std::endl;
00320 }
00321 
00322 TEMPLATE
00323 void THIS::semiregularizeHelper(bool& flag, 
00324                                 int& n_element_refined)
00325 {
00326   RootIterator the_ele = beginRootElement();
00327   RootIterator end_ele = endRootElement();
00328   for (;the_ele != end_ele;++ the_ele) {
00329     semiregularizeHelper(flag, *the_ele, n_element_refined);
00330   }
00331 }
00332 
00333 TEMPLATE
00334 void THIS::semiregularizeHelper(bool& flag, 
00335                                 element_t& element, 
00336                                 int& n_element_refined)
00337 {
00338   if (element.value == 0) { // if this element is a leaf element
00339     h_element_t& h_element = *(element.h_element);
00340     if (! Tools().isSemiregular(h_element)) { // if this element is not semiregular
00341       flag = true;
00342       element.refine();
00343       element.value = 1;
00344       for (int i = 0;i < element_t::n_child;i ++) {
00345         element.child[i]->value = 0;
00346         Tools().setGeometryUsed(*(h_element.child[i]));
00347       }
00348       n_element_refined ++;
00349     }
00350   } else { // if its not a leaf element
00351     assert (element.value == 1);
00352     for (int i = 0;i < element_t::n_child;i ++) { // then check its children
00353       semiregularizeHelper(flag, *element.child[i], n_element_refined);
00354     }
00355   }
00356 }
00357 
00358 TEMPLATE
00359 void THIS::prepareSemiregularize()
00360 {
00361   Tools tools;
00362   RootIterator the_root_element = beginRootElement();
00363   RootIterator end_root_element = endRootElement();
00364   for (;the_root_element != end_root_element;++ the_root_element) {
00365     tools.setGeometryUnusedRecursively(*(the_root_element->h_element));
00366   }
00367   RootFirstIterator 
00368     the_ele = beginRootFirstElement(),
00369     end_ele = endRootFirstElement();
00370   for (;the_ele != end_ele;++ the_ele) {
00371     tools.setGeometryUsed(*(the_ele->h_element));
00372   }
00373 }
00374 
00375 TEMPLATE
00376 THIS::IrregularMesh(tree_t& h_geometry_tree)
00377 {
00378   setGeometryTree(&h_geometry_tree);
00379   regular_mesh = NULL;
00380 }
00381 
00382 TEMPLATE void 
00383 THIS::reinit(tree_t& h_geometry_tree, 
00384              bool is_bare)
00385 {
00386   if (is_bare) {
00387     geometry_tree = &h_geometry_tree;
00388   } else {
00389     clear();
00390     setGeometryTree(&h_geometry_tree);
00391   }
00392 }
00393 
00394 TEMPLATE
00395 void THIS::globalRefine(unsigned int i)
00396 {
00397   MeshAdaptor<DIM, DOW> mesh_adaptor(*this);
00398   mesh_adaptor.globalRefine(i);
00399 }
00400 
00401 TEMPLATE
00402 void THIS::randomRefine(double percent)
00403 {
00404   MeshAdaptor<DIM, DOW> mesh_adaptor(*this);
00405   mesh_adaptor.randomRefine(percent);
00406 }
00407 
00408 TEMPLATE
00409 void THIS::setGeometryTree(tree_t * h_geometry_tree)
00410 {
00411   std::cerr << "Constructing the root mesh from hierarchy geometry tree ..." << std::endl;
00412   int i, j;
00413   geometry_tree = h_geometry_tree;
00414 
00415   // construct the root elements at first       
00416   std::cerr << "\tconstructing elements ..." << std::flush;
00417   unsigned int n_root_element = geometry_tree->n_rootElement();
00418   std::vector<element_t *> h_element(n_root_element);
00419   typename tree_t::RootIterator 
00420     the_h_element = geometry_tree->beginRootElement(),
00421     end_h_element = geometry_tree->endRootElement();
00422   for (i = 0;the_h_element != end_h_element;++ the_h_element) 
00423     the_h_element->index = i ++;
00424   the_h_element = geometry_tree->beginRootElement();
00425   for (i = 0;the_h_element != end_h_element;++ the_h_element, ++ i) {
00426     element_t * element = new element_t();
00427     element->value = 0;
00428     element->h_element = &*the_h_element;
00429     root_element.push_back(element);
00430     h_element[i] = element;
00431   }
00432   std::cerr << " OK!" << std::endl;
00433 }
00434 
00435 TEMPLATE
00436 THIS::~IrregularMesh()
00437 {
00438   clear();
00439 }
00440 
00441 TEMPLATE
00442 void THIS::clear()
00443 {
00444   if (geometry_tree != NULL)
00445     geometry_tree = NULL;
00446 
00447   RootIterator the_ele = beginRootElement();
00448   RootIterator end_ele = endRootElement();
00449   for (;the_ele != end_ele;++ the_ele) {
00450     this->deleteTree(&*the_ele);
00451   }
00452   root_element.clear();
00453 
00454   if (regular_mesh != NULL) {
00455     delete regular_mesh;
00456     regular_mesh = NULL;
00457   }
00458 }
00459 
00460 TEMPLATE
00461 void THIS::checkIntegrity()
00462 {
00463   RootIterator the_ele = beginRootElement();
00464   RootIterator end_ele = endRootElement();
00465   for (;the_ele != end_ele;++ the_ele) {
00466     the_ele->checkIntegrity();
00467   }
00468 }
00469 
00470 TEMPLATE
00471 void THIS::deleteTree(element_t * element)
00472 {
00473   if (element->isRefined()) {
00474     for (int i = 0;i < element_t::n_child;i ++) {
00475       this->deleteTree(element->child[i]);
00476     }
00477   }
00478   delete element;
00479 }
00480 
00481 TEMPLATE
00482 void THIS::copyTree(const element_t * src,
00483                     element_t * dst)
00484 {
00485   dst->index = src->index;
00486   dst->value = src->value;
00487   dst->indicator = src->indicator;
00488   dst->h_element = src->h_element;
00489   if (src->isRefined()) {
00490     dst->refine();
00491     for (int i = 0;i < element_t::n_child;i ++) {
00492       this->copyTree(src->child[i], dst->child[i]);
00493     }
00494   }
00495 }
00496 
00497 TEMPLATE
00498 void THIS::copyNonnegtiveSubtree(const element_t * src,
00499                                  element_t * dst)
00500 {
00501   assert (src->value == 0 || src->value == 1);
00502   dst->value = src->value;
00503   dst->index = src->index;
00504   dst->h_element = src->h_element;
00505   if (src->value == 1) {
00506     dst->refine();
00507     for (int i = 0;i < element_t::n_child;i ++) {
00508       this->copyNonnegtiveSubtree(src->child[i], dst->child[i]);
00509     }
00510   }
00511 }
00512 
00513 TEMPLATE
00514 void THIS::writeFormatted(const std::string& filename)
00515 {
00516   std::ofstream os(filename.c_str());
00517   os << (*this);
00518   os.close();
00519 }
00520 
00521 
00522 
00523 TEMPLATE
00524 THIS::IrregularMesh() :
00525 geometry_tree(NULL), regular_mesh(NULL)
00526 {}
00527 
00528 
00529 TEMPLATE
00530 THIS::IrregularMesh(const ir_mesh_t& mesh)
00531 {
00532   if (mesh.geometry_tree != NULL) {
00533     setGeometryTree(mesh.geometry_tree);
00534     copyNonnegtiveSubtree(mesh);
00535   }
00536   regular_mesh = NULL;
00537 }
00538 
00539 
00540         
00541 TEMPLATE
00542 void THIS::copyTree(const ir_mesh_t& mesh)
00543 {
00544   ConstRootIterator the_ele = mesh.beginRootElement();
00545   ConstRootIterator end_ele = mesh.endRootElement();
00546   RootIterator the_ele_1 = beginRootElement();
00547   for (;the_ele != end_ele;++ the_ele, ++ the_ele_1) {
00548     this->copyTree(&*the_ele, &*the_ele_1);
00549   }
00550 }
00551 
00552 
00553 
00554 TEMPLATE
00555 void THIS::copyNonnegtiveSubtree(const ir_mesh_t& mesh)
00556 {
00557   ConstRootIterator the_ele = mesh.beginRootElement();
00558   ConstRootIterator end_ele = mesh.endRootElement();
00559   RootIterator the_ele_1 = beginRootElement();
00560   for (;the_ele != end_ele;++ the_ele, ++ the_ele_1) {
00561     this->copyNonnegtiveSubtree(&*the_ele, &*the_ele_1);
00562   }
00563 }
00564 
00565 
00566 
00567 TEMPLATE
00568 typename THIS::ir_mesh_t& THIS::operator=(const ir_mesh_t& mesh)
00569 {
00570   clear();
00571   setGeometryTree(mesh.geometry_tree);
00572   copyNonnegtiveSubtree(mesh);
00573   return *this;
00574 }
00575 
00576 
00577 
00578 TEMPLATE
00579 typename THIS::RootFirstIterator THIS::beginRootFirstElement()
00580 {
00581   typename std::list<element_t *>::iterator element = root_element.begin();
00582   return RootFirstIterator(this, element, *element);
00583 }
00584 
00585 
00586 
00587 TEMPLATE
00588 typename THIS::RootFirstIterator THIS::endRootFirstElement()
00589 {
00590   typename std::list<element_t *>::iterator element = root_element.end();
00591   return RootFirstIterator(this, element, NULL);
00592 }
00593 
00594 
00595 
00596 TEMPLATE
00597 typename THIS::ActiveIterator THIS::beginActiveElement()
00598 {
00599   RootFirstIterator it = this->beginRootFirstElement();
00600   while (it->value > 0) ++ it;
00601   return ActiveIterator(it);
00602 }
00603 
00604 
00605 
00606 TEMPLATE
00607 typename THIS::ActiveIterator THIS::endActiveElement()
00608 {
00609   typename std::list<element_t *>::iterator element = root_element.end();
00610   return ActiveIterator(this, element, NULL);
00611 }
00612 
00613 TEMPLATE
00614 void THIS::refineElement(element_t& ele) {
00615   ele.refine();
00616   ele.value = 1;
00617   for (int k = 0;k < ele.n_child;k ++) {
00618     ele.child[k]->value = 0;
00619   }
00620 }
00621 
00622 TEMPLATE
00623 void THIS::renumerateElement()
00624 {
00625   Assert (regular_mesh != NULL, ExcInternalError());
00626   int i, j, k, l, m, n;
00627 
00628   std::cerr << "Renumerating element of the mesh ..." << std::endl;
00629   int n_ele = regular_mesh->n_geometry(DIM);
00630   std::list<int> element_index;
00631   std::vector<std::list<int>::iterator> element_index_iterator(n_ele);
00632   for (i = 0;i < n_ele;i ++) {
00633     element_index_iterator[i] = 
00634       element_index.insert(element_index.end(), 
00635                            i);
00636   }
00637 
00638   std::vector<std::list<std::pair<int,std::list<int>::iterator> > >
00639     element_to_node(regular_mesh->n_point());
00640   for (i = 0;i < n_ele;i ++) {
00641     GeometryBM& ele = regular_mesh->geometry(DIM,i);
00642     std::list<int>::iterator& the_it = element_index_iterator[i];
00643     for (j = 0;j < ele.n_vertex();j ++) {
00644       element_to_node[ele.vertex(j)].push_back
00645         (std::pair<int,std::list<int>::iterator>(i, the_it));
00646     }
00647   }
00648 
00649   std::vector<int> value(regular_mesh->n_geometry(DIM), 0);
00650   std::vector<int> new_index(regular_mesh->n_geometry(DIM));
00651   std::list<std::list<int>::iterator> involved_element_index;
00652   for (i = 0, n = -1;i < n_ele;i ++) {
00653     if (involved_element_index.empty()) {
00654       j = element_index.front();
00655       element_index.pop_front();
00656       value[j] ++;
00657     }
00658     else {
00659       std::list<std::list<int>::iterator>::iterator 
00660         it = involved_element_index.begin(),
00661         end = involved_element_index.end(),
00662         the_it = it;
00663       int n_the_used_vtx = value[**the_it];
00664       for (;it != end;++ it) {
00665         int& idx = **it;
00666         int& n_used_vtx = value[idx];
00667         if (regular_mesh->geometry(DIM,idx).n_vertex() == n_used_vtx) {
00668           the_it = it; break;
00669         } else if (n_the_used_vtx < n_used_vtx) {
00670           the_it = it;
00671           n_the_used_vtx = n_used_vtx;
00672         }
00673       }
00674       j = **the_it;
00675       element_index.erase(*the_it);
00676       involved_element_index.erase(the_it);
00677     }
00678 
00679     GeometryBM& ele = regular_mesh->geometry(DIM,j);
00680     for (k = 0;k < ele.n_vertex();k ++) {
00681       m = ele.vertex(k);
00682       std::list<std::pair<int,std::list<int>::iterator> >::iterator
00683         it = element_to_node[m].begin(),
00684         end = element_to_node[m].end();
00685       for (;it != end;++ it) {
00686         if (value[it->first] == 0) {
00687           involved_element_index.push_back(it->second);
00688         }
00689         value[it->first] ++;
00690       }
00691     }
00692     new_index[i] = j;
00693     if (100*i/n_ele > n) {
00694       n = 100*i/n_ele;
00695       std::cerr << "\r" << n << "% OK!";
00696     }
00697   }
00698 
00699   std::vector<GeometryBM> tmp_ele(regular_mesh->geometry(DIM));
00700   std::vector<int> old_index(n_ele);
00701 #ifdef __SERIALIZATION__
00702   std::vector<HBuffer*> hgp(regular_mesh->h_geometry_ptr[DIM]);
00703 #endif
00704   for (i = 0;i < n_ele;i ++) {
00705     GeometryBM& ele = regular_mesh->geometry(DIM,i);
00706     ele = tmp_ele[new_index[i]];
00707     ele.index() = i;
00708     old_index[new_index[i]] = i;
00709 #ifdef __SERIALIZATION__
00710     regular_mesh->h_geometry_ptr[DIM][i] = hgp[new_index[i]];
00711 #endif
00712   }
00713   ActiveIterator 
00714     the_ele = beginActiveElement(),
00715     end_ele = endActiveElement();
00716   for (;the_ele != end_ele;++ the_ele) {
00717     the_ele->index = old_index[the_ele->index];
00718   }
00719   std::cerr << " OK!" << std::endl;
00720 }
00721 
00722 #undef THIS /// IrregularMesh<DIM,DOW>
00723 
00725 
00726 TEMPLATE std::ostream& 
00727 operator<<(std::ostream& os, const HGeometry<DIM,DOW>& geometry)
00728 {
00729   for (int i = 0;i < geometry.n_boundary;i ++)
00730     os << *(geometry.boundary[i]);
00731   return os;
00732 }
00733 
00734 TEMPLATE
00735 std::ostream& operator<<(std::ostream& os, const HElement<DIM, DOW>& element)
00736 {
00737   if (element.value == 1) {
00738     for (int i = 0;i < element.n_child;i ++) {
00739       os << *(element.child[i]);
00740     }
00741   }
00742   else if (element.value == 0) {
00743     os << *(element.h_element);
00744   }
00745   else {
00746     Assert(false, ExcInternalError()); // what happeden? something must be wrong!
00747   }
00748   return os;
00749 }
00750 
00751 TEMPLATE
00752 std::ostream& operator<<(std::ostream& os, IrregularMesh<DIM, DOW>& mesh)
00753 {
00754   //    IrregularMesh<DIM, DOW>::RootElementIterator the_ele = mesh.beginRootElement();
00755   //    IrregularMesh<DIM, DOW>::RootElementIterator end_ele = mesh.endRootElement();
00756   //    for (;the_ele != end_ele;++ the_ele)
00757   //            os << *the_ele;
00759   //    ActiveElementIterator<DIM, DOW> the_ele = mesh.beginActiveElement();
00760   //    ActiveElementIterator<DIM, DOW> end_ele = mesh.endActiveElement();
00761   //    for (;the_ele != end_ele;++ the_ele)
00762   //            os << *(the_ele->h_element);
00763   return os;
00764 }
00765 
00766 TEMPLATE
00767 ElementIterator<DIM, DOW>::ElementIterator() :
00768   mesh(NULL), element(NULL) {}
00769 
00771 
00772 #define THIS ElementIterator<DIM,DOW>
00773 
00774 TEMPLATE
00775 THIS::ElementIterator(IrregularMesh<DIM, DOW> * m, 
00776                       root_t& r, 
00777                       HElement<DIM, DOW> * e) :
00778 mesh(m), root_element(r), element(e) {}
00779 
00780 TEMPLATE
00781 THIS::ElementIterator(const ElementIterator<DIM, DOW>& it) :
00782 mesh(it.mesh), root_element(it.root_element), element(it.element) {}
00783 
00784 TEMPLATE
00785 THIS::~ElementIterator()
00786 {}
00787 
00788 TEMPLATE
00789 ElementIterator<DIM, DOW>& THIS::operator=(const ElementIterator<DIM, DOW>& it)
00790 {
00791   mesh = it.mesh;
00792   root_element = it.root_element;
00793   element = it.element;
00794   return *this;
00795 }
00796 
00797 #undef THIS /// ElementIterator<DIM,DOW>
00798 
00800 
00801 TEMPLATE
00802 bool operator==(const ElementIterator<DIM, DOW>& it0,
00803                 ElementIterator<DIM, DOW>& it1)
00804 {
00805   return (it0.mesh == it1.mesh &&
00806           it0.root_element == it1.root_element &&
00807           it0.element == it1.element);
00808 }
00809 
00810 TEMPLATE
00811 bool operator!=(const ElementIterator<DIM, DOW>& it0,
00812                 ElementIterator<DIM, DOW>& it1)
00813 {
00814   return (it0.mesh != it1.mesh ||
00815           it0.root_element != it1.root_element ||
00816           it0.element != it1.element);
00817 }
00818 
00820 
00824 TEMPLATE
00825 RootFirstElementIterator<DIM, DOW>& 
00826   RootFirstElementIterator<DIM, DOW>::operator++()
00827 {
00828   if (element == NULL) return *this; // do nothing
00829   else if (element->value == 1) { 
00830     element = element->child[0];
00831   } else {
00832     assert (element->value == 0);
00833 
00834     HElement<DIM, DOW> * child = element;
00835     HElement<DIM, DOW> * parent = child->parent;
00836     while (parent != NULL) {
00837       if (child != parent->child[n_child - 1]) break;
00838       child = parent;
00839       parent = child->parent;
00840     };
00841     if (parent == NULL) {
00842       ++ root_element;
00843       if (root_element == mesh->rootElement().end()) {
00844         element = NULL;
00845       } else {
00846         element = *(root_element);
00847       }
00848     } else {
00849       int i = 0;
00850       for (;child != parent->child[i];++ i) {} 
00851       element = parent->child[++ i];
00852     }
00853   }
00854   return *this;
00855 }
00856 
00857 TEMPLATE
00858 ActiveElementIterator<DIM, DOW>& 
00859   ActiveElementIterator<DIM, DOW>::operator++()
00860 {
00861   do {
00862     RootFirstElementIterator<DIM, DOW>::operator++();
00863     if (this->element == NULL) break;
00864   } while (this->element->value > 0);
00865   return *this;
00866 }
00867 
00869 
00870 #define THIS IrregularMeshPair<DIM, DOW>
00871 
00872 TEMPLATE
00873 THIS::IrregularMeshPair(ir_mesh_t& m0, ir_mesh_t& m1) :
00874 mesh0(&m0), mesh1(&m1)
00875 {
00876   Assert(mesh0->geometry_tree == mesh1->geometry_tree, ExcInternalError());
00877 }
00878 
00879 TEMPLATE
00880 THIS::IrregularMeshPair(ir_mesh_t * m0, ir_mesh_t * m1) :
00881 mesh0(m0), mesh1(m1)
00882 {
00883   Assert(mesh0->geometry_tree == mesh1->geometry_tree, ExcInternalError());
00884 }
00885 
00886 TEMPLATE
00887 THIS::~IrregularMeshPair()
00888 {}
00889 
00890 TEMPLATE
00891 typename THIS::iterator THIS::beginActiveElementPair()
00892 {
00893   RootFirstElementIterator<DIM, DOW> 
00894     it0 = mesh0->beginRootFirstElement(),
00895     it1 = mesh1->beginRootFirstElement();
00896         
00897   while ((*it0).value == 1 && (*it1).value == 1) {
00898     ++ it0; ++ it1;
00899   }
00900   typename iterator::State state;
00901   if ((*it0).value == 0 && (*it1).value == 0) {
00902     state = iterator::EQUAL;
00903   }
00904   else if ((*it0).value == 0) { // then (*it1).value == 1
00905     while ((*it1).value > 0) ++ it1;
00906     state = iterator::GREAT_THAN;
00907   }
00908   else { // then (*it0).value == 1 && (*it1).value == 0
00909     while ((*it0).value > 0) ++ it0;
00910     state = iterator::LESS_THAN;
00911   }
00912   return iterator(this, state, it0, it1);
00913 }
00914 
00915 TEMPLATE
00916 typename THIS::iterator THIS::endActiveElementPair()
00917 {
00918   RootFirstElementIterator<DIM, DOW> 
00919     it0 = mesh0->endRootFirstElement(),
00920     it1 = mesh1->endRootFirstElement();
00921   return iterator(this, iterator::EQUAL, it0, it1);
00922 }
00923 
00924 #undef THIS /// IrregularMeshPair<DIM, DOW>
00925 
00927 
00928 #define THIS ActiveElementPairIterator<DIM, DOW>
00929 
00930 TEMPLATE
00931 THIS::ActiveElementPairIterator(const THIS& i) :
00932 mesh_pair(i.mesh_pair), st(i.st),
00933   iterator0(i.iterator0), iterator1(i.iterator1) {}
00934 
00935 TEMPLATE
00936 THIS& THIS::operator=(const THIS& i)
00937 {
00938   mesh_pair = i.mesh_pair;
00939   st = i.st;
00940   iterator0 = i.iterator0;
00941   iterator1 = i.iterator1;
00942         
00943   return *this;
00944 }
00945 
00946 TEMPLATE
00947 THIS& THIS::operator++()
00948 {
00949   if (iterator0.element == NULL && iterator1.element == NULL) {
00950     Assert(st == EQUAL, ExcInternalError());
00951   } else if (st == EQUAL) {
00952     ++ iterator0;
00953     ++ iterator1;
00954     if (iterator0.element == NULL || iterator1.element == NULL) {
00955       Assert (iterator0.element == NULL && iterator1.element == NULL, ExcInternalError());
00956       return *this;
00957     }
00958     while (iterator0->value > 0 && iterator1->value > 0) {
00959       ++ iterator0;
00960       ++ iterator1;
00961       if (iterator0.element == NULL || iterator1.element == NULL) {
00962         Assert(iterator0.element == NULL && iterator1.element == NULL, ExcInternalError());
00963         return *this;
00964       }
00965     };
00966     if (iterator0->value == 0 && iterator1->value == 0) {
00967       st = EQUAL;
00968     } else if (iterator0->value == 0) { // then iterator1->value > 0
00969       while (iterator1->value > 0) ++ iterator1;
00970       st = GREAT_THAN;
00971     } else { // iterator0->value > 0 && iterator1->value == 0
00972       while (iterator0->value > 0) ++ iterator0;
00973       st = LESS_THAN;
00974     }
00975   } else if (st == GREAT_THAN) {
00976     RootFirstElementIterator<DIM, DOW> next0 = iterator0;
00977     ++ next0;
00978     ++ iterator1;
00979     if (iterator1.element == NULL) {
00980       Assert(next0.element == NULL, ExcInternalError());
00981       iterator0 = next0;
00982       st = EQUAL;
00983     } else if (next0.element == NULL) {
00984       while (iterator1->value > 0) ++ iterator1;
00985     } else if (next0->h_element == iterator1->h_element) {
00986       iterator0 = next0;
00987       while (iterator0->value > 0 && iterator1->value > 0) {
00988         ++ iterator0;
00989         ++ iterator1;
00990       };
00991       if (iterator0->value == 0 && iterator1->value == 0) {
00992         st = EQUAL;
00993       } else if (iterator0->value == 0) { // then iterator1->value > 0
00994         while (iterator1->value > 0) ++ iterator1;
00995         st = GREAT_THAN;
00996       } else { // iterator0->value > 0 && iterator1->value == 0
00997         while (iterator0->value > 0) ++ iterator0;
00998         st = LESS_THAN;
00999       }
01000     } else {
01001       while (iterator1->value > 0) ++ iterator1;
01002     }
01003   } else { // st == LESS_THAN
01004     RootFirstElementIterator<DIM, DOW> next1 = iterator1;
01005     ++ next1;
01006     ++ iterator0;
01007     if (iterator0.element == NULL) {
01008       Assert(next1.element == NULL, ExcInternalError());
01009       iterator1 = next1;
01010       st = EQUAL;
01011     } else if (next1.element == NULL) {
01012       while (iterator0->value > 0) ++ iterator0;
01013     } else if (next1->h_element == iterator0->h_element) {
01014       iterator1 = next1;
01015       while (iterator0->value > 0 && iterator1->value > 0) {
01016         ++ iterator0;
01017         ++ iterator1;
01018       };
01019       if (iterator0->value == 0 && iterator1->value == 0) {
01020         st = EQUAL;
01021       } else if (iterator0->value == 0) { // then iterator1->value > 0
01022         while (iterator1->value > 0) ++ iterator1;
01023         st = GREAT_THAN;
01024       } else { // iterator0->value > 0 && iterator1->value == 0
01025         while (iterator0->value > 0) ++ iterator0;
01026         st = LESS_THAN;
01027       }
01028     } else {
01029       while (iterator0->value > 0) ++ iterator0;
01030     }
01031   }
01032   return *this;
01033 }
01034 
01035 TEMPLATE
01036 bool operator==(const THIS& i0,
01037                 THIS& i1)
01038 {
01039   return (i0.mesh_pair == i1.mesh_pair &&
01040           i0.st == i1.st &&
01041           i0.iterator0 == i1.iterator0 &&
01042           i0.iterator1 == i1.iterator1);
01043 }
01044 
01045 TEMPLATE
01046 bool operator!=(const THIS& i0,
01047                 THIS& i1)
01048 {
01049   return (i0.mesh_pair != i1.mesh_pair ||
01050           i0.st != i1.st ||
01051           i0.iterator0 != i1.iterator0 ||
01052           i0.iterator1 != i1.iterator1);
01053 }
01054 
01055 #undef THIS /// ActiveElementPairIterator<DIM, DOW>
01056 
01058 
01059 #define THIS MeshAdaptor<DIM, DOW>
01060 
01061 TEMPLATE
01062 THIS::MeshAdaptor() :
01063 from_mesh(NULL),
01064   to_mesh(NULL),
01065   ind(NULL),
01066   convergence_order(1),
01067   refine_step(1),
01068   refine_threshold(1.33333),
01069   coarse_threshold(0.75),
01070   _is_refine_only(false)
01071 {}
01072 
01073 
01074 
01075 TEMPLATE
01076 THIS::MeshAdaptor(ir_mesh_t& f) :
01077 from_mesh(&f), 
01078   to_mesh(&f),
01079   ind(NULL),
01080   convergence_order(1),
01081   refine_step(1),
01082   refine_threshold(1.33333),
01083   coarse_threshold(0.75),
01084   _is_refine_only(false) 
01085 {}
01086 
01087 
01088 
01089 TEMPLATE
01090 THIS::MeshAdaptor(ir_mesh_t& f, ir_mesh_t& t) :
01091 from_mesh(&f), 
01092   to_mesh(&t),
01093   ind(NULL),
01094   convergence_order(1),
01095   refine_step(1),
01096   refine_threshold(1.33333),
01097   coarse_threshold(0.75),
01098   _is_refine_only(false) 
01099 {}
01100 
01101 
01102 
01103 TEMPLATE
01104 THIS::~MeshAdaptor()
01105 {}
01106 
01107 
01108 
01109 TEMPLATE
01110 void THIS::globalRefine(unsigned int s)
01111 {
01112   typedef typename ir_mesh_t::ActiveIterator iterator;
01113   std::cerr << "Global refine the mesh ..." << std::endl;
01114   for (unsigned int i = 0;i < s;i ++) {
01115     std::cerr << "\r\tround " << i+1 << " ..." << std::flush;
01116     iterator
01117       the_active_ele = to_mesh->beginActiveElement(),
01118       end_active_ele = to_mesh->endActiveElement();
01119     for (;the_active_ele != end_active_ele;) {
01120       iterator the_ele = the_active_ele;
01121       ++ the_active_ele;
01122       the_ele->refine();
01123       the_ele->value = 1;
01124       for (int k = 0;k < the_ele->n_child;k ++) {
01125         the_ele->child[k]->value = 0;
01126       }
01127     }
01128   }
01129   std::cerr << std::endl;
01130 }
01131 
01132 
01133 
01134 TEMPLATE
01135 void THIS::randomRefine(double percent)
01136 {
01137   typedef typename ir_mesh_t::ActiveIterator iterator;
01138   std::cerr << "Randomly refine the mesh ..." << std::endl;
01139   iterator
01140     the_active_ele = to_mesh->beginActiveElement(),
01141     end_active_ele = to_mesh->endActiveElement();
01142   for (;the_active_ele != end_active_ele;) {
01143     iterator the_ele = the_active_ele;
01144     ++ the_active_ele;
01145     int r = rand();
01146     if (100.0*r >= RAND_MAX*percent) continue;
01147 
01148     the_ele->refine();
01149     the_ele->value = 1;
01150     for (int k = 0;k < the_ele->n_child;k ++) {
01151       the_ele->child[k]->value = 0;
01152     }
01153   }
01154   std::cerr << std::endl;
01155 }
01156 
01157 
01158 
01159 TEMPLATE
01160 void THIS::adapt()
01161 {
01162   prepareToMesh();
01163   collectIndicator();
01164   implementAdaption();
01165 }
01166 
01167 TEMPLATE
01168 void THIS::collectIndicator(HElement<DIM,DOW>& ele,
01169                             double convergenceCoefficient) 
01170 {
01171   if (ele.value == 0) {
01172     ele.indicator = indicator(ele.index);
01173   } else {
01174     int n_chd = 0;
01175     ele.indicator = 0.0;
01176     for (int i = 0;i < ele.n_child;++ i) {
01177       HElement<DIM,DOW> * p_chd = ele.child[i];
01178       collectIndicator(*p_chd, convergenceCoefficient);
01179       ele.indicator += p_chd->indicator;
01180       n_chd += 1;
01181     }
01182     ele.indicator *= convergenceCoefficient*ele.n_child/n_chd;
01183   }
01184 }
01185 
01186 TEMPLATE
01187 void THIS::collectIndicator()
01188 {
01189   double c = pow(2.0, convergenceOrder());
01190   typename ir_mesh_t::RootIterator
01191     the_root = to_mesh->beginRootElement(),
01192     end_root = to_mesh->endRootElement();
01193   for (;the_root != end_root;++ the_root) {
01194     this->collectIndicator(*the_root, c);
01195   }
01196 }
01197 
01198 
01199 
01200 TEMPLATE
01201 void THIS::prepareToMesh()
01202 {
01203   if (from_mesh == to_mesh) return;
01204   *to_mesh = *from_mesh;
01205 }
01206 
01207 TEMPLATE
01208 void THIS::adaptElement(HElement<DIM,DOW>& ele,
01209                         double convergenceCoefficient,
01210                         int refine_level) {
01211   if ((! is_refine_only()) && is_indicator_underflow(ele.indicator)) {
01212     ele.value = 0; 
01213   } else if (ele.value == 0 && 
01214              refine_level <= refine_step && 
01215              is_indicator_overflow(ele.indicator, convergenceCoefficient)) { 
01216     ele.refine(); 
01217     ele.value = 1; 
01218     for (int k = 0;k < ele.n_child;k ++) { 
01219       ele.child[k]->value = 0; 
01220 
01221       ele.child[k]->indicator = ele.indicator/convergenceCoefficient;
01223       adaptElement(*ele.child[k], convergenceCoefficient, refine_level + 1);
01224     }
01225   } else if (ele.value == 1) { 
01226     for (int i = 0;i < ele.n_child;i ++) {
01227       adaptElement(*ele.child[i], convergenceCoefficient, refine_level);
01228     }
01229   }
01230 }
01231 
01232 TEMPLATE
01233 void THIS::implementAdaption()
01234 {
01235   std::cerr << "Implementing mesh adaption ..." << std::flush;
01236   double convergenceCoefficient = pow(2.0, DIM + convergenceOrder());
01237   typename ir_mesh_t::RootIterator
01238     the_root = to_mesh->beginRootElement(),
01239     end_root = to_mesh->endRootElement();
01240   for (;the_root != end_root;++ the_root) {
01241     this->adaptElement(*the_root, convergenceCoefficient, 0);
01242   }
01243   std::cerr << " OK!" << std::endl;
01244 }
01245 
01246 #undef THIS /// MeshAdaptor<DIM,DOW>
01247 
01249 
01250 #define THIS RegularMesh<DIM,DOW>
01251 
01252 TEMPLATE
01253   void THIS::renumerateElementHSFC(void (*f)(double,double,double,double&,double&,double&))
01254 {
01255   std::cerr << "Renumerating element of the mesh using Hibert space curve filling ..." 
01256             << std::flush;
01257   int n_ele = this->n_geometry(DIM);
01258   std::vector<double> x(n_ele, 0.0), y(n_ele, 0.0), z(n_ele, 0.0);
01259   for (int i = 0;i < n_ele;++ i) {
01260     GeometryBM& ele = this->geometry(DIM, i);
01261     int n_vtx = ele.n_vertex();
01262     for (int j = 0;j < n_vtx;++ j) {
01263       int vtx_idx = this->geometry(0, ele.vertex(j)).vertex(0);
01264       Point<DOW>& pnt = this->point(vtx_idx);
01265       x[i] += pnt[0]; y[i] += pnt[1];
01266       if (DOW == 3) z[i] += pnt[2];
01267     }
01268     x[i] /= n_vtx; y[i] /= n_vtx;
01269     if (DOW == 3) z[i] /= n_vtx;
01270   }
01271   std::vector<int> new_index(n_ele);
01272   if (f == NULL) {
01273     hsfc_renumerate(n_ele, &x[0], &y[0], &z[0], &new_index[0]);
01274   } else {
01275     hsfc_renumerate(n_ele, &x[0], &y[0], &z[0], &new_index[0], f);
01276   }
01277 
01278   std::vector<GeometryBM> tmp_ele(this->geometry(DIM));
01279   std::vector<int> old_index(n_ele);
01280 #ifdef __SERIALIZATION__
01281   std::vector<HBuffer*> hgp(h_geometry_ptr[DIM]);
01282 #endif
01283   for (int i = 0;i < n_ele;i ++) {
01284     GeometryBM& ele = this->geometry(DIM,i);
01285     ele = tmp_ele[new_index[i]];
01286     ele.index() = i;
01287     old_index[new_index[i]] = i;
01288 #ifdef __SERIALIZATION__
01289     h_geometry_ptr[DIM][i] = hgp[new_index[i]];
01290 #endif
01291   }
01292   typename ir_mesh_t::ActiveIterator 
01293     the_ele = irregularMesh().beginActiveElement(),
01294     end_ele = irregularMesh().endActiveElement();
01295   for (;the_ele != end_ele;++ the_ele) {
01296     the_ele->index = old_index[the_ele->index];
01297   }
01298   std::cerr << " OK!" << std::endl;
01299 }
01300 
01301 TEMPLATE
01302 void THIS::writeEasyMesh(const std::string& filename) const
01303 {
01304   Assert (DIM == 2, ExcInternalError());
01305 }
01306 
01307 
01308 
01309 TEMPLATE
01310 void THIS::writeTecplotData(const std::string& filename) const
01311 {}
01312 
01313 #undef TEMPLATE
01314 
01315 #endif // _HGeometry_templates_h_
01316