LCOV - code coverage report
Current view: top level - ugbase/lib_grid/file_io - file_io_ugx_impl.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 295 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 35 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              : #ifndef __H__LIB_GRID__FILE_IO_UGX_IMPL__
      34              : #define __H__LIB_GRID__FILE_IO_UGX_IMPL__
      35              : 
      36              : #include <sstream>
      37              : #include <cstring>
      38              : #include "lib_grid/algorithms/debug_util.h"
      39              : #include "lib_grid/global_attachments.h"
      40              : #include "lib_grid/refinement/projectors/projection_handler.h"
      41              : 
      42              : namespace ug
      43              : {
      44              : 
      45              : ////////////////////////////////////////////////////////////////////////
      46              : template <class TAPosition>
      47            0 : bool SaveGridToUGX(Grid& grid, ISubsetHandler& sh, const char* filename,
      48              :                                    TAPosition& aPos)
      49              : {
      50            0 :         GridWriterUGX ugxWriter;
      51            0 :         ugxWriter.add_grid(grid, "defGrid", aPos);
      52            0 :         ugxWriter.add_subset_handler(sh, "defSH", 0);
      53              : 
      54            0 :         return ugxWriter.write_to_file(filename);
      55            0 : };
      56              : 
      57              : ////////////////////////////////////////////////////////////////////////
      58              : template <class TAPosition>
      59            0 : bool LoadGridFromUGX(Grid& grid, SPProjectionHandler& ph, size_t& num_ph, ISubsetHandler& sh, std::vector<std::string> additionalSHNames,
      60              :                                                 std::vector<SmartPtr<ISubsetHandler>> ash, const char* filename, TAPosition& aPos)
      61              : {
      62            0 :         GridReaderUGX ugxReader;
      63            0 :         if(!ugxReader.parse_file(filename)){
      64            0 :                 UG_LOG("ERROR in LoadGridFromUGX: File not found: " << filename << std::endl);
      65              :                 return false;
      66              :         }
      67              :         
      68            0 :         if(ugxReader.num_grids() < 1){
      69              :                 UG_LOG("ERROR in LoadGridFromUGX: File contains no grid.\n");
      70              :                 return false;
      71              :         }
      72              : 
      73            0 :         ugxReader.grid(grid, 0, aPos);
      74              : 
      75            0 :         if(ugxReader.num_subset_handlers(0) > 0)
      76            0 :                 ugxReader.subset_handler(sh, 0, 0);
      77              :         
      78            0 :         for(size_t i_name = 0; i_name < additionalSHNames.size(); ++i_name){
      79              :                 std::string shName = additionalSHNames[i_name];
      80            0 :                 for(size_t i_sh = 0; i_sh < ugxReader.num_subset_handlers(0); ++i_sh){
      81            0 :                         if(shName == ugxReader.get_subset_handler_name(0, i_sh)){
      82            0 :                                 ugxReader.subset_handler(*ash[i_name], i_sh, 0);
      83              :                         }
      84              :                 }
      85              :         }
      86              : 
      87            0 :         if((num_ph = ugxReader.num_projection_handlers(0)) != 0){
      88            0 :                 ugxReader.projection_handler(*ph, 0, 0);
      89            0 :                 size_t shIndex = ugxReader.get_projection_handler_subset_handler_index(0, 0);
      90              :                 std::string shName2;
      91            0 :                 shName2 = std::string(ugxReader.get_subset_handler_name(0, shIndex));
      92              : 
      93            0 :                 if (shIndex > 0)
      94              :                 {
      95            0 :                         for(size_t i_name = 0; i_name < additionalSHNames.size(); ++i_name)
      96            0 :                                 if(shName2==additionalSHNames[i_name])
      97              :                                 {
      98            0 :                                         try {ph->set_subset_handler(ash[i_name]);}
      99            0 :                                         UG_CATCH_THROW("Additional subset handler '"<< shName2 << "' has not been added to the domain.\n"
     100              :                                                                         "Do so by using Domain::create_additional_subset_handler(std::string name).");
     101              :                                 }
     102              :                 }
     103              :         }
     104              : 
     105              :         return true;
     106            0 : }
     107              : 
     108              : template <class TAPosition>
     109            0 : bool LoadGridFromUGX(Grid& grid, ISubsetHandler& sh, const char* filename,
     110              :                                          TAPosition& aPos)
     111              : {
     112            0 :         GridReaderUGX ugxReader;
     113            0 :         if(!ugxReader.parse_file(filename)){
     114            0 :                 UG_LOG("ERROR in LoadGridFromUGX: File not found: " << filename << std::endl);
     115              :                 return false;
     116              :         }
     117              : 
     118            0 :         if(ugxReader.num_grids() < 1){
     119              :                 UG_LOG("ERROR in LoadGridFromUGX: File contains no grid.\n");
     120              :                 return false;
     121              :         }
     122              : 
     123            0 :         ugxReader.grid(grid, 0, aPos);
     124              : 
     125            0 :         if(ugxReader.num_subset_handlers(0) > 0)
     126            0 :                 ugxReader.subset_handler(sh, 0, 0);
     127              : 
     128              :         return true;
     129            0 : }
     130              : 
     131              : 
     132              : ////////////////////////////////////////////////////////////////////////
     133              : template <class TPositionAttachment>
     134            0 : bool GridWriterUGX::
     135              : add_grid(Grid& grid, const char* name,
     136              :                  TPositionAttachment& aPos)
     137              : {
     138              :         using namespace rapidxml;
     139              :         using namespace std;
     140              : //      access node data
     141            0 :         if(!grid.has_vertex_attachment(aPos)){
     142            0 :                 UG_LOG("  position attachment missing in grid " << name << endl);
     143            0 :                 return false;
     144              :         }
     145              : 
     146              :         Grid::VertexAttachmentAccessor<TPositionAttachment> aaPos(grid, aPos);
     147              : 
     148              : //      create a new grid-node
     149            0 :         xml_node<>* gridNode = m_doc.allocate_node(node_element, "grid");
     150            0 :         gridNode->append_attribute(m_doc.allocate_attribute("name", name));
     151              : 
     152              : //      store the grid and the node in an entry
     153            0 :         m_vEntries.push_back(Entry(&grid, gridNode));
     154              : 
     155              : //      append it to the document
     156            0 :         m_doc.append_node(gridNode);
     157              : 
     158              : //      initialize the grids attachments
     159            0 :         init_grid_attachments(grid);
     160              :         
     161              : //      access indices
     162            0 :         Grid::EdgeAttachmentAccessor<AInt> aaIndEDGE(grid, m_aInt);
     163              :         Grid::FaceAttachmentAccessor<AInt> aaIndFACE(grid, m_aInt);
     164              :         
     165              : //      write vertices
     166            0 :         if(grid.num<RegularVertex>() > 0)
     167            0 :                 gridNode->append_node(create_vertex_node(grid.begin<RegularVertex>(),
     168              :                                                                                 grid.end<RegularVertex>(), aaPos));
     169              : 
     170              : //      write constrained vertices
     171            0 :         if(grid.num<ConstrainedVertex>() > 0)
     172            0 :                 gridNode->append_node(create_constrained_vertex_node(
     173              :                                                                                 grid.begin<ConstrainedVertex>(),
     174              :                                                                                 grid.end<ConstrainedVertex>(),
     175              :                                                                                 aaPos, aaIndEDGE, aaIndFACE));
     176              : 
     177              : //      add the remaining grid elements to the nodes
     178            0 :         add_elements_to_node(gridNode, grid);
     179              : 
     180            0 :         process_global_attachments<Vertex>(grid, gridNode);
     181            0 :         process_global_attachments<Edge>(grid, gridNode);
     182            0 :         process_global_attachments<Face>(grid, gridNode);
     183            0 :         process_global_attachments<Volume>(grid, gridNode);
     184              : 
     185              :         return true;
     186              : }
     187              : 
     188              : //template <class TPositionAttachment>
     189              : //void GridWriterUGX::
     190              : //add_grid(MultiGrid& mg, const char* name,
     191              : //               TPositionAttachment& aPos)
     192              : //{
     193              : //}
     194              : 
     195              : template <class TElem>
     196              : const char* GridWriterUGX::
     197              : attachment_node_name()
     198              : {
     199              :         static const char* attachmentNodeNames[4] = {"vertex_attachment",
     200              :                                                                                                  "edge_attachment",
     201              :                                                                                                  "face_attachment",
     202              :                                                                                                  "volume_attachment"};
     203            0 :         return attachmentNodeNames[TElem::BASE_OBJECT_ID];
     204              : }
     205              : 
     206              : 
     207              : template <class TElem, class TAttachment>
     208              : void GridWriterUGX::
     209              : add_attachment(TAttachment attachment,
     210              :                            const char* name,
     211              :                            size_t refGridIndex)
     212              : {
     213              :         using namespace rapidxml;
     214              :         using namespace std;
     215              : 
     216              :         UG_COND_THROW(refGridIndex >= m_vEntries.size(),
     217              :                                   "Invalid refGridIndex: " << refGridIndex
     218              :                                   << ", but only " << m_vEntries.size() << " grids available.");
     219              : 
     220              :         Grid& grid = *m_vEntries[refGridIndex].grid;
     221              :         stringstream ss;
     222              : 
     223              :         if(!grid.has_attachment<TElem>(attachment))
     224              :                 return;
     225              : 
     226              :         Grid::AttachmentAccessor<TElem, TAttachment> aaVal(grid, attachment);
     227              : 
     228              :         const typename Grid::traits<TElem>::iterator iterEnd = grid.end<TElem>();
     229              :         for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
     230              :                 iter != iterEnd;)
     231              :         {
     232              :                 attachment_io_traits<TAttachment>::write_value(ss, aaVal[*iter]);
     233              :                 UG_COND_THROW(!ss, "Failed to write attachment entry.\n");
     234              :                 ++iter;
     235              :                 if(iter != iterEnd)
     236              :                         ss << " ";
     237              :         }
     238              : 
     239              : //      create the node
     240              :         xml_node<>* node = m_doc.allocate_node(
     241              :                                                                 node_element,
     242              :                                                                 attachment_node_name<TElem>(),
     243              :                                                                 m_doc.allocate_string(ss.str().c_str()));
     244              : 
     245              : //      attributes      
     246              :         node->append_attribute(
     247              :                 m_doc.allocate_attribute(
     248              :                         "name",
     249              :                         m_doc.allocate_string(name)));
     250              : 
     251              :         node->append_attribute(
     252              :                 m_doc.allocate_attribute(
     253              :                         "type",
     254              :                         m_doc.allocate_string(
     255              :                                 attachment_info_traits<TAttachment>::type_name().c_str())));
     256              : 
     257              : //todo: only default pass-on is stored, not the actual used one!
     258              :         node->append_attribute(
     259              :                 m_doc.allocate_attribute(
     260              :                         "passOn",
     261              :                         m_doc.allocate_string(mkstr(int(attachment.default_pass_on_behaviour())).c_str())));
     262              : 
     263              :         m_vEntries[refGridIndex].node->append_node(node);
     264              : }
     265              : 
     266              : 
     267              : template <class TAAPos>
     268              : rapidxml::xml_node<>*
     269            0 : GridWriterUGX::
     270              : create_vertex_node(RegularVertexIterator vrtsBegin,
     271              :                                   RegularVertexIterator vrtsEnd,
     272              :                                   TAAPos& aaPos)
     273              : {
     274              :         using namespace rapidxml;
     275              :         using namespace std;
     276              : //      the number of coordinates
     277              :         const int numCoords = (int)TAAPos::ValueType::Size;
     278              : 
     279              : //      write the vertices to a temporary stream
     280            0 :         stringstream ss;
     281              :         ss.precision(18);
     282            0 :         for(RegularVertexIterator iter = vrtsBegin; iter != vrtsEnd; ++iter)
     283              :         {
     284            0 :                 for(int i = 0; i < numCoords; ++i)
     285            0 :                         ss << aaPos[*iter][i] << " ";
     286              :         }
     287              : 
     288              : //      create the node
     289              :         xml_node<>* node = NULL;
     290              : 
     291            0 :         if(ss.str().size() > 0){
     292              :         //      allocate a string and erase last character(' ')
     293            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     294            0 :                 nodeData[ss.str().size()-1] = 0;
     295              :         //      create a node with some data
     296            0 :                 node = m_doc.allocate_node(node_element, "vertices", nodeData);
     297              :         }
     298              :         else{
     299              :         //      create an emtpy node
     300            0 :                 node = m_doc.allocate_node(node_element, "vertices");
     301              :         }
     302              : 
     303            0 :         char* buff = m_doc.allocate_string(NULL, 10);
     304              :         snprintf(buff, 10, "%d", numCoords);
     305            0 :         node->append_attribute(m_doc.allocate_attribute("coords", buff));
     306              : 
     307              : //      return the node
     308            0 :         return node;
     309            0 : }
     310              : 
     311              : template <class TAAPos>
     312              : rapidxml::xml_node<>*
     313            0 : GridWriterUGX::
     314              : create_constrained_vertex_node(ConstrainedVertexIterator vrtsBegin,
     315              :                                                                 ConstrainedVertexIterator vrtsEnd,
     316              :                                                                 TAAPos& aaPos,
     317              :                                                                 AAEdgeIndex aaIndEDGE,
     318              :                                                                 AAFaceIndex aaIndFACE)
     319              : {
     320              :         using namespace rapidxml;
     321              :         using namespace std;
     322              : //      the number of coordinates
     323              :         const int numCoords = (int)TAAPos::ValueType::Size;
     324              : 
     325              : //      write the vertices to a temporary stream
     326            0 :         stringstream ss;
     327              :         ss.precision(18);
     328            0 :         for(ConstrainedVertexIterator iter = vrtsBegin; iter != vrtsEnd; ++iter)
     329              :         {
     330            0 :                 for(int i = 0; i < numCoords; ++i)
     331            0 :                         ss << aaPos[*iter][i] << " ";
     332              :                         
     333              :         //      write index and local coordinate of associated constraining element
     334              :         //      codes:  -1: no constraining element
     335              :         //                      0: vertex. index follows (not yet supported)
     336              :         //                      1: edge. index and 1 local coordinate follow.
     337              :         //                      2: face. index and 2 local coordinates follow.
     338              :         //                      3: volume. index and 3 local coordinates follow. (not yet supported)
     339            0 :                 Edge* ce = dynamic_cast<Edge*>((*iter)->get_constraining_object());
     340            0 :                 Face* cf = dynamic_cast<Face*>((*iter)->get_constraining_object());
     341            0 :                 if(ce)
     342            0 :                         ss << "1 " << aaIndEDGE[ce] << " " << (*iter)->get_local_coordinate_1() << " ";
     343            0 :                 else if(cf)
     344            0 :                         ss << "2 " << aaIndFACE[cf] << " " << (*iter)->get_local_coordinate_1()
     345            0 :                            << " " << (*iter)->get_local_coordinate_2() << " ";
     346              :                 else
     347            0 :                         ss << "-1 ";
     348              :         }
     349              : 
     350              : //      create the node
     351              :         xml_node<>* node = NULL;
     352              : 
     353            0 :         if(ss.str().size() > 0){
     354              :         //      allocate a string and erase last character(' ')
     355            0 :                 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
     356            0 :                 nodeData[ss.str().size()-1] = 0;
     357              :         //      create a node with some data
     358            0 :                 node = m_doc.allocate_node(node_element, "constrained_vertices", nodeData);
     359              :         }
     360              :         else{
     361              :         //      create an emtpy node
     362            0 :                 node = m_doc.allocate_node(node_element, "constrained_vertices");
     363              :         }
     364              : 
     365            0 :         char* buff = m_doc.allocate_string(NULL, 10);
     366              :         snprintf(buff, 10, "%d", numCoords);
     367            0 :         node->append_attribute(m_doc.allocate_attribute("coords", buff));
     368              : 
     369              : //      return the node
     370            0 :         return node;
     371            0 : }
     372              : 
     373              : 
     374              : template <class TElem>
     375            0 : void GridWriterUGX::
     376              : process_global_attachments(Grid& grid, rapidxml::xml_node<>* gridNode)
     377              : {
     378              :         using namespace std;
     379              :         using namespace rapidxml;
     380              :         const vector<string>& attachmentNames = GlobalAttachments::declared_attachment_names();
     381              : 
     382            0 :         for(size_t ia = 0; ia < attachmentNames.size(); ++ia){
     383              :                 const std::string& name = attachmentNames[ia];
     384            0 :                 if(!GlobalAttachments::is_attached<TElem>(grid, name))
     385            0 :                         continue;
     386              : 
     387            0 :                 stringstream ss;
     388            0 :                 GlobalAttachments::write_attachment_values<TElem>(ss, grid, name);
     389              : 
     390              :         //      create the node
     391            0 :                 xml_node<>* node = m_doc.allocate_node(
     392              :                                                                         node_element,
     393              :                                                                         attachment_node_name<TElem>(),
     394            0 :                                                                         m_doc.allocate_string(ss.str().c_str()));
     395              : 
     396              :         //      attributes      
     397            0 :                 node->append_attribute(
     398              :                         m_doc.allocate_attribute(
     399              :                                 "name",
     400            0 :                                 m_doc.allocate_string(name.c_str())));
     401              : 
     402            0 :                 node->append_attribute(
     403              :                         m_doc.allocate_attribute(
     404              :                                 "type",
     405            0 :                                 m_doc.allocate_string(
     406              :                                         GlobalAttachments::type_name(name))));
     407              : 
     408            0 :                 node->append_attribute(
     409              :                         m_doc.allocate_attribute(
     410              :                                 "passOn",
     411            0 :                                 m_doc.allocate_string(mkstr(int(
     412              :                                         GlobalAttachments::attachment_pass_on_behaviour(name))).c_str())));
     413              : 
     414            0 :                 node->append_attribute(
     415              :                         m_doc.allocate_attribute(
     416              :                                 "global",
     417            0 :                                 m_doc.allocate_string("1")));
     418              : 
     419              :                 gridNode->append_node(node);
     420              :         }
     421            0 : }
     422              : 
     423              : 
     424              : ////////////////////////////////////////////////////////////////////////
     425              : ////////////////////////////////////////////////////////////////////////
     426              : //      implementation of GridReaderUGX
     427              : template <class TPositionAttachment>
     428            0 : bool GridReaderUGX::
     429              : grid(Grid& gridOut, size_t index,
     430              :                   TPositionAttachment& aPos)
     431              : {
     432              :         using namespace rapidxml;
     433              :         using namespace std;
     434              : 
     435              : //      make sure that a node at the given index exists
     436            0 :         if(num_grids() <= index){
     437              :                 UG_LOG("  GridReaderUGX::read: bad grid index!\n");
     438            0 :                 return false;
     439              :         }
     440              : 
     441              :         Grid& grid = gridOut;
     442              : 
     443              : //      Since we have to create all elements in the correct order and
     444              : //      since we have to make sure that no elements are created in between,
     445              : //      we'll first disable all grid-options and reenable them later on
     446            0 :         uint gridopts = grid.get_options();
     447            0 :         grid.set_options(GRIDOPT_NONE);
     448              : 
     449              : //      access node data
     450            0 :         if(!grid.has_vertex_attachment(aPos)){
     451            0 :                 grid.attach_to_vertices(aPos);
     452              :         }
     453              : 
     454              :         Grid::VertexAttachmentAccessor<TPositionAttachment> aaPos(grid, aPos);
     455              : 
     456              : //      store the grid in the grid-vector and assign indices to the vertices
     457            0 :         m_entries[index].grid = &grid;
     458              : 
     459              : //      get the grid-node and the vertex-vector
     460            0 :         xml_node<>* gridNode = m_entries[index].node;
     461            0 :         vector<Vertex*>& vertices = m_entries[index].vertices;
     462            0 :         vector<Edge*>& edges = m_entries[index].edges;
     463            0 :         vector<Face*>& faces = m_entries[index].faces;
     464            0 :         vector<Volume*>& volumes = m_entries[index].volumes;
     465              : 
     466              : //      we'll record constraining objects for constrained-vertices and constrained-edges
     467              :         std::vector<std::pair<int, int> > constrainingObjsVRT;
     468              :         std::vector<std::pair<int, int> > constrainingObjsEDGE;
     469              :         std::vector<std::pair<int, int> > constrainingObjsTRI;
     470              :         std::vector<std::pair<int, int> > constrainingObjsQUAD;
     471              :         
     472              : //      iterate through the nodes in the grid and create the entries
     473              :         xml_node<>* curNode = gridNode->first_node();
     474            0 :         for(;curNode; curNode = curNode->next_sibling()){
     475              :                 bool bSuccess = true;
     476              :                 const char* name = curNode->name();
     477            0 :                 if(strcmp(name, "vertices") == 0)
     478            0 :                         bSuccess = create_vertices(vertices, grid, curNode, aaPos);
     479            0 :                 else if(strcmp(name, "constrained_vertices") == 0)
     480            0 :                         bSuccess = create_constrained_vertices(vertices, constrainingObjsVRT,
     481              :                                                                                                    grid, curNode, aaPos);
     482            0 :                 else if(strcmp(name, "edges") == 0)
     483            0 :                         bSuccess = create_edges(edges, grid, curNode, vertices);
     484            0 :                 else if(strcmp(name, "constraining_edges") == 0)
     485            0 :                         bSuccess = create_constraining_edges(edges, grid, curNode, vertices);
     486            0 :                 else if(strcmp(name, "constrained_edges") == 0)
     487            0 :                         bSuccess = create_constrained_edges(edges, constrainingObjsEDGE,
     488              :                                                                                                 grid, curNode, vertices);
     489            0 :                 else if(strcmp(name, "triangles") == 0)
     490            0 :                         bSuccess = create_triangles(faces, grid, curNode, vertices);
     491            0 :                 else if(strcmp(name, "constraining_triangles") == 0)
     492            0 :                         bSuccess = create_constraining_triangles(faces, grid, curNode, vertices);
     493            0 :                 else if(strcmp(name, "constrained_triangles") == 0)
     494            0 :                         bSuccess = create_constrained_triangles(faces, constrainingObjsTRI,
     495              :                                                                                                 grid, curNode, vertices);
     496            0 :                 else if(strcmp(name, "quadrilaterals") == 0)
     497            0 :                         bSuccess = create_quadrilaterals(faces, grid, curNode, vertices);
     498            0 :                 else if(strcmp(name, "constraining_quadrilaterals") == 0)
     499            0 :                         bSuccess = create_constraining_quadrilaterals(faces, grid, curNode, vertices);
     500            0 :                 else if(strcmp(name, "constrained_quadrilaterals") == 0)
     501            0 :                         bSuccess = create_constrained_quadrilaterals(faces, constrainingObjsQUAD,
     502              :                                                                                                 grid, curNode, vertices);
     503            0 :                 else if(strcmp(name, "tetrahedrons") == 0)
     504            0 :                         bSuccess = create_tetrahedrons(volumes, grid, curNode, vertices);
     505            0 :                 else if(strcmp(name, "hexahedrons") == 0)
     506            0 :                         bSuccess = create_hexahedrons(volumes, grid, curNode, vertices);
     507            0 :                 else if(strcmp(name, "prisms") == 0)
     508            0 :                         bSuccess = create_prisms(volumes, grid, curNode, vertices);
     509            0 :                 else if(strcmp(name, "pyramids") == 0)
     510            0 :                         bSuccess = create_pyramids(volumes, grid, curNode, vertices);
     511            0 :                 else if(strcmp(name, "octahedrons") == 0)
     512            0 :                         bSuccess = create_octahedrons(volumes, grid, curNode, vertices);
     513              : 
     514            0 :                 else if(strcmp(name, "vertex_attachment") == 0)
     515            0 :                         bSuccess = read_attachment<Vertex>(grid, curNode);
     516            0 :                 else if(strcmp(name, "edge_attachment") == 0)
     517            0 :                         bSuccess = read_attachment<Edge>(grid, curNode);
     518            0 :                 else if(strcmp(name, "face_attachment") == 0)
     519            0 :                         bSuccess = read_attachment<Face>(grid, curNode);
     520            0 :                 else if(strcmp(name, "volume_attachment") == 0)
     521            0 :                         bSuccess = read_attachment<Volume>(grid, curNode);
     522              : 
     523              : 
     524            0 :                 if(!bSuccess){
     525            0 :                         grid.set_options(gridopts);
     526              :                         return false;
     527              :                 }
     528              :         }
     529              :         
     530              : //      resolve constrained object relations
     531            0 :         if(!constrainingObjsVRT.empty()){
     532              :                 //UG_LOG("num-edges: " << edges.size() << std::endl);
     533              :         //      iterate over the pairs.
     534              :         //      at the same time we'll iterate over the constrained vertices since
     535              :         //      they are synchronized.
     536              :                 ConstrainedVertexIterator hvIter = grid.begin<ConstrainedVertex>();
     537            0 :                 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsVRT.begin();
     538            0 :                         iter != constrainingObjsVRT.end(); ++iter, ++hvIter)
     539              :                 {
     540              :                         ConstrainedVertex* hv = *hvIter;
     541              :                         
     542            0 :                         switch(iter->first){
     543              :                                 case 1: // constraining object is an edge
     544              :                                 {
     545              :                                 //      make sure that the index is valid
     546            0 :                                         if(iter->second >= 0 && iter->second < (int)edges.size()){
     547              :                                         //      get the edge
     548            0 :                                                 ConstrainingEdge* edge = dynamic_cast<ConstrainingEdge*>(edges[iter->second]);
     549            0 :                                                 if(edge){
     550              :                                                         hv->set_constraining_object(edge);
     551            0 :                                                         edge->add_constrained_object(hv);
     552              :                                                 }
     553              :                                                 else{
     554            0 :                                                         UG_LOG("WARNING: Type-ID / type mismatch. Ignoring edge " << iter->second << ".\n");
     555              :                                                 }
     556              :                                         }
     557              :                                         else{
     558            0 :                                                 UG_LOG("ERROR in GridReaderUGX: Bad edge index in constrained vertex: " << iter->second << "\n");
     559              :                                         }
     560              :                                 }break;
     561              :                                 
     562              :                                 case 2: // constraining object is an face
     563              :                                 {
     564              :                                 //      make sure that the index is valid
     565            0 :                                         if(iter->second >= 0 && iter->second < (int)faces.size()){
     566              :                                         //      get the edge
     567            0 :                                                 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
     568            0 :                                                 if(face){
     569              :                                                         hv->set_constraining_object(face);
     570            0 :                                                         face->add_constrained_object(hv);
     571              :                                                 }
     572              :                                                 else{
     573            0 :                                                         UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
     574              :                                                 }
     575              :                                         }
     576              :                                         else{
     577            0 :                                                 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained vertex: " << iter->second << "\n");
     578              :                                         }
     579              :                                 }break;
     580              :                                 
     581              :                                 default:
     582              :                                 {
     583              : //                                      UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining vertex"
     584              : //                                                      << " at " << GetGridObjectCenter(grid, hv) << "\n");
     585              :                                         break;
     586              :                                 }
     587              :                         }
     588              :                 }
     589              :         }
     590              : 
     591            0 :         if(!constrainingObjsEDGE.empty()){
     592              :         //      iterate over the pairs.
     593              :         //      at the same time we'll iterate over the constrained vertices since
     594              :         //      they are synchronized.
     595              :                 ConstrainedEdgeIterator ceIter = grid.begin<ConstrainedEdge>();
     596            0 :                 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsEDGE.begin();
     597            0 :                         iter != constrainingObjsEDGE.end(); ++iter, ++ceIter)
     598              :                 {
     599              :                         ConstrainedEdge* ce = *ceIter;
     600              :                         
     601            0 :                         switch(iter->first){
     602              :                                 case 1: // constraining object is an edge
     603              :                                 {
     604              :                                 //      make sure that the index is valid
     605            0 :                                         if(iter->second >= 0 && iter->second < (int)edges.size()){
     606              :                                         //      get the edge
     607            0 :                                                 ConstrainingEdge* edge = dynamic_cast<ConstrainingEdge*>(edges[iter->second]);
     608            0 :                                                 if(edge){
     609              :                                                         ce->set_constraining_object(edge);
     610            0 :                                                         edge->add_constrained_object(ce);
     611              :                                                 }
     612              :                                                 else{
     613            0 :                                                         UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring edge " << iter->second << ".\n");
     614              :                                                 }
     615              :                                         }
     616              :                                         else{
     617              :                                                 UG_LOG("ERROR in GridReaderUGX: Bad edge index in constrained edge.\n");
     618              :                                         }
     619              :                                 }break;
     620              :                                 case 2: // constraining object is an face
     621              :                                 {
     622              :                                 //      make sure that the index is valid
     623            0 :                                         if(iter->second >= 0 && iter->second < (int)faces.size()){
     624              :                                         //      get the edge
     625            0 :                                                 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
     626            0 :                                                 if(face){
     627              :                                                         ce->set_constraining_object(face);
     628            0 :                                                         face->add_constrained_object(ce);
     629              :                                                 }
     630              :                                                 else{
     631            0 :                                                         UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
     632              :                                                 }
     633              :                                         }
     634              :                                         else{
     635            0 :                                                 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained edge: " << iter->second << "\n");
     636              :                                         }
     637              :                                 }break;
     638              :                                 
     639              :                                 default:
     640              :                                 {
     641              : //                                      UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining edge"
     642              : //                                                      << " at " << GetGridObjectCenter(grid, ce) << "\n");
     643              :                                         break;
     644              :                                 }
     645              :                         }
     646              :                 }
     647              :         }
     648              : 
     649            0 :         if(!constrainingObjsTRI.empty()){
     650              :         //      iterate over the pairs.
     651              :         //      at the same time we'll iterate over the constrained vertices since
     652              :         //      they are synchronized.
     653              :                 ConstrainedTriangleIterator cfIter = grid.begin<ConstrainedTriangle>();
     654            0 :                 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsTRI.begin();
     655            0 :                         iter != constrainingObjsTRI.end(); ++iter, ++cfIter)
     656              :                 {
     657              :                         ConstrainedFace* cdf = *cfIter;
     658              :                         
     659            0 :                         switch(iter->first){
     660              :                                 case 2: // constraining object is an face
     661              :                                 {
     662              :                                 //      make sure that the index is valid
     663            0 :                                         if(iter->second >= 0 && iter->second < (int)faces.size()){
     664              :                                         //      get the edge
     665            0 :                                                 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
     666            0 :                                                 if(face){
     667              :                                                         cdf->set_constraining_object(face);
     668            0 :                                                         face->add_constrained_object(cdf);
     669              :                                                 }
     670              :                                                 else{
     671            0 :                                                         UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
     672              :                                                 }
     673              :                                         }
     674              :                                         else{
     675            0 :                                                 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained face: " << iter->second << "\n");
     676              :                                         }
     677              :                                 }break;
     678              :                                 
     679              :                                 default:
     680              :                                 {
     681              : //                                      UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining triangle"
     682              : //                                                      << " at " << GetGridObjectCenter(grid, cdf) << "\n");
     683              :                                         break;
     684              :                                 }
     685              :                         }
     686              :                 }
     687              :         }
     688              : 
     689            0 :         if(!constrainingObjsQUAD.empty()){
     690              :         //      iterate over the pairs.
     691              :         //      at the same time we'll iterate over the constrained vertices since
     692              :         //      they are synchronized.
     693              :                 ConstrainedQuadrilateralIterator cfIter = grid.begin<ConstrainedQuadrilateral>();
     694            0 :                 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsQUAD.begin();
     695            0 :                         iter != constrainingObjsQUAD.end(); ++iter, ++cfIter)
     696              :                 {
     697              :                         ConstrainedFace* cdf = *cfIter;
     698              :                         
     699            0 :                         switch(iter->first){
     700              :                                 case 2: // constraining object is an face
     701              :                                 {
     702              :                                 //      make sure that the index is valid
     703            0 :                                         if(iter->second >= 0 && iter->second < (int)faces.size()){
     704              :                                         //      get the edge
     705            0 :                                                 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
     706            0 :                                                 if(face){
     707              :                                                         cdf->set_constraining_object(face);
     708            0 :                                                         face->add_constrained_object(cdf);
     709              :                                                 }
     710              :                                                 else{
     711            0 :                                                         UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
     712              :                                                 }
     713              :                                         }
     714              :                                         else{
     715            0 :                                                 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained face: " << iter->second << "\n");
     716              :                                         }
     717              :                                 }break;
     718              :                                 
     719              :                                 default:
     720              :                                 {
     721              : //                                      UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining quadrilateral"
     722              : //                                                      << " at " << GetGridObjectCenter(grid, cdf) << "\n");
     723              :                                         break;
     724              :                                 }
     725              :                         }
     726              :                 }
     727              :         }
     728              : 
     729              : //      reenable the grids options.
     730            0 :         grid.set_options(gridopts);
     731              : 
     732              :         return true;
     733            0 : }
     734              : 
     735              : template <class TAAPos>
     736            0 : bool GridReaderUGX::
     737              : create_vertices(std::vector<Vertex*>& vrtsOut, Grid& grid,
     738              :                                 rapidxml::xml_node<>* vrtNode, TAAPos aaPos)
     739              : {
     740              :         using namespace rapidxml;
     741              :         using namespace std;
     742              : 
     743            0 :         int numSrcCoords = -1;
     744            0 :         xml_attribute<>* attrib = vrtNode->first_attribute("coords");
     745            0 :         if(attrib)
     746            0 :                 numSrcCoords = atoi(attrib->value());
     747              : 
     748            0 :         int numDestCoords = (int)TAAPos::ValueType::Size;
     749              : 
     750              :         assert(numDestCoords > 0 && "bad position attachment type");
     751              : 
     752            0 :         if(numSrcCoords < 1 || numDestCoords < 1)
     753              :                 return false;
     754              : 
     755              : //      create a buffer with which we can access the data
     756            0 :         string str(vrtNode->value(), vrtNode->value_size());
     757            0 :         stringstream ss(str, ios_base::in);
     758              : 
     759              : //      if numDestCoords == numSrcCoords parsing will be faster
     760            0 :         if(numSrcCoords == numDestCoords){
     761            0 :                 while(!ss.eof()){
     762              :                 //      read the data
     763              :                         typename TAAPos::ValueType v;
     764              : 
     765            0 :                         for(int i = 0; i < numSrcCoords; ++i)
     766            0 :                                 ss >> v[i];
     767              : 
     768              :                 //      make sure that everything went right
     769            0 :                         if(ss.fail())
     770              :                                 break;
     771              : 
     772              :                 //      create a new vertex
     773            0 :                         RegularVertex* vrt = *grid.create<RegularVertex>();
     774            0 :                         vrtsOut.push_back(vrt);
     775              : 
     776              :                 //      set the coordinates
     777              :                         aaPos[vrt] = v;
     778              :                 }
     779              :         }
     780              :         else{
     781              :         //      we have to be careful with reading.
     782              :         //      if numDestCoords < numSrcCoords we'll ignore some coords,
     783              :         //      in the other case we'll add some 0's.
     784            0 :                 int minNumCoords = min(numSrcCoords, numDestCoords);
     785            0 :                 typename TAAPos::ValueType::value_type dummy = 0;
     786              : 
     787            0 :                 while(!ss.eof()){
     788              :                 //      read the data
     789              :                         typename TAAPos::ValueType v;
     790              : 
     791              :                         int iMin;
     792            0 :                         for(iMin = 0; iMin < minNumCoords; ++iMin)
     793            0 :                                 ss >> v[iMin];
     794              : 
     795              :                 //      ignore unused entries in the input buffer
     796            0 :                         for(int i = iMin; i < numSrcCoords; ++i)
     797              :                                 ss >> dummy;
     798              : 
     799              :                 //      add 0's to the vector
     800            0 :                         for(int i = iMin; i < numDestCoords; ++i)
     801            0 :                                 v[i] = 0;
     802              : 
     803              :                 //      make sure that everything went right
     804            0 :                         if(ss.fail())
     805              :                                 break;
     806              : 
     807              :                 //      create a new vertex
     808            0 :                         RegularVertex* vrt = *grid.create<RegularVertex>();
     809            0 :                         vrtsOut.push_back(vrt);
     810              : 
     811              :                 //      set the coordinates
     812              :                         aaPos[vrt] = v;
     813              :                 }
     814              :         }
     815              : 
     816              :         return true;
     817            0 : }
     818              : 
     819              : template <class TAAPos>
     820            0 : bool GridReaderUGX::
     821              : create_constrained_vertices(std::vector<Vertex*>& vrtsOut,
     822              :                                                         std::vector<std::pair<int, int> >& constrainingObjsOut,
     823              :                                                         Grid& grid, rapidxml::xml_node<>* vrtNode, TAAPos aaPos)
     824              : {
     825              :         using namespace rapidxml;
     826              :         using namespace std;
     827              : 
     828            0 :         int numSrcCoords = -1;
     829            0 :         xml_attribute<>* attrib = vrtNode->first_attribute("coords");
     830            0 :         if(attrib)
     831            0 :                 numSrcCoords = atoi(attrib->value());
     832              : 
     833            0 :         int numDestCoords = (int)TAAPos::ValueType::Size;
     834              : 
     835              :         assert(numDestCoords > 0 && "bad position attachment type");
     836              : 
     837            0 :         if(numSrcCoords < 1 || numDestCoords < 1)
     838              :                 return false;
     839              : 
     840              : //      create a buffer with which we can access the data
     841            0 :         string str(vrtNode->value(), vrtNode->value_size());
     842            0 :         stringstream ss(str, ios_base::in);
     843              : 
     844              : //      we have to be careful with reading.
     845              : //      if numDestCoords < numSrcCoords we'll ignore some coords,
     846              : //      in the other case we'll add some 0's.
     847            0 :         int minNumCoords = min(numSrcCoords, numDestCoords);
     848            0 :         typename TAAPos::ValueType::value_type dummy = 0;
     849              : 
     850              : //todo: speed could be improved, if dest and src position types have the same dimension
     851            0 :         while(!ss.eof()){
     852              :         //      read the data
     853              :                 typename TAAPos::ValueType v;
     854              : 
     855              :                 int iMin;
     856            0 :                 for(iMin = 0; iMin < minNumCoords; ++iMin)
     857            0 :                         ss >> v[iMin];
     858              : 
     859              :         //      ignore unused entries in the input buffer
     860            0 :                 for(int i = iMin; i < numSrcCoords; ++i)
     861              :                         ss >> dummy;
     862              : 
     863              :         //      add 0's to the vector
     864            0 :                 for(int i = iMin; i < numDestCoords; ++i)
     865            0 :                         v[i] = 0;
     866              : 
     867              :         //      now read the type of the constraining object and its index
     868            0 :                 int conObjType = -1;
     869            0 :                 int conObjIndex = -1;
     870            0 :                 ss >> conObjType;
     871              :                 
     872            0 :                 if(conObjType != -1)
     873            0 :                         ss >> conObjIndex;
     874              : 
     875              :         //      depending on the constrainings object type, we'll read local coordinates
     876              :                 vector3 localCoords(0, 0, 0);
     877            0 :                 switch(conObjType){
     878              :                         case 1: // an edge. read one local coord
     879              :                                 ss >> localCoords.x();
     880              :                                 break;
     881              :                         case 2: // a face. read two local coords
     882              :                                 ss >> localCoords.x() >> localCoords.y();
     883              :                                 break;
     884              :                         default:
     885              :                                 break;
     886              :                 }
     887              :                                 
     888              :         //      make sure that everything went right
     889            0 :                 if(ss.fail())
     890              :                         break;
     891              : 
     892              :         //      create a new vertex
     893            0 :                 ConstrainedVertex* vrt = *grid.create<ConstrainedVertex>();
     894            0 :                 vrtsOut.push_back(vrt);
     895              : 
     896              :         //      set the coordinates
     897              :                 aaPos[vrt] = v;
     898              :                 
     899              :         //      set local coordinates
     900            0 :                 vrt->set_local_coordinates(localCoords.x(), localCoords.y());
     901              :                 
     902              :         //      add the constraining object id and index to the list
     903            0 :                 constrainingObjsOut.push_back(std::make_pair(conObjType, conObjIndex));
     904              :         }
     905              : 
     906              :         return true;
     907            0 : }
     908              : 
     909              : 
     910              : template <class TElem>
     911            0 : bool GridReaderUGX::
     912              : read_attachment(Grid& grid, rapidxml::xml_node<>* node)
     913              : {
     914              :         using namespace rapidxml;
     915              :         using namespace std;
     916              : 
     917            0 :         xml_attribute<>* attribName = node->first_attribute("name");
     918            0 :         UG_COND_THROW(!attribName, "Invalid attachment entry: No 'name' attribute was supplied!");
     919            0 :         string name = attribName->value();
     920              : 
     921            0 :         xml_attribute<>* attribType = node->first_attribute("type");
     922            0 :         UG_COND_THROW(!attribType, "Invalid attachment entry: No 'type' attribute was supplied!");
     923            0 :         string type = attribType->value();
     924              : 
     925              :         bool global = false;
     926            0 :         if (xml_attribute<>* attrib = node->first_attribute("global")){
     927            0 :                 global = bool(atoi(attrib->value()));
     928              :         }
     929              : 
     930              :         bool passOn = false;
     931            0 :         if (xml_attribute<>* attrib = node->first_attribute("passOn")){
     932            0 :                 passOn = bool(atoi(attrib->value()));
     933              :         }
     934              :         
     935            0 :         if(global && !GlobalAttachments::is_declared(name)){
     936            0 :                 if(GlobalAttachments::type_is_registered(type)){
     937            0 :                         GlobalAttachments::declare_attachment(name, type, passOn);
     938              :                         // GlobalAttachments::mark_attachment_as_locally_declared(name);
     939              :                 }
     940              :                 else
     941              :                         return true;
     942              :         }
     943              : 
     944            0 :         UG_COND_THROW(type.compare(GlobalAttachments::type_name(name)) != 0,
     945              :                                   "Attachment type mismatch. Expecting type: " << 
     946              :                                   GlobalAttachments::type_name(name)
     947              :                                   << ", but given type is: " << type);
     948              : 
     949            0 :         string str(node->value(), node->value_size());
     950            0 :         stringstream ss(str, ios_base::in);
     951            0 :         GlobalAttachments::read_attachment_values<TElem>(ss, grid, name);
     952              : 
     953              :         return true;
     954            0 : }
     955              : 
     956              : }//     end of namespace
     957              : 
     958              : #endif
        

Generated by: LCOV version 2.0-1