OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
24template <typename Vps>
26{
27public:
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
50template <typename Vpp>
52{
53public:
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
83template<typename ele_v, typename St>
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
207template<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 {
249v_out += " <PDataArray type=\"Float32\" Name=\"domain\"/>\n </PPointData>\n";
250 }
251};
252
263template <typename pair>
264class 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
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
586public:
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,double time=-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 if(time==-1){
631 vtk_header = "<VTKFile type=\"PPolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n <PPolyData>\n <PPointData>\n";
632 }
633 else{
634 vtk_header = "<VTKFile type=\"PPolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n <PPolyData>\n <FieldData> \n <DataArray type=\"Float64\" Name=\"TimeValue\" NumberOfTuples=\"1\" format=\"ASCII\">\n "+std::to_string(time)+"\n </DataArray>\n </FieldData>\n <PPointData>\n";
635 }
636 prop_out_v_pvtp< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(Name_data,prop_names);
637 boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp);
638 pp.lastProp();
639 PpointEnd += " <PPoints>\n <PDataArray type=\""+getTypeNew<typename decltype(vps)::value_type::value_type::value_type::coord_type>()+"\" Name=\"Points\" NumberOfComponents=\"3\"/>\n </PPoints>\n";
640
641
642 if (timestamp==-1) {
643 for (int i = 0; i < n; i++)
644 { Piece += " <Piece Source=\"" + file.substr(0, file.size()) + "_" +std::to_string(i) + ".vtp\"/>\n";}
645 file += ".pvtp";
646 }
647 else{
648 for (int i = 0; i < n; i++)
649 { Piece += " <Piece Source=\"" + file.substr(0, file.size()) + "_" +std::to_string(i) + "_" + std::to_string(timestamp) + ".vtp\"/>\n";}
650 file += "_" + std::to_string(timestamp) + ".pvtp";
651 }
652 std::string closingFile=" </PPolyData>\n</VTKFile>";
653
654 // write the file
655 std::ofstream ofs(file);
656
657 // Check if the file is open
658 if (ofs.is_open() == false)
659 {std::cerr << "Error cannot create the PVTP file: " + file + "\n";}
660
661 ofs << vtk_header << Name_data <<PpointEnd<< Piece << closingFile;
662
663 // Close the file
664
665 ofs.close();
666
667 return true;
668 }
669
682 template<int prp = -1> bool write(std::string file,
683 const openfpm::vector<std::string> & prop_names,
684 std::string f_name = "points" ,
685 std::string meta_data = "",
686 file_type ft = file_type::ASCII)
687 {
688 // Header for the vtk
689 std::string vtk_header;
690 // Point list of the VTK
691 std::string point_list;
692 // Vertex list of the VTK
693 std::string vertex_list;
694 // Graph header
695 std::string vtk_binary_or_ascii;
696 // vertex properties header
697 std::string point_prop_header;
698 // edge properties header
699 std::string vertex_prop_header;
700 // Data point header
701 std::string point_data_header;
702 // Data point
703 std::string point_data;
704
705 // VTK header
706 vtk_header = "<VTKFile type=\"PolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n";
707
708 vtk_header +=" <PolyData>\n";
709
710 // Choose if binary or ASCII
711/* if (ft == file_type::ASCII)
712 {vtk_header += "ASCII\n";}
713 else
714 {vtk_header += "BINARY\n";}*/
715
716 // Data type for graph is DATASET POLYDATA
717 //vtk_header += "DATASET POLYDATA\n";
718
719 vtk_header += add_meta_data(meta_data,ft);
720
721 // point properties header
722 point_prop_header = get_point_properties_list(ft);
723
724 // Get point list
725 point_list = get_point_list(ft);
726
727 // vertex properties header
728 vertex_prop_header = get_vertex_properties_list(ft);
729
730 // Get vertex list
731 vertex_list = get_vertex_list(ft);
732
733 // Get the point data header
734 point_data_header = get_point_data_header();
735
736 // For each property in the vertex type produce a point data
737
738 prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, prop_names,ft);
739
740 if (prp == -1)
741 {boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp);}
742 else
743 {boost::mpl::for_each< boost::mpl::range_c<int,prp, prp> >(pp);}
744
745 // Add the last property
746 pp.lastProp();
747
748 std::string closingFile=" </PointData>\n </Piece>\n </PolyData>\n</VTKFile>";
749
750 // write the file
751 std::ofstream ofs(file);
752
753 // Check if the file is open
754 if (ofs.is_open() == false)
755 {std::cerr << "Error cannot create the VTK file: " + file + "\n";}
756
757 ofs << vtk_header << point_prop_header << point_list <<
758 vertex_prop_header << vertex_list << point_data_header << point_data << closingFile;
759
760 // Close the file
761
762 ofs.close();
763
764 // Completed succefully
765 return true;
766 }
767};
768
769
770#endif /* OPENFPM_IO_SRC_VTKWRITER_POINT_SET_HPP_ */
bool getOption(std::string opt, T &value)
Return the option opt in value.
bool parse(std::string &opts)
Parse the string of options.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
std::string get_vertex_properties_list(file_type &opt)
It get the vertex properties list.
bool write_pvtp(std::string file, const openfpm::vector< std::string > &prop_names, size_t n, long int timestamp=-1, double time=-1)
It write a Merged VTP type file from a vector of points.
std::string get_point_list(file_type &opt)
Create the VTK point list.
size_t get_total()
Get the total number of points.
std::string add_meta_data(std::string &meta_data, file_type &opt)
return the meta data string
std::string get_point_properties_list(file_type ft)
It get the point position header string.
openfpm::vector< ele_vps< typename pair::first > > vps
Vector of position.
void add(const typename pair::first &vps, const typename pair::second &vpp, size_t mark)
Add a vector dataset.
std::string get_vertex_list(file_type ft)
Create the VTK vertex list.
openfpm::vector< ele_vpp< typename pair::second > > vpp
Vector of properties.
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.
std::string get_point_data_header()
Get the point data header.
Store a reference to the vector properties.
const Vpp & g
Reference to the particle properties.
ele_vpp(const Vpp &vpp, size_t mark)
constructor
size_t mark
ghost marker
Vpp value_type
type of vector that store the particle properties
Store a reference to the vector position.
ele_vps(const Vps &g, size_t mark)
constructor
const Vps & g
particle position vector
size_t mark
ghost marker
Vps value_type
type of vector that store the particle position
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
check for T to be writable
This class is an helper to create properties output from scalar and compile-time array elements.
It model an expression expr1 * expr2.
Definition mul.hpp:120
this class is a functor for "for_each" algorithm
std::string & v_out
property output string
void operator()(T &t) const
It produce an output for each property.
const openfpm::vector< std::string > & prop_names
properties names
prop_out_v_pvtp(std::string &v_out, const openfpm::vector< std::string > &prop_names)
constructor
this class is a functor for "for_each" algorithm
file_type ft
Binary or ASCII.
void operator()(T &t) const
It produce an output for each property.
const openfpm::vector< std::string > & prop_names
properties names
std::string & v_out
property output string
const openfpm::vector_std< ele_v > & vv
vector that we are processing
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