KASKADE 7 development version
gridscanner.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2011 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef GRIDSCANNER_HH
14#define GRIDSCANNER_HH
15
16#include <vector>
17#include <string>
18#include <fstream>
19
20#include "dune/grid/common/grid.hh"
21#include "dune/common/fmatrix.hh"
22
24
25namespace Kaskade
26{
34
47 template<class Function>
49 public:
50
51 typedef typename Function::Space Space;
52 typedef typename Space::Grid Grid;
53 static int const spaceDim = Grid::dimension;
54
55
57
68 Function const& fu,
69 bool dataIsScalar = Function::components==1):
70 lowerbound(lb), upperbound(ub), step(st), scalar(dataIsScalar)
71 {
72 size=getSize();
73 for(int i=0; i < spaceDim; i++)
74 step[i]=(upperbound[i]-lowerbound[i])/(size[i]-1);
75 scanData(fu);
76 }
77
79 void writeVTK(std::string name)
80 {
81 name = name + ".vtr";
82 std::ofstream out(name.c_str());
83 if(!out)
84 throw FileIOException("Failed to open file for writing.",name,__FILE__,__LINE__);
85
86 out << "<VTKFile type=\"RectilinearGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
87 << " <RectilinearGrid WholeExtent=\"";
88 for (int i=0; i<spaceDim; ++i) out << "0 " << size[i]-1 << ' ';
89 for (int i=spaceDim; i<3; ++i) out << "0 0 ";
90 out << "\">\n"
91 << " <Piece Extent=\"";
92 for (int i=0; i<spaceDim; ++i) out << "0 " << size[i]-1 << ' ';
93 for (int i=spaceDim; i<3; ++i) out << "0 0 ";
94
95 int vtkComponents = Function::components==1? 1: 3;
96
97 out << "\">\n"
98 << " <PointData>\n"
99 << " <DataArray type=\"Float32\" format=\"ascii\" Name=\"u\" NumberOfComponents=\"" << vtkComponents << "\">\n";
100
101 // Note that x is innermost loop according to Paraview manual
102 for(int i=0; i<data.size(); ++i) {
103 for (int j=0; j<std::min(Function::components,vtkComponents); ++j)
104 out << static_cast<float>(data[i][j]) << ' ';
105 for (int j=std::min(Function::components,vtkComponents); j<vtkComponents; ++j)
106 out << "0 ";
107 out << std::endl;
108 }
109
110
111 out << " </DataArray>\n"
112 << " </PointData>\n"
113 << " <Coordinates>\n";
114
115 for (int i=0; i<3; ++i)
116 {
117 out << " <DataArray type=\"Float32\" format=\"ascii\" NumberOfComponents=\"1\" Name=\"" << (i==0? 'x': i==1? 'y': 'z') << "\">\n ";
118 if (i<spaceDim)
119 for (int j=0; j<size[i]; ++j)
120 out << lowerbound[i] + j*step[i] << ' ';
121 else
122 out << 0;
123 out << "\n"
124 << " </DataArray>\n";
125 }
126
127 out << " </Coordinates>\n"
128 << " </Piece>\n"
129 << " </RectilinearGrid>\n"
130 << "</VTKFile>\n";
131 }
132
133 private:
134
136 {
138 for(int i=0; i<spaceDim; i++)
139 size[i]=(int)floor((upperbound[i]-lowerbound[i])/step[i])+1;
140 return size;
141 }
142
143
144 void scanData(Function const& fu)
145 {
146
147 ShapeFunctionCache<Grid,typename Function::Scalar> sfCache;
148
149 Dune::FieldVector<int, spaceDim> ind, lrange, urange;
150 int datasize=1;
151 for(int i=0; i< spaceDim; i++) datasize *= size[i];
152 data.resize(datasize);
153 for(int i=0; i<datasize; ++i) data[i] = 0.0;
154 typename Space::Evaluator fkt(fu.space(),&sfCache);
155 typedef typename Grid::template Codim<0>::Entity Cell;
156
157 for (auto ci=fu.space().gridView().template begin<0>(); ci!=fu.space().gridView().template end<0>(); ++ci)
158 {
159 fkt.moveTo(*ci);
161 getIndexRange<Cell, Grid::dimension>(lrange,urange,*ci);
162 scanLocally<Cell, Grid::dimension>(fu, fkt, data,*ci,lrange,urange,at,spaceDim);
163 }
164 }
165
166 // Compute the bounding index box of the given cell
167 template<class Entity, int spaceDim>
168 void getIndexRange(Dune::FieldVector<int, spaceDim> &lower,
170 Entity const& ci)
171 {
172 Dune::FieldVector<typename Grid::ctype, spaceDim> ur(lowerbound),lr(upperbound);
173 for(int i=0; i<ci.geometry().corners(); i++)
174 {
175 auto x = ci.geometry().corner(i);
176 for(int k=0; k<spaceDim; k++)
177 {
178 lr[k]= std::min(lr[k],x[k]);
179 ur[k]= std::max(ur[k],x[k]);
180 }
181 }
182 for(int i=0; i< spaceDim; i++)
183 {
184 lower[i] = std::max((int)ceil((lr[i]-lowerbound[i])/step[i]), 0);
185 upper[i] = std::min((int)ceil((ur[i]-lowerbound[i])/step[i])+1,size[i]);
186 }
187 }
188
189 template<int spaceDim>
191 {
193 for(int i=0; i<spaceDim; i++)
194 x[i] = lowerbound[i]+step[i]*ind[i];
195 return x;
196 }
197
198
199 // Convert integer index coordinate tuple to linear array address.
200 // According to the Paraview user's guide, x is the innermost loop.
201 int getDataIndex(Dune::FieldVector<int, spaceDim> const& ind)
202 {
203 int index = 0;
204 int mult = 1;
205 for(int i=0; i<spaceDim; i++)
206 {
207 index += ind[i]*mult;
208 mult *= size[i];
209 }
210 return index;
211 }
212
213 template<class Entity, int spaceDim>
214 void scanLocally(Function const& fu,
215 typename Function::Space::Evaluator& fkt,
216 std::vector<typename Function::ValueType>& data,
217 Entity const& ci,
221 int dimnumber)
222 {
223 if(dimnumber>0)
224 {
225 for(at[dimnumber-1]=lrange[dimnumber-1]; at[dimnumber-1]<urange[dimnumber-1]; ++at[dimnumber-1])
226 scanLocally<Entity,spaceDim>(fu, fkt,data,ci,lrange,urange,at,dimnumber-1);
227 }
228 else
229 {
230 auto x = getCoord<spaceDim>(at);
231 auto xi = ci.geometry().local(x);
232 if (checkInside(ci.geometry().type(),xi) <= 0)
233 {
234 fkt.evaluateAt(xi);
235 int dataInd = getDataIndex(at);
236 data[dataInd] = fu.value(fkt);
237 }
238 }
239 }
240
241 Dune::FieldVector<typename Grid::ctype, spaceDim> lowerbound, upperbound, step;
242 bool scalar;
243 Dune::FieldVector<int, spaceDim> lrange, urange, size;
244 std::vector<typename Function::ValueType> data;
245 };
246
247 //---------------------------------------------------------------------
248
250
265 template<class Function>
267 {
268 public:
270
275 EdgeScanner(Function const& fu, int nEdgePoints)
276 {
277 scanEdges(fu,nEdgePoints);
278 }
279
281 void writeVTK(std::string name)
282 {
283 name = name +".vtk";
284 std::ofstream out(name.c_str());
285 if(!out)
286 {
287 std::cout << "Error when opening file!" << std::endl;
288 return;
289 }
290 out << "# vtk DataFile Version 2.0" <<std::endl;
291 out << "Scanned Data" <<std::endl;
292 out << "ASCII" <<std::endl;
293 out << "DATASET POLYDATA" << std::endl;
294
295 int npoints=0;
296 for(int i=0; i<data.size(); ++i)
297 npoints+=data[i].size();
298
299 out << "POINTS " << npoints << " float" << std::endl;
300 for(int i=0; i<data.size(); ++i)
301 for(int k=0; k<data[i].size(); ++k)
302 out << static_cast<float>(data[i][k][0]) << " "
303 << static_cast<float>(data[i][k][1]) << " "
304 << static_cast<float>(data[i][k][2]) << std::endl;
305 out << "LINES " << data.size() << " " << data.size()+npoints << std::endl;
306 int dind=0;
307 for(int i=0; i<data.size(); ++i)
308 {
309 out << data[i].size();
310 for(int k=0; k<data[i].size();++k)
311 {
312 out << " " << dind;
313 dind++;
314 }
315 out << std::endl;
316 }
317 out << "POINT_DATA " << npoints << std::endl;
318
319 out << "SCALARS data float 1" << std::endl;
320 out << "LOOKUP_TABLE default" << std::endl;
321
322 for(int i=0; i<data.size(); ++i)
323 {
324 for(int k=0; k<data[i].size();++k)
325 out << static_cast<float>(data[i][k][3]) << " ";
326 out << std::endl;
327 }
328
329 }
330
331 private:
332
333 void scanEdges(Function const& fu, int nEdgePoints)
334 {
335 typedef typename Function::Space Space;
336 typedef typename Space::Grid Grid;
337
339
340 typename Space::Evaluator fkt(fu.space(),&sfCache);
341 typedef typename Space::IndexSet::template Codim<0>::template Partition<Dune::All_Partition>::Iterator CellIterator;
342
344
345 for (CellIterator ci=fu.space().indexSet().template begin<0,Dune::All_Partition>();
346 ci!=fu.space().indexSet().template end<0,Dune::All_Partition>(); ++ci)
347 {
348 fkt.moveTo(*ci);
349 Dune::ReferenceElement<typename Grid::ctype,Grid::dimension> const&
350 r(Dune::ReferenceElements<typename Grid::ctype,Grid::dimension>::general(ci->type()));
351 for(int i=0; i < r.size(Grid::dimension-1); ++i)
352 {
353 std::vector<Dune::FieldVector<typename Grid::ctype,4> > dcell;
354 for(int k=0; k<nEdgePoints; k++)
355 {
356 onEdge[0]=k*1.0/(nEdgePoints-1);
357 Dune::FieldVector<typename Grid::ctype,Grid::dimension> v(r.template global<Grid::dimension-1>(onEdge,i,Grid::dimension-1));
358 fkt.evaluateAt(v);
359 v=ci->geometry().global(v);
361
362 for(int j=0; j<Grid::dimension;++j) dt[j]=v[j];
363 dt[3]=fu.value(fkt);
364 dcell.push_back(dt);
365 }
366 data.push_back(dcell);
367 }
368 }
369 }
370
371 std::vector< std::vector<Dune::FieldVector<typename Function::Space::Grid::ctype,4> > > data;
372 };
373} /* end of namespace Kaskade */
374#endif
Function is the interface for evaluatable functions .
Definition: concepts.hh:324
static int const components
Definition: concepts.hh:335
ValueType value(Cell const &cell, Dune::FieldVector< typename Cell::Geometry::ctype, Cell::dimension > const &localCoordinate) const
Class to scan functions along the edges of a computational grid.
Definition: gridscanner.hh:267
EdgeScanner(Function const &fu, int nEdgePoints)
Scans Function fu along the edges of the computational grid.
Definition: gridscanner.hh:275
void writeVTK(std::string name)
Print data in .vtk (Legacy) format. The extension ".vtk" is automatically appended.
Definition: gridscanner.hh:281
An exception class for file IO errors.
This class caches values and derivatives of shape functions at quadrature points.
Class that can sample a Function(View) on a uniform rectangular grid.
Definition: gridscanner.hh:48
UniformSampler(Dune::FieldVector< typename Grid::ctype, spaceDim > const &lb, Dune::FieldVector< typename Grid::ctype, spaceDim > const &ub, Dune::FieldVector< typename Grid::ctype, spaceDim > const &st, Function const &fu, bool dataIsScalar=Function::components==1)
Performs a uniform sampling of fu on the cuboid marked by lb, ub with stepsize st.
Definition: gridscanner.hh:65
static int const spaceDim
Definition: gridscanner.hh:53
void writeVTK(std::string name)
Print data in .vtk (Legacy) format. The extension ".vtk" is automatically appended.
Definition: gridscanner.hh:79
Function::Space Space
Definition: gridscanner.hh:51
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
LocalCoordinate::field_type checkInside(Dune::GeometryType const &gt, LocalCoordinate const &x)
Checks whether a point is inside or outside the reference element, and how much.
Definition: fixdune.hh:741