ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/bnd_reader.hpp
Go to the documentation of this file.
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