ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/opendx_writer.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_IO_OPENDX_WRITER_HPP
00002 #define VIENNAGRID_IO_OPENDX_WRITER_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    License:      MIT (X11), see file LICENSE in the base directory
00014 ======================================================================= */
00015 
00016 #include <fstream>
00017 #include <iostream>
00018 #include "viennagrid/forwards.hpp"
00019 #include "viennagrid/mesh/mesh.hpp"
00020 #include "viennagrid/io/helper.hpp"
00021 #include "viennagrid/accessor.hpp"
00022 
00027 namespace viennagrid
00028 {
00029   namespace io
00030   {
00031 
00033 
00034 
00041     template <typename FloatingPointType>
00042     FloatingPointType DXfixer(FloatingPointType value)
00043     {
00044       if ( std::fabs(value * 10000 - static_cast<long>(value * 10000)) < FloatingPointType(1.0))
00045         return value + 0.00001;
00046 
00047       return value;
00048     }
00049 
00051     template <int DIM>
00052     struct DXHelper {};
00053 
00054     template <>
00055     struct DXHelper<1>
00056     {
00057       static std::string getAttributes()
00058       { return "attribute \"element type\" string \"line\" "; }
00059     };
00060 
00061     template <>
00062     struct DXHelper<2>
00063     {
00064       static std::string getAttributes()
00065       { return "attribute \"element type\" string \"triangles\" "; }
00066     };
00067 
00068     template <>
00069     struct DXHelper<3>
00070     {
00071       static std::string getAttributes()
00072       { return "attribute \"element type\" string \"tetrahedra\" "; }
00073     };
00074 
00079     template <typename MeshType>
00080     class opendx_writer
00081     {
00082 
00083         typedef typename viennagrid::result_of::point<MeshType>::type PointType;
00084         typedef typename viennagrid::result_of::coord<PointType>::type CoordType;
00085         static const int geometric_dim = viennagrid::result_of::static_size<PointType>::value;
00086 
00087         typedef typename viennagrid::result_of::cell_tag<MeshType>::type CellTag;
00088 
00089         typedef typename result_of::element<MeshType, viennagrid::vertex_tag>::type                           VertexType;
00090         typedef typename result_of::element<MeshType, CellTag>::type     CellType;
00091 
00092         typedef typename viennagrid::result_of::const_element_range<MeshType, viennagrid::vertex_tag>::type   VertexRange;
00093         typedef typename viennagrid::result_of::iterator<VertexRange>::type              VertexIterator;
00094 
00095         typedef typename viennagrid::result_of::const_element_range<MeshType, CellTag>::type     CellRange;
00096         typedef typename viennagrid::result_of::iterator<CellRange>::type                                        CellIterator;
00097 
00098         typedef typename viennagrid::result_of::const_element_range<CellType, viennagrid::vertex_tag>::type      VertexOnCellRange;
00099         typedef typename viennagrid::result_of::iterator<VertexOnCellRange>::type         VertexOnCellIterator;
00100 
00101         typedef base_dynamic_field<const double, VertexType> VertexScalarBaseAccessor;
00102         typedef std::map< std::string, VertexScalarBaseAccessor * > VertexScalarOutputAccessorContainer;
00103 
00104         typedef base_dynamic_field<const double, CellType> CellScalarBaseAccessor;
00105         typedef std::map< std::string, CellScalarBaseAccessor * > CellScalarOutputAccessorContainer;
00106 
00107 
00108       public:
00114         void operator()(MeshType const & mesh_obj, std::string const & filename)
00115         {
00116           typedef DXHelper<geometric_dim>  DXHelper;
00117 
00118           std::ofstream writer(filename.c_str());
00119           if (!writer.is_open())
00120           {
00121             throw cannot_open_file_exception("* ViennaGrid: opendx_writer::operator(): File " + filename + ": Cannot open file!");
00122           }
00123 
00124           std::size_t pointnum = viennagrid::elements<vertex_tag>(mesh_obj).size();
00125 
00126           writer << "object \"points\" class array type float rank 1 shape " << geometric_dim << " items ";
00127           writer << pointnum << " data follows" << std::endl;
00128 
00129           //Nodes:
00130           VertexRange vertices = viennagrid::elements<vertex_tag>(mesh_obj);
00131           for (VertexIterator vit = vertices.begin();
00132               vit != vertices.end();
00133               ++vit)
00134           {
00135             PointWriter<geometric_dim>::write(writer, viennagrid::point( mesh_obj, *vit ) );
00136             writer << std::endl;
00137           }
00138           writer << std::endl;
00139 
00140           //Cells:
00141           std::size_t cellnum = viennagrid::elements<CellTag>(mesh_obj).size();
00142           writer << "object \"grid_Line_One\" class array type int rank 1 shape " << (geometric_dim + 1) << " items " << cellnum << " data follows" << std::endl;
00143 
00144           CellRange cells = viennagrid::elements<CellTag>(mesh_obj);
00145           for (CellIterator cit = cells.begin();
00146               cit != cells.end();
00147               ++cit)
00148           {
00149             VertexOnCellRange vertices_for_cell = viennagrid::elements<vertex_tag>(*cit);
00150             for (VertexOnCellIterator vocit = vertices_for_cell.begin();
00151                 vocit != vertices_for_cell.end();
00152                 ++vocit)
00153             {
00154               VertexType const & vertex = *vocit;
00155               writer << vertex.id() << " ";
00156             }
00157             writer << std::endl;
00158           }
00159 
00160           writer << DXHelper::getAttributes() << std::endl;
00161           writer << "attribute \"ref\" string \"positions\" " << std::endl;
00162           writer << std::endl;
00163 
00164           //set output-format:
00165           writer.flags(std::ios::fixed);
00166           writer.precision(5);
00167 
00168           //write quantity:
00169           if (vertex_scalar_data.size() > 0)
00170           {
00171             writer << "object \"VisData\" class array items " << pointnum << " data follows" << std::endl;
00172             //some quantity here
00173 
00174             for (VertexIterator vit = vertices.begin();
00175                 vit != vertices.end();
00176                 ++vit)
00177             {
00178               writer << DXfixer( vertex_scalar_data.begin()->second->at(*vit) );
00179               writer << std::endl;
00180             }
00181 
00182             writer << "attribute \"dep\" string \"positions\"" << std::endl;
00183           }
00184           else if (cell_scalar_data.size() > 0)
00185           {
00186             writer << "object \"VisData\" class array items " << cellnum << " data follows" << std::endl;
00187 
00188             //some quantity here
00189             for (CellIterator cit = cells.begin();
00190                 cit != cells.end();
00191                 ++cit)
00192             {
00193               writer << DXfixer( cell_scalar_data.begin()->second->at(*cit) );
00194               writer << std::endl;
00195             }
00196             writer << "attribute \"dep\" string \"connections\"" << std::endl;
00197           }
00198 
00199           writer << std::endl;
00200           writer << "object \"AttPotential\" class field " << std::endl;
00201           writer << "component \"data\" \"VisData\" " << std::endl;
00202           writer << "component \"positions\" \"points\"" << std::endl;
00203           writer << "component \"connections\" \"grid_Line_One\"" << std::endl;
00204         } // operator()
00205 
00206 
00207     private:
00208 
00209 
00210       template<typename MapType, typename AccessorOrFieldType>
00211       void add_to_container(MapType & map, AccessorOrFieldType const accessor_or_field, std::string const & name)
00212       {
00213           typename MapType::iterator it = map.find(name);
00214           if (it != map.end())
00215           {
00216             delete it->second;
00217             it->second = new dynamic_field_wrapper<const AccessorOrFieldType>( accessor_or_field );
00218           }
00219           else
00220             map[name] = new dynamic_field_wrapper<const AccessorOrFieldType>( accessor_or_field );
00221       }
00222 
00223 
00224     public:
00225 
00226 
00228         template <typename T>
00229         void add_scalar_data_on_vertices(T const accessor, std::string name)
00230         {
00231           if (vertex_scalar_data.size() > 0)
00232             std::cout << "* ViennaGrid: Warning: OpenDX vertex data " << name
00233                       << " will be ignored, because other data is already available!" << std::endl;
00234 
00235           add_to_container( vertex_scalar_data, accessor, name );
00236         }
00237 
00239         template <typename T>
00240         void add_scalar_data_on_cells(T const accessor, std::string name)
00241         {
00242           if (cell_scalar_data.size() > 0)
00243             std::cout << "* ViennaGrid: Warning: OpenDX cell data " << name
00244                       << " will be ignored, because other cell data is already available!" << std::endl;
00245 
00246           if (vertex_scalar_data.size() > 0)
00247             std::cout << "* ViennaGrid: Warning: OpenDX cell data " << name
00248                       << " will be ignored, because other vertex data is already available!" << std::endl;
00249 
00250           add_to_container( cell_scalar_data, accessor, name );
00251         }
00252 
00253 
00254       private:
00255 
00256         VertexScalarOutputAccessorContainer          vertex_scalar_data;
00257         CellScalarOutputAccessorContainer            cell_scalar_data;
00258 
00259     }; // opendx_writer
00260 
00261 
00270     template <typename MeshT, typename AccessorT>
00271     opendx_writer<MeshT> & add_scalar_data_on_vertices(opendx_writer<MeshT> & writer,
00272                                                          AccessorT const accessor,
00273                                                          std::string const & quantity_name)
00274     {
00275       writer.add_scalar_data_on_vertices(accessor, quantity_name);
00276       return writer;
00277     }
00278 
00279 
00280 
00289     template <typename MeshT, typename AccessorT>
00290     opendx_writer<MeshT> & add_scalar_data_on_cells(opendx_writer<MeshT> & writer,
00291                                                       AccessorT const accessor,
00292                                                       std::string const & quantity_name)
00293     {
00294       writer.add_scalar_data_on_cells(accessor, quantity_name);
00295       return writer;
00296     }
00297 
00298 
00299 
00300   } //namespace io
00301 } //namespace viennagrid
00302 
00303 #endif
00304 
00305