ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_BND_READER_HPP 00002 #define VIENNAGRID_BND_READER_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 #include "viennagrid/io/helper.hpp" 00017 // #include "viennagrid/io/bnd.hpp" 00018 #include "viennagrid/mesh/element_creation.hpp" 00019 00025 namespace viennagrid 00026 { 00027 namespace io 00028 { 00029 /* 00030 INFORMATION ON THE BND FILE FORMAT: 00031 00032 --## tested with the generated bnd files of the Synopsis Structure Editor E-2010.12 ##-- 00033 00034 ELEMENT TYPES: 00035 type 10: polyhedron used in 3d bnd files for the segment description 00036 syntax: 10 number_of_faces face-index0 face-index1 ... face-index-n 00037 00038 type 4: polygon used in 2d bnd files for the segment description 00039 syntax: 4 number_of_faces face-index0 face-index1 ... face-index-n 00040 00041 type 2: triangle informally also known as 'direct' or 'contact' triangle, used in 3d bnd files 00042 syntax: 2 edge-index0 edge-index1 edge-index2 00043 00044 type 1: line informally also known as 'direct' or 'contact' line, used in 2d bnd files 00045 syntax: 1 vertex-index0 vertex-index1 00046 00047 CONTACTS: 00048 in 3d, only faces can be contacts. although the synopsis structure editor 00049 allows to declare an edge to be a contact, it is not exported to the bnd file. 00050 a 3d-contact is defined by a type '2' element, which refers to _three_ edges, 00051 and they again to the points. which makes sense, because the 2d polygon, 00052 which can be a face in 3d, is a triangle (that's why it's called a simplex, btw ..) 00053 so, for example, a quardilateral contact consists therefore of two type '2' elements. 00054 00055 in 2d, respectively, only edges can be contacts. 00056 a 2d-contact is defined by a type '1' element, which refers to two points, hence an edge 00057 */ 00058 00059 struct print 00060 { 00061 template<typename T1, std::size_t Size> 00062 void operator()(viennagrid::static_array<T1, Size> const& vec, std::ostream& ostr = std::cout) 00063 { 00064 for(typename viennagrid::static_array<T1, Size>::const_iterator iter = vec.begin(); 00065 iter != vec.end(); iter++) 00066 { 00067 ostr << *iter << " "; 00068 } 00069 std::cout << std::endl; 00070 } 00071 00072 template<typename T1, std::size_t Size> 00073 void operator()(viennagrid::static_array<T1, Size> & vec, std::ostream& ostr = std::cout) 00074 { 00075 for(typename viennagrid::static_array<T1, Size>::iterator iter = vec.begin(); 00076 iter != vec.end(); iter++) 00077 { 00078 ostr << *iter << " "; 00079 } 00080 std::cout << std::endl; 00081 } 00082 00083 template<typename T1> 00084 void operator()(std::vector<T1> const& vec, std::ostream& ostr = std::cout) 00085 { 00086 for(typename std::vector<T1>::const_iterator iter = vec.begin(); 00087 iter != vec.end(); iter++) 00088 { 00089 ostr << *iter << " "; 00090 } 00091 std::cout << std::endl; 00092 } 00093 00094 template<typename T1> 00095 void operator()(std::vector<T1> & vec, std::ostream& ostr = std::cout) 00096 { 00097 for(typename std::vector<T1>::iterator iter = vec.begin(); 00098 iter != vec.end(); iter++) 00099 { 00100 ostr << *iter << " "; 00101 } 00102 std::cout << std::endl; 00103 } 00104 00105 template<typename T0, typename T1> 00106 void operator()(std::map<T0, T1> const& vec, std::ostream& ostr = std::cout) 00107 { 00108 for(typename std::map<T0, T1>::const_iterator iter = vec.begin(); 00109 iter != vec.end(); iter++) 00110 { 00111 ostr << iter->first << " - " << iter->second << std::endl; 00112 } 00113 } 00114 00115 template<typename T0, typename T1> 00116 void operator()(std::map<T0, T1> & vec, std::ostream& ostr = std::cout) 00117 { 00118 for(typename std::map<T0, T1>::iterator iter = vec.begin(); 00119 iter != vec.end(); iter++) 00120 { 00121 ostr << iter->first << " - " << iter->second << std::endl; 00122 } 00123 } 00124 }; 00125 00126 struct boolalpha_bool; 00127 00128 namespace detail 00129 { 00130 template<typename DestinationT> 00131 struct lexical_cast_impl 00132 { 00133 public: 00134 typedef DestinationT result_type; 00135 00136 template<typename SourceT> 00137 lexical_cast_impl(SourceT const & src) 00138 { 00139 ss << src; 00140 } 00141 00142 operator result_type() 00143 { 00144 result_type tmp; 00145 ss >> tmp; 00146 return tmp; 00147 } 00148 00149 private: 00150 std::stringstream ss; 00151 }; 00152 00153 template<> 00154 struct lexical_cast_impl<boolalpha_bool> 00155 { 00156 public: 00157 typedef bool result_type; 00158 00159 template<typename SourceT> 00160 lexical_cast_impl(SourceT const & src) 00161 { 00162 ss << std::boolalpha << src; 00163 } 00164 00165 operator result_type() 00166 { 00167 result_type tmp; 00168 ss >> std::boolalpha >> tmp; 00169 return tmp; 00170 } 00171 00172 private: 00173 std::stringstream ss; 00174 }; 00175 } 00176 00177 template<typename DestinationT, typename SourceT> 00178 typename detail::lexical_cast_impl<DestinationT>::result_type lexical_cast( SourceT const & src ) 00179 { 00180 return detail::lexical_cast_impl<DestinationT>(src); 00181 } 00182 00183 00184 inline std::string remove_begin_end_chars( std::string const & str ) 00185 { 00186 std::string::size_type start = 0; 00187 for (; start != str.size(); ++start) 00188 { 00189 char const & cur = str[start]; 00190 if ((cur != ' ') && (cur != '\n') && (cur != '\t')) 00191 break; 00192 } 00193 00194 std::string::size_type end = str.size()-1; 00195 for (; end != std::size_t(-1); --end) 00196 { 00197 char const & cur = str[end]; 00198 if ((cur != ' ') && (cur != '\n') && (cur != '\t')) 00199 break; 00200 } 00201 00202 return str.substr( start, end-start+1 ); 00203 } 00204 00205 00206 00207 00208 struct bnd_helper 00209 { 00210 00211 typedef double numeric_type; 00212 //typedef viennagrid::static_array<numeric_type, DIMG> point_type; 00213 typedef std::vector<numeric_type> point_type; 00214 typedef std::vector<point_type> geometry_container_type; 00215 00216 typedef long index_type; 00217 00218 typedef std::vector< index_type > edge_type; 00219 typedef std::vector<edge_type> edge_container_type; 00220 00221 00222 typedef std::vector< index_type > polygon_type; 00223 typedef std::vector< polygon_type > polygon_container_type; 00224 00225 // a contact can be a line (2d) or a triangle (3d) 00226 typedef std::vector< index_type > contact_face_type; 00227 typedef std::vector< contact_face_type > contact_face_container_type; 00228 typedef std::vector< contact_face_container_type > contact_groups_type; 00229 00230 // segment name, material container 00231 typedef std::vector<std::pair<std::string, std::string> > segment_id_container_type; 00232 00233 // contact name container 00234 typedef std::vector<std::string> contact_id_container_type; 00235 00236 // a domain-segment is a set of polygons 00237 // 00238 typedef std::vector<polygon_container_type> domain_type; 00239 00240 00241 int operator()(std::string const & filename) 00242 { 00243 std::ifstream reader(filename.c_str()); 00244 00245 if (!reader){ 00246 std::cerr << "Cannot open file " << filename << std::endl; 00247 throw cannot_open_file_exception("* ViennaGrid: bnd_helper::operator(): File " + filename + ": Cannot open file!"); 00248 } 00249 00250 try{ 00251 00252 std::string token; 00253 00254 #ifdef VIENNAGRID_DEBUG_IO 00255 std::cout << "reading geometry dimension .. " << std::endl; 00256 #endif 00257 int DIMG; 00258 while(1) 00259 { 00260 reader >> token; 00261 if(token == "dimension") 00262 { 00263 reader >> token; 00264 reader >> DIMG; 00265 break; 00266 } 00267 } 00268 #ifdef VIENNAGRID_DEBUG_IO 00269 std::cout << "geometry dimension: " << DIMG << std::endl; 00270 #endif 00271 dim_geometry = DIMG; 00272 00273 #ifdef VIENNAGRID_DEBUG_IO 00274 std::cout << "reading region information .. " << std::endl; 00275 #endif 00276 while(1) 00277 { 00278 reader >> token; 00279 if(token == "nb_regions") 00280 { 00281 reader >> token; 00282 reader >> number_of_regions; 00283 break; 00284 } 00285 } 00286 #ifdef VIENNAGRID_DEBUG_IO 00287 std::cout << "number of regions: " << number_of_regions << std::endl; 00288 #endif 00289 00290 00291 00292 std::size_t vertices = 0; 00293 00294 #ifdef VIENNAGRID_DEBUG_IO 00295 std::cout << "reading geometry information .. " << std::endl; 00296 #endif 00297 00298 while(1) 00299 { 00300 std::getline(reader, token); 00301 00302 if(token.find("Vertices") != std::string::npos) 00303 { 00304 std::string::size_type delimiter_left = token.find("(")+1; 00305 std::string::size_type delimiter_right = token.find(")"); 00306 std::string vertices_str = token.substr(delimiter_left, delimiter_right-delimiter_left); 00307 vertices = lexical_cast<std::size_t>(vertices_str); 00308 break; 00309 } 00310 } 00311 00312 #ifdef VIENNAGRID_DEBUG_IO 00313 std::cout << "vertices: " << vertices << std::endl; 00314 #endif 00315 00316 geometry.resize(vertices); 00317 00318 point_type coords(DIMG); 00319 00320 for(std::size_t vi = 0; vi < vertices; vi++) 00321 { 00322 for (int j=0; j < DIMG; j++) 00323 { 00324 reader >> coords[j]; 00325 } 00326 geometry[vi] = coords; 00327 } 00328 00329 #ifdef VIENNAGRID_DEBUG_IO 00330 std::cout << " finished loading point vectors .. " << std::endl; 00331 #endif 00332 00333 #ifdef VIENNAGRID_DEBUG_IO 00334 std::cout << "reading topology information .. " << std::endl; 00335 #endif 00336 00337 00338 #ifdef VIENNAGRID_DEBUG_IO 00339 std::cout << "reading edge information .. " << std::endl; 00340 #endif 00341 00342 std::size_t edges = 0; 00343 00344 while(1) 00345 { 00346 std::getline(reader, token); 00347 00348 if(token.find("Edges") != std::string::npos) 00349 { 00350 std::string::size_type delimiter_left = token.find("(")+1; 00351 std::string::size_type delimiter_right = token.find(")"); 00352 std::string edges_str = token.substr(delimiter_left, delimiter_right-delimiter_left); 00353 edges = lexical_cast<std::size_t>(edges_str); 00354 break; 00355 } 00356 } 00357 00358 #ifdef VIENNAGRID_DEBUG_IO 00359 std::cout << "edges: " << edges << std::endl; 00360 #endif 00361 00362 edge_cont.resize(edges); 00363 00364 edge_type edge(2); 00365 for(std::size_t i = 0; i < edges; i++) 00366 { 00367 reader >> edge[0]; 00368 reader >> edge[1]; 00369 edge_cont[i] = edge; 00370 } 00371 00372 #ifdef VIENNAGRID_DEBUG_IO 00373 std::cout << " finished loading edges .. " << std::endl; 00374 #endif 00375 00376 if(DIMG == 3) 00377 { 00378 std::size_t faces = 0; 00379 00380 while(1) 00381 { 00382 std::getline(reader, token); 00383 00384 if(token.find("Faces") != std::string::npos) 00385 { 00386 std::string::size_type delimiter_left = token.find("(")+1; 00387 std::string::size_type delimiter_right = token.find(")"); 00388 std::string faces_str = token.substr(delimiter_left, delimiter_right-delimiter_left); 00389 faces = lexical_cast<std::size_t>(faces_str); 00390 break; 00391 } 00392 } 00393 00394 #ifdef VIENNAGRID_DEBUG_IO 00395 std::cout << "faces: " << faces << std::endl; 00396 #endif 00397 00398 polygon_cont.resize(faces); 00399 00400 std::size_t face_dim = 0; 00401 00402 for(std::size_t fi = 0; fi < faces; fi++) 00403 { 00404 reader >> face_dim; // number of vertices of this face 00405 00406 //std::cout << "face dim: " << face_dim << std::endl; 00407 00408 polygon_cont[fi].resize(face_dim); 00409 00410 for (std::size_t j=0; j < face_dim; j++) 00411 { 00412 reader >> polygon_cont[fi][j]; 00413 } 00414 } 00415 00416 #ifdef VIENNAGRID_DEBUG_IO 00417 std::cout << " finished loading faces .. " << std::endl; 00418 #endif 00419 } // end DIMG == 3 00420 00421 #ifdef VIENNAGRID_DEBUG_IO 00422 std::cout << "reading segment information .. " << std::endl; 00423 #endif 00424 00425 std::size_t elements = 0; 00426 00427 while(1) 00428 { 00429 std::getline(reader, token); 00430 00431 if(token.find("Elements") != std::string::npos) 00432 { 00433 std::string::size_type delimiter_left = token.find("(")+1; 00434 std::string::size_type delimiter_right = token.find(")"); 00435 std::string elements_str = token.substr(delimiter_left, delimiter_right-delimiter_left); 00436 elements = lexical_cast<std::size_t>(elements_str); 00437 break; 00438 } 00439 } 00440 00441 #ifdef VIENNAGRID_DEBUG_IO 00442 std::cout << "elements: " << elements << std::endl; 00443 #endif 00444 00445 domain.resize(elements); 00446 00447 for(std::size_t i = 0; i < elements; i++) 00448 { 00449 reader >> token; // element type, ie, 10 ... polyhedron 00450 00451 if(token == "10") // aka a 3d bnd file segment 00452 { 00453 std::size_t element_faces = 0; 00454 reader >> element_faces; 00455 00456 #ifdef VIENNAGRID_DEBUG_IO 00457 std::cout << " type: segment-polyhedron" << std::endl; 00458 std::cout << " element: " << i << " - faces: " << element_faces << std::endl; 00459 #endif 00460 00461 for(std::size_t f = 0; f < element_faces; f++) 00462 { 00463 index_type face; 00464 reader >> face; 00465 index_type mapped_face = map(face); 00466 00467 polygon_type polygon = polygon_cont[mapped_face]; 00468 00469 polygon_type polygon_new; 00470 std::map<index_type, bool> uniquer; 00471 00472 for(std::size_t vi = 0; vi < polygon.size(); vi++) 00473 { 00474 index_type vertex = polygon[vi]; 00475 index_type mapped_vertex = map(vertex); 00476 00477 edge_type edge = edge_cont[mapped_vertex]; 00478 00479 if(vertex < 0) std::reverse(edge.begin(),edge.end()); 00480 00481 if(!uniquer[edge[0]]) 00482 { 00483 polygon_new.push_back(edge[0]); 00484 uniquer[edge[0]] = true; 00485 } 00486 if(!uniquer[edge[1]]) 00487 { 00488 polygon_new.push_back(edge[1]); 00489 uniquer[edge[1]] = true; 00490 } 00491 } 00492 //std::cout << "adapt: " << polygon_new; 00493 domain[i].push_back(polygon_new); 00494 } 00495 } 00496 else if(token == "4") // aka a 2d bnd file segment 00497 { 00498 std::size_t element_faces = 0; 00499 reader >> element_faces; 00500 00501 #ifdef VIENNAGRID_DEBUG_IO 00502 std::cout << " type: segment-polygon" << std::endl; 00503 std::cout << " element: " << i << " - linesegments: " << element_faces << std::endl; 00504 #endif 00505 00506 for(std::size_t f = 0; f < element_faces; f++) 00507 { 00508 index_type face; 00509 reader >> face; 00510 index_type mapped_face = map(face); 00511 00512 edge_type edge = edge_cont[mapped_face]; 00513 00514 //std::cout << "adapt: " << polygon_new; 00515 //std::cout << "adding edge: " << edge[0] << " " << edge[1] << std::endl; 00516 domain[i].push_back(edge); 00517 } 00518 00519 } 00520 else if(token == "2") // aka a 3d bnd file contact 00521 { 00522 // reader >> token; 00523 // reader >> token; 00524 // reader >> token; 00525 // domain.resize(domain.size()-1); 00526 #ifdef VIENNAGRID_DEBUG_IO 00527 std::cout << " type: contact-triangle" << std::endl; 00528 #endif 00529 contact_face_type contact_face(3); 00530 reader >> contact_face[0]; 00531 reader >> contact_face[1]; 00532 reader >> contact_face[2]; 00533 //std::cout << contact_face[0] << " " << contact_face[1] << " " << contact_face[2] << std::endl; 00534 contact_face_cont.push_back(contact_face); 00535 00536 // we have to reduce the domain size, as this is not a valid segment 00537 domain.resize(domain.size()-1); 00538 } 00539 else if(token == "1") // aka a 2d bnd file contact 00540 { 00541 // reader >> token; 00542 // reader >> token; 00543 // domain.resize(domain.size()-1); 00544 #ifdef VIENNAGRID_DEBUG_IO 00545 std::cout << " type: contact-line" << std::endl; 00546 #endif 00547 contact_face_type contact_face(2); 00548 reader >> contact_face[0]; 00549 reader >> contact_face[1]; 00550 //std::cout << contact_face[0] << " " << contact_face[1] << std::endl; 00551 contact_face_cont.push_back(contact_face); 00552 00553 // we have to reduce the domain size, as this is not a valid segment 00554 domain.resize(domain.size()-1); 00555 } 00556 else 00557 { 00558 std::cerr << "BND-READER-Error: Elements of type: " << token << " are not supported .." << std::endl; 00559 throw std::runtime_error("BND-READER-Error: Elements of type: " + token + " are not supported .."); 00560 } 00561 } 00562 00563 #ifdef VIENNAGRID_DEBUG_IO 00564 std::cout << " finished loading elements .. " << std::endl; 00565 #endif 00566 00567 #ifdef VIENNAGRID_DEBUG_IO 00568 std::cout << "reading material and contact information .. " << std::endl; 00569 #endif 00570 // the domainsize acts as an offset for the number of elements 00571 std::size_t domainsize = domain.size(); 00572 segment_id_cont.resize(domainsize); 00573 std::size_t region_cnt = 0; 00574 00575 contact_groups.resize(number_of_regions-domainsize); 00576 00577 while(1) 00578 { 00579 std::getline(reader, token); 00580 00581 if(token.find("Region") != std::string::npos) 00582 { 00583 00584 region_cnt++; 00585 00586 std::string::size_type delimiter_left = token.find("(\"")+2; 00587 std::string::size_type delimiter_right = token.find("\")"); 00588 std::string name = token.substr(delimiter_left, delimiter_right-delimiter_left); 00589 name = remove_begin_end_chars(name); 00590 00591 while(1) 00592 { 00593 std::getline(reader, token); 00594 00595 if(token.find("material") != std::string::npos) 00596 { 00597 std::string::size_type delimiter_left = token.find("=")+1; 00598 std::string::size_type delimiter_right = token.find("\n"); 00599 std::string material = token.substr(delimiter_left, delimiter_right-delimiter_left); 00600 material = remove_begin_end_chars(material); 00601 00602 //std::cout << "name: -" << name << "- material: -" << material << "-" << std::endl; 00603 00604 std::size_t elements = 0; 00605 while(1) 00606 { 00607 std::getline(reader, token); 00608 00609 if(token.find("Elements") != std::string::npos) 00610 { 00611 std::string::size_type delimiter_left = token.find("(")+1; 00612 std::string::size_type delimiter_right = token.find(")"); 00613 std::string elements_str = token.substr(delimiter_left, delimiter_right-delimiter_left); 00614 elements = lexical_cast<std::size_t>(elements_str); 00615 break; 00616 } 00617 } 00618 std::size_t ei; 00619 if( material == "Contact" ) 00620 { 00621 // store the contact name 00622 contact_id_cont.push_back(name); 00623 00624 for(std::size_t i = 0; i < elements; i++) 00625 { 00626 // read the elment id 00627 reader >> ei; 00628 00629 // determine the contact cells 00630 if(DIMG == 2) 00631 { 00632 contact_groups[contact_id_cont.size()-1].push_back(contact_face_cont[ei-domainsize]); 00633 } 00634 else // 3D 00635 { 00636 contact_face_type edge_index_cont = contact_face_cont[ei-domainsize]; 00637 00638 std::map<index_type, bool> uniquer; 00639 contact_face_type contact_triangle; 00640 00641 for(std::size_t ei = 0; ei < edge_index_cont.size(); ei++) 00642 { 00643 index_type edge_index = edge_index_cont[ei]; 00644 index_type mapped_edge_index = map(edge_index); 00645 edge_type edge = edge_cont[mapped_edge_index]; 00646 if(edge_index < 0) std::reverse(edge.begin(),edge.end()); 00647 00648 if(!uniquer[edge[0]]) 00649 { 00650 contact_triangle.push_back(edge[0]); 00651 uniquer[edge[0]] = true; 00652 } 00653 if(!uniquer[edge[1]]) 00654 { 00655 contact_triangle.push_back(edge[1]); 00656 uniquer[edge[1]] = true; 00657 } 00658 } 00659 //std::cout << contact_triangle << std::endl; 00660 contact_groups[contact_id_cont.size()-1].push_back(contact_triangle); 00661 } 00662 } 00663 } 00664 else 00665 { 00666 for(std::size_t i = 0; i < elements; i++) 00667 { 00668 // read the elment id 00669 reader >> ei; 00670 00671 // store the name and material info on the related segment id 00672 segment_id_cont[ei] = std::pair<std::string, std::string>(name, material); 00673 } 00674 } 00675 break; 00676 } 00677 } 00678 } 00679 if(region_cnt == number_of_regions) break; 00680 } 00681 00682 } catch (...) { 00683 std::cerr << "Problems while reading file " << filename << std::endl; 00684 } 00685 00686 return EXIT_SUCCESS; 00687 } //operator() 00688 00689 struct negate 00690 { 00691 template<typename T> 00692 void operator()(T& x) { x*=-1; } 00693 }; 00694 00695 void dump(std::ostream& ostr = std::cout) 00696 { 00697 ostr << "## GEOMETRY" << std::endl; 00698 for(std::size_t gi = 0; gi < geometry.size(); gi++) 00699 { 00700 ostr << " point - id: " << gi << " - data: "; 00701 viennagrid::io::print()(geometry[gi], ostr); 00702 } 00703 00704 ostr << "## TOPOLOGY" << std::endl; 00705 for(std::size_t si = 0; si < domain.size(); si++) 00706 { 00707 ostr << " segment: " << si << std::endl; 00708 for(std::size_t fi = 0; fi < domain[si].size(); fi++) 00709 { 00710 ostr << " face - id: " << fi << " - size: " << domain[si][fi].size() << " - eles: "; 00711 viennagrid::io::print()(domain[si][fi], ostr); 00712 } 00713 } 00714 } 00715 00716 point_type& point(std::size_t index) 00717 { 00718 return geometry[index]; 00719 } 00720 00721 std::size_t geometry_size() 00722 { 00723 return geometry.size(); 00724 } 00725 00726 std::size_t segment_size() 00727 { 00728 return domain.size(); 00729 } 00730 00731 polygon_container_type& segment(std::size_t index) 00732 { 00733 return domain[index]; 00734 } 00735 00736 std::size_t dim_geom() 00737 { 00738 return dim_geometry; 00739 } 00740 00741 std::size_t contact_size() 00742 { 00743 return contact_id_cont.size(); 00744 } 00745 00746 std::string contact_name(std::size_t ci) 00747 { 00748 return contact_id_cont[ci]; 00749 } 00750 00751 contact_face_container_type contact_faces(std::size_t ci) 00752 { 00753 return contact_groups[ci]; 00754 } 00755 00756 std::string segment_name(std::size_t ci) 00757 { 00758 return segment_id_cont[ci].first; 00759 } 00760 00761 std::string segment_material(std::size_t ci) 00762 { 00763 return segment_id_cont[ci].second; 00764 } 00765 00766 00767 void clear() 00768 { 00769 geometry.clear(); 00770 edge_cont.clear(); 00771 polygon_cont.clear(); 00772 contact_face_cont.clear(); 00773 contact_groups.clear(); 00774 domain.clear(); 00775 segment_id_cont.clear(); 00776 contact_id_cont.clear(); 00777 } 00778 00779 private: 00780 index_type map(index_type index) 00781 { 00782 if(index >= 0) return index; 00783 else return -(index)-1; // this is the specific mapping for negativ face and element values 00784 } 00785 00786 geometry_container_type geometry; 00787 edge_container_type edge_cont; 00788 polygon_container_type polygon_cont; 00789 contact_face_container_type contact_face_cont; 00790 contact_groups_type contact_groups; 00791 domain_type domain; 00792 segment_id_container_type segment_id_cont; 00793 contact_id_container_type contact_id_cont; 00794 std::size_t dim_geometry; 00795 std::size_t number_of_regions; 00796 00797 }; //class bnd_reader 00798 00799 00800 00801 00802 00803 00804 00805 00809 class bnd_reader 00810 { 00811 public: 00812 00819 template <typename MeshT, typename SegmentationT> 00820 void operator()(MeshT & mesh, SegmentationT & segmentation, std::string const & filename) const 00821 { 00822 typedef typename viennagrid::result_of::point<MeshT>::type PointType; 00823 typedef typename viennagrid::result_of::vertex_handle<MeshT>::type VertexHandleType; 00824 typedef typename viennagrid::result_of::cell_handle<MeshT>::type CellHandleType; 00825 typedef typename viennagrid::result_of::segment_handle<SegmentationT>::type SegmentHandleType; 00826 00827 const int mesh_dimension = viennagrid::result_of::geometric_dimension<MeshT>::value; 00828 const int num_vertices = viennagrid::boundary_elements<viennagrid::triangle_tag, viennagrid::vertex_tag>::num; 00829 00830 typedef viennagrid::io::bnd_helper BNDReaderType; 00831 typedef BNDReaderType::index_type BNDIndexType; 00832 typedef BNDReaderType::point_type BNDPointType; 00833 typedef BNDReaderType::polygon_container_type BNDPolygonContainerType; 00834 typedef BNDReaderType::polygon_type BNDPolygonType; 00835 00836 00837 BNDReaderType bnd; 00838 if (bnd(filename) != EXIT_SUCCESS) 00839 throw bad_file_format_exception("* ViennaGrid: bnd_reader::operator(): File " + filename + ": BND reading error"); 00840 00841 if ( mesh_dimension != bnd.dim_geom() ) 00842 throw bad_file_format_exception("* ViennaGrid: bnd_reader::operator(): File " + filename + ": Geometric dimension mismatch."); 00843 00844 00845 std::map<BNDIndexType, VertexHandleType> vertices; 00846 std::map<BNDPolygonType, CellHandleType> cells; 00847 00848 00849 for (std::size_t segment_id = 0; segment_id != bnd.segment_size(); ++segment_id) 00850 { 00851 SegmentHandleType segment = segmentation.get_make_segment( segment_id ); 00852 BNDPolygonContainerType & polygons = bnd.segment( segment_id ); 00853 00854 00855 for (std::size_t poly_pos = 0; poly_pos != polygons.size(); ++poly_pos) 00856 { 00857 BNDPolygonType & polygon = polygons[poly_pos]; 00858 // std::cout << polygon.size() << std::endl; 00859 std::sort(polygon.begin(), polygon.end()); 00860 00861 if ((num_vertices > 0) && (num_vertices != polygon.size())) 00862 { 00863 std::stringstream ss; 00864 ss << "* ViennaGrid: bnd_reader::operator(): File " << filename << ": "; 00865 ss << "ERROR: polygon " << poly_pos << " has " << polygon.size() << " vertices but should have " << num_vertices << std::endl; 00866 00867 throw bad_file_format_exception(ss.str()); 00868 } 00869 00870 00871 00872 std::vector<VertexHandleType> vertex_handles; 00873 00874 typename std::map<BNDPolygonType, CellHandleType>::iterator cit = cells.find( polygon ); 00875 if (cit != cells.end()) 00876 { 00877 viennagrid::add( segment, cit->second ); 00878 } 00879 else 00880 { 00881 for (std::size_t vtx_pos = 0; vtx_pos != polygon.size(); ++vtx_pos) 00882 { 00883 BNDIndexType vtx_index = polygon[vtx_pos]; 00884 00885 typename std::map<BNDIndexType, VertexHandleType>::iterator vit = vertices.find( vtx_index ); 00886 if (vit != vertices.end()) 00887 vertex_handles.push_back(vit->second); 00888 else 00889 { 00890 BNDPointType const & bnd_point = bnd.point( vtx_index ); 00891 PointType point; 00892 std::copy( bnd_point.begin(), bnd_point.end(), point.begin() ); 00893 00894 VertexHandleType vtx_handle = viennagrid::make_vertex( mesh, point ); 00895 00896 vertices[vtx_index] = vtx_handle; 00897 vertex_handles.push_back(vtx_handle); 00898 } 00899 } 00900 00901 cells[polygon] = viennagrid::make_cell( segment, vertex_handles.begin(), vertex_handles.end() ); 00902 } 00903 } 00904 } 00905 } 00906 00907 00908 00909 private: 00910 00911 }; 00912 00913 00914 00915 } 00916 } 00917 00918 00919 00920 #endif