version 3.11-dev
Loading...
Searching...
No Matches
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// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_IO_VTK_FUNCTION_HH
13#define DUMUX_IO_VTK_FUNCTION_HH
14
15#include <string>
16#include <memory>
17
18#include <dune/common/typetraits.hh>
19#include <dune/common/fvector.hh>
20
21#include <dune/grid/common/mcmgmapper.hh>
22#include <dune/grid/io/file/vtk/common.hh>
23#include <dune/grid/io/file/vtk/function.hh>
24
27
28namespace Dumux::Vtk {
29
30namespace Detail {
31
32template<class Field>
33double accessEntry(const Field& f, [[maybe_unused]] int mycomp, [[maybe_unused]] int i)
34{
35 if constexpr (Dune::IsIndexable<std::decay_t<decltype(std::declval<Field>()[0])>>{})
36 {
37 if constexpr (Dune::IsIndexable<std::decay_t<decltype(std::declval<Field>()[0][0])>>{})
38 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
39 else
40 return f[i][mycomp];
41 }
42 else
43 return f[i];
44}
45
46} // end namespace Detail
47
56template <typename GridView, typename Mapper, typename F>
57struct VectorP0VTKFunction : Dune::VTKFunction<GridView>
58{
59 enum { dim = GridView::dimension };
60 using ctype = typename GridView::ctype;
61 using Element = typename GridView::template Codim<0>::Entity;
62
63public:
64
66 int ncomps() const final { return nComps_; }
67
69 std::string name() const final { return name_; }
70
72 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>&) const final
73 { return Detail::accessEntry(field_, mycomp, mapper_.index(e)); }
74
76 Dumux::Vtk::Precision precision() const final
77 { return precision_; }
78
80 VectorP0VTKFunction(const GridView& gridView,
81 const Mapper& mapper,
82 const F& field,
83 const std::string& name,
84 int nComps,
85 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
86 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
87 {
88 if (field.size()!=(unsigned int)(mapper.size()))
89 DUNE_THROW(Dune::IOError, "VectorP0VTKFunction: size mismatch between field "
90 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
91 }
92
93private:
94 const F& field_;
95 const std::string name_;
96 int nComps_;
97 const Mapper& mapper_;
98 Dumux::Vtk::Precision precision_;
99};
100
109template <typename GridView, typename Mapper, typename F>
110struct VectorP1VTKFunction : Dune::VTKFunction<GridView>
111{
112 enum { dim = GridView::dimension };
113 using ctype = typename GridView::ctype;
114 using Element = typename GridView::template Codim<0>::Entity;
115
116public:
117
119 int ncomps() const final { return nComps_; }
120
122 std::string name() const final { return name_; }
123
125 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& xi) const final
126 {
127 const unsigned int dim = Element::mydimension;
128 const unsigned int nVertices = e.subEntities(dim);
129
130 std::vector<Dune::FieldVector<ctype, 1>> cornerValues(nVertices);
131 for (unsigned i = 0; i < nVertices; ++i)
132 cornerValues[i] = Detail::accessEntry(field_, mycomp, mapper_.subIndex(e, i, dim));
133
134 // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars
135 const Dune::MultiLinearGeometry<ctype, dim, 1> interpolation(e.type(), std::move(cornerValues));
136 return interpolation.global(xi)[0];
137 }
138
140 Dumux::Vtk::Precision precision() const final
141 { return precision_; }
142
144 VectorP1VTKFunction(const GridView& gridView,
145 const Mapper& mapper,
146 const F& field,
147 const std::string& name,
148 int nComps,
149 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
150 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
151 {
152 if (field.size()!=(unsigned int)( mapper.size() ))
153 DUNE_THROW(Dune::IOError, "VectorP1VTKFunction: size mismatch between field "
154 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
155 }
156private:
157 const F& field_;
158 const std::string name_;
159 int nComps_;
160 const Mapper& mapper_;
161 Dumux::Vtk::Precision precision_;
162};
163
176template <typename GridView, typename Mapper, typename F>
177struct VectorP1NonConformingVTKFunction : Dune::VTKFunction<GridView>
178{
179 enum { dim = GridView::dimension };
180 using ctype = typename GridView::ctype;
181 using Element = typename GridView::template Codim<0>::Entity;
182
183public:
184
186 int ncomps() const final { return nComps_; }
187
189 std::string name() const final { return name_; }
190
192 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& xi) const final
193 {
194 const unsigned int dim = Element::mydimension;
195 const unsigned int nVertices = e.subEntities(dim);
196
197 std::vector<Dune::FieldVector<ctype, 1>> cornerValues(nVertices);
198 for (unsigned i = 0; i < nVertices; ++i)
199 cornerValues[i] = accessEntry_(mycomp, mapper_.index(e), i);
200
201 // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars
202 const Dune::MultiLinearGeometry<ctype, dim, 1> interpolation(e.type(), std::move(cornerValues));
203 return interpolation.global(xi)[0];
204 }
205
207 Dumux::Vtk::Precision precision() const final
208 { return precision_; }
209
211 VectorP1NonConformingVTKFunction(const GridView& gridView,
212 const Mapper& mapper,
213 const F& field,
214 const std::string& name,
215 int nComps,
216 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
217 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
218 {
219 if (field.size()!=(unsigned int)(mapper.size()))
220 DUNE_THROW(Dune::IOError, "VectorP1NonConformingVTKFunction: size mismatch between field "
221 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
222 }
223private:
225 double accessEntry_([[maybe_unused]] int mycomp, [[maybe_unused]] int eIdx, [[maybe_unused]] int cornerIdx) const
226 {
227 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0])>{})
228 {
229 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0][0])>{})
230 return field_[eIdx][cornerIdx][mycomp];
231 else
232 return field_[eIdx][cornerIdx];
233 }
234 else
235 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
236 }
237
238 const F& field_;
239 const std::string name_;
240 int nComps_;
241 const Mapper& mapper_;
242 Dumux::Vtk::Precision precision_;
243
244};
245
257template <typename GridView, typename Mapper, typename F>
258struct VectorP1FaceNonConformingVTKFunction : Dune::VTKFunction<GridView>
259{
260 static constexpr int dim = GridView::dimension;
261 using ctype = typename GridView::ctype;
262 using Element = typename GridView::template Codim<0>::Entity;
263
264public:
265
267 int ncomps() const final { return nComps_; }
268
270 std::string name() const final { return name_; }
271
273 double evaluate(int mycomp, const Element& e, const Dune::FieldVector<ctype, dim>& localPos) const final
274 {
275 using ShapeValues = std::vector<Dune::FieldVector<ctype, 1>>;
276 ShapeValues N;
277 feCache_.get(e.type()).localBasis().evaluateFunction(localPos, N);
278
279 const auto eIdx = mapper_.index(e);
280 double result = 0.0;
281 for (int i = 0; i < N.size(); ++i)
282 result += accessEntry_(mycomp, eIdx, i)*N[i][0];
283 return result;
284 }
285
287 Dumux::Vtk::Precision precision() const final
288 { return precision_; }
289
292 const GridView& gridView,
293 const Mapper& mapper,
294 const F& field,
295 const std::string& name,
296 int nComps,
297 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32
298 )
299 : field_(field), name_(name), nComps_(nComps), mapper_(mapper), precision_(precision)
300 {
301 if (field.size()!=(unsigned int)(mapper.size()))
302 DUNE_THROW(Dune::IOError, "VectorP1FaceNonConformingVTKFunction: size mismatch between field "
303 << name << " (" << field.size() << ") and mapper (" << mapper.size() << ")");
304 }
305private:
307 double accessEntry_([[maybe_unused]] int mycomp, [[maybe_unused]] int eIdx, [[maybe_unused]] int faceIdx) const
308 {
309 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0])>{})
310 {
311 if constexpr (Dune::IsIndexable<decltype(std::declval<F>()[0][0])>{})
312 return field_[eIdx][faceIdx][mycomp];
313 else
314 return field_[eIdx][faceIdx];
315 }
316 else
317 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
318 }
319
320 const F& field_;
321 const std::string name_;
322 int nComps_;
323 const Mapper& mapper_;
324 Dumux::Vtk::Precision precision_;
325 NonconformingFECache<ctype, ctype, dim> feCache_ = {};
326};
327
334template<class GridView>
335class Field
336{
337 static constexpr int dim = GridView::dimension;
338 using ctype = typename GridView::ctype;
339 using Element = typename GridView::template Codim<0>::Entity;
340
341public:
342 // template constructor selects the right VTKFunction implementation
343 template <typename F, class Mapper>
344 Field(const GridView& gridView, const Mapper& mapper, F const& f,
345 const std::string& name, int numComp = 1, int codim = 0,
346 Dune::VTK::DataMode dm = Dune::VTK::conforming,
347 Dumux::Vtk::Precision precision = Dumux::Vtk::Precision::float32)
348 : codim_(codim)
349 {
350 if constexpr (dim > 1)
351 {
352 if (codim == dim)
353 {
354 if (dm == Dune::VTK::conforming)
355 field_ = std::make_shared< VectorP1VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
356 else
357 field_ = std::make_shared< VectorP1NonConformingVTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
358 }
359 else if (codim == 1)
360 {
361 if (dm == Dune::VTK::conforming)
362 DUNE_THROW(Dune::NotImplemented, "Only non-conforming output is implemented");
363 else
364 field_ = std::make_shared< VectorP1FaceNonConformingVTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
365 }
366 else if (codim == 0)
367 field_ = std::make_shared< VectorP0VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
368 else
369 DUNE_THROW(Dune::NotImplemented, "Only element, face or vertex quantities allowed.");
370 }
371 else
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 == 0)
381 field_ = std::make_shared< VectorP0VTKFunction<GridView, Mapper, F> >(gridView, mapper, f, name, numComp, precision);
382 else
383 DUNE_THROW(Dune::NotImplemented, "Only element or vertex quantities allowed.");
384 }
385 }
386
388 std::string name () const { return field_->name(); }
389
391 int ncomps() const { return field_->ncomps(); }
392
394 Dumux::Vtk::Precision precision() const
395 { return field_->precision(); }
396
398 int codim() const { return codim_; }
399
401 double evaluate(int mycomp,
402 const Element &element,
403 const Dune::FieldVector< ctype, dim > &xi) const
404 { return field_->evaluate(mycomp, element, xi); }
405
407 std::shared_ptr<const Dune::VTKFunction<GridView>> get() const
408 { return field_; }
409
410private:
411 int codim_;
412 // can point to anything fulfilling the VTKFunction interface
413 std::shared_ptr<Dune::VTKFunction<GridView>> field_;
414};
415
416} // end namespace Dumux::Vtk
417
418#endif
struct that can hold any field that fulfills the VTKFunction interface
Definition function.hh:336
double evaluate(int mycomp, const Element &element, const Dune::FieldVector< ctype, dim > &xi) const
element-local evaluation of the field
Definition function.hh:401
std::string name() const
return the name of this field
Definition function.hh:388
int ncomps() const
return the number of components of this field
Definition function.hh:391
std::shared_ptr< const Dune::VTKFunction< GridView > > get() const
returns the underlying vtk function
Definition function.hh:407
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:344
Dumux::Vtk::Precision precision() const
return the precision of this field
Definition function.hh:394
int codim() const
codimension of the entities on which the field values live
Definition function.hh:398
@ element
Definition fieldtype.hh:23
Definition function.hh:30
double accessEntry(const Field &f, int mycomp, int i)
Definition function.hh:33
Definition fieldtype.hh:15
A finite element cache for the non-conforming FE spaces RT and CR.
Vtk output precision options available in Dumux.
typename GridView::ctype ctype
Definition function.hh:60
@ dim
Definition function.hh:59
typename GridView::template Codim< 0 >::Entity Element
Definition function.hh:61
std::string name() const final
get name
Definition function.hh:69
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:80
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &) const final
evaluate
Definition function.hh:72
int ncomps() const final
return number of components
Definition function.hh:66
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition function.hh:76
std::string name() const final
get name
Definition function.hh:270
int ncomps() const final
return number of components
Definition function.hh:267
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &localPos) const final
evaluate
Definition function.hh:273
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition function.hh:287
typename GridView::template Codim< 0 >::Entity Element
Definition function.hh:262
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:291
static constexpr int dim
Definition function.hh:260
typename GridView::ctype ctype
Definition function.hh:261
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &xi) const final
evaluate
Definition function.hh:192
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:211
typename GridView::template Codim< 0 >::Entity Element
Definition function.hh:181
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition function.hh:207
int ncomps() const final
return number of components
Definition function.hh:186
typename GridView::ctype ctype
Definition function.hh:180
std::string name() const final
get name
Definition function.hh:189
Dumux::Vtk::Precision precision() const final
get output precision for the field
Definition function.hh:140
double evaluate(int mycomp, const Element &e, const Dune::FieldVector< ctype, dim > &xi) const final
evaluate
Definition function.hh:125
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:144
typename GridView::template Codim< 0 >::Entity Element
Definition function.hh:114
typename GridView::ctype ctype
Definition function.hh:113
std::string name() const final
get name
Definition function.hh:122
@ dim
Definition function.hh:112
int ncomps() const final
return number of components
Definition function.hh:119