3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
function.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_IO_VTK_FUNCTION_HH
25#define DUMUX_IO_VTK_FUNCTION_HH
26
27#include <string>
28#include <memory>
29
30#include <dune/common/typetraits.hh>
31#include <dune/common/fvector.hh>
32#include <dune/common/reservedvector.hh>
33
34#include <dune/grid/common/mcmgmapper.hh>
35#include <dune/grid/io/file/vtk/common.hh>
36#include <dune/grid/io/file/vtk/function.hh>
37
40
41namespace Dumux::Vtk {
42
43namespace Detail {
44
45template<class Field>
46double accessEntry(const Field& f, [[maybe_unused]] int mycomp, [[maybe_unused]] int i)
47{
48 if constexpr (Dune::IsIndexable<std::decay_t<decltype(std::declval<Field>()[0])>>{})
49 {
50 if constexpr (Dune::IsIndexable<std::decay_t<decltype(std::declval<Field>()[0][0])>>{})
51 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
52 else
53 return f[i][mycomp];
54 }
55 else
56 return f[i];
57}
58
59} // end namespace Detail
60
69template <typename GridView, typename Mapper, typename F>
70struct VectorP0VTKFunction : Dune::VTKFunction<GridView>
71{
72 enum { dim = GridView::dimension };
73 using ctype = typename GridView::ctype;
74 using Element = typename GridView::template Codim<0>::Entity;
75
76public:
77
79 int ncomps() const final { return nComps_; }
80
82 std::string name() const final { return name_; }
83
85 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>&) const final
86 { return Detail::accessEntry(field_, mycomp, mapper_.index(e)); }
87
89 Dumux::Vtk::Precision precision() const final
90 { return precision_; }
91
93 VectorP0VTKFunction(const GridView& gridView,
94 const Mapper& mapper,
95 const F& field,
96 const std::string& name,
97 int nComps,
98 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
99 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
100 {
101 if (field.size()!=(unsigned int)(mapper.size()))
102 DUNE_THROW(Dune::IOError, "VectorP0VTKFunction: size mismatch between field "
103 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
104 }
105
106private:
107 const F& field_;
108 const std::string name_;
109 int nComps_;
110 const Mapper& mapper_;
111 Dumux::Vtk::Precision precision_;
112};
113
122template <typename GridView, typename Mapper, typename F>
123struct VectorP1VTKFunction : Dune::VTKFunction<GridView>
124{
125 enum { dim = GridView::dimension };
126 using ctype = typename GridView::ctype;
127 using Element = typename GridView::template Codim<0>::Entity;
128
129public:
130
132 int ncomps() const final { return nComps_; }
133
135 std::string name() const final { return name_; }
136
138 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& xi) const final
139 {
140 const unsigned int dim = Element::mydimension;
141 const unsigned int nVertices = e.subEntities(dim);
142
143 std::vector<Dune::FieldVector<ctype, 1>> cornerValues(nVertices);
144 for (unsigned i = 0; i < nVertices; ++i)
145 cornerValues[i] = Detail::accessEntry(field_, mycomp, mapper_.subIndex(e, i, dim));
146
147 // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars
148 const Dune::MultiLinearGeometry<ctype, dim, 1> interpolation(e.type(), std::move(cornerValues));
149 return interpolation.global(xi);
150 }
151
153 Dumux::Vtk::Precision precision() const final
154 { return precision_; }
155
157 VectorP1VTKFunction(const GridView& gridView,
158 const Mapper& mapper,
159 const F& field,
160 const std::string& name,
161 int nComps,
162 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
163 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
164 {
165 if (field.size()!=(unsigned int)( mapper.size() ))
166 DUNE_THROW(Dune::IOError, "VectorP1VTKFunction: size mismatch between field "
167 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
168 }
169private:
170 const F& field_;
171 const std::string name_;
172 int nComps_;
173 const Mapper& mapper_;
174 Dumux::Vtk::Precision precision_;
175};
176
189template <typename GridView, typename Mapper, typename F>
190struct VectorP1NonConformingVTKFunction : Dune::VTKFunction<GridView>
191{
192 enum { dim = GridView::dimension };
193 using ctype = typename GridView::ctype;
194 using Element = typename GridView::template Codim<0>::Entity;
195
196public:
197
199 int ncomps() const final { return nComps_; }
200
202 std::string name() const final { return name_; }
203
205 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& xi) const final
206 {
207 const unsigned int dim = Element::mydimension;
208 const unsigned int nVertices = e.subEntities(dim);
209
210 std::vector<Dune::FieldVector<ctype, 1>> cornerValues(nVertices);
211 for (unsigned i = 0; i < nVertices; ++i)
212 cornerValues[i] = accessEntry_(mycomp, mapper_.index(e), i);
213
214 // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars
215 const Dune::MultiLinearGeometry<ctype, dim, 1> interpolation(e.type(), std::move(cornerValues));
216 return interpolation.global(xi);
217 }
218
220 Dumux::Vtk::Precision precision() const final
221 { return precision_; }
222
224 VectorP1NonConformingVTKFunction(const GridView& gridView,
225 const Mapper& mapper,
226 const F& field,
227 const std::string& name,
228 int nComps,
229 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
230 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
231 {
232 if (field.size()!=(unsigned int)(mapper.size()))
233 DUNE_THROW(Dune::IOError, "VectorP1NonConformingVTKFunction: size mismatch between field "
234 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
235 }
236private:
238 double accessEntry_([[maybe_unused]] int mycomp, [[maybe_unused]] int eIdx, [[maybe_unused]] int cornerIdx) const
239 {
240 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0])>{})
241 {
242 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0][0])>{})
243 return field_[eIdx][cornerIdx][mycomp];
244 else
245 return field_[eIdx][cornerIdx];
246 }
247 else
248 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
249 }
250
251 const F& field_;
252 const std::string name_;
253 int nComps_;
254 const Mapper& mapper_;
255 Dumux::Vtk::Precision precision_;
256
257};
258
270template <typename GridView, typename Mapper, typename F>
271struct VectorP1FaceNonConformingVTKFunction : Dune::VTKFunction<GridView>
272{
273 static constexpr int dim = GridView::dimension;
274 using ctype = typename GridView::ctype;
275 using Element = typename GridView::template Codim<0>::Entity;
276
277public:
278
280 int ncomps() const final { return nComps_; }
281
283 std::string name() const final { return name_; }
284
286 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& localPos) const final
287 {
288 const unsigned int dim = Element::mydimension;
289 const unsigned int nFaces = e.subEntities(1);
290
291 // assemble coefficient vector
292 using Coefficients = Dune::ReservedVector<ctype, 2*dim>;
293 Coefficients faceValues;
294 faceValues.resize(nFaces);
295 for (int i = 0; i < nFaces; ++i)
296 faceValues[i] = accessEntry_(mycomp, mapper_.index(e), i);
297
298 using ShapeValues = std::vector<Dune::FieldVector<ctype, 1>>;
299 ShapeValues N;
300 feCache_.get(e.type()).localBasis().evaluateFunction(localPos, N);
301 double result = 0.0;
302 for (int i = 0; i < N.size(); ++i)
303 result += faceValues[i]*N[i];
304 return result;
305 }
306
308 Dumux::Vtk::Precision precision() const final
309 { return precision_; }
310
313 const GridView& gridView,
314 const Mapper& mapper,
315 const F& field,
316 const std::string& name,
317 int nComps,
318 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32
319 )
320 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
321 {
322 if (field.size()!=(unsigned int)(mapper.size()))
323 DUNE_THROW(Dune::IOError, "VectorP1FaceNonConformingVTKFunction: size mismatch between field "
324 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
325 }
326private:
328 double accessEntry_([[maybe_unused]] int mycomp, [[maybe_unused]] int eIdx, [[maybe_unused]] int faceIdx) const
329 {
330 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0])>{})
331 {
332 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0][0])>{})
333 return field_[eIdx][faceIdx][mycomp];
334 else
335 return field_[eIdx][faceIdx];
336 }
337 else
338 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
339 }
340
341 const F& field_;
342 const std::string name_;
343 int nComps_;
344 const Mapper& mapper_;
345 Dumux::Vtk::Precision precision_;
346 NonconformingFECache<ctype, ctype, dim> feCache_ = {};
347};
348
355template<class GridView>
356class Field
357{
358 static constexpr int dim = GridView::dimension;
359 using ctype = typename GridView::ctype;
360 using Element = typename GridView::template Codim<0>::Entity;
361
362public:
363 // template constructor selects the right VTKFunction implementation
364 template <typename F, class Mapper>
365 Field(const GridView& gridView, const Mapper& mapper, F const& f,
366 const std::string& name, int numComp = 1, int codim = 0,
367 Dune::VTK::DataMode dm = Dune::VTK::conforming,
368 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
369 : codim_(codim)
370 {
371 if constexpr (dim > 1)
372 {
373 if (codim == dim)
374 {
375 if (dm == Dune::VTK::conforming)
376 field_ = std::make_shared< VectorP1VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
377 else
378 field_ = std::make_shared< VectorP1NonConformingVTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
379 }
380 else if (codim == 1)
381 {
382 if (dm == Dune::VTK::conforming)
383 DUNE_THROW(Dune::NotImplemented, "Only non-conforming output is implemented");
384 else
385 field_ = std::make_shared< VectorP1FaceNonConformingVTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
386 }
387 else if (codim == 0)
388 field_ = std::make_shared< VectorP0VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
389 else
390 DUNE_THROW(Dune::NotImplemented, "Only element, face or vertex quantities allowed.");
391 }
392 else
393 {
394 if (codim == dim)
395 {
396 if (dm == Dune::VTK::conforming)
397 field_ = std::make_shared< VectorP1VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
398 else
399 field_ = std::make_shared< VectorP1NonConformingVTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
400 }
401 else if (codim == 0)
402 field_ = std::make_shared< VectorP0VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
403 else
404 DUNE_THROW(Dune::NotImplemented, "Only element or vertex quantities allowed.");
405 }
406 }
407
409 std::string name () const { return field_->name(); }
410
412 int ncomps() const { return field_->ncomps(); }
413
415 Dumux::Vtk::Precision precision() const
416 { return field_->precision(); }
417
419 int codim() const { return codim_; }
420
422 double evaluate(int mycomp,
423 const Element &element,
424 const Dune::FieldVector< ctype, dim > &xi) const
425 { return field_->evaluate(mycomp, element, xi); }
426
428 std::shared_ptr<const Dune::VTKFunction<GridView>> get() const
429 { return field_; }
430
431private:
432 int codim_;
433 // can point to anything fulfilling the VTKFunction interface
434 std::shared_ptr<Dune::VTKFunction<GridView>> field_;
435};
436
437} // end namespace Dumux::Vtk
438
439#endif
A finite element cache for the non-conforming FE spaces RT and CR.
Vtk output precision options available in Dumux.
Definition: fieldtype.hh:27
double accessEntry(const Field &f, int mycomp, int i)
Definition: function.hh:46
const FiniteElementType & get(const Dune::GeometryType &gt) const
Get local finite element for given GeometryType.
Definition: nonconformingfecache.hh:58
a VTK function that supports both scalar and vector values for each element
Definition: function.hh:71
typename GridView::ctype ctype
Definition: function.hh:73
typename GridView::template Codim< 0 >::Entity Element
Definition: function.hh:74
@ dim
Definition: function.hh:72
std::string name() const final
get name
Definition: function.hh:82
VectorP0VTKFunction(const GridView &gridView, const Mapper &mapper, const F &field, const std::string &name, int nComps, Dumux::Vtk::Precision precision=Dumux::Vtk::Precision::float32)
Constructor.
Definition: function.hh:93
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &) const final
evaluate
Definition: function.hh:85
int ncomps() const final
return number of components
Definition: function.hh:79
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition: function.hh:89
a VTK function that supports both scalar and vector values for each vertex
Definition: function.hh:124
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition: function.hh:153
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &xi) const final
evaluate
Definition: function.hh:138
VectorP1VTKFunction(const GridView &gridView, const Mapper &mapper, const F &field, const std::string &name, int nComps, Dumux::Vtk::Precision precision=Dumux::Vtk::Precision::float32)
Constructor.
Definition: function.hh:157
@ dim
Definition: function.hh:125
typename GridView::template Codim< 0 >::Entity Element
Definition: function.hh:127
typename GridView::ctype ctype
Definition: function.hh:126
std::string name() const final
get name
Definition: function.hh:135
int ncomps() const final
return number of components
Definition: function.hh:132
A VTK function that supports both scalar and vector values for each vertex. This expects the data to ...
Definition: function.hh:191
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &xi) const final
evaluate
Definition: function.hh:205
VectorP1NonConformingVTKFunction(const GridView &gridView, const Mapper &mapper, const F &field, const std::string &name, int nComps, Dumux::Vtk::Precision precision=Dumux::Vtk::Precision::float32)
Constructor.
Definition: function.hh:224
typename GridView::template Codim< 0 >::Entity Element
Definition: function.hh:194
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition: function.hh:220
int ncomps() const final
return number of components
Definition: function.hh:199
typename GridView::ctype ctype
Definition: function.hh:193
std::string name() const final
get name
Definition: function.hh:202
A VTK function that supports both scalar and vector values for each face. This expects the data to be...
Definition: function.hh:272
std::string name() const final
get name
Definition: function.hh:283
int ncomps() const final
return number of components
Definition: function.hh:280
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &localPos) const final
evaluate
Definition: function.hh:286
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition: function.hh:308
typename GridView::template Codim< 0 >::Entity Element
Definition: function.hh:275
VectorP1FaceNonConformingVTKFunction(const GridView &gridView, const Mapper &mapper, const F &field, const std::string &name, int nComps, Dumux::Vtk::Precision precision=Dumux::Vtk::Precision::float32)
Constructor.
Definition: function.hh:312
static constexpr int dim
Definition: function.hh:273
typename GridView::ctype ctype
Definition: function.hh:274
struct that can hold any field that fulfills the VTKFunction interface
Definition: function.hh:357
double evaluate(int mycomp, const Element &element, const Dune::FieldVector< ctype, dim > &xi) const
element-local evaluation of the field
Definition: function.hh:422
std::string name() const
return the name of this field
Definition: function.hh:409
int ncomps() const
return the number of components of this field
Definition: function.hh:412
std::shared_ptr< const Dune::VTKFunction< GridView > > get() const
returns the underlying vtk function
Definition: function.hh:428
Field(const GridView &gridView, const Mapper &mapper, F const &f, const std::string &name, int numComp=1, int codim=0, Dune::VTK::DataMode dm=Dune::VTK::conforming, Dumux::Vtk::Precision precision=Dumux::Vtk::Precision::float32)
Definition: function.hh:365
Dumux::Vtk::Precision precision() const
return the precision of this field
Definition: function.hh:415
int codim() const
codimension of the entities on which the field values live
Definition: function.hh:419