OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
VTKWriter_grids_st.hpp
1 /*
2  * VTKWriter_grids_st.hpp
3  *
4  * Created on: Sep 3, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #ifndef SRC_VTKWRITER_GRIDS_ST_HPP_
9 #define SRC_VTKWRITER_GRIDS_ST_HPP_
10 
11 
12 #include <boost/mpl/pair.hpp>
13 #include "VTKWriter_grids_util.hpp"
14 #include "util/util_debug.hpp"
15 #include "util/convert.hpp"
16 
22 template <typename Grid>
23 struct cell_grid
24 {
27 
31 
32  cell_grid() {}
33 
40  :cmb(cmb)
41  {}
42 
49  {
50  this->operator=(cg);
51  }
52 
59  {
60  this->operator=(cg);
61  }
62 
71  {
72  cmb = cg.cmb;
73  grids = cg.grids;
74 
75  return *this;
76  }
77 
86  {
87  cmb = cg.cmb;
88  grids = cg.grids;
89 
90  return *this;
91  }
92 };
93 
100 template <typename Grid, typename St>
101 class ele_g_st
102 {
103 public:
104 
106  typedef Grid value_type;
107 
109  ele_g_st(){};
110 
120  const Box<Grid::dims,St> & dom)
122  {}
123 
125  std::string dataset;
134 
140  inline ele_g_st(const ele_g_st & ele)
141  {
142  this->operator=(ele);
143  }
144 
150  inline ele_g_st(ele_g_st && ele)
151  {
152  this->operator=(ele);
153  }
154 
163  {
164  dataset = ele.dataset;
165  g = ele.g;
166  offset = ele.offset;
167  spacing = ele.spacing;
168  dom = ele.dom;
169 
170  return *this;
171  }
172 
181  {
182  dataset = ele.dataset;
183  g = ele.g;
184  offset = ele.offset;
185  spacing = ele.spacing;
186  dom = ele.dom;
187 
188  return *this;
189  }
190 };
191 
201 template <typename pair>
202 class VTKWriter<pair,VECTOR_ST_GRIDS>
203 {
206 
212  size_t get_total()
213  {
214  size_t tot = 0;
215 
217  for (size_t i = 0 ; i < vg.size() ; i++)
218  {
219  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
220  {
221  if (vg.get(i).g.get(j).grids.size() != 0)
222  tot += vg.get(i).g.get(j).grids.get(0)->size();
223  }
224  }
225  return tot;
226  }
227 
237  {
239  std::string v_out;
240 
241  // write the number of vertex
242  v_out += "VERTICES " + std::to_string(get_total()) + " " + std::to_string(get_total() * 2) + "\n";
243 
244  // return the vertex properties string
245  return v_out;
246  }
247 
257  {
259  std::string v_out;
260 
261  // write the number of vertex
262  v_out += "POINTS " + std::to_string(get_total()) + " float" + "\n";
263 
264  // return the vertex properties string
265  return v_out;
266  }
267 
273  std::string get_point_list()
274  {
276  std::stringstream v_out;
277 
279  for (size_t i = 0 ; i < vg.size() ; i++)
280  {
281  // For each position in the cell
282  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
283  {
284  // If there are no grid in this position
285  if (vg.get(i).g.get(j).grids.size() == 0)
286  continue;
287 
289  auto it = vg.get(i).g.get(j).grids.get(0)->getIterator();
290 
293 
294  // Calculate the offset of the grid considering its cell position
295  Point<pair::first::dims,typename pair::second> middle = vg.get(i).spacing / 2;
297  one.one();
298  one = one + toPoint<pair::first::dims,typename pair::second>::convert(vg.get(i).g.get(j).cmb);
299  Point<pair::first::dims,typename pair::second> offset = pmul(middle,one) + vg.get(i).offset;
300 
301  // if there is the next element
302  while (it.isNext())
303  {
305  p = it.get().toPoint();
306  p = pmul(p,vg.get(i).spacing) + offset;
307 
308  if (pair::first::dims == 2)
309  v_out << p.toString() << " 0.0" << "\n";
310  else
311  v_out << p.toString() << "\n";
312 
313  // increment the iterator
314  ++it;
315  }
316  }
317  }
318 
319  // return the vertex list
320  return v_out.str();
321  }
322 
330  std::string get_prop_components(size_t k)
331  {
332  std::stringstream v_out;
333 
335  for (size_t i = 0 ; i < vg.size() ; i++)
336  {
337  // For each position in the cell
338  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
339  {
340  if (k < vg.get(i).g.get(j).grids.size())
341  {
342  // get the combination string
343  v_out << vg.get(i).g.get(j).cmb.to_string();
344  }
345  }
346  }
347 
348  return v_out.str();
349  }
350 
359  std::string get_properties_output(size_t k, std::string prop_name)
360  {
362  std::stringstream v_out;
363 
364  // Check if T is a supported format
365  // for now we support only scalar of native type
366 
367  typedef typename boost::mpl::at<typename pair::first::value_type::type,boost::mpl::int_<0>>::type ctype;
368 
369  std::string type = getType<ctype>();
370 
371  // if the type is not supported return
372  if (type.size() == 0)
373  {
374 #ifndef DISABLE_ALL_RTTI
375  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the type " << demangle(typeid(ctype).name()) << " is not supported by vtk\n";
376 #endif
377  return "";
378  }
379 
380  std::string prp_cp = get_prop_components(k);
381 
382  // Create point data properties
383  v_out << "SCALARS " << prop_name << "_" << prp_cp << " " << type + "\n";
384 
385  // Default lookup table
386  v_out << "LOOKUP_TABLE default\n";
387 
389  for (size_t i = 0 ; i < vg.size() ; i++)
390  {
391  // For each position in the cell
392  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
393  {
394  // If there are no grid in this position
395  if (vg.get(i).g.get(j).grids.size() == 0)
396  continue;
397 
398  if (k < vg.get(i).g.get(j).grids.size())
399  {
400  // Grid source
401  auto & g_src = *vg.get(i).g.get(j).grids.get(k);
402 
404  auto it = g_src.getIterator();
405 
408 
409  // if there is the next element
410  while (it.isNext())
411  {
412  auto key = it.get();
413 
414  v_out << std::to_string(g_src.template get<0>(key)) << "\n";
415 
416  // increment the iterator
417  ++it;
418  }
419  }
420  else
421  {
422  // Grid source
423  auto & g_src = *vg.get(i).g.get(j).grids.get(0);
424 
426  auto it = g_src.getIterator();
427 
430 
431  // if there is the next element
432  while (it.isNext())
433  {
434  v_out << "0\n";
435 
436  // increment the iterator
437  ++it;
438  }
439  }
440  }
441  }
442 
443  // return the vertex list
444  return v_out.str();
445  }
446 
452  std::string lastProp()
453  {
455  std::stringstream v_out;
456 
457  // Create point data properties
458  v_out << "SCALARS domain float\n";
459 
460  // Default lookup table
461  v_out << "LOOKUP_TABLE default\n";
462 
464  for (size_t i = 0 ; i < vg.size() ; i++)
465  {
466  // For each position in the cell
467  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
468  {
469  // If there are no grid in this position
470  if (vg.get(i).g.get(j).grids.size() == 0)
471  continue;
472 
474  auto it = vg.get(i).g.get(j).grids.get(0)->getIterator();
475 
476  // if there is the next element
477  while (it.isNext())
478  {
479  if (vg.get(i).dom.isInside(it.get().toPoint()) == true)
480  v_out << "1.0\n";
481  else
482  v_out << "0.0\n";
483 
484  // increment the iterator and counter
485  ++it;
486  }
487  }
488  }
489 
490  return v_out.str();
491  }
492 
498  size_t getMaxFused()
499  {
500  size_t max = 0;
501 
503  for (size_t i = 0 ; i < vg.size() ; i++)
504  {
505  // For each position in the cell
506  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
507  {
508  // If there are no grid in this position
509  if (vg.get(i).g.get(j).grids.size() > max)
510  max = vg.get(i).g.get(j).grids.size();
511  }
512  }
513 
514  return max;
515  }
516 
522  std::string get_vertex_list()
523  {
525  std::string v_out;
526 
527  size_t k = 0;
528 
530  for (size_t i = 0 ; i < vg.size() ; i++)
531  {
532  // For each position in the cell
533  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
534  {
535  // If there are no grid in this position
536  if (vg.get(i).g.get(j).grids.size() == 0)
537  continue;
539  auto it = vg.get(i).g.get(j).grids.get(0)->getIterator();
540 
541  while (it.isNext())
542  {
543  v_out += "1 " + std::to_string(k) + "\n";
544 
545  ++k;
546  ++it;
547  }
548  }
549  }
550  // return the vertex list
551  return v_out;
552  }
553 
560  std::string get_point_data_header()
561  {
562  std::string v_out;
563 
564  v_out += "POINT_DATA " + std::to_string(get_total()) + "\n";
565 
566  return v_out;
567  }
568 
579  void append_grid(size_t id, const typename pair::first & g, const comb<pair::first::dims> & cmb)
580  {
581  for(size_t i = 0 ; i < vg.get(id).g.size() ; i++)
582  {
583  // for each defined grid if exist the combination fuse
584  if (cmb == vg.get(id).g.get(i).cmb)
585  {
586  vg.get(id).g.get(i).grids.add(&g);
587  return;
588  }
589  }
590 
591  // if the combination does not exist add the grid
593  vg.get(id).g.add(cg);
594  vg.get(id).g.last().grids.add(&g);
595  }
596 
597 public:
598 
605  {}
606 
617  void add(size_t i,
618  const typename pair::first & g,
622  const comb<pair::first::dims> & cmb)
623  {
625  if (i >= vg.size())
626  vg.resize(i+1);
627 
628  vg.get(i).offset = offset;
629  vg.get(i).spacing = spacing;
630  vg.get(i).dom = dom;
631 
632  // append the grid
633  append_grid(i,g,cmb);
634  }
635 
648  template<int prp = -1> bool write(std::string file,
649  std::string g_name = "grids",
650  file_type ft = file_type::ASCII)
651  {
652  // Header for the vtk
653  std::string vtk_header;
654  // Point list of the VTK
655  std::string point_list;
656  // Vertex list of the VTK
657  std::string vertex_list;
658  // Graph header
659  std::string vtk_binary_or_ascii;
660  // vertex properties header
661  std::string point_prop_header;
662  // edge properties header
663  std::string vertex_prop_header;
664  // Data point header
665  std::string point_data_header;
666  // Data point
667  std::string point_data;
668 
669  // VTK header
670  vtk_header = "# vtk DataFile Version 3.0\n"
671  + g_name + "\n";
672 
673  // Choose if binary or ASCII
674  if (ft == file_type::ASCII)
675  {vtk_header += "ASCII\n";}
676  else
677  {vtk_header += "BINARY\n";}
678 
679  // Data type for graph is DATASET POLYDATA
680  vtk_header += "DATASET POLYDATA\n";
681 
682  // point properties header
683  point_prop_header = get_point_properties_list();
684 
685  // Get point list
686  point_list = get_point_list();
687 
688  // vertex properties header
689  vertex_prop_header = get_vertex_properties_list();
690 
691  // Get vertex list
692  vertex_list = get_vertex_list();
693 
694  // Get the point data header
695  point_data_header = get_point_data_header();
696 
697  // Get the maximum number of fused grids
698  size_t mf = getMaxFused();
699 
700  // For each property in the vertex type produce a point data
701  for (size_t i = 0 ; i < mf ; i++)
702  point_data += get_properties_output(i,g_name);
703 
704  lastProp();
705 
706 
707  // write the file
708  std::ofstream ofs(file);
709 
710  // Check if the file is open
711  if (ofs.is_open() == false)
712  {std::cerr << "Error cannot create the VTK file: " + file + "\n";}
713 
714  ofs << vtk_header << point_prop_header << point_list <<
715  vertex_prop_header << vertex_list << point_data_header << point_data;
716 
717  // Close the file
718 
719  ofs.close();
720 
721  // Completed succefully
722  return true;
723  }
724 };
725 
726 
727 #endif /* SRC_VTKWRITER_GRIDS_ST_HPP_ */
openfpm::vector< cell_grid< Grid > > g
fused grids
ele_g_st< Grid, St > & operator=(ele_g_st &&ele)
Copy the object.
std::string get_point_list()
Create the VTK point definition.
std::string dataset
output string
std::string get_point_data_header()
Get the point data header.
std::string get_point_properties_list()
It get the vertex properties list.
size_t get_total()
Get the total number of points.
void add(size_t i, const typename pair::first &g, const Point< pair::first::dims, typename pair::second > &offset, const Point< pair::first::dims, typename pair::second > &spacing, const Box< pair::first::dims, typename pair::second > &dom, const comb< pair::first::dims > &cmb)
Add grid dataset.
static Point< dim, St > convert(const comb< dim > &c)
Return the combination converted to point.
Definition: convert.hpp:25
Box< Grid::dims, size_t > dom
Part of the grid that is real domain.
ele_g_st< Grid, St > & operator=(const ele_g_st &ele)
Copy the object.
ele_g_st(const Point< Grid::dims, St > &offset, const Point< Grid::dims, St > &spacing, const Box< Grid::dims, St > &dom)
convert a staggered grid property into a string
cell_grid(cell_grid< Grid > &&cg)
copy constructor
size_t size()
Stub size.
Definition: map_vector.hpp:211
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:398
comb< Grid::dims > cmb
ele_g_st()
constructor
std::string get_prop_components(size_t k)
It generate a name for the property cell component.
openfpm::vector< const Grid * > grids
vector of fused grids
size_t getMaxFused()
Get the maximum number of fused grid.
cell_grid< Grid > & operator=(cell_grid< Grid > &&cg)
Copy the cell grid.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
void one()
Set to one the point coordinate.
Definition: Point.hpp:296
for each combination in the cell grid you can have different grids
This class represent an N-dimensional box.
Definition: Box.hpp:60
Point< Grid::dims, St > spacing
spacing of the grid
std::string get_vertex_list()
Create the VTK vertex definition.
Point< Grid::dims, St > offset
offset where it start the grid
cell_grid(const comb< Grid::dims > &cmb)
construct a cell grid
convert a staggered element into a string for vtk write
std::string lastProp()
Return the output of the domain property.
void append_grid(size_t id, const typename pair::first &g, const comb< pair::first::dims > &cmb)
Append the grid to the sub-domain, if for a sub-domain we have a grid that is overlapping fuse them,...
openfpm::vector< ele_g_st< typename pair::first, typename pair::second > > vg
Vector of grids.
ele_g_st(ele_g_st &&ele)
Copy constructor.
std::string get_properties_output(size_t k, std::string prop_name)
Create the VTK properties output.
ele_g_st(const ele_g_st &ele)
Copy constructor.
cell_grid(const cell_grid< Grid > &cg)
copy contructor
Grid value_type
grid type
std::string get_vertex_properties_list()
It get the vertex properties list.
bool write(std::string file, std::string g_name="grids", file_type ft=file_type::ASCII)
It write a VTK file from a graph.
cell_grid< Grid > & operator=(const cell_grid< Grid > &cg)
Copy the cell grid.