KASKADE 7 development version
shapefunctioncache.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-2019 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 SHAPEFUNCTIONCACHE_HH
14#define SHAPEFUNCTIONCACHE_HH
15#include <map>
16#include <tuple>
17
18#include "boost/multi_array.hpp"
19#include "boost/signals2.hpp"
20#include "boost/thread.hpp"
21
22#include <boost/fusion/algorithm.hpp>
23#include <boost/fusion/sequence.hpp>
24#include <boost/mpl/int.hpp>
25#include <boost/mpl/range_c.hpp>
26
27#include "dune/geometry/quadraturerules.hh"
28#include "dune/istl/bvector.hh"
29
30#include "fem/fetransfer.hh"
32#include "linalg/tensor.hh"
34
35
36//---------------------------------------------------------------------
37namespace Kaskade
38{
51 template <typename Scalar, int dim, int components=1>
53 {
55
60
66 explicit VariationalArg(ValueType const& value_)
67 : value(value_), derivative(0), hessian(0) {}
68
69
72 : value(value_), derivative(derivative_), hessian(0) {}
73
77 : value(value_), derivative(derivative_), hessian(hessian_) {}
78
79
84
90 };
91
92 //------------------------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------------------------
94
114 template <class G, class T, int ComponentsEnd=4>
116 {
117
118 private:
119 typedef typename boost::mpl::range_c<int,1,ComponentsEnd>::type ComponentRange;
120
121 // This is a functor that, given a number of
122 // components (a boost::mpl integer), defines an associative container type
123 // with a tuple (shape function set address, quadrature rule address) as key
124 // and a twodimensional boost::multi_array of pairs of vector and
125 // matrix with given components as value type.
126 struct MakeMapType
127 {
128 template <class Int>
129 auto operator()(Int i)
130 {
131 static int const nComp = Int::value;
132
133 typedef VariationalArg<T,G::dimension,nComp> EntryType;
134 typedef boost::multi_array<EntryType,2> DataType;
136 typedef std::tuple<Sfs const*,void const*> KeyType;
137 return std::map<KeyType,DataType>();
138 }
139 };
140
141 typedef typename boost::fusion::result_of::as_vector<
142 typename boost::fusion::result_of::transform<ComponentRange,MakeMapType>::type
143 >::type MapsType;
144
145 public:
146
153 template <int nComp>
154 struct DataType
155 {
156 typedef typename std::result_of<MakeMapType(boost::mpl::int_<nComp>)>::type::mapped_type type;
157 };
158
165 template <int nComp>
167 {
168 typedef typename DataType<nComp>::type::template const_array_view<1>::type type;
169 };
170
171
179 template <int nComp, int subDim>
181 Dune::QuadratureRule<typename G::ctype,subDim> const& qr, int ip, int subId)
182 {
183 assert(0<=isf && isf<sfs.size());
184 assert(0<=ip && ip<qr.size());
185 return get(sfs,qr,subId)[ip][isf].value;
186 }
187
195 template <int nComp, int subDim>
198 int subId)
199 {
200 assert(0<=isf && isf<sfs.size());
201 assert(0<=ip && ip<qr.size());
202 return get(sfs,qr,subId)[ip][isf].derivative;
203 }
204
218 template <int nComp, int subDim>
221 Dune::QuadratureRule<typename G::ctype,subDim> const& qr, int ip, int subId)
222 {
223 typedef typename DataType<nComp>::type DType;
224 typedef typename DType::index_range range;
225 typename DType::index_gen indices;
226 assert(sfs.size()>=0);
227 return get(sfs,qr,subId)[indices[ip][range(0,sfs.size())]];
228 }
229
230
244 template <int nComp, int subDim>
247 {
248 return get(sfs,qr,subId);
249 }
250
251
252
257 {
258 return maxSubId;
259 }
260
261 private:
262 // TODO: use boost::container::flat_map from boost 1.49 on
263 static int const maxSubId = 11; // 12 edges in a cube - that's the upper limit (up to 3d, of course...)
264
265 // For each subentity number, we maintain a different cache for direct access
266 MapsType caches[maxSubId+1];
267
268 template <int nComp, int subDim>
269 typename DataType<nComp>::type const&
271 {
272 assert(0<=subId && subId<=maxSubId);
273 using MapType = typename std::result_of<MakeMapType(boost::mpl::int_<nComp>)>::type;
274 typedef typename MapType::key_type KeyType;
275 typedef typename DataType<nComp>::type DType;
276 MapType& cache = boost::fusion::at_c<nComp-1>(caches[subId]);
277
278 typename MapType::const_iterator i = cache.find(KeyType(&sfs,&qr));
279
280 // check whether the shape functions' values are already available
281 if (i==cache.end())
282 {
283 // No, they are not. Evaluate shape functions and store the result.
285 auto const& refElem = sfs.referenceElement();
286 assert(sfs.size()>=0);
287 DType data(boost::extents[qr.size()][sfs.size()]);
288
289 if (G::dimension != subDim)
290 for (int isf=0; isf<sfs.size(); ++isf)
291 for (int ip=0; ip<qr.size(); ++ip)
292 {
293 {
294 boost::mutex::scoped_lock lock(refElementMutex);
295 pos = refElem.template geometry<G::dimension-subDim>(subId).global(qr[ip].position());
296 }
297 data[ip][isf].value = sfs[isf].evaluateFunction(pos);
298 data[ip][isf].derivative = sfs[isf].evaluateDerivative(pos);
299 data[ip][isf].hessian = sfs[isf].evaluate2ndDerivative(pos);
300 }
301 else
302 for (int isf=0; isf<sfs.size(); ++isf)
303 for (int ip=0; ip<qr.size(); ++ip)
304 {
305 pos = refElem.template geometry<G::dimension-subDim>(subId).global(qr[ip].position());
306 data[ip][isf].value = sfs[isf].evaluateFunction(pos);
307 data[ip][isf].derivative = sfs[isf].evaluateDerivative(pos);
308 data[ip][isf].hessian = sfs[isf].evaluate2ndDerivative(pos);
309 }
310
311 // store the values, obtaining an iterator pointing to the newly inserted values
312 i = cache.insert(cache.begin(),typename MapType::value_type(KeyType(&sfs,&qr),data));
313 }
314
315 // From here on, the values are in the map (at the position pointed to by i).
316 return i->second;
317 }
318 };
319} // end of namespace Kaskade
320//---------------------------------------------------------------------
321//---------------------------------------------------------------------
322
323
324#endif
This class caches values and derivatives of shape functions at quadrature points.
int maximumSubentityIndex() const
Reports the maximum subentity number that is allowed.
DataType< nComp >::type const & evaluate(ShapeFunctionSet< typename G::ctype, G::dimension, T, nComp > const &sfs, Dune::QuadratureRule< typename G::ctype, subDim > const &qr, int subId)
Returns the values of all shape functions.
Dune::FieldVector< T, nComp > evaluateFunction(ShapeFunctionSet< typename G::ctype, G::dimension, T, nComp > const &sfs, int isf, Dune::QuadratureRule< typename G::ctype, subDim > const &qr, int ip, int subId)
Evaluate comp-th component of isf-th shape function of the shape function set sfs ath the ip-th integ...
Dune::FieldMatrix< T, nComp, G::dimension > const & evaluateDerivative(ShapeFunctionSet< typename G::ctype, G::dimension, T, nComp > const &sfs, int isf, Dune::QuadratureRule< typename G::ctype, subDim > const &qr, int ip, int subId)
Evaluate derivative of comp-th component of isf-th shape function of the shape function set sfs ath t...
LocalDataType< nComp >::type evaluate(ShapeFunctionSet< typename G::ctype, G::dimension, T, nComp > const &sfs, Dune::QuadratureRule< typename G::ctype, subDim > const &qr, int ip, int subId)
Returns the values of all shape functions at given integration point.
A set of shape functions.
virtual int size() const
Number of shape functions in the set.
Tools for transfer of data between grids.
boost::mutex refElementMutex
A global lock for the Dune::GenericReferenceElement singletons, which are not thread-safe.
Defines the type returned by evaluate(sfs,qr,subId).
std::result_of< MakeMapType(boost::mpl::int_< nComp >)>::type::mapped_type type
Defines the type returned by evaluate(sfs,qr,ip,subId).
DataType< nComp >::type::template const_array_view< 1 >::type type
A class that stores values, gradients, and Hessians of evaluated shape functions.
VariationalArg(ValueType const &value_, Dune::FieldMatrix< Scalar, components, dim > const &derivative_, Tensor< Scalar, components, dim, dim > const &hessian_)
Dune::FieldMatrix< Scalar, components, dim > derivative
The shape function's spatial derivative, a components x dim matrix.
ValueType value
The shape function's value, a vector of dimension components
VariationalArg(ValueType const &value_, Dune::FieldMatrix< Scalar, components, dim > const &derivative_)
VariationalArg(ValueType const &value_)
Constructor.
Tensor< Scalar, components, dim, dim > hessian