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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-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 <fstream>
      34              : #include "lib_grid/lg_base.h"
      35              : #include "lib_grid/algorithms/serialization.h"
      36              : #include "file_io_lgb.h"
      37              : 
      38              : #include <sstream>
      39              : #include <boost/archive/text_oarchive.hpp>
      40              : #include <boost/archive/text_iarchive.hpp>
      41              : #include "common/boost_serialization_routines.h"
      42              : #include "common/util/archivar.h"
      43              : #include "common/util/factory.h"
      44              : #include "lib_grid/refinement/projectors/projection_handler.h"
      45              : #include "lib_grid/refinement/projectors/projectors.h"
      46              : 
      47              : using namespace std;
      48              : 
      49              : namespace ug
      50              : {
      51              : 
      52              : enum LGBConstants
      53              : {
      54              :         LGBC_NONE = 0,
      55              :         LGBC_POS2D = 1,
      56              :         LGBC_POS3D = 1 << 1,
      57              :         LGBC_SUBSET_HANDLER = 1 << 2,
      58              :         LGBC_SELECTOR = 1 << 3,
      59              :         LGBC_PROJECTION_HANDLER = 1 << 4
      60              : };
      61              : 
      62            0 : void SerializeProjector(BinaryBuffer& out, RefinementProjector& proj)
      63              : {
      64            0 :         static Factory<RefinementProjector, ProjectorTypes>       projFac;
      65            0 :         static Archivar<boost::archive::text_oarchive, RefinementProjector, ProjectorTypes>       archivar;
      66              :         
      67            0 :         const string& projName = projFac.class_name(proj);
      68              : 
      69            0 :         Serialize(out, projName);
      70              : 
      71            0 :         stringstream ss;
      72              :         boost::archive::text_oarchive ar(ss, boost::archive::no_header);
      73              :         archivar.archive(ar, proj);
      74              : 
      75            0 :         Serialize(out, ss.str());
      76            0 : }
      77              : 
      78              : 
      79            0 : void SerializeProjectionHandler(BinaryBuffer& out, ProjectionHandler& ph)
      80              : {
      81            0 :         const int magicNumber = 978523;
      82            0 :         out.write((char*)&magicNumber, sizeof(int));
      83              : 
      84            0 :         if(ph.default_projector().valid()){
      85            0 :                 byte b = 1;
      86            0 :                 out.write((char*)&b, sizeof(b));
      87            0 :                 SerializeProjector(out, *ph.default_projector());
      88              :         }
      89              :         else{
      90            0 :                 byte b = 0;
      91            0 :                 out.write((char*)&b, sizeof(b));
      92              :         }
      93              : 
      94            0 :         int numProjectors = (int)ph.num_projectors();
      95            0 :         out.write((char*)&numProjectors, sizeof(int));
      96              : 
      97            0 :         for(int i = -1; i < numProjectors; ++i){
      98            0 :                 if(!ph.projector(i).valid()){
      99            0 :                         const int invInd = -2;
     100            0 :                         out.write((char*)& invInd, sizeof(int));
     101              :                         continue;
     102            0 :                 }
     103              : 
     104            0 :                 RefinementProjector& proj= *ph.projector(i);
     105              : 
     106            0 :                 out.write((char*)& i, sizeof(int));
     107            0 :                 SerializeProjector(out, proj);
     108              :         }
     109            0 :         out.write((char*)&magicNumber, sizeof(int));
     110            0 : }
     111              : 
     112              : 
     113            0 : SPRefinementProjector DeserializeProjector(BinaryBuffer& in)
     114              : {
     115              :         static Archivar<boost::archive::text_iarchive,
     116              :                                 RefinementProjector,
     117              :                                 ProjectorTypes>
     118            0 :                         archivar;
     119              : 
     120            0 :         static Factory<RefinementProjector, ProjectorTypes>       projFac;
     121              : 
     122              :         std::string name;
     123            0 :         Deserialize(in, name);
     124              : 
     125            0 :         if(name.empty())
     126              :                 return SPRefinementProjector();
     127              :         
     128              :         SPRefinementProjector proj = projFac.create(name);
     129              : 
     130              :         std::string data;
     131            0 :         Deserialize(in, data);
     132            0 :         std::stringstream ss(data, std::ios_base::in);
     133              :         boost::archive::text_iarchive ar(ss, boost::archive::no_header);
     134              :         archivar.archive(ar, *proj);
     135              :         return proj;
     136            0 : }
     137              : 
     138              : 
     139            0 : void DeserializeProjectionHandler(BinaryBuffer& in, ProjectionHandler& ph)
     140              : {
     141              :         const int magicNumber = 978523;
     142              :         int tmpMagicNumber;
     143            0 :         in.read((char*)&tmpMagicNumber, sizeof(int));
     144            0 :         UG_COND_THROW(tmpMagicNumber != magicNumber,
     145              :                       "Magic number mismatch in DeserializeProjectionHandler (1)!");
     146              : 
     147            0 :         ph.clear();
     148              :         
     149              :         byte b;
     150            0 :         in.read((char*)&b, sizeof(b));
     151            0 :         if(b){
     152            0 :                 ph.set_default_projector(DeserializeProjector(in));
     153              :         }
     154              :         else
     155            0 :                 ph.set_default_projector(SPRefinementProjector());
     156              : 
     157              :         int numProjectors;
     158            0 :         in.read((char*)&numProjectors, sizeof(int));
     159              : 
     160            0 :         for(int i = -1; i < numProjectors; ++i){
     161              :                 int index;
     162            0 :                 in.read((char*)& index, sizeof(int));
     163            0 :                 if(index == -2){
     164            0 :                         continue;
     165              :                 }
     166              : 
     167            0 :                 ph.set_projector(index, DeserializeProjector(in));
     168              :         }
     169              : 
     170            0 :         in.read((char*)&tmpMagicNumber, sizeof(int));
     171            0 :         UG_COND_THROW(tmpMagicNumber != magicNumber,
     172              :                       "Magic number mismatch in DeserializeProjectionHandler (2)!");
     173            0 : }
     174              : 
     175              : 
     176              : 
     177              : 
     178            0 : bool SaveGridToLGB(Grid& grid, const char* filename,
     179              :                                    ISubsetHandler** ppSH, int numSHs,
     180              :                                    ProjectionHandler* pPH,
     181              :                                    APosition aPos)
     182              : {
     183            0 :         return SaveGridToLGB (grid, filename,ppSH, numSHs, NULL, 0, pPH, aPos);
     184              : }
     185              : 
     186              : 
     187            0 : bool SaveGridToLGB(Grid& grid, const char* filename,
     188              :                                    ISubsetHandler** ppSH, int numSHs,
     189              :                                    ISelector** ppSel, int numSels,
     190              :                                    ProjectionHandler* pPH,
     191              :                                    APosition aPos)
     192              : {
     193              : //      make sure that aPos is attached to the grid
     194            0 :         if(!grid.has_vertex_attachment(aPos))
     195              :                 return false;
     196              : 
     197            0 :         BinaryBuffer tbuf;
     198              : 
     199              : //      write the header
     200            0 :         byte endianess = 1;
     201            0 :         byte intSize = (byte)sizeof(int);
     202            0 :         byte numberSize = (byte)sizeof(number);
     203            0 :         int versionNumber = 4;
     204              :         
     205            0 :         tbuf.write((char*)&endianess, sizeof(byte));
     206            0 :         tbuf.write((char*)&intSize, sizeof(byte));
     207            0 :         tbuf.write((char*)&numberSize, sizeof(byte));
     208            0 :         tbuf.write((char*)&versionNumber, sizeof(int));
     209              : 
     210              : //      the options
     211            0 :         uint opts = LGBC_POS3D;
     212            0 :         if(numSHs > 0)
     213            0 :                 opts |= LGBC_SUBSET_HANDLER;
     214            0 :         if(numSels > 0)
     215            0 :                 opts |= LGBC_SELECTOR;
     216            0 :         if(pPH)
     217            0 :                 opts |= LGBC_PROJECTION_HANDLER;
     218              : 
     219              : //      write the options
     220            0 :         tbuf.write((char*)&opts, sizeof(uint));
     221              : 
     222              : //      serialize the grid
     223            0 :         SerializeGridElements(grid, tbuf);
     224              : 
     225              : //      serialize the position-attachment
     226            0 :         SerializeAttachment<Vertex>(grid, aPos, tbuf);
     227              : 
     228              : //      Serialize the subset-handler
     229            0 :         if(numSHs > 0){
     230              :         //      write the number of subset handlers which shall be serialized
     231            0 :                 tbuf.write((char*)&numSHs, sizeof(int));
     232            0 :                 for(int i = 0; i< numSHs; ++i)
     233            0 :                         SerializeSubsetHandler(grid, *ppSH[i], tbuf);
     234              :         }
     235              : 
     236              : //      Serialize the selectors
     237            0 :         if(numSels > 0){
     238            0 :                 tbuf.write((char*)&numSels, sizeof(int));
     239            0 :                 for(int i = 0; i< numSels; ++i)
     240            0 :                         SerializeSelector(grid, *ppSel[i], tbuf);
     241              :         }
     242              : 
     243              : //      Serializie the projection handler
     244            0 :         if(pPH){
     245              :                 ProjectionHandler& ph = *pPH;
     246              : 
     247              :                 //      find corresponding subset handler
     248              :                 {
     249            0 :                         UG_COND_THROW(numSHs < 1, "If a ProjectionHandler is specified, the corresponding SubsetHandler also has to be specified!");
     250              : 
     251            0 :                         int i = 0;
     252            0 :                         for (; i < numSHs; ++i)
     253            0 :                                 if (ppSH[i] == ph.subset_handler())
     254              :                                         break;
     255              : 
     256            0 :                         UG_COND_THROW(i == numSHs, "ERROR in 'SaveGridToLGB': "
     257              :                                 "No matching SubsetHandler could be found.\n"
     258              :                                 "Please make sure to add the associated SubsetHandler before adding a ProjectionHandler");
     259              : 
     260              :                 //      write index of corresponding subset handler
     261            0 :                         tbuf.write((char*)&i, sizeof(int));
     262              :                 }
     263              : 
     264            0 :                 SerializeProjectionHandler(tbuf, ph);
     265              :         }
     266              : 
     267              : //      write a magic-number that allows us to check during read
     268              : //      whether everything went ok.
     269            0 :         int magicNumber = 3478384;
     270            0 :         tbuf.write((char*)&magicNumber, sizeof(int));
     271              : 
     272              : //      open the outstream
     273            0 :         ofstream out(filename, ios::binary);
     274            0 :         if(!out) return false;
     275              : 
     276            0 :         out.write(tbuf.buffer(), tbuf.write_pos());
     277              : 
     278              : //      done
     279            0 :         out.close();
     280              :         return true;
     281            0 : }
     282              : 
     283              : 
     284              : 
     285            0 : bool LoadGridFromLGB(Grid& grid, const char* filename,
     286              :                                    ISubsetHandler** ppSH, int numSHs,
     287              :                                    ProjectionHandler* pPH,
     288              :                                    APosition aPos)
     289              : {
     290            0 :         return LoadGridFromLGB (grid, filename, ppSH, numSHs, NULL, 0, pPH, aPos);
     291              : }
     292              : 
     293              : 
     294            0 : bool LoadGridFromLGB(Grid& grid, const char* filename,
     295              :                                    ISubsetHandler** ppSH, int numSHs,
     296              :                                    ISelector** ppSel, int numSels,
     297              :                                    ProjectionHandler* pPH,
     298              :                                    APosition aPos)
     299              : {
     300            0 :         grid.clear_geometry();
     301              : 
     302              : //      if aPos is not yet attached to the grid, we'll do it now.
     303            0 :         if(!grid.has_vertex_attachment(aPos))
     304            0 :                 grid.attach_to_vertices(aPos);
     305              : 
     306              : //      open the outstream
     307            0 :         ifstream in(filename, ios::binary);
     308            0 :         if(!in){
     309            0 :                 UG_LOG("ERROR in LoadGridFromLGB: couldn't open file: " << filename << endl);
     310              :                 return false;
     311              :         }
     312              : 
     313              : //      read the whole file into a binary buffer
     314            0 :         BinaryBuffer tbuf;
     315            0 :         in.seekg(0, ios::end);
     316            0 :         streampos fileLen = in.tellg();
     317            0 :         in.seekg(0, ios::beg);
     318              : 
     319            0 :         tbuf.reserve(fileLen);
     320            0 :         in.read(tbuf.buffer(), fileLen);
     321            0 :         tbuf.set_write_pos(fileLen);
     322              : 
     323            0 :         in.close();
     324              : 
     325              : //      read the header
     326              :         byte endianess;
     327              :         byte intSize;
     328              :         byte numberSize;
     329              :         int versionNumber;
     330              : 
     331            0 :         tbuf.read((char*)&endianess, sizeof(byte));
     332            0 :         tbuf.read((char*)&intSize, sizeof(byte));
     333            0 :         tbuf.read((char*)&numberSize, sizeof(byte));
     334            0 :         tbuf.read((char*)&versionNumber, sizeof(int));
     335              : 
     336              : //      check whether the values are ok
     337            0 :         if(endianess != 1)
     338              :         {
     339              :                 LOG("ERROR in LoadGridFromLGB: wrong endianess\n");
     340              :                 return false;
     341              :         }
     342            0 :         if(intSize != sizeof(int))
     343              :         {
     344              :                 LOG("ERROR in LoadGridFromLGB: bad integer-size\n");
     345              :                 return false;
     346              :         }
     347            0 :         if(numberSize != sizeof(number))
     348              :         {
     349              :                 LOG("ERROR in LoadGridFromLGB: bad number-size\n");
     350              :                 return false;
     351              :         }
     352            0 :         if((versionNumber < 2) || (versionNumber > 4))
     353              :         {
     354            0 :                 LOG("ERROR in LoadGridFromLGB: bad file-version: " << versionNumber << ". Expected 2 or 3.\n");
     355              :                 return false;
     356              :         }
     357              : 
     358              : //      from version 3 on grids write a small header
     359            0 :         bool readGridHeader = (versionNumber >= 3);
     360              : 
     361              : //      read the options
     362              :         uint opts;
     363            0 :         tbuf.read((char*)&opts, sizeof(uint));
     364              : 
     365              : //      to avoid problems with autgenerated elements we'll deactivate
     366              : //      all options and reactivate them later on
     367            0 :         uint gridOptions = grid.get_options();
     368            0 :         grid.set_options(GRIDOPT_NONE);
     369              : 
     370              : //      deserialize the grid
     371            0 :         DeserializeGridElements(grid, tbuf, readGridHeader);
     372              : 
     373              : //      deserialize the position-attachment
     374            0 :         DeserializeAttachment<Vertex>(grid, aPos, tbuf);
     375              : 
     376              : //      Serialize the subset-handler
     377            0 :         if((opts & LGBC_SUBSET_HANDLER) == LGBC_SUBSET_HANDLER)
     378              :         {
     379              :         //      read number of subset handlers
     380              :                 int numSrcSHs;
     381            0 :                 tbuf.read((char*)&numSrcSHs, sizeof(int));
     382              :                 
     383              :         //      starting from version 4, subset-infos contain a property-map
     384            0 :                 bool readPropertyMap = (versionNumber >= 4);
     385              : 
     386              :                 int i;
     387            0 :                 for(i = 0; i < min(numSrcSHs, numSHs); ++i){
     388            0 :                         DeserializeSubsetHandler(grid, *ppSH[i], tbuf, readPropertyMap);
     389              :                 }
     390              :                 
     391              :         //      read the rest
     392            0 :                 for(; i < numSrcSHs; ++i)
     393              :                 {
     394            0 :                         SubsetHandler sh(grid);
     395            0 :                         DeserializeSubsetHandler(grid, sh, tbuf, readPropertyMap);
     396            0 :                 }
     397              :         }
     398              : 
     399            0 :         if((opts & LGBC_SELECTOR) == LGBC_SELECTOR)
     400              :         {
     401              :         //      read number of subset handlers
     402              :                 int numSrcSels;
     403            0 :                 tbuf.read((char*)&numSrcSels, sizeof(int));
     404              :                 
     405              :                 int i;
     406            0 :                 for(i = 0; i < min(numSrcSels, numSels); ++i){
     407            0 :                         DeserializeSelector(grid, *ppSel[i], tbuf);
     408              :                 }
     409              :                 
     410              :         //      read the rest
     411            0 :                 for(; i < numSrcSels; ++i)
     412              :                 {
     413            0 :                         Selector sel(grid);
     414            0 :                         DeserializeSelector(grid, sel, tbuf);
     415            0 :                 }
     416              :         }
     417              : 
     418              : 
     419            0 :         if((opts & LGBC_PROJECTION_HANDLER) == LGBC_PROJECTION_HANDLER)
     420              :         {
     421              :         //      read number of subset handlers
     422              :                 int shIndex;
     423            0 :                 tbuf.read((char*)&shIndex, sizeof(int));
     424              :                 
     425            0 :                 if(pPH)
     426            0 :                         DeserializeProjectionHandler(tbuf, *pPH);
     427              :                 else{
     428            0 :                         ProjectionHandler ph;
     429            0 :                         DeserializeProjectionHandler(tbuf, ph);
     430            0 :                 }
     431              :         }
     432              : 
     433              : //      reactivate the grid-options
     434            0 :         grid.set_options(gridOptions);
     435              : 
     436              : //      check the magic-number
     437              :         int magicNumber;
     438            0 :         tbuf.read((char*)&magicNumber, sizeof(int));
     439              : 
     440            0 :         if(magicNumber != 3478384){
     441            0 :                 LOG("ERROR in LoadGridFromLGB: Bad magic number at end of file: " << magicNumber << endl);
     442              :                 return false;
     443              :         }
     444              : //      done
     445              :         return true;
     446            0 : }
     447              : 
     448              : }//     end of namespace
        

Generated by: LCOV version 2.0-1