|
AFEPack
|
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
1.7.4