ViennaGrid - The Vienna Grid Library
2.1.0
|
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