OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
VTKWriter_point_set.hpp
1 /*
2  * VTKWriter_point_set.hpp
3  *
4  * Created on: Feb 6, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_IO_SRC_VTKWRITER_POINT_SET_HPP_
9 #define OPENFPM_IO_SRC_VTKWRITER_POINT_SET_HPP_
10 
11 #include <cstddef>
12 #include <boost/mpl/pair.hpp>
13 #include "VTKWriter_grids_util.hpp"
14 #include "is_vtk_writable.hpp"
15 #include <string>
16 #include "byteswap_portable.hpp"
17 #include "MetaParser/MetaParser.hpp"
18 
24 template <typename Vps>
25 class ele_vps
26 {
27 public:
28 
30  typedef Vps value_type;
31 
33  const Vps & g;
34 
36  size_t mark;
37 
39  ele_vps(const Vps & g, size_t mark)
40  :g(g),mark(mark)
41  {}
42 
43 };
44 
50 template <typename Vpp>
51 class ele_vpp
52 {
53 public:
54 
56  typedef Vpp value_type;
57 
58 
60  const Vpp & g;
61 
63  size_t mark;
64 
66  ele_vpp(const Vpp & vpp, size_t mark)
67  :g(vpp),mark(mark)
68  {}
69 
70 };
71 
72 
83 template<typename ele_v, typename St>
84 struct prop_out_v
85 {
87  file_type ft;
88 
90  std::string & v_out;
91 
94 
97 
105  prop_out_v(std::string & v_out,
108  file_type ft)
110  {};
111 
117  template<typename T>
118  void operator()(T& t) const
119  {
120  typedef typename boost::mpl::at<typename ele_v::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype;
121  typedef typename std::remove_all_extents<ptype>::type base_ptype;
122 
124  }
125 
126  void lastProp()
127  {
128  std::string v_outToEncode,v_Encoded;
129  // Create point data properties
130  //v_out += "SCALARS domain float\n";
131  // Default lookup table
132  //v_out += "LOOKUP_TABLE default\n";
133  v_out += " <DataArray type=\"Float32\" Name=\"domain\"";
134  if (ft == file_type::ASCII) {
135  v_out += " format=\"ascii\">\n";
136  }
137  else {
138  v_out += " format=\"binary\">\n";
139  }
140 
141  if (ft == file_type::BINARY) {
142  v_outToEncode.append(8,0);
143  }
144  // Produce point data
145  for (size_t k = 0 ; k < vv.size() ; k++)
146  {
148  auto it = vv.get(k).g.getIterator();
149 
150  // if there is the next element
151  while (it.isNext())
152  {
153  if (ft == file_type::ASCII)
154  {
155  if (it.get() < vv.get(k).mark)
156  v_outToEncode += "1.0\n";
157  else
158  v_outToEncode += "0.0\n";
159  }
160  else
161  {
162  if (it.get() < vv.get(k).mark)
163  {
164  float one = 1;
165  //one = swap_endian_lt(one);
166  v_outToEncode.append((const char *)&one,sizeof(int));
167  }
168  else
169  {
170  float zero = 0;
171  //zero = swap_endian_lt(zero);
172  v_outToEncode.append((const char *)&zero,sizeof(int));
173  }
174  }
175 
176  // increment the iterator and counter
177  ++it;
178  }
179  }
180  if (ft == file_type::BINARY)
181  {
182  *(size_t *) &v_outToEncode[0] = v_outToEncode.size()-sizeof(size_t);
183  v_Encoded.resize(v_outToEncode.size()/3*4+4);
184  size_t sz=EncodeToBase64((const unsigned char*)&v_outToEncode[0],v_outToEncode.size(),(unsigned char *)&v_Encoded[0],0);
185  v_Encoded.resize(sz);
186  v_out += v_Encoded + "\n";
187  }
188  else{
189  v_out += v_outToEncode;
190  };
191  v_out+=" </DataArray>\n";
192  }
193 
194 };
195 
196 
207 template<typename ele_v, typename St>
209 {
211  std::string & v_out;
212 
215 
223  prop_out_v_pvtp(std::string & v_out,
226  {
227  //meta_prop_new<boost::mpl::int_<T::value> ,ele_v,St, ptype, is_vtk_writable<base_ptype>::value > m(vv,v_out,prop_names,ft);
228  };
229 
235  template<typename T>
236  void operator()(T& t) const
237  {
238  typedef typename boost::mpl::at<typename ele_v::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype;
239  typedef typename std::remove_all_extents<ptype>::type base_ptype;
240 
241  //std::string type = getTypeNew<base_ptype>();
243  //v_out += " <PDataArray type=\""+type+"\" Name=\""+getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp)+"\""+" NumberOfComponents=\"3\"";
244  }
245 
246 
247  void lastProp()
248  {
249  v_out += " <PDataArray type=\"Float32\" Name=\"domain\"/>\n </PPointData>\n";
250  }
251 };
252 
263 template <typename pair>
264 class VTKWriter<pair,VECTOR_POINTS>
265 {
270 
276  size_t get_total()
277  {
278  size_t tot = 0;
279 
281  for (size_t i = 0 ; i < vps.size() ; i++)
282  {
283  tot += vps.get(i).g.size();
284  }
285  return tot;
286  }
287 
295  std::string get_vertex_properties_list(file_type & opt)
296  {
298  std::string v_out;
299 
300  v_out += " <Verts>\n";
301  if (opt == file_type::ASCII)
302 
303  {
304  v_out+=" <DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\">\n";
305  }
306  else
307  {
308  v_out+=" <DataArray type=\"Int64\" Name=\"connectivity\" format=\"binary\">\n";
309  }
310 
311  // write the number of vertex
312  //v_out += "VERTICES " + std::to_string(get_total()) + " " + std::to_string(get_total() * 2) + "\n";
313  // return the vertex properties string
314  return v_out;
315  }
316 
324  std::string get_point_properties_list(file_type ft)
325  {
327  std::string v_out;
328 
329  // write the number of vertex
330 
331  v_out += " <Piece NumberOfPoints=\"" + std::to_string(get_total()) + "\" " +"NumberOfVerts=\"" + std::to_string(get_total()) + "\">\n";
332 
333  // return the vertex properties string
334  return v_out;
335  }
336 
344  std::string get_point_list(file_type & opt)
345  {
347  std::stringstream v_out;
348 
349  v_out<<" <Points>\n";
350 
351  if (std::is_same<float,typename pair::first::value_type::coord_type>::value == true)
352  {
353  if (opt == file_type::ASCII)
354  {
355  v_out<<" <DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\">\n";
356  }
357  else
358  {
359  v_out<<" <DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"binary\">\n";
360  }
361  }
362  else
363  {
364  if (opt == file_type::ASCII)
365  {
366  v_out<<" <DataArray type=\"Float64\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\">\n";
367  }
368  else
369  {
370  v_out<<" <DataArray type=\"Float64\" Name=\"Points\" NumberOfComponents=\"3\" format=\"binary\">\n";
371  }
372  }
373 
374  std::stringstream binaryToEncode;
375  if (std::is_same<float,typename pair::first::value_type::coord_type>::value == true)
376  {
377  binaryToEncode << std::setprecision(7);
378  }
379  else
380  {
381  binaryToEncode << std::setprecision(16);
382  }
383 
385  if (opt == file_type::BINARY)
386  {
387  size_t tmp=0;
388  binaryToEncode.write((const char *)&tmp,sizeof(tmp));
389  }
390 
391  for (size_t i = 0 ; i < vps.size() ; i++)
392  {
394  auto it = vps.get(i).g.getIterator();
395 
396  // if there is the next element
397  while (it.isNext())
398  {
400  p = vps.get(i).g.get(it.get());
401 
402  output_point_new<pair::first::value_type::dims,typename pair::first::value_type::coord_type>(p,binaryToEncode,opt);
403 
404  // increment the iterator and counter
405  ++it;
406  }
407  }
409  if (opt == file_type::BINARY){
410  std::string buffer_out,buffer_bin;
411  buffer_bin=binaryToEncode.str();
412  *(size_t *)&buffer_bin[0]=buffer_bin.size()-8;
413  buffer_out.resize(buffer_bin.size()/3*4+4);
414  unsigned long sz = EncodeToBase64((const unsigned char*)&buffer_bin[0],buffer_bin.size(),(unsigned char*)&buffer_out[0],0);
415  buffer_out.resize(sz);
416  v_out << buffer_out<<std::endl;
417  }
418  else
419  {
420  v_out<<binaryToEncode.str();
421  }
422  v_out<<" </DataArray>\n";
423  v_out<<" </Points>\n";
424  // return the vertex list
425  return v_out.str();
426  }
427 
435  std::string get_vertex_list(file_type ft)
436  {
437  // vertex node output string
438  std::string v_out,v_outToEncode,v_Encoded;
439 
440  size_t k = 0;
441  if (ft == file_type::BINARY) {
442  v_outToEncode.append(8,0);
443  }
444  for (size_t i = 0 ; i < vps.size() ; i++)
445  {
447  auto it = vps.get(i).g.getIterator();
448 
449  while (it.isNext())
450  {
451  output_vertex_new(k,v_outToEncode,ft);
452 
453  ++k;
454  ++it;
455  }
456  }
458  if (ft == file_type::BINARY)
459  {
460  *(size_t *) &v_outToEncode[0] = v_outToEncode.size()-sizeof(size_t);
461  v_Encoded.resize(v_outToEncode.size()/3*4+4);
462  size_t sz=EncodeToBase64((const unsigned char*)&v_outToEncode[0],v_outToEncode.size(),(unsigned char *)&v_Encoded[0],0);
463  v_Encoded.resize(sz);
464  v_out += v_Encoded + "\n";
465  }
466  else{
467  v_out += v_outToEncode;
468  };
469  v_out += " </DataArray>\n";
470  v_out += " <DataArray type=\"Int64\" Name=\"offsets\" ";
471 
472  if (ft == file_type::ASCII)
473  {
474  v_out += "format=\"ascii\">\n";
475  }
476  else{
477  v_out += "format=\"binary\">\n";
478  }
479 
480  k=0;
481  v_outToEncode.clear();
482  if (ft == file_type::BINARY) {
483  v_outToEncode.append(8,0);
484  }
485 
486  for (size_t i = 0 ; i < vps.size() ; i++)
487  {
489  auto it = vps.get(i).g.getIterator();
490  while (it.isNext())
491  {
492  output_vertex_new(k+1,v_outToEncode,ft);
493 
494  ++k;
495  ++it;
496  }
497  }
498  if (ft == file_type::BINARY)
499  {
500  *(size_t *) &v_outToEncode[0] = v_outToEncode.size()-sizeof(size_t);
501  v_Encoded.resize(v_outToEncode.size()/3*4+4);
502  size_t sz=EncodeToBase64((const unsigned char*)&v_outToEncode[0],v_outToEncode.size(),(unsigned char *)&v_Encoded[0],0);
503  v_Encoded.resize(sz);
504  v_out += v_Encoded + "\n";
505  }
506  else{
507  v_out += v_outToEncode;
508  };
509  v_out += " </DataArray>\n";
510  v_out += " </Verts>\n";
511  // return the vertex list
512  return v_out;
513  }
514 
520  std::string get_point_data_header()
521  {
522  std::string v_out;
523 
524  v_out += " <PointData>\n";
525 
526  return v_out;
527  }
528  struct doubleint{
529  long int i;
530  double d;
531  };
537  std::string add_meta_data(std::string & meta_data, file_type & opt)
538  {
539  std::string meta_string;
540 
541  // check for time metadata
542  MetaParser_options opts;
543  opts.add_options()
544  ("time", MetaParser_def::value<double>());
545 
546  MetaParser mp(opts);
547  mp.parse(meta_data);
548 
549  double time = 0.0;
550  bool exist = mp.getOption("time",time);
551 
552  if (exist == true)
553  {
554  //<DataArray type="Float64" Name="TimeValue" NumberOfTuples="1" format="ascii" RangeMin="2" RangeMax="2">
555  //meta_string += "";
556  meta_string += " <FieldData>\n";
557 
558  if (opt == file_type::ASCII)
559  { meta_string += " <DataArray type=\"Float64\" Name=\"TimeValue\" NumberOfTuples=\"1\" format=\"ascii\">\n";
560  meta_string += std::to_string(time);
561  }
562  else
563  {
564  meta_string += " <DataArray type=\"Float64\" Name=\"TimeValue\" NumberOfTuples=\"1\" format=\"binary\">\n";
565 
566  //time = swap_endian_lt(time);
567  unsigned char time_string[24];//= base64_encode((const unsigned char*)&time,6);
568  //const unsigned char Time=(const unsigned char)time;
569  doubleint timeInit;
570  timeInit.i=8;
571  timeInit.d=time;
572  size_t sz=EncodeToBase64((const unsigned char*)&timeInit,16,time_string,0);
573  //meta_string.append((const char *)&time,sizeof(double));
574  //meta_string += time_string;
575  meta_string.append((const char *)time_string,sz);
576  }
577  meta_string += "\n";
578  meta_string += " </DataArray>\n";
579  meta_string += " </FieldData>\n";
580  }
581 
582 
583  return meta_string;
584  }
585 
586 public:
587 
594  {}
595 
604  void add(const typename pair::first & vps,
605  const typename pair::second & vpp,
606  size_t mark)
607  {
610 
611  this->vps.add(t1);
612  this->vpp.add(t2);
613  }
614 
622  bool write_pvtp(std::string file,const openfpm::vector<std::string> & prop_names,size_t n,long int timestamp=-1)
623  {
624  //openfpm::vector< ele_vpp<typename pair::second>> vpp;
625  // Header for the vtk
626  std::string vtk_header;
627  std::string Name_data;
628  std::string PpointEnd;
629  std::string Piece;
630 
631  vtk_header = "<VTKFile type=\"PPolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n <PPolyData>\n <PPointData>\n";
632  prop_out_v_pvtp< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(Name_data,prop_names);
633  boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp);
634  pp.lastProp();
635  PpointEnd += " <PPoints>\n <PDataArray type=\""+getTypeNew<typename decltype(vps)::value_type::value_type::value_type::coord_type>()+"\" Name=\"Points\" NumberOfComponents=\"3\"/>\n </PPoints>\n";
636 
637 
638  if (timestamp==-1) {
639  for (int i = 0; i < n; i++)
640  { Piece += " <Piece Source=\"" + file.substr(0, file.size()) + "_" +std::to_string(i) + ".vtp\"/>\n";}
641  file += ".pvtp";
642  }
643  else{
644  for (int i = 0; i < n; i++)
645  { Piece += " <Piece Source=\"" + file.substr(0, file.size()) + "_" +std::to_string(i) + "_" + std::to_string(timestamp) + ".vtp\"/>\n";}
646  file += "_" + std::to_string(timestamp) + ".pvtp";
647  }
648  std::string closingFile=" </PPolyData>\n</VTKFile>";
649 
650  // write the file
651  std::ofstream ofs(file);
652 
653  // Check if the file is open
654  if (ofs.is_open() == false)
655  {std::cerr << "Error cannot create the PVTP file: " + file + "\n";}
656 
657  ofs << vtk_header << Name_data <<PpointEnd<< Piece << closingFile;
658 
659  // Close the file
660 
661  ofs.close();
662 
663  return true;
664  }
665 
678  template<int prp = -1> bool write(std::string file,
679  const openfpm::vector<std::string> & prop_names,
680  std::string f_name = "points" ,
681  std::string meta_data = "",
682  file_type ft = file_type::ASCII)
683  {
684  // Header for the vtk
685  std::string vtk_header;
686  // Point list of the VTK
687  std::string point_list;
688  // Vertex list of the VTK
689  std::string vertex_list;
690  // Graph header
691  std::string vtk_binary_or_ascii;
692  // vertex properties header
693  std::string point_prop_header;
694  // edge properties header
695  std::string vertex_prop_header;
696  // Data point header
697  std::string point_data_header;
698  // Data point
699  std::string point_data;
700 
701  // VTK header
702  vtk_header = "<VTKFile type=\"PolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n";
703 
704  vtk_header +=" <PolyData>\n";
705 
706  // Choose if binary or ASCII
707 /* if (ft == file_type::ASCII)
708  {vtk_header += "ASCII\n";}
709  else
710  {vtk_header += "BINARY\n";}*/
711 
712  // Data type for graph is DATASET POLYDATA
713  //vtk_header += "DATASET POLYDATA\n";
714 
715  vtk_header += add_meta_data(meta_data,ft);
716 
717  // point properties header
718  point_prop_header = get_point_properties_list(ft);
719 
720  // Get point list
721  point_list = get_point_list(ft);
722 
723  // vertex properties header
724  vertex_prop_header = get_vertex_properties_list(ft);
725 
726  // Get vertex list
727  vertex_list = get_vertex_list(ft);
728 
729  // Get the point data header
730  point_data_header = get_point_data_header();
731 
732  // For each property in the vertex type produce a point data
733 
734  prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, prop_names,ft);
735 
736  if (prp == -1)
737  {boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp);}
738  else
739  {boost::mpl::for_each< boost::mpl::range_c<int,prp, prp> >(pp);}
740 
741  // Add the last property
742  pp.lastProp();
743 
744  std::string closingFile=" </PointData>\n </Piece>\n </PolyData>\n</VTKFile>";
745 
746  // write the file
747  std::ofstream ofs(file);
748 
749  // Check if the file is open
750  if (ofs.is_open() == false)
751  {std::cerr << "Error cannot create the VTK file: " + file + "\n";}
752 
753  ofs << vtk_header << point_prop_header << point_list <<
754  vertex_prop_header << vertex_list << point_data_header << point_data << closingFile;
755 
756  // Close the file
757 
758  ofs.close();
759 
760  // Completed succefully
761  return true;
762  }
763 };
764 
765 
766 #endif /* OPENFPM_IO_SRC_VTKWRITER_POINT_SET_HPP_ */
file_type ft
Binary or ASCII.
this class is a functor for "for_each" algorithm
openfpm::vector< ele_vpp< typename pair::second > > vpp
Vector of properties.
const Vps & g
particle position vector
prop_out_v_pvtp(std::string &v_out, const openfpm::vector< std::string > &prop_names)
constructor
openfpm::vector< ele_vps< typename pair::first > > vps
Vector of position.
ele_vpp(const Vpp &vpp, size_t mark)
constructor
std::string get_point_list(file_type &opt)
Create the VTK point list.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
Store a reference to the vector position.
size_t size()
Stub size.
Definition: map_vector.hpp:211
const openfpm::vector_std< ele_v > & vv
vector that we are processing
const openfpm::vector< std::string > & prop_names
properties names
void operator()(T &t) const
It produce an output for each property.
std::string get_vertex_properties_list(file_type &opt)
It get the vertex properties list.
this class is a functor for "for_each" algorithm
bool write(std::string file, const openfpm::vector< std::string > &prop_names, std::string f_name="points", std::string meta_data="", file_type ft=file_type::ASCII)
It write a VTK file from a vector of points.
ele_vps(const Vps &g, size_t mark)
constructor
It model an expression expr1 * expr2.
Definition: mul.hpp:119
std::string get_point_properties_list(file_type ft)
It get the point position header string.
std::string get_point_data_header()
Get the point data header.
std::string get_vertex_list(file_type ft)
Create the VTK vertex list.
Store a reference to the vector properties.
Vps value_type
type of vector that store the particle position
size_t mark
ghost marker
const Vpp & g
Reference to the particle properties.
std::string & v_out
property output string
bool parse(std::string &opts)
Parse the string of options.
Definition: MetaParser.hpp:42
size_t get_total()
Get the total number of points.
This class is an helper to create properties output from scalar and compile-time array elements.
size_t mark
ghost marker
bool getOption(std::string opt, T &value)
Return the option opt in value.
Definition: MetaParser.hpp:62
Vpp value_type
type of vector that store the particle properties
void operator()(T &t) const
It produce an output for each property.
std::string add_meta_data(std::string &meta_data, file_type &opt)
return the meta data string
prop_out_v(std::string &v_out, const openfpm::vector_std< ele_v > &vv, const openfpm::vector< std::string > &prop_names, file_type ft)
constructor
std::string & v_out
property output string
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
bool write_pvtp(std::string file, const openfpm::vector< std::string > &prop_names, size_t n, long int timestamp=-1)
It write a Merged VTP type file from a vector of points.
void add(const typename pair::first &vps, const typename pair::second &vpp, size_t mark)
Add a vector dataset.
const openfpm::vector< std::string > & prop_names
properties names
check for T to be writable