dune-grid  2.11
printgrid.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 #ifndef DUNE_PRINTGRID_HH
6 #define DUNE_PRINTGRID_HH
7 
8 #include <fstream>
9 #include <string>
10 
11 #include <dune/common/exceptions.hh>
12 #include <dune/common/parallel/mpihelper.hh>
14 
15 namespace Dune {
16 
17  namespace {
18 
19  template<int dim>
20  struct ElementDataLayout
21  {
22  bool contains (Dune::GeometryType gt)
23  {
24  return gt.dim()==dim;
25  }
26  };
27 
28  template<int dim>
29  struct NodeDataLayout
30  {
31  bool contains (Dune::GeometryType gt)
32  {
33  return gt.dim()==0;
34  }
35  };
36 
37  // Move a point closer to basegeo's center by factor scale (used for drawing relative to the element)
38  template <typename B, typename C>
39  C centrify (const B& basegeo, const C& coords, const double scale) {
40  C ret = coords;
41  ret -= basegeo.center();
42  ret *= scale;
43  ret += basegeo.center();
44  return ret;
45  }
46 
47  // Add a line to the plotfile from p1 to p2
48  template <typename Coord>
49  void draw_line (std::ofstream &plotfile, const Coord &p1, const Coord &p2, std::string options) {
50  plotfile << "set object poly from ";
51  plotfile << p1[0] << "," << p1[1] << " to ";
52  plotfile << p2[0] << "," << p2[1] << " to ";
53  plotfile << p1[0] << "," << p1[1];
54  plotfile << " " << options << std::endl;
55  }
56 
57  }
58 
71  template <typename GridType>
72  void printGrid (const GridType& grid, std::string output_file,
73  int size = 2000, bool execute_plot = true, bool png = true, bool local_corner_indices = true,
74  bool local_intersection_indices = true, bool outer_normals = true)
75  {
76  // Create output file
77  std::string plot_file_name = output_file + ".gnuplot";
78  std::ofstream plotfile (plot_file_name, std::ios::out | std::ios::trunc);
79  if (!plotfile.is_open()) {
80  DUNE_THROW(Dune::IOError, "Could not create plot file " << output_file << "!");
81  return;
82  }
83 
84  // Basic plot settings
85  plotfile << "set size ratio -1" << std::endl;
86  if (png) {
87  plotfile << "set terminal png size " << size << "," << size << std::endl;
88  plotfile << "set output '" << output_file << ".png'" << std::endl;
89  } else {
90  plotfile << "set terminal svg size " << size << "," << size << " enhanced background rgb 'white'" << std::endl;
91  plotfile << "set output '" << output_file << ".svg'" << std::endl;
92  }
93 
94  // Get GridView
95  typedef typename GridType::LeafGridView GV;
96  const GV gv = grid.leafGridView();
97 
98  // Create mappers used to retrieve indices
100  const Mapper elementmapper(gv, mcmgElementLayout());
101  const Mapper nodemapper(gv, mcmgVertexLayout());
102 
103  // Create iterators
104  typedef typename GV::template Codim<0 >::Iterator LeafIterator;
106 
107  LeafIterator it = gv.template begin<0>();
108 
109  // Will contain min/max coordinates. Needed for scaling of the plot
110  Dune::FieldVector<typename GridType::ctype,2> max_coord (it->geometry().center()), min_coord (max_coord);
111 
112  // Iterate over elements
113  for (; it != gv.template end<0>(); ++it) {
114 
115  const auto& entity = *it;
116  auto geo = entity.geometry();
117 
118  // Plot element index
119  int element_id = elementmapper.index(entity);
120  plotfile << "set label at " << geo.center()[0] << "," << geo.center()[1] << " '"
121  << element_id << "' center" << std::endl;
122 
123  for (int i = 0; i < geo.corners(); ++i) {
124  // Plot corner indices
125  const int globalNodeNumber1 = nodemapper.subIndex(entity, i, 2);
126  auto labelpos = centrify (geo, geo.corner(i), 0.7);
127  plotfile << "set label at " << labelpos[0] << "," << labelpos[1] << " '" << globalNodeNumber1;
128  if (local_corner_indices)
129  plotfile << "(" << i << ")";
130  plotfile << "' center" << std::endl;
131 
132  // Adapt min / max coordinates
133  for (int dim = 0; dim < 2; ++dim) {
134  if (geo.corner(i)[dim] < min_coord[dim])
135  min_coord[dim] = geo.corner(i)[dim];
136  else if (geo.corner(i)[dim] > max_coord[dim])
137  max_coord[dim] = geo.corner(i)[dim];
138  }
139  }
140 
141  // Iterate over intersections
142  for (IntersectionIterator is = gv.ibegin(entity); is != gv.iend(entity); ++is) {
143 
144  const auto& intersection = *is;
145  auto igeo = intersection.geometry();
146 
147  // Draw intersection line
148  draw_line (plotfile, igeo.corner(0), igeo.corner(1), "fs empty border 1");
149 
150  // Plot local intersection index
151  if (local_intersection_indices) {
152  auto label_pos = centrify (geo, igeo.center(), 0.8);
153  plotfile << "set label at " << label_pos[0] << "," << label_pos[1]
154  << " '" << intersection.indexInInside() << "' center" << std::endl;
155  }
156 
157  // Plot outer normal
158  if (outer_normals) {
159  auto intersection_pos = igeo.center();
160  auto normal = intersection.centerUnitOuterNormal();
161  normal *= 0.15 * igeo.volume();
162  auto normal_end = intersection_pos + normal;
163  plotfile << "set arrow from " << intersection_pos[0] << "," << intersection_pos[1]
164  << " to " << normal_end[0] << "," << normal_end[1] << " lt rgb \"gray\"" << std::endl;
165  }
166 
167  // Get corners for inner intersection representation
168  auto inner_corner1 = centrify (geo, igeo.corner(0), 0.5);
169  auto inner_corner2 = centrify (geo, igeo.corner(1), 0.5);
170 
171  // Thick line in case of boundary()
172  if (intersection.boundary())
173  draw_line (plotfile, inner_corner1, inner_corner2, "fs empty border 3 lw 4");
174 
175  // Thin line with color according to neighbor()
176  if (intersection.neighbor())
177  draw_line (plotfile, inner_corner1, inner_corner2, "fs empty border 2");
178  else
179  draw_line (plotfile, inner_corner1, inner_corner2, "fs empty border 1");
180  }
181 
182  }
183 
184  // Finish plot, pass extend of the grid
185  Dune::FieldVector<typename GridType::ctype,2> extend (max_coord - min_coord);
186 
187  extend *= 0.2;
188  min_coord -= extend;
189  max_coord += extend;
190  plotfile << "plot [" << min_coord[0] << ":" << max_coord[0] << "] [" << min_coord[1]
191  << ":" << max_coord[1] << "] NaN notitle" << std::endl;
192  plotfile.close();
193 
194  if (execute_plot) {
195  std::string cmd = "gnuplot -p '" + plot_file_name + "'";
196  if (std::system (cmd.c_str()) != 0)
197  DUNE_THROW(Dune::Exception,"Error running GNUPlot: " << cmd);
198  }
199  }
200 
201 
215  template <typename GridType>
216  void printGrid (const GridType& grid, const Dune::MPIHelper& helper, std::string output_file = "printgrid",
217  int size = 2000, bool execute_plot = true, bool png = true, bool local_corner_indices = true,
218  bool local_intersection_indices = true, bool outer_normals = true)
219  {
220  printGrid(grid, output_file + "_" + std::to_string(helper.rank()), size, execute_plot, png, local_corner_indices, local_intersection_indices, outer_normals);
221  }
222 }
223 
224 #endif // #ifndef DUNE_PRINTGRID_HH
concept IntersectionIterator
Model of an intersection iterator.
Definition: concepts/intersectioniterator.hh:21
void printGrid(const GridType &grid, std::string output_file, int size=2000, bool execute_plot=true, bool png=true, bool local_corner_indices=true, bool local_intersection_indices=true, bool outer_normals=true)
Print a grid as a gnuplot for testing and development.
Definition: printgrid.hh:72
Mapper for multiple codim and multiple geometry types.
Index index(const EntityType &e) const
Map entity to array index.
Definition: mapper.hh:122
Index subIndex(const typename G::Traits::template Codim< 0 >::Entity &e, int i, unsigned int codim) const
Map subentity i of codim cc of a codim 0 entity to array index.
Definition: mapper.hh:136
MCMGLayout mcmgElementLayout()
layout for elements (codim-0 entities)
Definition: mcmgmapper.hh:97
Include standard header files.
Definition: agrid.hh:59
Implementation class for a multiple codim and multiple geometry type mapper.
Definition: mcmgmapper.hh:127
Mesh entities of codimension 0 ("elements") allow to visit all intersections with "neighboring" eleme...
Definition: common/grid.hh:347
MCMGLayout mcmgVertexLayout()
layout for vertices (dim-0 entities)
Definition: mcmgmapper.hh:107
GeometryType
Type representing VTK&#39;s entity geometry types.
Definition: common.hh:132
Mapper interface.
Definition: mapper.hh:109