OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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)
121  :offset(offset),spacing(spacing),dom(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  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the type " << demangle(typeid(ctype).name()) << " is not supported by vtk\n";
375  return "";
376  }
377 
378  std::string prp_cp = get_prop_components(k);
379 
380  // Create point data properties
381  v_out << "SCALARS " << prop_name << "_" << prp_cp << " " << type + "\n";
382 
383  // Default lookup table
384  v_out << "LOOKUP_TABLE default\n";
385 
387  for (size_t i = 0 ; i < vg.size() ; i++)
388  {
389  // For each position in the cell
390  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
391  {
392  // If there are no grid in this position
393  if (vg.get(i).g.get(j).grids.size() == 0)
394  continue;
395 
396  if (k < vg.get(i).g.get(j).grids.size())
397  {
398  // Grid source
399  auto & g_src = *vg.get(i).g.get(j).grids.get(k);
400 
402  auto it = g_src.getIterator();
403 
406 
407  // if there is the next element
408  while (it.isNext())
409  {
410  auto key = it.get();
411 
412  v_out << std::to_string(g_src.template get<0>(key)) << "\n";
413 
414  // increment the iterator
415  ++it;
416  }
417  }
418  else
419  {
420  // Grid source
421  auto & g_src = *vg.get(i).g.get(j).grids.get(0);
422 
424  auto it = g_src.getIterator();
425 
428 
429  // if there is the next element
430  while (it.isNext())
431  {
432  v_out << "0\n";
433 
434  // increment the iterator
435  ++it;
436  }
437  }
438  }
439  }
440 
441  // return the vertex list
442  return v_out.str();
443  }
444 
450  std::string lastProp()
451  {
453  std::stringstream v_out;
454 
455  // Create point data properties
456  v_out << "SCALARS domain float\n";
457 
458  // Default lookup table
459  v_out << "LOOKUP_TABLE default\n";
460 
462  for (size_t i = 0 ; i < vg.size() ; i++)
463  {
464  // For each position in the cell
465  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
466  {
467  // If there are no grid in this position
468  if (vg.get(i).g.get(j).grids.size() == 0)
469  continue;
470 
472  auto it = vg.get(i).g.get(j).grids.get(0)->getIterator();
473 
474  // if there is the next element
475  while (it.isNext())
476  {
477  if (vg.get(i).dom.isInside(it.get().toPoint()) == true)
478  v_out << "1.0\n";
479  else
480  v_out << "0.0\n";
481 
482  // increment the iterator and counter
483  ++it;
484  }
485  }
486  }
487 
488  return v_out.str();
489  }
490 
496  size_t getMaxFused()
497  {
498  size_t max = 0;
499 
501  for (size_t i = 0 ; i < vg.size() ; i++)
502  {
503  // For each position in the cell
504  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
505  {
506  // If there are no grid in this position
507  if (vg.get(i).g.get(j).grids.size() > max)
508  max = vg.get(i).g.get(j).grids.size();
509  }
510  }
511 
512  return max;
513  }
514 
520  std::string get_vertex_list()
521  {
523  std::string v_out;
524 
525  size_t k = 0;
526 
528  for (size_t i = 0 ; i < vg.size() ; i++)
529  {
530  // For each position in the cell
531  for (size_t j = 0 ; j < vg.get(i).g.size() ; j++)
532  {
533  // If there are no grid in this position
534  if (vg.get(i).g.get(j).grids.size() == 0)
535  continue;
537  auto it = vg.get(i).g.get(j).grids.get(0)->getIterator();
538 
539  while (it.isNext())
540  {
541  v_out += "1 " + std::to_string(k) + "\n";
542 
543  ++k;
544  ++it;
545  }
546  }
547  }
548  // return the vertex list
549  return v_out;
550  }
551 
558  std::string get_point_data_header()
559  {
560  std::string v_out;
561 
562  v_out += "POINT_DATA " + std::to_string(get_total()) + "\n";
563 
564  return v_out;
565  }
566 
577  void append_grid(size_t id, const typename pair::first & g, const comb<pair::first::dims> & cmb)
578  {
579  for(size_t i = 0 ; i < vg.get(id).g.size() ; i++)
580  {
581  // for each defined grid if exist the combination fuse
582  if (cmb == vg.get(id).g.get(i).cmb)
583  {
584  vg.get(id).g.get(i).grids.add(&g);
585  return;
586  }
587  }
588 
589  // if the combination does not exist add the grid
591  vg.get(id).g.add(cg);
592  vg.get(id).g.last().grids.add(&g);
593  }
594 
595 public:
596 
603  {}
604 
615  void add(size_t i,
616  const typename pair::first & g,
620  const comb<pair::first::dims> & cmb)
621  {
623  if (i >= vg.size())
624  vg.resize(i+1);
625 
626  vg.get(i).offset = offset;
627  vg.get(i).spacing = spacing;
628  vg.get(i).dom = dom;
629 
630  // append the grid
631  append_grid(i,g,cmb);
632  }
633 
646  template<int prp = -1> bool write(std::string file,
647  std::string g_name = "grids",
648  file_type ft = file_type::ASCII)
649  {
650  // Header for the vtk
651  std::string vtk_header;
652  // Point list of the VTK
653  std::string point_list;
654  // Vertex list of the VTK
655  std::string vertex_list;
656  // Graph header
657  std::string vtk_binary_or_ascii;
658  // vertex properties header
659  std::string point_prop_header;
660  // edge properties header
661  std::string vertex_prop_header;
662  // Data point header
663  std::string point_data_header;
664  // Data point
665  std::string point_data;
666 
667  // VTK header
668  vtk_header = "# vtk DataFile Version 3.0\n"
669  + g_name + "\n";
670 
671  // Choose if binary or ASCII
672  if (ft == file_type::ASCII)
673  {vtk_header += "ASCII\n";}
674  else
675  {vtk_header += "BINARY\n";}
676 
677  // Data type for graph is DATASET POLYDATA
678  vtk_header += "DATASET POLYDATA\n";
679 
680  // point properties header
681  point_prop_header = get_point_properties_list();
682 
683  // Get point list
684  point_list = get_point_list();
685 
686  // vertex properties header
687  vertex_prop_header = get_vertex_properties_list();
688 
689  // Get vertex list
690  vertex_list = get_vertex_list();
691 
692  // Get the point data header
693  point_data_header = get_point_data_header();
694 
695  // Get the maximum number of fused grids
696  size_t mf = getMaxFused();
697 
698  // For each property in the vertex type produce a point data
699  for (size_t i = 0 ; i < mf ; i++)
700  point_data += get_properties_output(i,g_name);
701 
702  lastProp();
703 
704 
705  // write the file
706  std::ofstream ofs(file);
707 
708  // Check if the file is open
709  if (ofs.is_open() == false)
710  {std::cerr << "Error cannot create the VTK file: " + file + "\n";}
711 
712  ofs << vtk_header << point_prop_header << point_list <<
713  vertex_prop_header << vertex_list << point_data_header << point_data;
714 
715  // Close the file
716 
717  ofs.close();
718 
719  // Completed succefully
720  return true;
721  }
722 };
723 
724 
725 #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 toString() const
Return the string with the point coordinate.
Definition: Point.hpp:371
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
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.
void one()
Set to one the point coordinate.
Definition: Point.hpp:267
for each combination in the cell grid you can have different grids
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
This class represent an N-dimensional box.
Definition: Box.hpp:56
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
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.