ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/serialization.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_IO_SERIALIZATION_HPP
00002 #define VIENNAGRID_IO_SERIALIZATION_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    License:      MIT (X11), see file LICENSE in the base directory
00014 ======================================================================= */
00015 
00020 #include "viennagrid/forwards.hpp"
00021 #include "viennagrid/mesh/mesh.hpp"
00022 
00023 
00024 #include <boost/archive/text_iarchive.hpp>
00025 #include <boost/archive/text_oarchive.hpp>
00026 #include <boost/serialization/base_object.hpp>
00027 #include <boost/serialization/utility.hpp>
00028 #include <boost/serialization/list.hpp>
00029 #include <boost/serialization/assume_abstract.hpp>
00030 #include <boost/shared_ptr.hpp>
00031 
00036 namespace viennagrid
00037 {
00038   namespace io
00039   {
00040 
00042     class bad_serialization_state_exception : public std::exception
00043     {
00044       public:
00045         virtual const char* what() const throw()
00046         {
00047           std::stringstream ss;
00048           ss << "* ViennaGrid: Bad serialization state: " << msg_ << "!";
00049           return ss.str().c_str();
00050         }
00051 
00052         bad_serialization_state_exception(std::string msg) : msg_(msg) {}
00053 
00054         virtual ~bad_serialization_state_exception() throw() {}
00055 
00056       private:
00057         std::string msg_;
00058     };
00059 
00060 
00061 
00065     template<typename MeshT>
00066     struct mesh_serializer
00067     {
00068     private:
00069       typedef typename viennagrid::result_of::cell_tag<MeshT>::type                        CellTag;
00070       typedef typename viennagrid::result_of::const_vertex_range<MeshT>::type              ConstVertexRange;
00071       typedef typename viennagrid::result_of::iterator<ConstVertexRange>::type             ConstVertexIterator;
00072       typedef typename viennagrid::result_of::point<MeshT>::type                           PointType;
00073       typedef typename viennagrid::result_of::vertex<MeshT>::type                          VertexType;
00074       typedef typename viennagrid::result_of::vertex_handle<MeshT>::type                   VertexHandleType;
00075       typedef typename viennagrid::result_of::id<VertexType>::type                         VertexIDType;
00076       typedef typename viennagrid::result_of::cell<MeshT>::type                            CellType;
00077       typedef typename viennagrid::result_of::const_cell_range<MeshT>::type                ConstCellRange;
00078       typedef typename viennagrid::result_of::iterator<ConstCellRange>::type               ConstCellIterator;
00079       typedef typename viennagrid::result_of::const_vertex_range<CellType>::type           ConstVertexOnCellRange;
00080       typedef typename viennagrid::result_of::iterator<ConstVertexOnCellRange>::type       ConstVertexOnCellIterator;
00081 
00082       static const int DIMG = PointType::dim;
00083 
00084       friend class boost::serialization::access;
00085 
00087       template<class Archive>
00088       void save(Archive & ar, const unsigned int version) const
00089       {
00090         if (!mesh_pointer)
00091           throw bad_serialization_state_exception( "Mesh not loaded into serialzer object" );
00092 
00093         MeshT const & mesh_obj = *mesh_pointer;
00094 
00095         // -----------------------------------------------
00096         // the geometry is read and transmitted
00097         //
00098         std::size_t point_size = viennagrid::vertices(mesh_obj).size();
00099         ar & point_size;
00100         ConstVertexRange vertices(mesh_obj);
00101         for (ConstVertexIterator vit = vertices.begin();
00102              vit != vertices.end(); ++vit)
00103         {
00104           for(int d = 0; d < DIMG; d++)
00105             ar & viennagrid::point(*vit)[d];
00106         }
00107 
00108 
00109         // -----------------------------------------------
00110         // the specific cells are read and transmitted
00111         //
00112         ConstCellRange cells(mesh_obj);
00113 
00114         std::size_t cell_size = viennagrid::cells(mesh_obj).size();
00115         ar & cell_size;
00116 
00117         for (ConstCellIterator cit = cells.begin();
00118         cit != cells.end(); ++cit)
00119         {
00120           ConstVertexOnCellRange vertices_on_cell(*cit);
00121 
00122           for (ConstVertexOnCellIterator vocit = vertices_on_cell.begin();
00123           vocit != vertices_on_cell.end();
00124           ++vocit)
00125           {
00126             std::size_t id = vocit->id().get();
00127             ar & id;
00128           }
00129         }
00130         // -----------------------------------------------
00131       }
00132 
00134       template<class Archive>
00135       void load(Archive & ar, const unsigned int version)
00136       {
00137         if (!mesh_pointer)
00138           throw bad_serialization_state_exception( "Mesh not loaded into serialzer object" );
00139 
00140         MeshT & mesh_obj = *mesh_pointer;
00141 
00142         // -----------------------------------------------
00143         // the geometry is received and stored
00144         //
00145         std::size_t point_size;
00146         ar & point_size;
00147 
00148         for(std::size_t i = 0; i < point_size; i++)
00149         {
00150           PointType p;
00151           for(int d = 0; d < DIMG; d++)
00152             ar & p[d];
00153 
00154           viennagrid::make_vertex( *mesh_pointer, p );
00155         }
00156         // -----------------------------------------------
00157 
00158 
00159         // -----------------------------------------------
00160         // the specific cells are received and stored
00161         //
00162 
00163         std::size_t cell_size;
00164         ar & cell_size;
00165         for(std::size_t ci = 0; ci < cell_size; ci++)
00166         {
00167           const int num_vertices = viennagrid::boundary_elements<CellTag, vertex_tag>::num;
00168           VertexHandleType vertices[num_vertices];
00169 
00170           for (int j=0; j< num_vertices; ++j)
00171           {
00172             std::size_t id;
00173             ar & id;
00174             vertices[j] = viennagrid::find_by_id( mesh_obj, VertexIDType(id) ).handle();
00175           }
00176 
00177           viennagrid::make_cell( mesh_obj, vertices, vertices + num_vertices);
00178         }
00179         // -----------------------------------------------
00180       }
00181 
00182       // -----------------------------------------------
00183       // notify Boost Serialization that the save and load
00184       // procedures differ
00185       //
00186       BOOST_SERIALIZATION_SPLIT_MEMBER()
00187       // -----------------------------------------------
00188     public:
00190       mesh_serializer() : mesh_pointer(0) {}
00191 
00193       mesh_serializer(MeshT & mesh_obj) : mesh_pointer(mesh_obj) {}
00194 
00197       inline void load(MeshT & mesh_obj) { mesh_pointer = &mesh;  }
00198 
00201       inline MeshT & get() { return *mesh_pointer; }
00202       inline MeshT const & get() const { return *mesh_pointer; }
00203 
00205       MeshT & operator()() { return *mesh_pointer; }
00206       MeshT const & operator()() const { return *mesh_pointer; }
00207 
00210     private:
00211       MeshT * mesh_pointer;
00212     };
00213 
00214   } //namespace io
00215 } //namespace viennagrid
00216 
00217 #endif
00218