Go to the documentation of this file.00001 #ifndef VIENNAGRID_IO_OPENDX_WRITER_GUARD
00002 #define VIENNAGRID_IO_OPENDX_WRITER_GUARD
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <fstream>
00022 #include <iostream>
00023 #include "viennagrid/forwards.h"
00024 #include "viennagrid/io/helper.hpp"
00025 #include "viennagrid/io/data_accessor.hpp"
00026
00031 namespace viennagrid
00032 {
00033 namespace io
00034 {
00035
00037
00038
00045 template <typename FloatingPointType>
00046 FloatingPointType DXfixer(FloatingPointType value)
00047 {
00048 if (value * 10000 == static_cast<long>(value * 10000))
00049 return value + 0.00001;
00050
00051 return value;
00052 }
00053
00055 template <int DIM>
00056 struct DXHelper {};
00057
00058 template <>
00059 struct DXHelper<1>
00060 {
00061 static std::string getAttributes()
00062 { return "attribute \"element type\" string \"line\" "; }
00063 };
00064
00065 template <>
00066 struct DXHelper<2>
00067 {
00068 static std::string getAttributes()
00069 { return "attribute \"element type\" string \"triangles\" "; }
00070 };
00071
00072 template <>
00073 struct DXHelper<3>
00074 {
00075 static std::string getAttributes()
00076 { return "attribute \"element type\" string \"tetrahedra\" "; }
00077 };
00078
00083 template <typename DomainType>
00084 class opendx_writer
00085 {
00086 typedef typename DomainType::config_type DomainConfiguration;
00087
00088 typedef typename DomainConfiguration::numeric_type CoordType;
00089 typedef typename DomainConfiguration::coordinate_system_tag CoordinateSystemTag;
00090 typedef typename DomainConfiguration::cell_tag CellTag;
00091
00092 typedef typename result_of::point<DomainConfiguration>::type PointType;
00093 typedef typename result_of::ncell<DomainConfiguration, 0>::type VertexType;
00094 typedef typename result_of::ncell<DomainConfiguration, CellTag::dim>::type CellType;
00095
00096 typedef typename viennagrid::result_of::const_ncell_range<DomainType, 0>::type VertexRange;
00097 typedef typename viennagrid::result_of::iterator<VertexRange>::type VertexIterator;
00098
00099 typedef typename viennagrid::result_of::const_ncell_range<DomainType, CellTag::dim>::type CellRange;
00100 typedef typename viennagrid::result_of::iterator<CellRange>::type CellIterator;
00101
00102 typedef typename viennagrid::result_of::const_ncell_range<CellType, 0>::type VertexOnCellRange;
00103 typedef typename viennagrid::result_of::iterator<VertexOnCellRange>::type VertexOnCellIterator;
00104
00105
00106 public:
00112 int operator()(DomainType const & domain, std::string const & filename)
00113 {
00114 typedef DXHelper<CoordinateSystemTag::dim> DXHelper;
00115
00116 std::ofstream writer(filename.c_str());
00117 if (!writer.is_open())
00118 {
00119 throw cannot_open_file_exception(filename);
00120 return EXIT_FAILURE;
00121 }
00122
00123 std::size_t pointnum = viennagrid::ncells<0>(domain).size();
00124
00125 writer << "object \"points\" class array type float rank 1 shape " << CoordinateSystemTag::dim << " items ";
00126 writer << pointnum << " data follows" << std::endl;
00127
00128
00129 VertexRange vertices = viennagrid::ncells<0>(domain);
00130 for (VertexIterator vit = vertices.begin();
00131 vit != vertices.end();
00132 ++vit)
00133 {
00134 PointWriter<CoordinateSystemTag::dim>::write(writer, vit->point());
00135 writer << std::endl;
00136 }
00137 writer << std::endl;
00138
00139
00140 std::size_t cellnum = viennagrid::ncells<CellTag::dim>(domain).size();
00141 writer << "object \"grid_Line_One\" class array type int rank 1 shape " << (CoordinateSystemTag::dim + 1) << " items " << cellnum << " data follows" << std::endl;
00142
00143 CellRange cells = viennagrid::ncells<CellTag::dim>(domain);
00144 for (CellIterator cit = cells.begin();
00145 cit != cells.end();
00146 ++cit)
00147 {
00148 VertexOnCellRange vertices_for_cell = viennagrid::ncells<0>(*cit);
00149 for (VertexOnCellIterator vocit = vertices_for_cell.begin();
00150 vocit != vertices_for_cell.end();
00151 ++vocit)
00152 {
00153 VertexType const & vertex = *vocit;
00154 writer << vertex.id() << " ";
00155 }
00156 writer << std::endl;
00157 }
00158
00159 writer << DXHelper::getAttributes() << std::endl;
00160 writer << "attribute \"ref\" string \"positions\" " << std::endl;
00161 writer << std::endl;
00162
00163
00164 writer.flags(std::ios::fixed);
00165 writer.precision(5);
00166
00167
00168 if (vertex_data_scalar.size() > 0)
00169 {
00170 writer << "object \"VisData\" class array items " << pointnum << " data follows" << std::endl;
00171
00172
00173 for (VertexIterator vit = vertices.begin();
00174 vit != vertices.end();
00175 ++vit)
00176 {
00177 std::string value = vertex_data_scalar[0](*vit);
00178 writer << DXfixer(atof(value.c_str()));
00179 writer << std::endl;
00180 }
00181
00182 writer << "attribute \"dep\" string \"positions\"" << std::endl;
00183 }
00184 else if (cell_data_scalar.size() > 0)
00185 {
00186 writer << "object \"VisData\" class array items " << cellnum << " data follows" << std::endl;
00187
00188
00189 for (CellIterator cit = cells.begin();
00190 cit != cells.end();
00191 ++cit)
00192 {
00193 std::string value = cell_data_scalar[0](*cit);
00194 writer << DXfixer(atof(value.c_str()));
00195 writer << std::endl;
00196 }
00197 writer << "attribute \"dep\" string \"connections\"" << std::endl;
00198 }
00199
00200 writer << std::endl;
00201 writer << "object \"AttPotential\" class field " << std::endl;
00202 writer << "component \"data\" \"VisData\" " << std::endl;
00203 writer << "component \"positions\" \"points\"" << std::endl;
00204 writer << "component \"connections\" \"grid_Line_One\"" << std::endl;
00205
00206 return EXIT_SUCCESS;
00207
00208 }
00209
00211 template <typename T>
00212 void add_scalar_data_on_vertices(T const & accessor, std::string name)
00213 {
00214 data_accessor_wrapper<VertexType> wrapper(accessor.clone());
00215 if (vertex_data_scalar.size() > 0)
00216 std::cout << "* ViennaGrid: Warning: OpenDX vertex data " << name
00217 << " will be ignored, because other data is already available!" << std::endl;
00218 vertex_data_scalar.push_back(wrapper);
00219 }
00220
00222 template <typename T>
00223 void add_scalar_data_on_cells(T const & accessor, std::string name)
00224 {
00225 data_accessor_wrapper<CellType> wrapper(accessor.clone());
00226
00227 if (cell_data_scalar.size() > 0)
00228 std::cout << "* ViennaGrid: Warning: OpenDX cell data " << name
00229 << " will be ignored, because other cell data is already available!" << std::endl;
00230
00231 if (vertex_data_scalar.size() > 0)
00232 std::cout << "* ViennaGrid: Warning: OpenDX cell data " << name
00233 << " will be ignored, because other vertex data is already available!" << std::endl;
00234
00235 cell_data_scalar.push_back(wrapper);
00236 }
00237
00238
00239 private:
00240 std::vector< data_accessor_wrapper<VertexType> > vertex_data_scalar;
00241 std::vector< data_accessor_wrapper<CellType> > cell_data_scalar;
00242
00243 };
00244
00245
00255 template <typename KeyType, typename DataType, typename DomainType>
00256 opendx_writer<DomainType> & add_scalar_data_on_vertices(opendx_writer<DomainType> & writer,
00257 KeyType const & key,
00258 std::string quantity_name)
00259 {
00260 typedef typename DomainType::config_type DomainConfiguration;
00261 typedef typename result_of::ncell<DomainConfiguration, 0>::type VertexType;
00262
00263 data_accessor_wrapper<VertexType> wrapper(new global_scalar_data_accessor<VertexType, KeyType, DataType>(key));
00264 writer.add_scalar_data_on_vertices(wrapper, quantity_name);
00265 return writer;
00266 }
00267
00277 template <typename KeyType, typename DataType, typename DomainType>
00278 opendx_writer<DomainType> & add_scalar_data_on_cells(opendx_writer<DomainType> & writer,
00279 KeyType const & key,
00280 std::string quantity_name)
00281 {
00282 typedef typename DomainType::config_type DomainConfiguration;
00283 typedef typename DomainConfiguration::cell_tag CellTag;
00284 typedef typename result_of::ncell<DomainConfiguration, CellTag::dim>::type CellType;
00285
00286 data_accessor_wrapper<CellType> wrapper(new global_scalar_data_accessor<CellType, KeyType, DataType>(key));
00287 writer.add_scalar_data_on_cells(wrapper, quantity_name);
00288 return writer;
00289 }
00290
00291
00292 }
00293 }
00294
00295 #endif
00296
00297