dune-vtk 2.12
Loading...
Searching...
No Matches
gridfunction.hh
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <memory>
6#include <numeric>
7#include <string>
8#include <type_traits>
9#include <vector>
10
14#include <dune/vtk/types.hh>
20
21namespace Dune::Vtk {
22namespace Impl {
23
24template <class GridViewType, class ComponentMapperType>
25struct GridFunctionDefinition
26{
27 using GridView = GridViewType;
28 using ComponentMapper = ComponentMapperType;
29 using Element = typename GridView::template Codim<0>::Entity;
30 using Domain = typename Element::Geometry::GlobalCoordinate;
31 using LocalFunction = Vtk::LocalFunction<Element,ComponentMapper>;
32
33 // Definition of the interface a LocalFunction must fulfill
34 struct Interface
35 {
36 virtual ~Interface() = default;
37 virtual Interface* clone () const = 0;
38 virtual double evaluate (int, Domain const&) const = 0;
39 virtual LocalFunction asLocalFunction(std::vector<int> const&) const = 0;
40
41 };
42
43 // Templatized implementation of the interface
44 template <class Impl>
45 struct Model : public Interface
46 {
47 template <class I, disableCopyMove<Model,I> = 0>
48 Model(I&& impl) : impl_(std::forward<I>(impl)) {}
49 Model* clone() const final { return new Model(*this); }
50 auto& impl() { return resolveRef(impl_); }
51 const auto& impl() const { return resolveRef(impl_); }
52
53 double evaluate(int i, Domain const& x) const final {
54 return ComponentMapper::map(i, x, impl()); }
55 LocalFunction asLocalFunction(std::vector<int> const& comp) const final {
56 return LocalFunction{localFunction(impl()), comp};
57 }
58
59 private:
60 Impl impl_;
61 };
62
63 // The Concept definition of a LocalFunction
64 struct Concept
65 {
66 using LFConcept = typename LocalFunctionDefinition<Element,ComponentMapper>::Concept;
67
68 template <class F>
69 auto require(F&& f) -> decltype
70 (
71 Dune::Concept::requireConcept<LFConcept>(localFunction(f))
72 );
73 };
74};
75
76} // end namespace Impl
77
78
79
82
85template <class GridView, class ComponentMapper = DefaultComponentMapper>
87{
88 using Definition = Impl::GridFunctionDefinition<GridView,ComponentMapper>;
89 using Interface = typename Definition::Interface;
90 using Domain = typename Definition::Domain;
91 using LocalFunction = typename Definition::LocalFunction;
92
93 template <class F>
94 using Model = typename Definition::template Model<std::remove_reference_t<F>>;
95
96public:
99 template <class F,
100 class R = RangeType<ResolveRef_t<F>,Domain>>
101 GridFunction (F&& f, std::string name, int numComponents = dimRange<R>())
103 {}
104
107 template <class F, disableCopyMove<GridFunction, F> = 0,
108 decltype(std::declval<F>().name(), bool{}) = true,
109 decltype(std::declval<F>().numComponents(), bool{}) = true,
110 decltype(std::declval<F>().dataType(), bool{}) = true>
112 : GridFunction(std::forward<F>(f), Vtk::FieldInfo{f.name(), f.numComponents(), rangeTypeImpl(f, Dune::PriorityTag<1>{}), f.dataType()})
113 {}
114
117 template <class F>
118 GridFunction (F&& f, const Vtk::FieldInfo& info)
119 : interface_(std::make_unique<Model<F>>(std::forward<F>(f)))
120 , name_(info.name())
121 , shape_(staticShape<ResolveRef_t<F>>())
122 {
123 static_assert(models<typename Definition::Concept,ResolveRef_t<F>>(),
124 "Implementation does not model the Function concept.");
125
126 setComponents(info.size());
127 setRangeType(info.rangeType());
128 setDataType(info.dataType());
129 }
130
133 GridFunction () = default;
136
139 : interface_(other.interface_ ? other.interface_->clone() : nullptr)
140 , name_(other.name_)
141 , components_(other.components_)
142 , shape_(other.shape_)
143 , outputMap_(other.outputMap_)
144 , dataType_(other.dataType_)
145 , rangeType_(other.rangeType_)
146 {}
147
150 {
151 return *this = GridFunction(other);
152 }
153
155 Impl::RangeProxy<GridFunction,Domain> operator() (Domain const& x) const
156 {
157 return {this, x};
158 }
159
161 double evaluate (int i, Domain const& x) const
162 {
163 return i < int(outputMap_.size()) && outputMap_[i] >= 0
164 ? interface_->evaluate(outputMap_[i], x) : 0.0;
165 }
166
168 friend LocalFunction localFunction (GridFunction const& self)
169 {
170 return self.interface_->asLocalFunction(self.outputMap_);
171 }
172
174 std::string const& name () const
175 {
176 return name_;
177 }
178
181 {
182 name_ = std::move(name);
183 }
184
186 int numComponents () const
187 {
188 return rangeType_ == Vtk::RangeTypes::SCALAR ? 1 :
189 rangeType_ == Vtk::RangeTypes::VECTOR ? 3 :
190 rangeType_ == Vtk::RangeTypes::TENSOR ? 9 : int(components_.size());
191 }
192
195 {
196 return components_;
197 }
198
201 {
202 components_ = components;
203 updateOutputMap();
204 }
205
207 void setComponents (int ncomps)
208 {
209 setComponents(allComponents(ncomps));
210 }
211
214 {
215 return dataType_;
216 }
217
220 {
221 dataType_ = type;
222 }
223
226 {
227 return rangeType_;
228 }
229
232 {
233 rangeType_ = type;
234 if (type == Vtk::RangeTypes::AUTO)
235 rangeType_ = rangeTypeOf(ncomp);
236 updateOutputMap();
237 }
238
240 void setFieldInfo (const Vtk::FieldInfo& info)
241 {
242 setName(info.name());
243 setComponents(info.size());
244 setRangeType(info.rangeType());
245 setDataType(info.dataType());
246 }
247
248private:
249 template <class F>
250 static constexpr std::array<int,2> staticShape ()
251 {
252 if constexpr (std::is_invocable_v<F const&, Domain const&>)
254 else
255 return {0,0};
256 }
257
258 // Shape {rows,cols} of the (selected) range interpreted as a tensor
259 std::array<int,2> tensorShape () const
260 {
261 const int n = components_.size();
262 if (shape_[0] > 0 && shape_[0]*shape_[1] <= n)
263 return shape_;
264 for (int k : {1,2,3})
265 if (k*k == n) return {k,k};
266 return {(n+2)/3, 3}; // unknown: fill the 3x3 tensor row-wise
267 }
268
269 // Map each output slot [0,numComponents()) to a range component, or -1 for zero padding
270 void updateOutputMap ()
271 {
272 outputMap_.assign(numComponents(), -1);
273 if (rangeType_ == Vtk::RangeTypes::TENSOR) {
274 auto [rows,cols] = tensorShape();
275 for (int r = 0; r < std::min(rows,3); ++r)
276 for (int c = 0; c < std::min(cols,3); ++c)
277 if (int k = r*cols + c; k < int(components_.size()))
278 outputMap_[3*r + c] = components_[k];
279 } else {
280 for (std::size_t i = 0; i < std::min(outputMap_.size(), components_.size()); ++i)
281 outputMap_[i] = components_[i];
282 }
283 }
284
285 std::vector<int> allComponents (int n) const
286 {
287 std::vector<int> components(n);
288 std::iota(components.begin(), components.end(), 0);
289 return components;
290 }
291
292 // Forward the range-type of `f` if available
293 template <class F>
294 static auto rangeTypeImpl (F const& f, Dune::PriorityTag<1>)
295 -> decltype(Vtk::RangeTypes(f.rangeType()))
296 {
297 return f.rangeType();
298 }
299
300 template <class F>
301 static Vtk::RangeTypes rangeTypeImpl (F const& /*f*/, Dune::PriorityTag<0>)
302 {
304 }
305
306private:
308 std::string name_{};
309 std::vector<int> components_{};
310 std::array<int,2> shape_{0,0};
311 std::vector<int> outputMap_{};
314};
315
316} // end namespace Dune::Vtk
STL namespace.
Definition writer.hh:16
constexpr std::array< int, 2 > rangeShape()
Static shape {rows,cols} of a matrix-valued range type, or {0,0} if unknown or not a matrix.
Definition rangetype.hh:57
RangeTypes
Type used to determine whether to limit output components to e.g. 3 (vector), or 9 (tensor)
Definition types.hh:34
DataTypes
Definition types.hh:51
Vtk::RangeTypes rangeTypeOf(Dune::VTK::FieldInfo::Type t)
Definition types.cc:55
const char * name()
auto rows(Matrix const &matrix)
auto cols(Matrix const &matrix)
SLList< T, A > & operator=(const SLList< T, A > &other)
constexpr T & resolveRef(T &gf) noexcept
virtual void operator()()=0
virtual ~Interface()
Implementation & impl()
GridView(const Implementation &imp)
ALBERTA EL Element
A Vtk::GridFunction is a function-like object that can be bound to a grid element an that provides an...
Definition gridfunction.hh:87
void setComponents(std::vector< int > components)
Set the components of the Range to visualize.
Definition gridfunction.hh:200
GridFunction(F &&f, std::string name, int numComponents=dimRange< R >())
Constructor. Pass any type F supporting the Function interface wrappers the name of the function and ...
Definition gridfunction.hh:101
int numComponents() const
Return the number of components of the Range as it is written to the file.
Definition gridfunction.hh:186
void setName(std::string name)
Set the function name.
Definition gridfunction.hh:180
GridFunction(F &&f, const Vtk::FieldInfo &info)
Constructor. Pass any type F supporting the Function interface wrappers and the FieldInfo describing ...
Definition gridfunction.hh:118
GridFunction(GridFunction &&)=default
void setFieldInfo(const Vtk::FieldInfo &info)
Set all the parameters from a FieldInfo object.
Definition gridfunction.hh:240
std::string const & name() const
Return a name associated with the function.
Definition gridfunction.hh:174
GridFunction(const GridFunction &other)
Copy constructor, clones the underlying implementation.
Definition gridfunction.hh:138
GridFunction(F &&f)
Constructor. Pass any type F supporting the Function interface wrappers that provides the field infor...
Definition gridfunction.hh:111
friend LocalFunction localFunction(GridFunction const &self)
Create the associated local function.
Definition gridfunction.hh:168
const std::vector< int > & components() const
Return the components vector.
Definition gridfunction.hh:194
void setDataType(Vtk::DataTypes type)
Set the data-type for the components.
Definition gridfunction.hh:219
Vtk::DataTypes dataType() const
Return the VTK Datatype associated with the functions range type.
Definition gridfunction.hh:213
Vtk::RangeTypes rangeType() const
The category of the range, SCALAR, VECTOR, TENSOR, or UNSPECIFIED.
Definition gridfunction.hh:225
GridFunction()=default
Default Constructor, creates an invalid function that must be assigned a valid function object.
void setRangeType(Vtk::RangeTypes type, std::size_t ncomp=1)
Set the category of the range, SCALAR, VECTOR, TENSOR, or UNSPECIFIED.
Definition gridfunction.hh:231
double evaluate(int i, Domain const &x) const
Evaluate the ith component of the Range value at coordinate x
Definition gridfunction.hh:161
void setComponents(int ncomps)
Set the number of components of the Range and generate component range [0...ncomps)
Definition gridfunction.hh:207
A Vtk::LocalFunction is a function-like object that can be bound to a grid element an that provides a...
Definition localfunction.hh:74
Definition types.hh:248
int size() const
The number of components in the data field.
Definition types.hh:273
std::string const & name() const
The name of the data field.
Definition types.hh:267
Vtk::RangeTypes rangeType() const
Return the category of the stored range.
Definition types.hh:279
Vtk::DataTypes dataType() const
Return the data tpe of the data field.
Definition types.hh:285
T forward(T... args)
T iota(T... args)
T min(T... args)
T size(T... args)