LCOV - code coverage report
Current view: top level - ugbase/lib_grid/file_io - file_io_ugx.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 897 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 96 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include <sstream>
      34              : #include <fstream>
      35              : #include <boost/archive/text_oarchive.hpp>
      36              : #include <boost/archive/text_iarchive.hpp>
      37              : #include "common/common.h"
      38              : #include "common/util/file_util.h"
      39              : #include "file_io_ugx.h"
      40              : #include "common/boost_serialization_routines.h"
      41              : #include "common/parser/rapidxml/rapidxml_print.hpp"
      42              : #include "common/util/archivar.h"
      43              : #include "common/util/factory.h"
      44              : #include "lib_grid/algorithms/attachment_util.h"
      45              : #include "lib_grid/refinement/projectors/projectors.h"
      46              : 
      47              : 
      48              : using namespace std;
      49              : using namespace rapidxml;
      50              : 
      51              : namespace ug
      52              : {
      53              : 
      54              : ////////////////////////////////////////////////////////////////////////
      55            0 : bool SaveGridToUGX(Grid& grid, ISubsetHandler& sh,
      56              :                                    const char* filename)
      57              : {
      58            0 :         if(grid.has_vertex_attachment(aPosition))
      59            0 :                 return SaveGridToUGX(grid, sh, filename, aPosition);
      60            0 :         else if(grid.has_vertex_attachment(aPosition2))
      61            0 :                 return SaveGridToUGX(grid, sh, filename, aPosition2);
      62            0 :         else if(grid.has_vertex_attachment(aPosition1))
      63            0 :                 return SaveGridToUGX(grid, sh, filename, aPosition1);
      64              : 
      65              :         UG_LOG("ERROR in SaveGridToUGX: no standard attachment found.\n");
      66            0 :         return false;
      67              : }
      68              : 
      69            0 : bool LoadGridFromUGX(Grid& grid, ISubsetHandler& sh,
      70              :                                         const char* filename)
      71              : {
      72            0 :         if(grid.has_vertex_attachment(aPosition))
      73            0 :                 return LoadGridFromUGX(grid, sh, filename, aPosition);
      74            0 :         else if(grid.has_vertex_attachment(aPosition2))
      75            0 :                 return LoadGridFromUGX(grid, sh, filename, aPosition2);
      76            0 :         else if(grid.has_vertex_attachment(aPosition1))
      77            0 :                 return LoadGridFromUGX(grid, sh, filename, aPosition1);
      78              : 
      79              : //      no standard position attachments are available.
      80              : //      Attach aPosition and use it.
      81              :         grid.attach_to_vertices(aPosition);
      82            0 :         return LoadGridFromUGX(grid, sh, filename, aPosition);
      83              : }
      84              : 
      85              : ////////////////////////////////////////////////////////////////////////
      86              : ////////////////////////////////////////////////////////////////////////
      87              : //      GridWriterUGX
      88            0 : GridWriterUGX::GridWriterUGX()
      89              : {
      90            0 :         xml_node<>* decl = m_doc.allocate_node(node_declaration);
      91            0 :         decl->append_attribute(m_doc.allocate_attribute("version", "1.0"));
      92            0 :         decl->append_attribute(m_doc.allocate_attribute("encoding", "utf-8"));
      93            0 :         m_doc.append_node(decl);
      94            0 : }
      95              : 
      96            0 : GridWriterUGX::~GridWriterUGX()
      97              : {
      98              : //      detach aInt from the vertices of the grid
      99            0 :         for(size_t i = 0; i < m_vEntries.size(); ++i)
     100            0 :                 m_vEntries[i].grid->detach_from_vertices(m_aInt);
     101            0 : }
     102              : 
     103            0 : bool GridWriterUGX::
     104              : write_to_stream(std::ostream& out)
     105              : {
     106            0 :         out << m_doc;
     107            0 :         return true;
     108              : }
     109              : 
     110            0 : bool GridWriterUGX::
     111              : write_to_file(const char* filename)
     112              : {
     113            0 :         ofstream out(filename);
     114            0 :         if(out){
     115            0 :                 return write_to_stream(out);
     116              :         }
     117              :         return false;
     118            0 : }
     119              : 
     120            0 : void GridWriterUGX::
     121              : add_subset_attributes(rapidxml::xml_node<>* targetNode,
     122              :                                           ISubsetHandler& sh, size_t subsetIndex)
     123              : {
     124            0 :         const SubsetInfo& si = sh.subset_info(subsetIndex);
     125              : //      write name
     126            0 :         targetNode->append_attribute(m_doc.allocate_attribute("name", si.name.c_str()));
     127              : 
     128              : //      write color
     129              :         {
     130            0 :                 stringstream ss;
     131            0 :                 for(size_t i = 0; i < 4; ++i){
     132            0 :                         ss << si.color[i] << " ";
     133              :                 }
     134              : 
     135              : 
     136              :         //      allocate a string and erase last character(' ')
     137            0 :                 char* colorData = m_doc.allocate_string(ss.str().c_str(), ss.str().size() );
     138            0 :                 colorData[ss.str().size() - 1] = 0;
     139            0 :                 targetNode->append_attribute(m_doc.allocate_attribute("color", colorData));
     140            0 :         }
     141              : //      write state
     142              :         {
     143            0 :                 stringstream ss;
     144            0 :                 ss << (size_t)si.subsetState;
     145            0 :                 char* stateData = m_doc.allocate_string(ss.str().c_str(), ss.str().size() + 1);
     146            0 :                 stateData[ss.str().size()] = 0;
     147            0 :                 targetNode->append_attribute(m_doc.allocate_attribute("state", stateData));
     148            0 :         }
     149            0 : }
     150              : 
     151            0 : void GridWriterUGX::
     152              : add_subset_handler(ISubsetHandler& sh, const char* name,
     153              :                                         size_t refGridIndex)
     154              : {
     155              : //      get the node of the referenced grid
     156            0 :         if(refGridIndex >= m_vEntries.size()){
     157              :                 UG_LOG("GridWriterUGX::add_subset_handler: bad refGridIndex. Aborting.\n");
     158            0 :                 return;
     159              :         }
     160              : 
     161              : //      add the subset handler to the grid entry
     162            0 :         m_vEntries[refGridIndex].subsetHandlers.push_back(&sh);
     163              : 
     164            0 :         xml_node<>* parentNode = m_vEntries[refGridIndex].node;
     165              : 
     166              : //      create the subset-handler node
     167            0 :         xml_node<>* ndSH = m_doc.allocate_node(node_element, "subset_handler");
     168            0 :         ndSH->append_attribute(m_doc.allocate_attribute("name", name));
     169              : 
     170              : //      add the subset-handler-node to the grid-node.
     171              :         parentNode->append_node(ndSH);
     172              : 
     173              : //      add the subsets
     174            0 :         for(int i = 0; i < sh.num_subsets(); ++i){
     175            0 :                 xml_node<>* ndSubset = m_doc.allocate_node(node_element, "subset");
     176            0 :                 add_subset_attributes(ndSubset, sh, i);
     177              :                 ndSH->append_node(ndSubset);
     178              : 
     179              :         //      add elements
     180            0 :                 if(sh.contains_vertices(i))
     181            0 :                         ndSubset->append_node(
     182              :                                 create_subset_element_node<Vertex>("vertices", sh, i));
     183            0 :                 if(sh.contains_edges(i))
     184            0 :                         ndSubset->append_node(
     185              :                                 create_subset_element_node<Edge>("edges", sh, i));
     186            0 :                 if(sh.contains_faces(i))
     187            0 :                         ndSubset->append_node(
     188              :                                 create_subset_element_node<Face>("faces", sh, i));
     189            0 :                 if(sh.contains_volumes(i))
     190            0 :                         ndSubset->append_node(
     191              :                                 create_subset_element_node<Volume>("volumes", sh, i));
     192              :         }
     193              : }
     194              : 
     195              : template <class TGeomObj>
     196            0 : rapidxml::xml_node<>* GridWriterUGX::
     197              : create_subset_element_node(const char* name, const ISubsetHandler& sh,
     198              :                                                         size_t si)
     199              : {
     200              : 
     201              : //      the stringstream to which we'll write the data
     202            0 :         stringstream ss;
     203              : 
     204            0 :         if(sh.grid()){
     205              :         //      access the grid
     206            0 :                 Grid& grid = *sh.grid();
     207              : 
     208              :         //      access the attachment
     209            0 :                 Grid::AttachmentAccessor<TGeomObj, AInt> aaInd(grid, m_aInt);
     210            0 :                 if(aaInd.valid()){
     211            0 :                         GridObjectCollection goc = sh.get_grid_objects_in_subset(si);
     212            0 :                         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
     213              :                                 for(typename geometry_traits<TGeomObj>::iterator iter =
     214            0 :                                         goc.begin<TGeomObj>(lvl); iter != goc.end<TGeomObj>(lvl); ++iter)
     215              :                                 {
     216            0 :                                         ss << aaInd[*iter] << " ";
     217              :                                 }
     218              :                         }
     219              :                 }
     220              :         }
     221              : 
     222            0 :         if(ss.str().size() > 0){
     223              :         //      allocate a string and erase last character(' ')
     224            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     225            0 :                 nodeData[ss.str().size()-1] = 0;
     226              :         //      create and return the node
     227            0 :                 return m_doc.allocate_node(node_element, name, nodeData);
     228              :         }
     229              :         else{
     230              :         //      return an emtpy node
     231            0 :                 return m_doc.allocate_node(node_element, name);
     232              :         }
     233            0 : }
     234              : 
     235              : template <class TGeomObj>
     236            0 : rapidxml::xml_node<>* GridWriterUGX::
     237              : create_selector_element_node(const char* name, const ISelector& sel)
     238              : {
     239              : //      the stringstream to which we'll write the data
     240            0 :         stringstream ss;
     241              : 
     242            0 :         if(sel.grid()){
     243              :         //      access the grid
     244              :                 Grid& grid = *sel.grid();
     245              : 
     246              :         //      access the attachment
     247            0 :                 Grid::AttachmentAccessor<TGeomObj, AInt> aaInd(grid, m_aInt);
     248            0 :                 if(aaInd.valid()){
     249            0 :                         GridObjectCollection goc = sel.get_grid_objects();
     250            0 :                         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
     251              :                                 for(typename geometry_traits<TGeomObj>::iterator iter =
     252            0 :                                         goc.begin<TGeomObj>(lvl); iter != goc.end<TGeomObj>(lvl); ++iter)
     253              :                                 {
     254            0 :                                         ss << aaInd[*iter] << " " << (int)sel.get_selection_status(*iter) << " ";
     255              :                                 }
     256              :                         }
     257              :                 }
     258              :         }
     259              : 
     260            0 :         if(ss.str().size() > 0){
     261              :         //      allocate a string and erase last character(' ')
     262            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     263            0 :                 nodeData[ss.str().size()-1] = 0;
     264              :         //      create and return the node
     265            0 :                 return m_doc.allocate_node(node_element, name, nodeData);
     266              :         }
     267              :         else{
     268              :         //      return an emtpy node
     269            0 :                 return m_doc.allocate_node(node_element, name);
     270              :         }
     271            0 : }
     272              : 
     273            0 : void GridWriterUGX::
     274              : add_selector(ISelector& sel, const char* name, size_t refGridIndex)
     275              : {
     276              : //      get the node of the referenced grid
     277            0 :         if(refGridIndex >= m_vEntries.size()){
     278              :                 UG_LOG("GridWriterUGX::add_selector: bad refGridIndex. Aborting.\n");
     279            0 :                 return;
     280              :         }
     281              : 
     282            0 :         xml_node<>* parentNode = m_vEntries[refGridIndex].node;
     283              : 
     284              : //      create the selector node
     285            0 :         xml_node<>* ndSel = m_doc.allocate_node(node_element, "selector");
     286            0 :         ndSel->append_attribute(m_doc.allocate_attribute("name", name));
     287              : 
     288              : //      add the selector node to the grid-node.
     289              :         parentNode->append_node(ndSel);
     290              : 
     291              : //      add elements
     292            0 :         if(sel.contains_vertices())
     293            0 :                 ndSel->append_node(create_selector_element_node<Vertex>("vertices", sel));
     294            0 :         if(sel.contains_edges())
     295            0 :                 ndSel->append_node(create_selector_element_node<Edge>("edges", sel));
     296            0 :         if(sel.contains_faces())
     297            0 :                 ndSel->append_node(create_selector_element_node<Face>("faces", sel));
     298            0 :         if(sel.contains_volumes())
     299            0 :                 ndSel->append_node(create_selector_element_node<Volume>("volumes", sel));
     300              : }
     301              : 
     302            0 : xml_node<>* GridWriterUGX::
     303              : create_projector_node(RefinementProjector& proj, const char* nodeName)
     304              : {
     305            0 :         static Factory<RefinementProjector, ProjectorTypes>       projFac;
     306            0 :         static Archivar<boost::archive::text_oarchive, RefinementProjector, ProjectorTypes>       archivar;
     307              :         
     308            0 :         const string& projName = projFac.class_name(proj);
     309              : 
     310            0 :         stringstream ss;
     311              :         boost::archive::text_oarchive ar(ss, boost::archive::no_header);
     312              :         archivar.archive(ar, proj);
     313              : 
     314            0 :         xml_node<>* ndProj = m_doc.allocate_node(node_element, nodeName,
     315            0 :                                                                         m_doc.allocate_string(ss.str().c_str()));
     316              : 
     317            0 :         ndProj->append_attribute(m_doc.allocate_attribute("type", projName.c_str()));
     318            0 :         return ndProj;
     319            0 : }
     320              : 
     321            0 : void GridWriterUGX::
     322              : add_projection_handler(ProjectionHandler& ph, const char* name, size_t refGridIndex)
     323              : {
     324              : //      get the node of the referenced grid
     325            0 :         if(refGridIndex >= m_vEntries.size()){
     326              :                 UG_LOG("GridWriterUGX::add_selector: bad refGridIndex. Aborting.\n");
     327            0 :                 return;
     328              :         }
     329              : 
     330            0 :         xml_node<>* parentNode = m_vEntries[refGridIndex].node;
     331              : 
     332              : //      create the selector node
     333            0 :         xml_node<>* ndHandler = m_doc.allocate_node(node_element, "projection_handler");
     334            0 :         ndHandler->append_attribute(m_doc.allocate_attribute("name", name));
     335              : 
     336              : //      find subset handler index in subset handler array
     337              :         size_t i = 0;
     338              :         const std::vector<const ISubsetHandler*>& vSH = m_vEntries[refGridIndex].subsetHandlers;
     339              :         size_t nSH = vSH.size();
     340            0 :         for (; i < nSH; ++i)
     341            0 :                 if (vSH[i] == ph.subset_handler())
     342              :                         break;
     343              : 
     344            0 :         UG_COND_THROW(i == nSH, "ERROR in 'GridWriterUGX::add_projection_handler': "
     345              :                 "No matching SubsetHandler could be found.\n"
     346              :                 "Please make sure to add the associated SubsetHandler before adding a ProjectionHandler");
     347              : 
     348              : // append subset handler index attribute to node
     349            0 :         ndHandler->append_attribute(m_doc.allocate_attribute("subset_handler",
     350            0 :                                                                         m_doc.allocate_string(mkstr(i).c_str())));
     351              : 
     352              : //      add the selector node to the grid-node.
     353              :         parentNode->append_node(ndHandler);
     354              : 
     355              : //      fill the content of the projector-node
     356            0 :         if(ph.default_projector().valid()){
     357            0 :                 ndHandler->append_node (create_projector_node(
     358            0 :                                                                         *ph.default_projector(), "default"));
     359              :         }
     360              : 
     361            0 :         for(int i = -1; i < (int)ph.num_projectors(); ++i){
     362            0 :                 if(!ph.projector(i).valid())
     363            0 :                         continue;
     364              : 
     365            0 :                 RefinementProjector& proj= *ph.projector(i);
     366              : 
     367            0 :                 xml_node<>* ndProj = create_projector_node(proj, "projector");
     368            0 :                 ndProj->append_attribute(m_doc.allocate_attribute("subset",
     369            0 :                                                                  m_doc.allocate_string(mkstr(i).c_str())));
     370              :                 ndHandler->append_node(ndProj);
     371              :         }
     372              : }
     373              : 
     374              : 
     375            0 : void GridWriterUGX::
     376              : init_grid_attachments(Grid& grid)
     377              : {
     378              : //      assign indices to the vertices, edges, faces and volumes
     379            0 :         grid.attach_to_vertices(m_aInt);
     380              :         grid.attach_to_edges(m_aInt);
     381              :         grid.attach_to_faces(m_aInt);
     382              :         grid.attach_to_volumes(m_aInt);
     383              : 
     384              : //      access and initialise indices
     385            0 :         Grid::VertexAttachmentAccessor<AInt> aaIndVRT(grid, m_aInt);
     386              :         Grid::EdgeAttachmentAccessor<AInt> aaIndEDGE(grid, m_aInt);
     387              :         Grid::FaceAttachmentAccessor<AInt> aaIndFACE(grid, m_aInt);
     388              :         Grid::VolumeAttachmentAccessor<AInt> aaIndVOL(grid, m_aInt);
     389              : 
     390              :         int baseInd = 0;
     391              :         AssignIndices(grid.begin<RegularVertex>(), grid.end<RegularVertex>(), aaIndVRT, baseInd);
     392            0 :         baseInd += grid.num<RegularVertex>();
     393              :         AssignIndices(grid.begin<ConstrainedVertex>(), grid.end<ConstrainedVertex>(),
     394              :                                   aaIndVRT, baseInd);
     395              : 
     396              :         baseInd = 0;
     397              :         AssignIndices(grid.begin<RegularEdge>(), grid.end<RegularEdge>(), aaIndEDGE, baseInd);
     398            0 :         baseInd += grid.num<RegularEdge>();
     399              :         AssignIndices(grid.begin<ConstrainingEdge>(), grid.end<ConstrainingEdge>(),
     400              :                                   aaIndEDGE, baseInd);
     401            0 :         baseInd += grid.num<ConstrainingEdge>();
     402              :         AssignIndices(grid.begin<ConstrainedEdge>(), grid.end<ConstrainedEdge>(),
     403              :                                   aaIndEDGE, baseInd);
     404              : 
     405              :         baseInd = 0;
     406              :         AssignIndices(grid.begin<Triangle>(), grid.end<Triangle>(), aaIndFACE, baseInd);
     407            0 :         baseInd += grid.num<Triangle>();
     408              :         AssignIndices(grid.begin<ConstrainingTriangle>(), grid.end<ConstrainingTriangle>(), aaIndFACE, baseInd);
     409            0 :         baseInd += grid.num<ConstrainingTriangle>();
     410              :         AssignIndices(grid.begin<ConstrainedTriangle>(), grid.end<ConstrainedTriangle>(), aaIndFACE, baseInd);
     411            0 :         baseInd += grid.num<ConstrainedTriangle>();
     412              :         
     413              :         AssignIndices(grid.begin<Quadrilateral>(), grid.end<Quadrilateral>(), aaIndFACE, baseInd);
     414            0 :         baseInd += grid.num<Quadrilateral>();
     415              :         AssignIndices(grid.begin<ConstrainingQuadrilateral>(), grid.end<ConstrainingQuadrilateral>(), aaIndFACE, baseInd);
     416            0 :         baseInd += grid.num<ConstrainingQuadrilateral>();
     417              :         AssignIndices(grid.begin<ConstrainedQuadrilateral>(), grid.end<ConstrainedQuadrilateral>(), aaIndFACE, baseInd);
     418              :         //baseInd += grid.num<ConstrainedQuadrilateral>();  // never used
     419              :         
     420              :         AssignIndices(grid.begin<Volume>(), grid.end<Volume>(), aaIndVOL, 0);
     421            0 : }
     422              : 
     423            0 : void GridWriterUGX::
     424              : add_elements_to_node(rapidxml::xml_node<>* node,
     425              :                                           Grid& grid)
     426              : {
     427              : //      access and initialise indices
     428            0 :         Grid::VertexAttachmentAccessor<AInt> aaIndVRT(grid, m_aInt);
     429              :         Grid::EdgeAttachmentAccessor<AInt> aaIndEDGE(grid, m_aInt);
     430              :         Grid::FaceAttachmentAccessor<AInt> aaIndFACE(grid, m_aInt);
     431              :         Grid::VolumeAttachmentAccessor<AInt> aaIndVOL(grid, m_aInt);
     432              : 
     433              : //      write edges
     434            0 :         if(grid.num<RegularEdge>() > 0)
     435            0 :                 node->append_node(create_edge_node(grid.begin<RegularEdge>(),
     436            0 :                                                                                 grid.end<RegularEdge>(), aaIndVRT));
     437              : 
     438              : //      write constraining edges
     439            0 :         if(grid.num<ConstrainingEdge>() > 0)
     440            0 :                 node->append_node(create_constraining_edge_node(
     441            0 :                                                                                 grid.begin<ConstrainingEdge>(),
     442            0 :                                                                                 grid.end<ConstrainingEdge>(), aaIndVRT));
     443              : 
     444              : //      write constrained edges
     445            0 :         if(grid.num<ConstrainedEdge>() > 0)
     446            0 :                 node->append_node(create_constrained_edge_node(
     447            0 :                                                                                 grid.begin<ConstrainedEdge>(),
     448            0 :                                                                                 grid.end<ConstrainedEdge>(),
     449              :                                                                                 aaIndVRT, aaIndEDGE, aaIndFACE));
     450              : //      write triangles
     451            0 :         if(grid.num<Triangle>() > 0)
     452            0 :                 node->append_node(create_triangle_node(grid.begin<Triangle>(),
     453            0 :                                                                                                 grid.end<Triangle>(), aaIndVRT));
     454              : 
     455              : //      write constraining triangles
     456            0 :         if(grid.num<ConstrainingTriangle>() > 0)
     457            0 :                 node->append_node(create_constraining_triangle_node(
     458            0 :                                                                                                 grid.begin<ConstrainingTriangle>(),
     459            0 :                                                                                                 grid.end<ConstrainingTriangle>(),
     460              :                                                                                                 aaIndVRT));
     461              : 
     462              : //      write constrained triangles
     463            0 :         if(grid.num<ConstrainedTriangle>() > 0)
     464            0 :                 node->append_node(create_constrained_triangle_node(
     465            0 :                                                                                                 grid.begin<ConstrainedTriangle>(),
     466            0 :                                                                                                 grid.end<ConstrainedTriangle>(),
     467              :                                                                                                 aaIndVRT, aaIndFACE));                                                                                          
     468              : //      write quadrilaterals
     469            0 :         if(grid.num<Quadrilateral>() > 0)
     470            0 :                 node->append_node(create_quadrilateral_node(grid.begin<Quadrilateral>(),
     471            0 :                                                                                                         grid.end<Quadrilateral>(), aaIndVRT));
     472              : 
     473              : //      write constraining quadrilaterals
     474            0 :         if(grid.num<ConstrainingQuadrilateral>() > 0)
     475            0 :                 node->append_node(create_constraining_quadrilateral_node(
     476            0 :                                                                                                 grid.begin<ConstrainingQuadrilateral>(),
     477            0 :                                                                                                 grid.end<ConstrainingQuadrilateral>(),
     478              :                                                                                                 aaIndVRT));
     479              : 
     480              : //      write constrained quadrilaterals
     481            0 :         if(grid.num<ConstrainedQuadrilateral>() > 0)
     482            0 :                 node->append_node(create_constrained_quadrilateral_node(
     483            0 :                                                                                                 grid.begin<ConstrainedQuadrilateral>(),
     484            0 :                                                                                                 grid.end<ConstrainedQuadrilateral>(),
     485              :                                                                                                 aaIndVRT, aaIndFACE));
     486              :                                                                                                                                                                                                         
     487              : //      write tetrahedrons
     488            0 :         if(grid.num<Tetrahedron>() > 0)
     489            0 :                 node->append_node(create_tetrahedron_node(grid.begin<Tetrahedron>(),
     490            0 :                                                                                                         grid.end<Tetrahedron>(), aaIndVRT));
     491              : 
     492              : //      write hexahedrons
     493            0 :         if(grid.num<Hexahedron>() > 0)
     494            0 :                 node->append_node(create_hexahedron_node(grid.begin<Hexahedron>(),
     495            0 :                                                                                                         grid.end<Hexahedron>(), aaIndVRT));
     496              : 
     497              : //      write prisms
     498            0 :         if(grid.num<Prism>() > 0)
     499            0 :                 node->append_node(create_prism_node(grid.begin<Prism>(),
     500            0 :                                                                                         grid.end<Prism>(), aaIndVRT));
     501              : 
     502              : //      write pyramids
     503            0 :         if(grid.num<Pyramid>() > 0)
     504            0 :                 node->append_node(create_pyramid_node(grid.begin<Pyramid>(),
     505            0 :                                                                                           grid.end<Pyramid>(), aaIndVRT));
     506              : 
     507              : //      write octahedrons
     508            0 :         if(grid.num<Octahedron>() > 0)
     509            0 :                 node->append_node(create_octahedron_node(grid.begin<Octahedron>(),
     510            0 :                                                                                           grid.end<Octahedron>(), aaIndVRT));
     511            0 : }
     512              : 
     513            0 : rapidxml::xml_node<>* GridWriterUGX::
     514              : create_edge_node(RegularEdgeIterator edgesBegin,
     515              :                                  RegularEdgeIterator edgesEnd,
     516              :                                  AAVrtIndex aaIndVRT)
     517              : {
     518              : //      write the elements to a temporary stream
     519            0 :         stringstream ss;
     520            0 :         for(RegularEdgeIterator iter = edgesBegin; iter != edgesEnd; ++iter)
     521              :         {
     522            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " ";
     523              :         }
     524              : 
     525            0 :         if(ss.str().size() > 0){
     526              :         //      allocate a string and erase last character(' ')
     527            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     528            0 :                 nodeData[ss.str().size()-1] = 0;
     529              :         //      create and return the node
     530            0 :                 return m_doc.allocate_node(node_element, "edges", nodeData);
     531              :         }
     532              :         else{
     533              :         //      return an emtpy node
     534            0 :                 return m_doc.allocate_node(node_element, "edges");
     535              :         }
     536            0 : }
     537              : 
     538            0 : rapidxml::xml_node<>* GridWriterUGX::
     539              : create_constraining_edge_node(ConstrainingEdgeIterator edgesBegin,
     540              :                                                           ConstrainingEdgeIterator edgesEnd,
     541              :                                                           AAVrtIndex aaIndVRT)
     542              : {
     543              : //      write the elements to a temporary stream
     544            0 :         stringstream ss;
     545            0 :         for(ConstrainingEdgeIterator iter = edgesBegin; iter != edgesEnd; ++iter)
     546              :         {
     547            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " ";
     548              :         }
     549              : 
     550            0 :         if(ss.str().size() > 0){
     551              :         //      allocate a string and erase last character(' ')
     552            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     553            0 :                 nodeData[ss.str().size()-1] = 0;
     554              :         //      create and return the node
     555            0 :                 return m_doc.allocate_node(node_element, "constraining_edges", nodeData);
     556              :         }
     557              :         else{
     558              :         //      return an emtpy node
     559            0 :                 return m_doc.allocate_node(node_element, "constraining_edges");
     560              :         }
     561            0 : }
     562              : 
     563            0 : rapidxml::xml_node<>* GridWriterUGX::
     564              : create_constrained_edge_node(ConstrainedEdgeIterator edgesBegin,
     565              :                                                          ConstrainedEdgeIterator edgesEnd,
     566              :                                                          AAVrtIndex aaIndVRT,
     567              :                                                          AAEdgeIndex aaIndEDGE,
     568              :                                                          AAFaceIndex aaIndFACE)
     569              : {
     570              : //      write the elements to a temporary stream
     571            0 :         stringstream ss;
     572            0 :         for(ConstrainedEdgeIterator iter = edgesBegin; iter != edgesEnd; ++iter)
     573              :         {
     574              :         //      write endpoint indices
     575            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " ";
     576              : 
     577              :         //      write index of associated constraining element
     578              :         //      codes:  -1: no constraining element
     579              :         //                      0: vertex. index follows
     580              :         //                      1: edge. index follows
     581              :         //                      2: face. index follows
     582              :         //                      3: volume. index follows
     583            0 :                 Edge* ce = dynamic_cast<Edge*>((*iter)->get_constraining_object());
     584            0 :                 Face* cf = dynamic_cast<Face*>((*iter)->get_constraining_object());
     585            0 :                 if(ce)
     586            0 :                         ss << "1 " << aaIndEDGE[ce] << " ";
     587            0 :                 else if(cf)
     588            0 :                         ss << "2 " << aaIndFACE[cf] << " ";
     589              :                 else
     590            0 :                         ss << "-1 ";
     591              :         }
     592              : 
     593            0 :         if(ss.str().size() > 0){
     594              :         //      allocate a string and erase last character(' ')
     595            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     596            0 :                 nodeData[ss.str().size()-1] = 0;
     597              :         //      create and return the node
     598            0 :                 return m_doc.allocate_node(node_element, "constrained_edges", nodeData);
     599              :         }
     600              :         else{
     601              :         //      return an emtpy node
     602            0 :                 return m_doc.allocate_node(node_element, "constrained_edges");
     603              :         }
     604            0 : }
     605              : 
     606            0 : rapidxml::xml_node<>* GridWriterUGX::
     607              : create_triangle_node(TriangleIterator trisBegin,
     608              :                                          TriangleIterator trisEnd,
     609              :                                          AAVrtIndex aaIndVRT)
     610              : {
     611              : //      write the elements to a temporary stream
     612            0 :         stringstream ss;
     613            0 :         for(TriangleIterator iter = trisBegin; iter != trisEnd; ++iter)
     614              :         {
     615            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)]
     616            0 :                         << " " << aaIndVRT[(*iter)->vertex(2)] << " " ;
     617              :         }
     618              : 
     619            0 :         if(ss.str().size() > 0){
     620              :         //      allocate a string and erase last character(' ')
     621            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     622            0 :                 nodeData[ss.str().size()-1] = 0;
     623              :         //      create and return the node
     624            0 :                 return m_doc.allocate_node(node_element, "triangles", nodeData);
     625              :         }
     626              :         else{
     627              :         //      return an emtpy node
     628            0 :                 return m_doc.allocate_node(node_element, "triangles");
     629              :         }
     630            0 : }
     631              : 
     632            0 : rapidxml::xml_node<>* GridWriterUGX::
     633              : create_constraining_triangle_node(ConstrainingTriangleIterator trisBegin,
     634              :                                                                   ConstrainingTriangleIterator trisEnd,
     635              :                                                                   AAVrtIndex aaIndVRT)
     636              : {
     637              : //      write the elements to a temporary stream
     638            0 :         stringstream ss;
     639            0 :         for(ConstrainingTriangleIterator iter = trisBegin; iter != trisEnd; ++iter)
     640              :         {
     641            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)]
     642            0 :                         << " " << aaIndVRT[(*iter)->vertex(2)] << " " ;
     643              :         }
     644              : 
     645            0 :         if(ss.str().size() > 0){
     646              :         //      allocate a string and erase last character(' ')
     647            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     648            0 :                 nodeData[ss.str().size()-1] = 0;
     649              :         //      create and return the node
     650            0 :                 return m_doc.allocate_node(node_element, "constraining_triangles", nodeData);
     651              :         }
     652              :         else{
     653              :         //      return an emtpy node
     654            0 :                 return m_doc.allocate_node(node_element, "constraining_triangles");
     655              :         }
     656            0 : }
     657              : 
     658            0 : rapidxml::xml_node<>* GridWriterUGX::
     659              : create_constrained_triangle_node(ConstrainedTriangleIterator trisBegin,
     660              :                                                                  ConstrainedTriangleIterator trisEnd,
     661              :                                                                  AAVrtIndex aaIndVRT,
     662              :                                                                  AAFaceIndex aaIndFACE)
     663              : {
     664              : //      write the elements to a temporary stream
     665            0 :         stringstream ss;
     666            0 :         for(ConstrainedTriangleIterator iter = trisBegin; iter != trisEnd; ++iter)
     667              :         {
     668              :         //      write endpoint indices
     669            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)]
     670            0 :                         << " " << aaIndVRT[(*iter)->vertex(2)] << " " ;
     671              :         //      write index of associated constraining element
     672              :         //      codes:  -1: no constraining element
     673              :         //                      0: vertex. index follows
     674              :         //                      1: edge. index follows
     675              :         //                      2: face. index follows
     676              :         //                      3: volume. index follows
     677            0 :                 Face* cf = dynamic_cast<Face*>((*iter)->get_constraining_object());
     678            0 :                 if(cf)
     679            0 :                         ss << "2 " << aaIndFACE[cf] << " ";
     680              :                 else
     681            0 :                         ss << "-1 ";
     682              :         }
     683              : 
     684            0 :         if(ss.str().size() > 0){
     685              :         //      allocate a string and erase last character(' ')
     686            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     687            0 :                 nodeData[ss.str().size()-1] = 0;
     688              :         //      create and return the node
     689            0 :                 return m_doc.allocate_node(node_element, "constrained_triangles", nodeData);
     690              :         }
     691              :         else{
     692              :         //      return an emtpy node
     693            0 :                 return m_doc.allocate_node(node_element, "constrained_triangles");
     694              :         }
     695            0 : }
     696              : 
     697              : 
     698            0 : rapidxml::xml_node<>* GridWriterUGX::
     699              : create_quadrilateral_node(QuadrilateralIterator quadsBegin,
     700              :                                                   QuadrilateralIterator quadsEnd,
     701              :                                                   AAVrtIndex aaIndVRT)
     702              : {
     703              : //      write the elements to a temporary stream
     704            0 :         stringstream ss;
     705            0 :         for(QuadrilateralIterator iter = quadsBegin; iter != quadsEnd; ++iter)
     706              :         {
     707            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     708            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " " ;
     709              :         }
     710              : 
     711            0 :         if(ss.str().size() > 0){
     712              :         //      allocate a string and erase last character(' ')
     713            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     714            0 :                 nodeData[ss.str().size()-1] = 0;
     715              :         //      create and return the node
     716            0 :                 return m_doc.allocate_node(node_element, "quadrilaterals", nodeData);
     717              :         }
     718              :         else{
     719              :         //      return an emtpy node
     720            0 :                 return m_doc.allocate_node(node_element, "quadrilaterals");
     721              :         }
     722            0 : }
     723              : 
     724            0 : rapidxml::xml_node<>* GridWriterUGX::
     725              : create_constraining_quadrilateral_node(ConstrainingQuadrilateralIterator quadsBegin,
     726              :                                                                            ConstrainingQuadrilateralIterator quadsEnd,
     727              :                                                                            AAVrtIndex aaIndVRT)
     728              : {
     729              : //      write the elements to a temporary stream
     730            0 :         stringstream ss;
     731            0 :         for(ConstrainingQuadrilateralIterator iter = quadsBegin; iter != quadsEnd; ++iter)
     732              :         {
     733            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     734            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " " ;
     735              :         }
     736              : 
     737            0 :         if(ss.str().size() > 0){
     738              :         //      allocate a string and erase last character(' ')
     739            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     740            0 :                 nodeData[ss.str().size()-1] = 0;
     741              :         //      create and return the node
     742            0 :                 return m_doc.allocate_node(node_element, "constraining_quadrilaterals", nodeData);
     743              :         }
     744              :         else{
     745              :         //      return an emtpy node
     746            0 :                 return m_doc.allocate_node(node_element, "constraining_quadrilaterals");
     747              :         }
     748            0 : }
     749              : 
     750            0 : rapidxml::xml_node<>* GridWriterUGX::
     751              : create_constrained_quadrilateral_node(ConstrainedQuadrilateralIterator quadsBegin,
     752              :                                                                           ConstrainedQuadrilateralIterator quadsEnd,
     753              :                                                                           AAVrtIndex aaIndVRT,
     754              :                                                                           AAFaceIndex aaIndFACE)
     755              : {
     756              : //      write the elements to a temporary stream
     757            0 :         stringstream ss;
     758            0 :         for(ConstrainedQuadrilateralIterator iter = quadsBegin; iter != quadsEnd; ++iter)
     759              :         {
     760            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     761            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " " ;
     762              :         //      write index of associated constraining element
     763              :         //      codes:  -1: no constraining element
     764              :         //                      0: vertex. index follows
     765              :         //                      1: edge. index follows
     766              :         //                      2: face. index follows
     767              :         //                      3: volume. index follows
     768            0 :                 Face* cf = dynamic_cast<Face*>((*iter)->get_constraining_object());
     769            0 :                 if(cf)
     770            0 :                         ss << "2 " << aaIndFACE[cf] << " ";
     771              :                 else
     772            0 :                         ss << "-1 ";
     773              :         }
     774              : 
     775            0 :         if(ss.str().size() > 0){
     776              :         //      allocate a string and erase last character(' ')
     777            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     778            0 :                 nodeData[ss.str().size()-1] = 0;
     779              :         //      create and return the node
     780            0 :                 return m_doc.allocate_node(node_element, "constrained_quadrilaterals", nodeData);
     781              :         }
     782              :         else{
     783              :         //      return an emtpy node
     784            0 :                 return m_doc.allocate_node(node_element, "constrained_quadrilaterals");
     785              :         }
     786            0 : }
     787              : 
     788            0 : rapidxml::xml_node<>* GridWriterUGX::
     789              : create_tetrahedron_node(TetrahedronIterator tetsBegin,
     790              :                                                   TetrahedronIterator tetsEnd,
     791              :                                                   AAVrtIndex aaIndVRT)
     792              : {
     793              : //      write the elements to a temporary stream
     794            0 :         stringstream ss;
     795            0 :         for(TetrahedronIterator iter = tetsBegin; iter != tetsEnd; ++iter)
     796              :         {
     797            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     798            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " " ;
     799              :         }
     800              : 
     801            0 :         if(ss.str().size() > 0){
     802              :         //      allocate a string and erase last character(' ')
     803            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     804            0 :                 nodeData[ss.str().size()-1] = 0;
     805              :         //      create and return the node
     806            0 :                 return m_doc.allocate_node(node_element, "tetrahedrons", nodeData);
     807              :         }
     808              :         else{
     809              :         //      return an emtpy node
     810            0 :                 return m_doc.allocate_node(node_element, "tetrahedrons");
     811              :         }
     812            0 : }
     813              : 
     814            0 : rapidxml::xml_node<>* GridWriterUGX::
     815              : create_hexahedron_node(HexahedronIterator hexasBegin,
     816              :                                                   HexahedronIterator hexasEnd,
     817              :                                                   AAVrtIndex aaIndVRT)
     818              : {
     819              : //      write the elements to a temporary stream
     820            0 :         stringstream ss;
     821            0 :         for(HexahedronIterator iter = hexasBegin; iter != hexasEnd; ++iter)
     822              :         {
     823            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     824            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " "
     825            0 :                         << aaIndVRT[(*iter)->vertex(4)] << " " << aaIndVRT[(*iter)->vertex(5)] << " "
     826            0 :                         << aaIndVRT[(*iter)->vertex(6)] << " " << aaIndVRT[(*iter)->vertex(7)] << " ";
     827              :         }
     828              : 
     829            0 :         if(ss.str().size() > 0){
     830              :         //      allocate a string and erase last character(' ')
     831            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     832            0 :                 nodeData[ss.str().size()-1] = 0;
     833              :         //      create and return the node
     834            0 :                 return m_doc.allocate_node(node_element, "hexahedrons", nodeData);
     835              :         }
     836              :         else{
     837              :         //      return an emtpy node
     838            0 :                 return m_doc.allocate_node(node_element, "hexahedrons");
     839              :         }
     840            0 : }
     841              : 
     842            0 : rapidxml::xml_node<>* GridWriterUGX::
     843              : create_prism_node(PrismIterator prismsBegin,
     844              :                                         PrismIterator prismsEnd,
     845              :                                         AAVrtIndex aaIndVRT)
     846              : {
     847              : //      write the elements to a temporary stream
     848            0 :         stringstream ss;
     849            0 :         for(PrismIterator iter = prismsBegin; iter != prismsEnd; ++iter)
     850              :         {
     851            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     852            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " "
     853            0 :                         << aaIndVRT[(*iter)->vertex(4)] << " " << aaIndVRT[(*iter)->vertex(5)] << " ";
     854              :         }
     855              : 
     856            0 :         if(ss.str().size() > 0){
     857              :         //      allocate a string and erase last character(' ')
     858            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     859            0 :                 nodeData[ss.str().size()-1] = 0;
     860              :         //      create and return the node
     861            0 :                 return m_doc.allocate_node(node_element, "prisms", nodeData);
     862              :         }
     863              :         else{
     864              :         //      return an emtpy node
     865            0 :                 return m_doc.allocate_node(node_element, "prisms");
     866              :         }
     867            0 : }
     868              : 
     869            0 : rapidxml::xml_node<>* GridWriterUGX::
     870              : create_pyramid_node(PyramidIterator pyrasBegin,
     871              :                                         PyramidIterator pyrasEnd,
     872              :                                         AAVrtIndex aaIndVRT)
     873              : {
     874              : //      write the elements to a temporary stream
     875            0 :         stringstream ss;
     876            0 :         for(PyramidIterator iter = pyrasBegin; iter != pyrasEnd; ++iter)
     877              :         {
     878            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     879            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " "
     880            0 :                         << aaIndVRT[(*iter)->vertex(4)] << " ";
     881              :         }
     882              : 
     883            0 :         if(ss.str().size() > 0){
     884              :         //      allocate a string and erase last character(' ')
     885            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     886            0 :                 nodeData[ss.str().size()-1] = 0;
     887              :         //      create and return the node
     888            0 :                 return m_doc.allocate_node(node_element, "pyramids", nodeData);
     889              :         }
     890              :         else{
     891              :         //      return an emtpy node
     892            0 :                 return m_doc.allocate_node(node_element, "pyramids");
     893              :         }
     894            0 : }
     895              : 
     896            0 : rapidxml::xml_node<>* GridWriterUGX::
     897              : create_octahedron_node(OctahedronIterator octsBegin,
     898              :                                                 OctahedronIterator octsEnd,
     899              :                                                 AAVrtIndex aaIndVRT)
     900              : {
     901              : //      write the elements to a temporary stream
     902            0 :         stringstream ss;
     903            0 :         for(OctahedronIterator iter = octsBegin; iter != octsEnd; ++iter)
     904              :         {
     905            0 :                 ss << aaIndVRT[(*iter)->vertex(0)] << " " << aaIndVRT[(*iter)->vertex(1)] << " "
     906            0 :                         << aaIndVRT[(*iter)->vertex(2)] << " " << aaIndVRT[(*iter)->vertex(3)] << " "
     907            0 :                         << aaIndVRT[(*iter)->vertex(4)] << " " << aaIndVRT[(*iter)->vertex(5)] << " ";
     908              :         }
     909              : 
     910            0 :         if(ss.str().size() > 0){
     911              :         //      allocate a string and erase last character(' ')
     912            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     913            0 :                 nodeData[ss.str().size()-1] = 0;
     914              :         //      create and return the node
     915            0 :                 return m_doc.allocate_node(node_element, "octahedrons", nodeData);
     916              :         }
     917              :         else{
     918              :         //      return an emtpy node
     919            0 :                 return m_doc.allocate_node(node_element, "octahedrons");
     920              :         }
     921            0 : }
     922              : 
     923              : 
     924              : ////////////////////////////////////////////////////////////////////////
     925              : ////////////////////////////////////////////////////////////////////////
     926              : //      implementation of GridReaderUGX
     927            0 : GridReaderUGX::GridReaderUGX()
     928              : {
     929            0 : }
     930              : 
     931            0 : GridReaderUGX::~GridReaderUGX()
     932              : {
     933            0 : }
     934              : 
     935            0 : const char* GridReaderUGX::
     936              : get_grid_name(size_t index) const
     937              : {
     938              :         assert(index < num_grids() && "Bad index!");
     939            0 :         xml_attribute<>* attrib = m_entries[index].node->first_attribute("name");
     940            0 :         if(attrib)
     941              :                 return attrib->value();
     942              :         return "";
     943              : }
     944              : 
     945            0 : size_t GridReaderUGX::num_subset_handlers(size_t refGridIndex) const
     946              : {
     947              : //      access the referred grid-entry
     948            0 :         if(refGridIndex >= m_entries.size()){
     949              :                 UG_LOG("GridReaderUGX::num_subset_handlers: bad refGridIndex. Aborting.\n");
     950            0 :                 return 0;
     951              :         }
     952              : 
     953            0 :         return m_entries[refGridIndex].subsetHandlerEntries.size();
     954              : }
     955              : 
     956            0 : const char* GridReaderUGX::
     957              : get_subset_handler_name(size_t refGridIndex, size_t subsetHandlerIndex) const
     958              : {
     959              :         assert(refGridIndex < num_grids() && "Bad refGridIndex!");
     960              :         const GridEntry& ge = m_entries[refGridIndex];
     961              :         assert(subsetHandlerIndex < ge.subsetHandlerEntries.size() && "Bad subsetHandlerIndex!");
     962              : 
     963            0 :         xml_attribute<>* attrib = ge.subsetHandlerEntries[subsetHandlerIndex].node->first_attribute("name");
     964            0 :         if(attrib)
     965              :                 return attrib->value();
     966              :         return "";
     967              : }
     968              : 
     969            0 : bool GridReaderUGX::
     970              : subset_handler(ISubsetHandler& shOut,
     971              :                                         size_t subsetHandlerIndex,
     972              :                                         size_t refGridIndex)
     973              : {
     974              : //      access the referred grid-entry
     975            0 :         if(refGridIndex >= m_entries.size()){
     976              :                 UG_LOG("GridReaderUGX::subset_handler: bad refGridIndex. Aborting.\n");
     977            0 :                 return false;
     978              :         }
     979              : 
     980              :         GridEntry& gridEntry = m_entries[refGridIndex];
     981              : 
     982              : //      get the referenced subset-handler entry
     983            0 :         if(subsetHandlerIndex >= gridEntry.subsetHandlerEntries.size()){
     984              :                 UG_LOG("GridReaderUGX::subset_handler: bad subsetHandlerIndex. Aborting.\n");
     985            0 :                 return false;
     986              :         }
     987              : 
     988              :         SubsetHandlerEntry& shEntry = gridEntry.subsetHandlerEntries[subsetHandlerIndex];
     989            0 :         shEntry.sh = &shOut;
     990              : 
     991            0 :         xml_node<>* subsetNode = shEntry.node->first_node("subset");
     992              :         size_t subsetInd = 0;
     993            0 :         while(subsetNode)
     994              :         {
     995              :         //      set subset info
     996              :         //      retrieve an initial subset-info from shOut, so that initialised values are kept.
     997            0 :                 SubsetInfo si = shOut.subset_info(subsetInd);
     998              : 
     999            0 :                 xml_attribute<>* attrib = subsetNode->first_attribute("name");
    1000            0 :                 if(attrib)
    1001              :                         si.name = attrib->value();
    1002              : 
    1003            0 :                 attrib = subsetNode->first_attribute("color");
    1004            0 :                 if(attrib){
    1005            0 :                         stringstream ss(attrib->value(), ios_base::in);
    1006            0 :                         for(size_t i = 0; i < 4; ++i)
    1007              :                                 ss >> si.color[i];
    1008            0 :                 }
    1009              : 
    1010            0 :                 attrib = subsetNode->first_attribute("state");
    1011            0 :                 if(attrib){
    1012            0 :                         stringstream ss(attrib->value(), ios_base::in);
    1013              :                         size_t state;
    1014              :                         ss >> state;
    1015            0 :                         si.subsetState = (uint)state;
    1016            0 :                 }
    1017              : 
    1018            0 :                 shOut.set_subset_info(subsetInd, si);
    1019              : 
    1020              :         //      read elements of this subset
    1021            0 :                 if(shOut.elements_are_supported(SHE_VERTEX))
    1022            0 :                         read_subset_handler_elements<Vertex>(shOut, "vertices",
    1023              :                                                                                                          subsetNode, subsetInd,
    1024            0 :                                                                                                          gridEntry.vertices);
    1025            0 :                 if(shOut.elements_are_supported(SHE_EDGE))
    1026            0 :                         read_subset_handler_elements<Edge>(shOut, "edges",
    1027              :                                                                                                          subsetNode, subsetInd,
    1028            0 :                                                                                                          gridEntry.edges);
    1029            0 :                 if(shOut.elements_are_supported(SHE_FACE))
    1030            0 :                         read_subset_handler_elements<Face>(shOut, "faces",
    1031              :                                                                                                  subsetNode, subsetInd,
    1032            0 :                                                                                                  gridEntry.faces);
    1033            0 :                 if(shOut.elements_are_supported(SHE_VOLUME))
    1034            0 :                         read_subset_handler_elements<Volume>(shOut, "volumes",
    1035              :                                                                                                  subsetNode, subsetInd,
    1036            0 :                                                                                                  gridEntry.volumes);
    1037              :         //      next subset
    1038            0 :                 subsetNode = subsetNode->next_sibling("subset");
    1039            0 :                 ++subsetInd;
    1040              :         }
    1041              : 
    1042              :         return true;
    1043              : }
    1044              : 
    1045              : template <class TGeomObj>
    1046            0 : bool GridReaderUGX::
    1047              : read_subset_handler_elements(ISubsetHandler& shOut,
    1048              :                                                          const char* elemNodeName,
    1049              :                                                          rapidxml::xml_node<>* subsetNode,
    1050              :                                                          int subsetIndex,
    1051              :                                                          std::vector<TGeomObj*>& vElems)
    1052              : {
    1053            0 :         xml_node<>* elemNode = subsetNode->first_node(elemNodeName);
    1054              : 
    1055            0 :         while(elemNode)
    1056              :         {
    1057              :         //      read the indices
    1058            0 :                 stringstream ss(elemNode->value(), ios_base::in);
    1059              : 
    1060              :                 size_t index;
    1061            0 :                 while(!ss.eof()){
    1062              :                         ss >> index;
    1063            0 :                         if(ss.fail())
    1064            0 :                                 continue;
    1065              : 
    1066            0 :                         if(index < vElems.size()){
    1067            0 :                                 shOut.assign_subset(vElems[index], subsetIndex);
    1068              :                         }
    1069              :                         else{
    1070            0 :                                 UG_LOG("Bad element index in subset-node " << elemNodeName <<
    1071              :                                                 ": " << index << ". Ignoring element.\n");
    1072              :                                 return false;
    1073              :                         }
    1074              :                 }
    1075              : 
    1076              :         //      get next element node
    1077            0 :                 elemNode = elemNode->next_sibling(elemNodeName);
    1078              :         }
    1079              : 
    1080              :         return true;
    1081              : }
    1082              : 
    1083              : 
    1084              : ///     returns the number of selectors for the given grid
    1085            0 : size_t GridReaderUGX::
    1086              : num_selectors(size_t refGridIndex) const
    1087              : {
    1088            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1089              :                                   "Bad refGridIndex: " << refGridIndex);
    1090              : 
    1091            0 :         return m_entries[refGridIndex].selectorEntries.size();
    1092              : }
    1093              : 
    1094              : ///     returns the name of the given selector
    1095            0 : const char* GridReaderUGX::
    1096              : get_selector_name(size_t refGridIndex, size_t selectorIndex) const
    1097              : {
    1098            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1099              :                                   "Bad refGridIndex: " << refGridIndex);
    1100              :         const GridEntry& ge = m_entries[refGridIndex];
    1101              :         assert(selectorIndex < ge.selectorEntries.size() && "Bad selectorIndex!");
    1102              : 
    1103            0 :         xml_attribute<>* attrib = ge.selectorEntries[selectorIndex].node->first_attribute("name");
    1104            0 :         if(attrib)
    1105              :                 return attrib->value();
    1106              :         return "";
    1107              : }
    1108              : 
    1109              : ///     fills the given selector
    1110            0 : bool GridReaderUGX::
    1111              : selector(ISelector& selOut, size_t selectorIndex, size_t refGridIndex)
    1112              : {
    1113              : //      access the referred grid-entry
    1114            0 :         if(refGridIndex >= m_entries.size()){
    1115              :                 UG_LOG("GridReaderUGX::selector: bad refGridIndex. Aborting.\n");
    1116            0 :                 return false;
    1117              :         }
    1118              : 
    1119              :         GridEntry& gridEntry = m_entries[refGridIndex];
    1120              : 
    1121              : //      get the referenced subset-handler entry
    1122            0 :         if(selectorIndex >= gridEntry.selectorEntries.size()){
    1123              :                 UG_LOG("GridReaderUGX::selector: bad selectorIndex. Aborting.\n");
    1124            0 :                 return false;
    1125              :         }
    1126              : 
    1127              :         SelectorEntry& selEntry = gridEntry.selectorEntries[selectorIndex];
    1128            0 :         selEntry.sel = &selOut;
    1129              : 
    1130            0 :         xml_node<>* selectorNode = selEntry.node;
    1131              : 
    1132              : //      read elements of this subset
    1133            0 :         if(selOut.elements_are_supported(SHE_VERTEX))
    1134            0 :                 read_selector_elements<Vertex>(selOut, "vertices",
    1135              :                                                                                         selectorNode,
    1136            0 :                                                                                         gridEntry.vertices);
    1137            0 :         if(selOut.elements_are_supported(SHE_EDGE))
    1138            0 :                 read_selector_elements<Edge>(selOut, "edges",
    1139              :                                                                                         selectorNode,
    1140            0 :                                                                                         gridEntry.edges);
    1141            0 :         if(selOut.elements_are_supported(SHE_FACE))
    1142            0 :                 read_selector_elements<Face>(selOut, "faces",
    1143              :                                                                                 selectorNode,
    1144            0 :                                                                                 gridEntry.faces);
    1145            0 :         if(selOut.elements_are_supported(SHE_VOLUME))
    1146            0 :                 read_selector_elements<Volume>(selOut, "volumes",
    1147              :                                                                                 selectorNode,
    1148            0 :                                                                                 gridEntry.volumes);
    1149              : 
    1150              :         return true;
    1151              : }
    1152              : 
    1153              : template <class TGeomObj>
    1154            0 : bool GridReaderUGX::
    1155              : read_selector_elements(ISelector& selOut, const char* elemNodeName,
    1156              :                                            rapidxml::xml_node<>* selNode,
    1157              :                                            std::vector<TGeomObj*>& vElems)
    1158              : {
    1159            0 :         xml_node<>* elemNode = selNode->first_node(elemNodeName);
    1160              : 
    1161            0 :         while(elemNode)
    1162              :         {
    1163              :         //      read the indices
    1164            0 :                 stringstream ss(elemNode->value(), ios_base::in);
    1165              : 
    1166              :                 size_t index;
    1167              :                 int state;
    1168              : 
    1169            0 :                 while(!ss.eof()){
    1170              :                         ss >> index;
    1171            0 :                         if(ss.fail())
    1172            0 :                                 continue;
    1173              : 
    1174            0 :                         ss >> state;
    1175            0 :                         if(ss.fail())
    1176            0 :                                 continue;
    1177              : 
    1178            0 :                         if(index < vElems.size()){
    1179            0 :                                 selOut.select(vElems[index], state);
    1180              :                         }
    1181              :                         else{
    1182            0 :                                 UG_LOG("Bad element index in subset-node " << elemNodeName <<
    1183              :                                                 ": " << index << ". Ignoring element.\n");
    1184              :                                 return false;
    1185              :                         }
    1186              :                 }
    1187              : 
    1188              :         //      get next element node
    1189            0 :                 elemNode = elemNode->next_sibling(elemNodeName);
    1190              :         }
    1191              :         return true;
    1192              : }
    1193              : 
    1194              : 
    1195            0 : size_t GridReaderUGX::
    1196              : num_projection_handlers(size_t refGridIndex) const
    1197              : {
    1198            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1199              :                                   "Bad refGridIndex: " << refGridIndex);
    1200              : 
    1201            0 :         return m_entries[refGridIndex].projectionHandlerEntries.size();
    1202              : }
    1203              : 
    1204            0 : const char* GridReaderUGX::
    1205              : get_projection_handler_name(size_t refGridIndex, size_t phIndex) const
    1206              : {
    1207            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1208              :                           "Bad refGridIndex: " << refGridIndex);
    1209              :         
    1210              :         const GridEntry& ge = m_entries[refGridIndex];
    1211            0 :         UG_COND_THROW(phIndex >= ge.projectionHandlerEntries.size(),
    1212              :                           "Bad projection-handler-index: " << phIndex);
    1213              : 
    1214            0 :         xml_attribute<>* attrib = ge.projectionHandlerEntries[phIndex]->first_attribute("name");
    1215            0 :         if(attrib)
    1216              :                 return attrib->value();
    1217              :         return "";
    1218              : }
    1219              : 
    1220              : 
    1221            0 : size_t GridReaderUGX::get_projection_handler_subset_handler_index(size_t phIndex, size_t refGridIndex)
    1222              : {
    1223            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1224              :                           "Bad refGridIndex: " << refGridIndex);
    1225              : 
    1226              :         const GridEntry& ge = m_entries[refGridIndex];
    1227            0 :         UG_COND_THROW(phIndex >= ge.projectionHandlerEntries.size(),
    1228              :                           "Bad projection-handler-index: " << phIndex);
    1229              : 
    1230            0 :         xml_node<>* phNode = ge.projectionHandlerEntries[phIndex];
    1231              : 
    1232              :         size_t shi = 0;
    1233            0 :         xml_attribute<>* attribSH = phNode->first_attribute("subset_handler");
    1234            0 :         if (attribSH) shi = atoi(attribSH->value());
    1235              : 
    1236            0 :         return shi;
    1237              : }
    1238              : 
    1239              : 
    1240            0 : SPRefinementProjector GridReaderUGX::
    1241              : read_projector(xml_node<>* projNode)
    1242              : {
    1243            0 :         static Factory<RefinementProjector, ProjectorTypes>       projFac;
    1244            0 :         static Archivar<boost::archive::text_iarchive, RefinementProjector, ProjectorTypes>       archivar;
    1245              : 
    1246            0 :         xml_attribute<>* attribType = projNode->first_attribute("type");
    1247            0 :         if(attribType){
    1248              :                 try {
    1249            0 :                         SPRefinementProjector proj = projFac.create(attribType->value());
    1250              : 
    1251            0 :                         string str(projNode->value(), projNode->value_size());
    1252            0 :                         stringstream ss(str, ios_base::in);
    1253              :                         boost::archive::text_iarchive ar(ss, boost::archive::no_header);
    1254              :                         archivar.archive(ar, *proj);
    1255              :                         return proj;
    1256            0 :                 }
    1257            0 :                 catch(boost::archive::archive_exception& e){
    1258            0 :                         UG_LOG("WARNING: Couldn't read projector of type '" <<
    1259              :                                         attribType->value() << "'." << std::endl);
    1260            0 :                 }
    1261              :         }
    1262              :         return SPRefinementProjector();
    1263              : }
    1264              : 
    1265            0 : bool GridReaderUGX::
    1266              : projection_handler(ProjectionHandler& phOut, size_t phIndex, size_t refGridIndex)
    1267              : {
    1268            0 :         UG_COND_THROW(refGridIndex >= m_entries.size(),
    1269              :                           "Bad refGridIndex: " << refGridIndex);
    1270              :         
    1271              :         const GridEntry& ge = m_entries[refGridIndex];
    1272            0 :         UG_COND_THROW(phIndex >= ge.projectionHandlerEntries.size(),
    1273              :                           "Bad projection-handler-index: " << phIndex);
    1274              : 
    1275            0 :         xml_node<>* phNode = ge.projectionHandlerEntries[phIndex];
    1276              :         
    1277            0 :         xml_node<>* defProjNode = phNode->first_node("default");
    1278            0 :         if(defProjNode){
    1279            0 :                 SPRefinementProjector proj = read_projector(defProjNode);
    1280            0 :                 if(proj.valid()){
    1281            0 :                         phOut.set_default_projector(proj);
    1282              :                 }
    1283              :         }
    1284              : 
    1285            0 :         xml_node<>* projNode = phNode->first_node("projector");
    1286            0 :         while(projNode){
    1287            0 :                 SPRefinementProjector proj = read_projector(projNode);
    1288            0 :                 if(!proj.valid())
    1289              :                         continue;
    1290              : 
    1291            0 :                 xml_attribute<>* attribSI = projNode->first_attribute("subset");
    1292            0 :                 if(attribSI){
    1293            0 :                         phOut.set_projector(atoi(attribSI->value()), proj);
    1294              :                 }
    1295              : 
    1296            0 :                 projNode = projNode->next_sibling("projector");
    1297              :         }
    1298              : 
    1299            0 :         return true;
    1300              : }
    1301              : 
    1302              : 
    1303            0 : bool GridReaderUGX::
    1304              : parse_file(const char* filename)
    1305              : {
    1306            0 :         ifstream in(filename, ios::binary);
    1307            0 :         if(!in)
    1308              :                 return false;
    1309              : 
    1310              : //      get the length of the file
    1311            0 :         streampos posStart = in.tellg();
    1312            0 :         in.seekg(0, ios_base::end);
    1313            0 :         streampos posEnd = in.tellg();
    1314              :         streamsize size = posEnd - posStart;
    1315              : 
    1316              : //      go back to the start of the file
    1317            0 :         in.seekg(posStart);
    1318              : 
    1319              : //      read the whole file en-block and terminate it with 0
    1320            0 :         char* fileContent = m_doc.allocate_string(0, size + 1);
    1321            0 :         in.read(fileContent, size);
    1322            0 :         fileContent[size] = 0;
    1323            0 :         in.close();
    1324              : 
    1325              : //      parse the xml-data
    1326            0 :         m_doc.parse<0>(fileContent);
    1327              : 
    1328              : //      notify derived classes that a new document has been parsed.
    1329            0 :         return new_document_parsed();
    1330            0 : }
    1331              : 
    1332            0 : bool GridReaderUGX::
    1333              : new_document_parsed()
    1334              : {
    1335              : //      update entries
    1336              :         m_entries.clear();
    1337              : 
    1338              : //      iterate through all grids
    1339            0 :         xml_node<>* curNode = m_doc.first_node("grid");
    1340            0 :         while(curNode){
    1341            0 :                 m_entries.push_back(GridEntry(curNode));
    1342              :                 GridEntry& gridEntry = m_entries.back();
    1343              : 
    1344              :         //      collect associated subset handlers
    1345            0 :                 xml_node<>* curSHNode = curNode->first_node("subset_handler");
    1346            0 :                 while(curSHNode){
    1347            0 :                         gridEntry.subsetHandlerEntries.push_back(SubsetHandlerEntry(curSHNode));
    1348            0 :                         curSHNode = curSHNode->next_sibling("subset_handler");
    1349              :                 }
    1350              : 
    1351              :         //      collect associated selectors
    1352            0 :                 xml_node<>* curSelNode = curNode->first_node("selector");
    1353            0 :                 while(curSelNode){
    1354            0 :                         gridEntry.selectorEntries.push_back(SelectorEntry(curSelNode));
    1355            0 :                         curSelNode = curSelNode->next_sibling("selector");
    1356              :                 }
    1357              : 
    1358              :         //      collect associated projectionHandlers
    1359            0 :                 xml_node<>* curPHNode = curNode->first_node("projection_handler");
    1360            0 :                 while(curPHNode){
    1361            0 :                         gridEntry.projectionHandlerEntries.push_back(curPHNode);
    1362            0 :                         curPHNode = curPHNode->next_sibling("projection_handler");
    1363              :                 }
    1364              : 
    1365            0 :                 curNode = curNode->next_sibling("grid");
    1366              :         }
    1367              : 
    1368            0 :         return true;
    1369              : }
    1370              : 
    1371            0 : bool GridReaderUGX::
    1372              : create_edges(std::vector<Edge*>& edgesOut,
    1373              :                         Grid& grid, rapidxml::xml_node<>* node,
    1374              :                         std::vector<Vertex*>& vrts)
    1375              : {
    1376              : //      create a buffer with which we can access the data
    1377            0 :         string str(node->value(), node->value_size());
    1378            0 :         stringstream ss(str, ios_base::in);
    1379              : 
    1380              : //      read the edges
    1381              :         int i1, i2;
    1382            0 :         while(!ss.eof()){
    1383              :         //      read the indices
    1384            0 :                 ss >> i1 >> i2;
    1385              : 
    1386              :         //      make sure that everything went right
    1387            0 :                 if(ss.fail())
    1388              :                         break;
    1389              : 
    1390              :         //      make sure that the indices are valid
    1391            0 :                 int maxInd = (int)vrts.size() - 1;
    1392            0 :                 if(i1 < 0 || i1 > maxInd ||
    1393            0 :                    i2 < 0 || i2 > maxInd)
    1394              :                 {
    1395            0 :                         UG_LOG("  ERROR in GridReaderUGX::create_edges: invalid vertex index: "
    1396              :                                         "(" << i1 << ", " << i2 << ")\n");
    1397              :                         return false;
    1398              :                 }
    1399              : 
    1400              :         //      create the edge
    1401            0 :                 edgesOut.push_back(*grid.create<RegularEdge>(EdgeDescriptor(vrts[i1], vrts[i2])));
    1402              :         }
    1403              : 
    1404              :         return true;
    1405            0 : }
    1406              : 
    1407            0 : bool GridReaderUGX::
    1408              : create_constraining_edges(std::vector<Edge*>& edgesOut,
    1409              :                                                   Grid& grid, rapidxml::xml_node<>* node,
    1410              :                                                   std::vector<Vertex*>& vrts)
    1411              : {
    1412              : //      create a buffer with which we can access the data
    1413            0 :         string str(node->value(), node->value_size());
    1414            0 :         stringstream ss(str, ios_base::in);
    1415              : 
    1416              : //      read the edges
    1417              :         int i1, i2;
    1418            0 :         while(!ss.eof()){
    1419              :         //      read the indices
    1420            0 :                 ss >> i1 >> i2;
    1421              : 
    1422              :         //      make sure that everything went right
    1423            0 :                 if(ss.fail())
    1424              :                         break;
    1425              : 
    1426              :         //      make sure that the indices are valid
    1427            0 :                 int maxInd = (int)vrts.size() - 1;
    1428            0 :                 if(i1 < 0 || i1 > maxInd ||
    1429            0 :                    i2 < 0 || i2 > maxInd)
    1430              :                 {
    1431              :                         UG_LOG("  ERROR in GridReaderUGX::create_constraining_edges: invalid vertex index.\n");
    1432              :                         return false;
    1433              :                 }
    1434              : 
    1435              :         //      create the edge
    1436            0 :                 edgesOut.push_back(*grid.create<ConstrainingEdge>(EdgeDescriptor(vrts[i1], vrts[i2])));
    1437              :         }
    1438              : 
    1439              :         return true;
    1440            0 : }
    1441              : 
    1442            0 : bool GridReaderUGX::
    1443              : create_constrained_edges(std::vector<Edge*>& edgesOut,
    1444              :                                                   std::vector<std::pair<int, int> >& constrainingObjsOut,
    1445              :                                                   Grid& grid, rapidxml::xml_node<>* node,
    1446              :                                                   std::vector<Vertex*>& vrts)
    1447              : {
    1448              : //      create a buffer with which we can access the data
    1449            0 :         string str(node->value(), node->value_size());
    1450            0 :         stringstream ss(str, ios_base::in);
    1451              : 
    1452              : //      read the edges
    1453              :         int i1, i2;
    1454            0 :         while(!ss.eof()){
    1455              :         //      read the indices
    1456            0 :                 ss >> i1 >> i2;
    1457              : 
    1458              :         //      read the type and index of the constraining object
    1459              :                 int conObjType, conObjIndex;
    1460            0 :                 ss >> conObjType;
    1461              : 
    1462            0 :                 if(conObjType != -1)
    1463            0 :                         ss >> conObjIndex;
    1464              : 
    1465              :         //      make sure that everything went right
    1466            0 :                 if(ss.fail())
    1467              :                         break;
    1468              : 
    1469              :         //      make sure that the indices are valid
    1470            0 :                 int maxInd = (int)vrts.size() - 1;
    1471            0 :                 if(i1 < 0 || i1 > maxInd ||
    1472            0 :                    i2 < 0 || i2 > maxInd)
    1473              :                 {
    1474              :                         UG_LOG("  ERROR in GridReaderUGX::create_edges: invalid vertex index.\n");
    1475            0 :                         return false;
    1476              :                 }
    1477              : 
    1478              :         //      create the edge
    1479            0 :                 ConstrainedEdge* edge = *grid.create<ConstrainedEdge>(EdgeDescriptor(vrts[i1], vrts[i2]));
    1480            0 :                 edgesOut.push_back(edge);
    1481              : 
    1482              :         //      add conObjType and conObjIndex to their list
    1483            0 :                 constrainingObjsOut.push_back(std::make_pair(conObjType, conObjIndex));
    1484              :         }
    1485              : 
    1486              :         return true;
    1487            0 : }
    1488              : 
    1489            0 : bool GridReaderUGX::
    1490              : create_triangles(std::vector<Face*>& facesOut,
    1491              :                                   Grid& grid, rapidxml::xml_node<>* node,
    1492              :                                   std::vector<Vertex*>& vrts)
    1493              : {
    1494              : //      create a buffer with which we can access the data
    1495            0 :         string str(node->value(), node->value_size());
    1496            0 :         stringstream ss(str, ios_base::in);
    1497              : 
    1498              : //      read the triangles
    1499              :         int i1, i2, i3;
    1500            0 :         while(!ss.eof()){
    1501              :         //      read the indices
    1502            0 :                 ss >> i1 >> i2 >> i3;
    1503              : 
    1504              :         //      make sure that everything went right
    1505            0 :                 if(ss.fail())
    1506              :                         break;
    1507              : 
    1508              :         //      make sure that the indices are valid
    1509            0 :                 int maxInd = (int)vrts.size() - 1;
    1510            0 :                 if(i1 < 0 || i1 > maxInd ||
    1511            0 :                    i2 < 0 || i2 > maxInd ||
    1512            0 :                    i3 < 0 || i3 > maxInd)
    1513              :                 {
    1514              :                         UG_LOG("  ERROR in GridReaderUGX::create_triangles: invalid vertex index.\n");
    1515              :                         return false;
    1516              :                 }
    1517              : 
    1518              :         //      create the triangle
    1519              :                 facesOut.push_back(
    1520            0 :                         *grid.create<Triangle>(TriangleDescriptor(vrts[i1], vrts[i2], vrts[i3])));
    1521              :         }
    1522              : 
    1523              :         return true;
    1524            0 : }
    1525              : 
    1526            0 : bool GridReaderUGX::
    1527              : create_constraining_triangles(std::vector<Face*>& facesOut,
    1528              :                                           Grid& grid, rapidxml::xml_node<>* node,
    1529              :                                           std::vector<Vertex*>& vrts)
    1530              : {
    1531              : //      create a buffer with which we can access the data
    1532            0 :         string str(node->value(), node->value_size());
    1533            0 :         stringstream ss(str, ios_base::in);
    1534              : 
    1535              : //      read the triangles
    1536              :         int i1, i2, i3;
    1537            0 :         while(!ss.eof()){
    1538              :         //      read the indices
    1539            0 :                 ss >> i1 >> i2 >> i3;
    1540              : 
    1541              :         //      make sure that everything went right
    1542            0 :                 if(ss.fail())
    1543              :                         break;
    1544              : 
    1545              :         //      make sure that the indices are valid
    1546            0 :                 int maxInd = (int)vrts.size() - 1;
    1547            0 :                 if(i1 < 0 || i1 > maxInd ||
    1548            0 :                    i2 < 0 || i2 > maxInd ||
    1549            0 :                    i3 < 0 || i3 > maxInd)
    1550              :                 {
    1551              :                         UG_LOG("  ERROR in GridReaderUGX::create_constraining_triangles: invalid vertex index.\n");
    1552              :                         return false;
    1553              :                 }
    1554              : 
    1555              :         //      create the triangle
    1556              :                 facesOut.push_back(
    1557            0 :                         *grid.create<ConstrainingTriangle>(TriangleDescriptor(vrts[i1], vrts[i2], vrts[i3])));
    1558              :         }
    1559              : 
    1560              :         return true;
    1561            0 : }
    1562              : 
    1563            0 : bool GridReaderUGX::
    1564              : create_constrained_triangles(std::vector<Face*>& facesOut,
    1565              :                                           std::vector<std::pair<int, int> >& constrainingObjsOut,
    1566              :                                           Grid& grid, rapidxml::xml_node<>* node,
    1567              :                                           std::vector<Vertex*>& vrts)
    1568              : {
    1569              : //      create a buffer with which we can access the data
    1570            0 :         string str(node->value(), node->value_size());
    1571            0 :         stringstream ss(str, ios_base::in);
    1572              : 
    1573              : //      read the triangles
    1574              :         int i1, i2, i3;
    1575            0 :         while(!ss.eof()){
    1576              :         //      read the indices
    1577            0 :                 ss >> i1 >> i2 >> i3;
    1578              : 
    1579              :         //      read the type and index of the constraining object
    1580              :                 int conObjType, conObjIndex;
    1581            0 :                 ss >> conObjType;
    1582              : 
    1583            0 :                 if(conObjType != -1)
    1584            0 :                         ss >> conObjIndex;
    1585              :                         
    1586              :         //      make sure that everything went right
    1587            0 :                 if(ss.fail())
    1588              :                         break;
    1589              : 
    1590              :         //      make sure that the indices are valid
    1591            0 :                 int maxInd = (int)vrts.size() - 1;
    1592            0 :                 if(i1 < 0 || i1 > maxInd ||
    1593            0 :                    i2 < 0 || i2 > maxInd ||
    1594            0 :                    i3 < 0 || i3 > maxInd)
    1595              :                 {
    1596              :                         UG_LOG("  ERROR in GridReaderUGX::create_constraining_triangles: invalid vertex index.\n");
    1597            0 :                         return false;
    1598              :                 }
    1599              : 
    1600              :         //      create the triangle
    1601              :                 facesOut.push_back(
    1602            0 :                         *grid.create<ConstrainedTriangle>(TriangleDescriptor(vrts[i1], vrts[i2], vrts[i3])));
    1603              :                         
    1604              :         //      add conObjType and conObjIndex to their list
    1605            0 :                 constrainingObjsOut.push_back(std::make_pair(conObjType, conObjIndex));
    1606              :         }
    1607              : 
    1608              :         return true;
    1609            0 : }
    1610              : 
    1611            0 : bool GridReaderUGX::
    1612              : create_quadrilaterals(std::vector<Face*>& facesOut,
    1613              :                                            Grid& grid, rapidxml::xml_node<>* node,
    1614              :                                            std::vector<Vertex*>& vrts)
    1615              : {
    1616              : //      create a buffer with which we can access the data
    1617            0 :         string str(node->value(), node->value_size());
    1618            0 :         stringstream ss(str, ios_base::in);
    1619              : 
    1620              : //      read the quadrilaterals
    1621              :         int i1, i2, i3, i4;
    1622            0 :         while(!ss.eof()){
    1623              :         //      read the indices
    1624            0 :                 ss >> i1 >> i2 >> i3 >> i4;
    1625              : 
    1626              :         //      make sure that everything went right
    1627            0 :                 if(ss.fail())
    1628              :                         break;
    1629              : 
    1630              :         //      make sure that the indices are valid
    1631            0 :                 int maxInd = (int)vrts.size() - 1;
    1632            0 :                 if(i1 < 0 || i1 > maxInd ||
    1633            0 :                    i2 < 0 || i2 > maxInd ||
    1634            0 :                    i3 < 0 || i3 > maxInd ||
    1635            0 :                    i4 < 0 || i4 > maxInd)
    1636              :                 {
    1637              :                         UG_LOG("  ERROR in GridReaderUGX::create_quadrilaterals: invalid vertex index.\n");
    1638              :                         return false;
    1639              :                 }
    1640              : 
    1641              :         //      create the quad
    1642              :                 facesOut.push_back(
    1643            0 :                         *grid.create<Quadrilateral>(QuadrilateralDescriptor(vrts[i1], vrts[i2],
    1644            0 :                                                                                                                            vrts[i3], vrts[i4])));
    1645              :         }
    1646              : 
    1647              :         return true;
    1648            0 : }
    1649              : 
    1650            0 : bool GridReaderUGX::
    1651              : create_constraining_quadrilaterals(std::vector<Face*>& facesOut,
    1652              :                                           Grid& grid, rapidxml::xml_node<>* node,
    1653              :                                           std::vector<Vertex*>& vrts)
    1654              : {
    1655              : //      create a buffer with which we can access the data
    1656            0 :         string str(node->value(), node->value_size());
    1657            0 :         stringstream ss(str, ios_base::in);
    1658              : 
    1659              : //      read the quadrilaterals
    1660              :         int i1, i2, i3, i4;
    1661            0 :         while(!ss.eof()){
    1662              :         //      read the indices
    1663            0 :                 ss >> i1 >> i2 >> i3 >> i4;
    1664              : 
    1665              :         //      make sure that everything went right
    1666            0 :                 if(ss.fail())
    1667              :                         break;
    1668              : 
    1669              :         //      make sure that the indices are valid
    1670            0 :                 int maxInd = (int)vrts.size() - 1;
    1671            0 :                 if(i1 < 0 || i1 > maxInd ||
    1672            0 :                    i2 < 0 || i2 > maxInd ||
    1673            0 :                    i3 < 0 || i3 > maxInd ||
    1674            0 :                    i4 < 0 || i4 > maxInd)
    1675              :                 {
    1676              :                         UG_LOG("  ERROR in GridReaderUGX::create_quadrilaterals: invalid vertex index.\n");
    1677              :                         return false;
    1678              :                 }
    1679              : 
    1680              :         //      create the quad
    1681              :                 facesOut.push_back(
    1682            0 :                         *grid.create<ConstrainingQuadrilateral>(QuadrilateralDescriptor(
    1683            0 :                                                                                                                         vrts[i1], vrts[i2],
    1684            0 :                                                                                                                         vrts[i3], vrts[i4])));
    1685              :         }
    1686              : 
    1687              :         return true;
    1688            0 : }
    1689              : 
    1690            0 : bool GridReaderUGX::
    1691              : create_constrained_quadrilaterals(std::vector<Face*>& facesOut,
    1692              :                                           std::vector<std::pair<int, int> >& constrainingObjsOut,
    1693              :                                           Grid& grid, rapidxml::xml_node<>* node,
    1694              :                                           std::vector<Vertex*>& vrts)
    1695              : {
    1696              : //      create a buffer with which we can access the data
    1697            0 :         string str(node->value(), node->value_size());
    1698            0 :         stringstream ss(str, ios_base::in);
    1699              : 
    1700              : //      read the quadrilaterals
    1701              :         int i1, i2, i3, i4;
    1702            0 :         while(!ss.eof()){
    1703              :         //      read the indices
    1704            0 :                 ss >> i1 >> i2 >> i3 >> i4;
    1705              : 
    1706              :         //      read the type and index of the constraining object
    1707              :                 int conObjType, conObjIndex;
    1708            0 :                 ss >> conObjType;
    1709              : 
    1710            0 :                 if(conObjType != -1)
    1711            0 :                         ss >> conObjIndex;
    1712              :                         
    1713              :         //      make sure that everything went right
    1714            0 :                 if(ss.fail())
    1715              :                         break;
    1716              : 
    1717              :         //      make sure that the indices are valid
    1718            0 :                 int maxInd = (int)vrts.size() - 1;
    1719            0 :                 if(i1 < 0 || i1 > maxInd ||
    1720            0 :                    i2 < 0 || i2 > maxInd ||
    1721            0 :                    i3 < 0 || i3 > maxInd ||
    1722            0 :                    i4 < 0 || i4 > maxInd)
    1723              :                 {
    1724              :                         UG_LOG("  ERROR in GridReaderUGX::create_quadrilaterals: invalid vertex index.\n");
    1725            0 :                         return false;
    1726              :                 }
    1727              : 
    1728              :         //      create the quad
    1729              :                 facesOut.push_back(
    1730            0 :                         *grid.create<ConstrainedQuadrilateral>(QuadrilateralDescriptor(
    1731            0 :                                                                                                                         vrts[i1], vrts[i2],
    1732            0 :                                                                                                                         vrts[i3], vrts[i4])));
    1733              :         
    1734              :         //      add conObjType and conObjIndex to their list
    1735            0 :                 constrainingObjsOut.push_back(std::make_pair(conObjType, conObjIndex));
    1736              :         }
    1737              : 
    1738              :         return true;
    1739            0 : }
    1740              : 
    1741              :                                           
    1742            0 : bool GridReaderUGX::
    1743              : create_tetrahedrons(std::vector<Volume*>& volsOut,
    1744              :                                          Grid& grid, rapidxml::xml_node<>* node,
    1745              :                                          std::vector<Vertex*>& vrts)
    1746              : {
    1747              : //      create a buffer with which we can access the data
    1748            0 :         string str(node->value(), node->value_size());
    1749            0 :         stringstream ss(str, ios_base::in);
    1750              : 
    1751              : //      read the tetrahedrons
    1752              :         int i1, i2, i3, i4;
    1753            0 :         while(!ss.eof()){
    1754              :         //      read the indices
    1755            0 :                 ss >> i1 >> i2 >> i3 >> i4;
    1756              : 
    1757              :         //      make sure that everything went right
    1758            0 :                 if(ss.fail())
    1759              :                         break;
    1760              : 
    1761              :         //      make sure that the indices are valid
    1762            0 :                 int maxInd = (int)vrts.size() - 1;
    1763            0 :                 if(i1 < 0 || i1 > maxInd ||
    1764            0 :                    i2 < 0 || i2 > maxInd ||
    1765            0 :                    i3 < 0 || i3 > maxInd ||
    1766            0 :                    i4 < 0 || i4 > maxInd)
    1767              :                 {
    1768              :                         UG_LOG("  ERROR in GridReaderUGX::create_tetrahedrons: invalid vertex index.\n");
    1769              :                         return false;
    1770              :                 }
    1771              : 
    1772              :         //      create the element
    1773              :                 volsOut.push_back(
    1774            0 :                         *grid.create<Tetrahedron>(TetrahedronDescriptor(vrts[i1], vrts[i2],
    1775            0 :                                                                                                                    vrts[i3], vrts[i4])));
    1776              :         }
    1777              : 
    1778              :         return true;
    1779            0 : }
    1780              : 
    1781            0 : bool GridReaderUGX::
    1782              : create_hexahedrons(std::vector<Volume*>& volsOut,
    1783              :                                         Grid& grid, rapidxml::xml_node<>* node,
    1784              :                                         std::vector<Vertex*>& vrts)
    1785              : {
    1786              : //      create a buffer with which we can access the data
    1787            0 :         string str(node->value(), node->value_size());
    1788            0 :         stringstream ss(str, ios_base::in);
    1789              : 
    1790              : //      read the hexahedrons
    1791              :         int i1, i2, i3, i4, i5, i6, i7, i8;
    1792            0 :         while(!ss.eof()){
    1793              :         //      read the indices
    1794            0 :                 ss >> i1 >> i2 >> i3 >> i4 >> i5 >> i6 >> i7 >> i8;
    1795              : 
    1796              :         //      make sure that everything went right
    1797            0 :                 if(ss.fail())
    1798              :                         break;
    1799              : 
    1800              :         //      make sure that the indices are valid
    1801            0 :                 int maxInd = (int)vrts.size() - 1;
    1802            0 :                 if(i1 < 0 || i1 > maxInd ||
    1803            0 :                    i2 < 0 || i2 > maxInd ||
    1804            0 :                    i3 < 0 || i3 > maxInd ||
    1805            0 :                    i4 < 0 || i4 > maxInd ||
    1806            0 :                    i5 < 0 || i5 > maxInd ||
    1807            0 :                    i6 < 0 || i6 > maxInd ||
    1808            0 :                    i7 < 0 || i7 > maxInd ||
    1809            0 :                    i8 < 0 || i8 > maxInd)
    1810              :                 {
    1811              :                         UG_LOG("  ERROR in GridReaderUGX::create_hexahedrons: invalid vertex index.\n");
    1812              :                         return false;
    1813              :                 }
    1814              : 
    1815              :         //      create the element
    1816              :                 volsOut.push_back(
    1817            0 :                         *grid.create<Hexahedron>(HexahedronDescriptor(vrts[i1], vrts[i2], vrts[i3], vrts[i4],
    1818            0 :                                                                                                                   vrts[i5], vrts[i6], vrts[i7], vrts[i8])));
    1819              :         }
    1820              : 
    1821              :         return true;
    1822            0 : }
    1823              : 
    1824            0 : bool GridReaderUGX::
    1825              : create_prisms(std::vector<Volume*>& volsOut,
    1826              :                           Grid& grid, rapidxml::xml_node<>* node,
    1827              :                           std::vector<Vertex*>& vrts)
    1828              : {
    1829              : //      create a buffer with which we can access the data
    1830            0 :         string str(node->value(), node->value_size());
    1831            0 :         stringstream ss(str, ios_base::in);
    1832              : 
    1833              : //      read the hexahedrons
    1834              :         int i1, i2, i3, i4, i5, i6;
    1835            0 :         while(!ss.eof()){
    1836              :         //      read the indices
    1837            0 :                 ss >> i1 >> i2 >> i3 >> i4 >> i5 >> i6;
    1838              : 
    1839              :         //      make sure that everything went right
    1840            0 :                 if(ss.fail())
    1841              :                         break;
    1842              : 
    1843              :         //      make sure that the indices are valid
    1844            0 :                 int maxInd = (int)vrts.size() - 1;
    1845            0 :                 if(i1 < 0 || i1 > maxInd ||
    1846            0 :                    i2 < 0 || i2 > maxInd ||
    1847            0 :                    i3 < 0 || i3 > maxInd ||
    1848            0 :                    i4 < 0 || i4 > maxInd ||
    1849            0 :                    i5 < 0 || i5 > maxInd ||
    1850            0 :                    i6 < 0 || i6 > maxInd)
    1851              :                 {
    1852              :                         UG_LOG("  ERROR in GridReaderUGX::create_prisms: invalid vertex index.\n");
    1853              :                         return false;
    1854              :                 }
    1855              : 
    1856              :         //      create the element
    1857              :                 volsOut.push_back(
    1858            0 :                         *grid.create<Prism>(PrismDescriptor(vrts[i1], vrts[i2], vrts[i3], vrts[i4],
    1859            0 :                                                                                                 vrts[i5], vrts[i6])));
    1860              :         }
    1861              : 
    1862              :         return true;
    1863            0 : }
    1864              : 
    1865            0 : bool GridReaderUGX::
    1866              : create_pyramids(std::vector<Volume*>& volsOut,
    1867              :                                 Grid& grid, rapidxml::xml_node<>* node,
    1868              :                                 std::vector<Vertex*>& vrts)
    1869              : {
    1870              : //      create a buffer with which we can access the data
    1871            0 :         string str(node->value(), node->value_size());
    1872            0 :         stringstream ss(str, ios_base::in);
    1873              : 
    1874              : //      read the hexahedrons
    1875              :         int i1, i2, i3, i4, i5;
    1876            0 :         while(!ss.eof()){
    1877              :         //      read the indices
    1878            0 :                 ss >> i1 >> i2 >> i3 >> i4 >> i5;
    1879              : 
    1880              :         //      make sure that everything went right
    1881            0 :                 if(ss.fail())
    1882              :                         break;
    1883              : 
    1884              :         //      make sure that the indices are valid
    1885            0 :                 int maxInd = (int)vrts.size() - 1;
    1886            0 :                 if(i1 < 0 || i1 > maxInd ||
    1887            0 :                    i2 < 0 || i2 > maxInd ||
    1888            0 :                    i3 < 0 || i3 > maxInd ||
    1889            0 :                    i4 < 0 || i4 > maxInd ||
    1890            0 :                    i5 < 0 || i5 > maxInd)
    1891              :                 {
    1892              :                         UG_LOG("  ERROR in GridReaderUGX::create_pyramids: invalid vertex index.\n");
    1893              :                         return false;
    1894              :                 }
    1895              : 
    1896              :         //      create the element
    1897              :                 volsOut.push_back(
    1898            0 :                         *grid.create<Pyramid>(PyramidDescriptor(vrts[i1], vrts[i2], vrts[i3],
    1899            0 :                                                                                                         vrts[i4], vrts[i5])));
    1900              :         }
    1901              : 
    1902              :         return true;
    1903            0 : }
    1904              : 
    1905            0 : bool GridReaderUGX::
    1906              : create_octahedrons(std::vector<Volume*>& volsOut,
    1907              :                                         Grid& grid, rapidxml::xml_node<>* node,
    1908              :                                         std::vector<Vertex*>& vrts)
    1909              : {
    1910              : //      create a buffer with which we can access the data
    1911            0 :         string str(node->value(), node->value_size());
    1912            0 :         stringstream ss(str, ios_base::in);
    1913              : 
    1914              : //      read the octahedrons
    1915              :         int i1, i2, i3, i4, i5, i6;
    1916            0 :         while(!ss.eof()){
    1917              :         //      read the indices
    1918            0 :                 ss >> i1 >> i2 >> i3 >> i4 >> i5 >> i6;
    1919              : 
    1920              :         //      make sure that everything went right
    1921            0 :                 if(ss.fail())
    1922              :                         break;
    1923              : 
    1924              :         //      make sure that the indices are valid
    1925            0 :                 int maxInd = (int)vrts.size() - 1;
    1926            0 :                 if(i1 < 0 || i1 > maxInd ||
    1927            0 :                    i2 < 0 || i2 > maxInd ||
    1928            0 :                    i3 < 0 || i3 > maxInd ||
    1929            0 :                    i4 < 0 || i4 > maxInd ||
    1930            0 :                    i5 < 0 || i5 > maxInd ||
    1931            0 :                    i6 < 0 || i6 > maxInd)
    1932              :                 {
    1933              :                         UG_LOG("  ERROR in GridReaderUGX::create_octahedrons: invalid vertex index.\n");
    1934              :                         return false;
    1935              :                 }
    1936              : 
    1937              :         //      create the element
    1938              :                 volsOut.push_back(
    1939            0 :                         *grid.create<Octahedron>(OctahedronDescriptor(    vrts[i1], vrts[i2], vrts[i3],
    1940            0 :                                                                                                                         vrts[i4], vrts[i5], vrts[i6])));
    1941              :         }
    1942              : 
    1943              :         return true;
    1944            0 : }
    1945              : 
    1946              : 
    1947            0 : UGXFileInfo::UGXFileInfo() :
    1948            0 :         m_fileParsed(false)
    1949              : {
    1950            0 : }
    1951              : 
    1952            0 : bool UGXFileInfo::parse_file(const char* filename)
    1953              : {
    1954              :         PROFILE_FUNC_GROUP("UGXFileInfo");
    1955            0 :         string tfile = FindFileInStandardPaths(filename);
    1956              : 
    1957            0 :         ifstream in(tfile.c_str(), ios::binary);
    1958            0 :         UG_COND_THROW(!in, "UGXFileInfo: couldn't find file '" << filename << "'");
    1959              : 
    1960              : //      get the length of the file
    1961            0 :         streampos posStart = in.tellg();
    1962            0 :         in.seekg(0, ios_base::end);
    1963            0 :         streampos posEnd = in.tellg();
    1964              :         streamsize size = posEnd - posStart;
    1965              : 
    1966              : //      go back to the start of the file
    1967            0 :         in.seekg(posStart);
    1968              : 
    1969              : //      read the whole file en-block and terminate it with 0
    1970              :         rapidxml::xml_document<> doc;
    1971            0 :         char* fileContent = doc.allocate_string(0, size + 1);
    1972            0 :         in.read(fileContent, size);
    1973            0 :         fileContent[size] = 0;
    1974            0 :         in.close();
    1975              : 
    1976              : //      parse the xml-data
    1977            0 :         doc.parse<0>(fileContent);
    1978              : 
    1979            0 :         xml_node<>* curNode = doc.first_node("grid");
    1980            0 :         while(curNode){
    1981            0 :                 m_grids.push_back(GridInfo());
    1982              :                 GridInfo& gInfo = m_grids.back();
    1983            0 :                 gInfo.m_name = node_name(curNode);
    1984              : 
    1985              :         //      collect associated subset handlers
    1986            0 :                 xml_node<>* curSHNode = curNode->first_node("subset_handler");
    1987            0 :                 while(curSHNode){
    1988            0 :                         gInfo.m_subsetHandlers.push_back(SubsetHandlerInfo());
    1989              :                         SubsetHandlerInfo& shInfo = gInfo.m_subsetHandlers.back();
    1990            0 :                         shInfo.m_name = node_name(curSHNode);
    1991              : 
    1992            0 :                         xml_node<>* curSubsetNode = curSHNode->first_node("subset");
    1993              : 
    1994            0 :                         while(curSubsetNode){
    1995            0 :                                 shInfo.m_subsets.push_back(SubsetInfo());
    1996              :                                 SubsetInfo& sInfo = shInfo.m_subsets.back();
    1997            0 :                                 sInfo.m_name = node_name(curSubsetNode);
    1998            0 :                                 curSubsetNode = curSubsetNode->next_sibling("subset");
    1999              :                         }
    2000              : 
    2001            0 :                         curSHNode = curSHNode->next_sibling("subset_handler");
    2002              :                 }
    2003              : 
    2004              :                 // loop through vertices to find bounding box of geometry
    2005              :                 AABox<vector3> box(vector3(0, 0, 0), vector3(0, 0, 0));
    2006            0 :                 xml_node<>* vrtNode = curNode->first_node("vertices");
    2007            0 :                 while (vrtNode)
    2008              :                 {
    2009              :                         // create a bounding box around the vertices contained in this xml node
    2010              :                         AABox<vector3> newBox;
    2011            0 :                         bool validBox = calculate_vertex_node_bbox(vrtNode, newBox);
    2012            0 :                     if (validBox)
    2013            0 :                         box = AABox<vector3>(box, newBox);
    2014              : 
    2015            0 :                     vrtNode = vrtNode->next_sibling("vertices");
    2016              :                 }
    2017              : 
    2018              :                 // TODO: Do we have to consider ConstrainedVertices here?
    2019              : 
    2020            0 :                 gInfo.m_extension = box.extension();
    2021              : 
    2022              :                 //      fill m_hasVertices, ...
    2023            0 :                 gInfo.m_hasVertices = curNode->first_node("vertices") != NULL;
    2024            0 :                 gInfo.m_hasVertices |= curNode->first_node("constrained_vertices") != NULL;
    2025              : 
    2026            0 :                 gInfo.m_hasEdges = curNode->first_node("edges") != NULL;
    2027            0 :                 gInfo.m_hasEdges |= curNode->first_node("constraining_edges") != NULL;
    2028            0 :                 gInfo.m_hasEdges |= curNode->first_node("constrained_edges") != NULL;
    2029              : 
    2030            0 :                 gInfo.m_hasFaces = curNode->first_node("triangles") != NULL;
    2031            0 :                 gInfo.m_hasFaces |= curNode->first_node("constraining_triangles") != NULL;
    2032            0 :                 gInfo.m_hasFaces |= curNode->first_node("constrained_triangles") != NULL;
    2033            0 :                 gInfo.m_hasFaces |= curNode->first_node("quadrilaterals") != NULL;
    2034            0 :                 gInfo.m_hasFaces |= curNode->first_node("constraining_quadrilaterals") != NULL;
    2035            0 :                 gInfo.m_hasFaces |= curNode->first_node("constrained_quadrilaterals") != NULL;
    2036              : 
    2037            0 :                 gInfo.m_hasVolumes = curNode->first_node("tetrahedrons") != NULL;
    2038            0 :                 gInfo.m_hasVolumes |= curNode->first_node("hexahedrons") != NULL;
    2039            0 :                 gInfo.m_hasVolumes |= curNode->first_node("prisms") != NULL;
    2040            0 :                 gInfo.m_hasVolumes |= curNode->first_node("pyramids") != NULL;
    2041              : 
    2042            0 :                 curNode = curNode->next_sibling("grid");
    2043              :         }
    2044              : 
    2045            0 :         m_fileParsed = true;
    2046            0 :         return true;
    2047            0 : }
    2048              : 
    2049            0 : size_t UGXFileInfo::num_grids() const
    2050              : {
    2051            0 :         check_file_parsed();
    2052            0 :         return m_grids.size();
    2053              : }
    2054              : 
    2055            0 : size_t UGXFileInfo::num_subset_handlers(size_t gridInd) const
    2056              : {
    2057            0 :         return grid_info(gridInd).m_subsetHandlers.size();
    2058              : }
    2059              : 
    2060            0 : size_t UGXFileInfo::num_subsets(size_t gridInd, size_t shInd) const
    2061              : {
    2062            0 :         return subset_handler_info(gridInd, shInd).m_subsets.size();
    2063              : }
    2064              : 
    2065            0 : std::string UGXFileInfo::grid_name(size_t gridInd) const
    2066              : {
    2067            0 :         return grid_info(gridInd).m_name;
    2068              : }
    2069              : 
    2070            0 : std::string UGXFileInfo::subset_handler_name(size_t gridInd, size_t shInd) const
    2071              : {
    2072            0 :         return subset_handler_info(gridInd, shInd).m_name;
    2073              : }
    2074              : 
    2075            0 : std::string UGXFileInfo::subset_name(size_t gridInd, size_t shInd, size_t subsetInd) const
    2076              : {
    2077            0 :         return subset_info(gridInd, shInd, subsetInd).m_name;
    2078              : }
    2079              : 
    2080            0 : bool UGXFileInfo::grid_has_vertices(size_t gridInd) const
    2081              : {
    2082            0 :         return grid_info(gridInd).m_hasVertices;
    2083              : }
    2084              : 
    2085            0 : bool UGXFileInfo::grid_has_edges(size_t gridInd) const
    2086              : {
    2087            0 :         return grid_info(gridInd).m_hasEdges;
    2088              : }
    2089              : 
    2090            0 : bool UGXFileInfo::grid_has_faces(size_t gridInd) const
    2091              : {
    2092            0 :         return grid_info(gridInd).m_hasFaces;
    2093              : }
    2094              : 
    2095            0 : bool UGXFileInfo::grid_has_volumes(size_t gridInd) const
    2096              : {
    2097            0 :         return grid_info(gridInd).m_hasVolumes;
    2098              : }
    2099              : 
    2100            0 : size_t UGXFileInfo::physical_grid_dimension(size_t gridInd) const
    2101              : {
    2102            0 :         const GridInfo& gi = grid_info(gridInd);
    2103              : 
    2104              :         const vector3& ext = gi.m_extension;
    2105            0 :         const number relSmall = SMALL * std::max(ext[0], std::max(ext[1], ext[2]));
    2106            0 :         for (int i = 2; i >= 0; --i)
    2107              :         {
    2108            0 :                 if (ext[i] > relSmall)
    2109            0 :                         return (size_t) (i + 1);
    2110              :         }
    2111              :         return 0;
    2112              : }
    2113              : 
    2114            0 : size_t UGXFileInfo::topological_grid_dimension(size_t gridInd) const
    2115              : {
    2116            0 :         const GridInfo& gi = grid_info(gridInd);
    2117              : 
    2118            0 :         if(gi.m_hasVolumes)
    2119              :                 return 3;
    2120            0 :         if(gi.m_hasFaces)
    2121              :                 return 2;
    2122            0 :         if(gi.m_hasEdges)
    2123            0 :                 return 1;
    2124              : 
    2125              :         return 0;
    2126              : }
    2127              : 
    2128            0 : size_t UGXFileInfo::grid_world_dimension(size_t gridInd) const
    2129              : {
    2130            0 :         return physical_grid_dimension(gridInd);
    2131              : }
    2132              : 
    2133            0 : std::string UGXFileInfo::node_name(rapidxml::xml_node<>* n) const
    2134              : {
    2135            0 :         xml_attribute<>* attrib = n->first_attribute("name");
    2136            0 :         if(attrib)
    2137            0 :                 return attrib->value();
    2138            0 :         return "";
    2139              : }
    2140              : 
    2141            0 : void UGXFileInfo::check_file_parsed() const
    2142              : {
    2143            0 :         if(!m_fileParsed){
    2144            0 :                 UG_THROW("UGXFileInfo: no file has been parsed!");
    2145              :         }
    2146            0 : }
    2147              : 
    2148              : const UGXFileInfo::GridInfo&
    2149            0 : UGXFileInfo::grid_info(size_t index) const
    2150              : {
    2151            0 :         check_file_parsed();
    2152            0 :         if(index >= m_grids.size()){
    2153            0 :                 UG_THROW("Grid index out of range: " << index
    2154              :                                  << ". Num grids available: " << m_grids.size());
    2155              :         }
    2156              : 
    2157            0 :         return m_grids[index];
    2158              : }
    2159              : 
    2160              : const UGXFileInfo::SubsetHandlerInfo&
    2161            0 : UGXFileInfo::subset_handler_info(size_t gridInd, size_t shInd) const
    2162              : {
    2163            0 :         const GridInfo& gi = grid_info(gridInd);
    2164            0 :         if(shInd >= gi.m_subsetHandlers.size()){
    2165            0 :                 UG_THROW("SubsetHandler index out of range: " << shInd
    2166              :                                  << ". Num subset-handlers available: "
    2167              :                                  << gi.m_subsetHandlers.size());
    2168              :         }
    2169              : 
    2170            0 :         return gi.m_subsetHandlers[shInd];
    2171              : }
    2172              : 
    2173              : const UGXFileInfo::SubsetInfo&
    2174            0 : UGXFileInfo::subset_info(size_t gridInd, size_t shInd, size_t subsetInd) const
    2175              : {
    2176            0 :         const SubsetHandlerInfo& shInfo = subset_handler_info(gridInd, shInd);
    2177            0 :         if(subsetInd >= shInfo.m_subsets.size()){
    2178            0 :                 UG_THROW("Subset index out of range: " << subsetInd
    2179              :                                  << ". Num subset available: "
    2180              :                                  << shInfo.m_subsets.size());
    2181              :         }
    2182              : 
    2183            0 :         return shInfo.m_subsets[subsetInd];
    2184              : }
    2185              : 
    2186              : bool
    2187            0 : UGXFileInfo::calculate_vertex_node_bbox(rapidxml::xml_node<>* vrtNode, AABox<vector3>& bb) const
    2188              : {
    2189              :         size_t numSrcCoords = 0;
    2190            0 :         rapidxml::xml_attribute<>* attrib = vrtNode->first_attribute("coords");
    2191            0 :         if (!attrib) return false;
    2192              : 
    2193            0 :         numSrcCoords = std::strtoul(attrib->value(), NULL, 10);
    2194              :         UG_ASSERT(errno != ERANGE, "Coordinate dimension in .ugx file is out of range.");
    2195              :         UG_ASSERT(numSrcCoords <= 3,
    2196              :                           "Coordinate dimension in .ugx file needs to be in {0,1,2,3}, but is "
    2197              :                           << numSrcCoords << ".");
    2198              : 
    2199            0 :         if (numSrcCoords > 3)
    2200              :                 return false;
    2201              : 
    2202              : //      create a buffer with which we can access the data
    2203            0 :         std::string str(vrtNode->value(), vrtNode->value_size());
    2204            0 :         std::stringstream ss(str, std::ios_base::in);
    2205              : 
    2206              :         AABox<vector3> box(vector3(0, 0, 0), vector3(0, 0, 0));
    2207              :         vector3 min(0, 0, 0);
    2208              :         vector3 max(0, 0, 0);
    2209              :         vector3 vrt(0, 0, 0);
    2210              :         size_t nVrt = 0;
    2211            0 :         while (!ss.eof())
    2212              :         {
    2213            0 :                 for (size_t i = 0; i < numSrcCoords; ++i)
    2214              :                         ss >> vrt[i];
    2215              : 
    2216            0 :                 if (ss.fail())
    2217              :                         break;
    2218              : 
    2219            0 :                 ++nVrt;
    2220              : 
    2221            0 :                 for (size_t j = 0; j < numSrcCoords; ++j)
    2222              :                 {
    2223            0 :                         min[j] = std::min(min[j], vrt[j]);
    2224            0 :                         max[j] = std::max(max[j], vrt[j]);
    2225              :                 }
    2226              :         }
    2227              : 
    2228              :         // create bounding box
    2229              :         bb = AABox<vector3>(min, max);
    2230              : 
    2231            0 :         return nVrt > 0;
    2232            0 : }
    2233              : 
    2234              : }//     end of namespace
        

Generated by: LCOV version 2.0-1