KASKADE 7 development version
functionspace.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-2023 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 FUNCTIONSPACE_HH
14#define FUNCTIONSPACE_HH
15
30#include <cassert>
31#include <map>
32#include <sstream>
33
34#include <boost/mpl/int.hpp>
35#include <boost/mpl/range_c.hpp>
36#include <boost/multi_array.hpp>
37#include <boost/signals2.hpp>
38#include <boost/type_traits/remove_pointer.hpp>
39#include <boost/type_traits/remove_reference.hpp>
40
41#include <boost/fusion/algorithm.hpp>
42#include <boost/fusion/sequence.hpp>
43
44#include "dune/common/config.h"
45// #include "dune/common/dynmatrixev.hh"
46#include "dune/common/fmatrixev.hh"
47#include "dune/geometry/quadraturerules.hh"
48#include "dune/istl/bvector.hh"
49
50#include "fem/gridmanager.hh"
53#include "linalg/crsutil.hh"
55
56namespace Kaskade
57{
58
59 // forward declarations
60 template <class LocalToGlobalMapper> class FEFunctionSpace;
61
62 template <template <class, class> class, class, class> class BoundaryMapper;
63
65 namespace FunctionSpace_Detail
66 {
67 template <class Mapper>
68 struct IsBoundaryMapperStruct : std::false_type {};
69 template<template <class, class> class DomainMapper, class Scalar, class GridView>
70 struct IsBoundaryMapperStruct<BoundaryMapper<DomainMapper,Scalar,GridView>> : std::true_type {};
71 // if Mapper is a BoundaryMapper this returns true, otherwise false
72 template <class Mapper>
73 constexpr bool isBoundaryMapper() {
74 return IsBoundaryMapperStruct<Mapper>::value;
75 }
76
77 template <class Mapper>
78 struct ChooseDomainMapperStruct {
79 using type = void;
80 };
81 template<template <class, class> class DomainMapper, class Scalar, class GridView>
82 struct ChooseDomainMapperStruct<BoundaryMapper<DomainMapper,Scalar,GridView>> {
83 using type = DomainMapper<Scalar,GridView>;
84 };
85 // if Mapper is a BoundaryMapper this gives the underlying FE mapper, otherwise it gives the void type
86 template<class Mapper>
87 using ChooseDomainMapper = typename ChooseDomainMapperStruct<Mapper>::type;
88
89 // checks whether two LeafGridViews are the same (i.e. whether they belong to the same grid (tested by memory address of grid))
90 template<class Grid>
91 bool gridViewsAreSame(typename Grid::LeafGridView gv1, typename Grid::LeafGridView gv2) {
92 return &(gv1.grid()) == &(gv2.grid());
93 }
94 // checks whether two LevelGridViews are the same (i.e. whether they belong to the same grid and are of the same level)
95 template<class Grid>
96 bool gridViewsAreSame(typename Grid::LevelGridView gv1, typename Grid::LevelGridView gv2) {
97 return (gv1.template begin<0>()->level() == gv2.template begin<0>()->level()) && (&(gv1.grid()) == &(gv2.grid()));
98 }
99
100 // --------------------------------------------------------------------------------------------
101
102 enum CoefficientTransfer { START, FINISH };
103 }
105
115
116 //---------------------------------------------------------------------
117 //---------------------------------------------------------------------
118
130 template <class Spaces, int Idx>
132 {
133 using type = std::remove_pointer_t<typename boost::fusion::result_of::value_at_c<Spaces,Idx>::type>;
134 };
135
136
137 //---------------------------------------------------------------------
138 //---------------------------------------------------------------------
139
157 template <class Cell, class ctype>
158 std::pair<Cell,Dune::FieldVector<ctype,Cell::dimension>>
160 {
161 ctype const tol = 100*std::numeric_limits<ctype>::epsilon();
162 assert(checkInside(cell.type(),xi) < tol);
163 assert(level>=0);
164
165 using namespace Dune;
166
167 if (level <= cell.level()) // go downwards - that's easy
168 {
169 while (level < cell.level())
170 {
171 xi = cell.geometryInFather().global(xi);
172 cell = cell.father();
173 }
174 }
175 else // go upwards - we have to check in which child the position is
176 {
177 // Move up if we have not yet blundered into the leaf or the max level
178 while (cell.level()<level && !cell.isLeaf())
179 // Check all the direct children
180 for (Cell const& c: descendantElements(cell,cell.level()+1))
181 {
182 auto xiC = c.geometryInFather().local(xi);
183 // and if the point is inside one child, that's it
184 if (checkInside(c.type(),xiC) < tol)
185 {
186 cell = c;
187 xi = xiC;
188 break;
189 }
190 }
191 }
192
193 return std::make_pair(cell,xi);
194 }
195
196
197 //---------------------------------------------------------------------
198
199
212 template <class GridView>
214 {
215 const double tol = 1e-12 ;
216
217 using namespace Dune;
218
219 // Do linear search on coarse grid (level 0).
220 auto coarseIterator = std::find_if(gv.grid().levelGridView(0).template begin<0>(), gv.grid().levelGridView(0).template end<0>(),
221 [&](Cell<GridView> const& cell)
222 {
223 return checkInside(cell.type(),cell.geometry().local(global)) < tol;
224 });
225
226 if (coarseIterator == gv.grid().levelGridView(0).template end<0>()) // not found
227 {
228 std::ostringstream msg;
229 msg << "findCell(): global point << " << global << " is not contained in any level 0 cell in the grid!";
230 msg.flush();
231 throw LookupException(msg.str(),__FILE__,__LINE__);
232 }
233
234 // Do a hierarchical search for a leaf cell containing the point.
235 Cell<GridView> ci(*coarseIterator);
236
237 int lastFound = 0;
238
239 for( int level = 0; level <= gv.grid().maxLevel(); level++ )
240 {
241 if (ci.isLeaf())
242 return ci;
243
244 for (auto hi = ci.hbegin(level+1); hi != ci.hend(level+1) ; ++hi)
245 if( checkInside(hi->type(),hi->geometry().local(global)) < tol )
246 {
247 ci = typename GridView::Grid::template Codim<0>::Entity(*hi);
248 lastFound = level;
249 break ;
250 }
251 }
252
253 // We should never get here... For a position outside the domain, no coarse grid cell should have been
254 // found, leading to an exception being raised above. If, on the other hand, a coarse grid cell has been
255 // found, there should be a leaf cell containing the given point as well.
256 std::cerr << "findCell() at " << __FILE__ << ':' << __LINE__ << '\n'
257 << "Global point << " << global
258 << " is not contained in any cell in the grid!\n"
259 << " last found on " << lastFound << " of " << gv.grid().maxLevel() << "\n";
260 abort();
261 return ci; // never get here! (just for formal correctness return something)
262 }
263
264
265 //---------------------------------------------------------------------
266
267
313 template <class FunctionSpace, int m>
315 {
316 public:
318 using Space = FunctionSpace;
319
321 using GridView = typename Space::GridView;
322
324 using ctype = typename GridView::ctype;
325
329 typedef typename Space::Scalar Scalar;
330
336 using field_type = typename Space::field_type;
337
340
344 using SfValueType = typename Space::SfValueType;
345
352
355
357 static int const components = Space::sfComponents * m;
358
361
375
378
379
390 data(fs.degreesOfFreedom()), sp(&fs), transferMe(*this)
391 {
392 data = 0;
393 transferConnection = sp->requestToRefine.connect(transferMe);
394 }
395
398 data(fse.data), sp(fse.sp), transferMe(*this)
399 {
400 transferConnection = sp->requestToRefine.connect(transferMe);
401 }
402
404 {
405 transferConnection.disconnect();
406 sp = 0;
407 }
408
425 Self& operator=(Self const& fse)
426 {
427 if(this != &fse) // nothing to do on self-assignment
428 {
429 if (sp == fse.sp) // the same function space
430 data = fse.data;
431 else // different function spaces
432 interpolateGlobally<PlainAverage>(*this,fse);
433 }
434 return *this;
435 }
436
445 {
446 if(this != &fse) { // nothing to do on self-assignment
447 if (sp == fse.sp) // the same function space
448 {
449 data = std::move(fse.data);
450 fse.transferConnection.disconnect();
451 }
452 else // different function spaces
453 interpolateGlobally<PlainAverage>(*this,fse);
454 }
455 return *this;
456 }
457
466 template <class OtherSpace>
468 {
469 interpolateGlobally<PlainAverage>(*this,f);
470 return *this;
471 }
472
483 template <template <class, class> class DomainMapper>
485 {
486 bool hasEquivalentUnderlyingMapper = !FunctionSpace_Detail::isBoundaryMapper<typename Space::Mapper>();
487 hasEquivalentUnderlyingMapper = (hasEquivalentUnderlyingMapper && std::is_same<DomainMapper<Scalar,typename Space::GridView>, typename Space::Mapper>::value);
488 hasEquivalentUnderlyingMapper = (hasEquivalentUnderlyingMapper && space().mapper().maxOrder()==bf.space().mapper().maxOrder());
489 hasEquivalentUnderlyingMapper = (hasEquivalentUnderlyingMapper && FunctionSpace_Detail::gridViewsAreSame<typename Space::GridView::Grid>(space().gridView(),bf.space().gridView()));
490 if(hasEquivalentUnderlyingMapper) {
491 BoundaryMapper<DomainMapper, Scalar, typename Space::GridView> const& boundaryMapper = bf.space().mapper();
492 *this = 0.0;
493 for(typename StorageType::size_type vi=0;vi<size();++vi) {
494 std::pair<bool,typename StorageType::size_type> restrictedIndex = boundaryMapper.unrestrictedToRestrictedIndex(vi);
495 if(restrictedIndex.first) {
496 data[vi] = bf[restrictedIndex.second];
497 }
498 }
499 } else {
500 // TODO: When interpolateGlobally works correctly (better said: as one would expect) for boundary functions as second argument remove the following three lines
501 FEFunctionSpace<DomainMapper<Scalar,typename Space::GridView>> domainSpace(bf.space().gridManager(),bf.space().gridView(),bf.space().mapper().maxOrder());
502 typename FEFunctionSpace<DomainMapper<Scalar,typename Space::GridView>>::template Element_t<m> df(domainSpace);
503 df = bf;
504 interpolateGlobally<PlainAverage>(*this,df);
505 }
506 return *this;
507 }
508
517 template <class Mapper>
518 std::enable_if_t<std::is_same<Mapper,FunctionSpace_Detail::ChooseDomainMapper<typename Space::Mapper>>::value,Self&>
520 {
521 bool hasEquivalentUnderlyingMapper = FunctionSpace_Detail::isBoundaryMapper<typename Space::Mapper>();
522 hasEquivalentUnderlyingMapper = (hasEquivalentUnderlyingMapper && space().mapper().maxOrder()==f.space().mapper().maxOrder());
523 hasEquivalentUnderlyingMapper = (hasEquivalentUnderlyingMapper && FunctionSpace_Detail::gridViewsAreSame<typename Space::GridView::Grid>(space().gridView(),f.space().gridView()));
524 if (hasEquivalentUnderlyingMapper)
525 {
526 typename Space::Mapper const& boundaryMapper = space().mapper();
527 for(typename StorageType::size_type vi=0;vi<f.size();++vi)
528 {
529 std::pair<bool,typename StorageType::size_type> restrictedIndex = boundaryMapper.unrestrictedToRestrictedIndex(vi);
530 if (restrictedIndex.first)
531 data[restrictedIndex.second] = f[vi];
532 }
533 }
534 else
535 interpolateGlobally<PlainAverage>(*this,f);
536
537 return *this;
538 }
539
554 template <class Functor>
556 {
558 return *this;
559 }
560
574 template <class Space, class Functor>
576 {
577 interpolateGlobally(*this,f);
578 return *this;
579 }
580
587 {
588 assert(data.size()==v.size());
589 data = v;
590 return *this;
591 }
592
599 Self& operator=(StorageValueType const& a) { for (int i=0; i<data.N(); ++i) data[i] = a; return *this; }
600
607 Self& operator=(Scalar val) { for(size_t i=0; i<data.N(); ++i) data[i] = val; return *this; }
608
622 Self& operator+=(Self const& f)
623 {
624 if (sp==f.sp) // same function space
625 coefficients() += f.coefficients();
626 else {
627 Self tmp(space()); tmp = f; *this += tmp;
628 }
629 return *this;
630 }
631
637 template <class OtherSpace>
639 {
640 Self tmp(space()); tmp = f; *this += tmp;
641 return *this;
642 }
643
647 Self& operator+=(StorageType const& v) { assert(data.size()==v.size()); data += v; return *this; }
648
655 {
656 for (int i=0; i<data.N(); ++i)
657 data[i] += val;
658 return *this;
659 }
660
668 {
669 if (sp==f.sp) // same function space
670 coefficients() -= f.coefficients();
671 else {
672 Self tmp(space()); tmp = f; *this -= tmp;
673 }
674 return *this;
675 }
676
682 template <class OtherSpace>
684 {
685 Self tmp(space()); tmp = f; *this -= tmp;
686 return *this;
687 }
688
693 {
694 assert(data.size()==v.size());
695 data -= v;
696 return *this;
697 }
698
704 Self& axpy(Scalar a, Self const& f)
705 {
706 if (sp==f.sp) // same function space
707 coefficients().axpy(a,f.coefficients());
708 else {
709 Self tmp(space()); tmp = f; this->axpy(a,tmp);
710 }
711 return *this;
712 }
713
719 template <class OtherSpace>
721 {
722 Self tmp(space()); tmp = f; this->axpy(a,tmp);
723 return *this;
724 }
725
729 Self& axpy(Scalar a, StorageType const& v) { assert(data.size()==v.size()); data.axpy(a,v); return *this; }
730
732 Self& operator*=(Scalar a) { data *= a; return *this; }
733
752 ValueType value(typename Space::Evaluator const& evaluator) const
753 {
754 ValueType y(0);
755
756 size_t esize = evaluator.size();
757
758 for (size_t i=0; i<esize; ++i)
759 {
760 StorageValueType const& coeff = data[evaluator.globalIndices()[i]];
761 auto const& sfVal = evaluator.evalData[i].value;
762 for (int n=0; n<m; ++n)
763 for (int l=0; l<Space::sfComponents; ++l)
764 y[n*Space::sfComponents+l] += coeff[n]*sfVal[l];
765 }
766
767 return y;
768 }
769
777 LocalPosition<GridView> const& local) const
778 {
779 typename Space::Evaluator eval(space());
780 eval.moveTo(cell);
781 eval.evaluateAt(local);
782
783 return value(eval);
784 }
785
793 {
794 auto cell = findCell(space().gridView(),x); // throws LookupException if no cell is found
795 auto xi = cell.geometry().local(x); // may end up slightly outside of reference element
796 // due to rounding errors...
797 return value(cell,xi); // ... but this should have a negligible impact.
798 }
799
800
807 DerivativeType derivative(typename FunctionSpace::Evaluator const& evaluator) const
808 {
809 DerivativeType dy(0);
810
811 size_t esize = evaluator.size();
812 for (size_t i=0; i<esize; ++i) // step through all restricted ansatz functions
813 {
814 auto const& coeff = data[evaluator.globalIndices()[i]];
815 auto const& sfGrad = evaluator.evalData[i].derivative;
816 for (int n=0; n<m; ++n) // step through all FE function components
817 for (int l=0; l<Space::sfComponents; ++l) // step through all shape function components
818 dy[n*Space::sfComponents+l] += coeff[n] * sfGrad[l];
819 }
820
821 return dy;
822 }
823
831 LocalPosition<GridView> const& local) const
832 {
833 typename Space::Evaluator eval(space());
834 eval.moveTo(cell);
835 eval.evaluateAt(local);
836
837 return derivative(eval);
838 }
839
846 {
847 auto ci = findCell(space().gridView(),global) ;
848
849 return derivative(ci,ci.geometry().local(global));
850 }
851
852
859 HessianType hessian(typename FunctionSpace::Evaluator const& evaluator) const
860 {
861 HessianType ddy(0);
862
863 assert(evaluator.derivatives() >= 2);
864
865 size_t esize = evaluator.size();
866 for (size_t i=0; i<esize; ++i) {
867 StorageValueType const& coeff = data[evaluator.globalIndices()[i]];
868 auto const& sfHess = evaluator.evalData[i].hessian;
869 for (int n=0; n<m; ++n)
870 for (int l=0; l<Space::sfComponents; ++l) {
871 auto hess = sfHess[l];
872 hess *= coeff[n];
873 ddy[n*Space::sfComponents+l] += hess;
874 }
875 }
876
877 return ddy;
878 }
879
887 LocalPosition<GridView> const& local) const
888 {
889 typename Space::Evaluator eval(space(),nullptr,2);
890 eval.moveTo(cell);
891 eval.evaluateAt(local);
892
893 return hessian(eval);
894 }
895
902 {
903 auto ci = findCell(space().gridView(),global);
904 return hessian(ci,ci.geometry().local(global));
905 }
906
919 StorageType const& coefficients() const { return data; }
920
925
929 StorageValueType& operator[](size_t i) { return data[i]; }
930
934 StorageValueType const& operator[](size_t i) const { return data[i]; }
935
946 int dim() const { return data.dim(); }
947
954 int size() const { assert(data.size()*m==dim()); return data.size(); }
955
959 Space const& space() const { return *sp; }
960
964 int order(Cell<GridView> const& cell) const
965 {
966 return space().mapper().shapefunctions(cell).order();
967 }
968
970 // Why not simply calling sfs.order directly? Can we delete this method?
971 template<class SFS>
972 [[deprecated]] int order(SFS const& sfs) const
973 {
974 return sfs.order();
975 }
976
982 void transfer(typename TransferData<Space>::TransferMatrix const& transferMatrix)
983 {
984 std::unique_ptr<Dune::BlockVector<StorageValueType>> newCoeff = transferMatrix.apply(data);
985 data = *newCoeff;
986 }
987
992 private:
993
994 struct TransferMe
995 {
996 TransferMe(Self& fe) : myFSE(fe) {}
997
998 TransferMe(TransferMe const& other)
999 : myFSE(other.myFSE)
1000 {}
1001
1002 void operator()(typename TransferData<Space>::TransferMatrix const* transfer)
1003 {
1004 if (transfer)
1005 {
1006 // auto f = [&]() { myFSE.transfer(*transfer); };
1007 // f();
1008 future = std::async(std::launch::async,[transfer,f=&myFSE]() { f->transfer(*transfer); });
1009 }
1010 else
1011 {
1012 assert(future.valid());
1013 future.get();
1014 }
1015 }
1016
1017 private:
1018 Self& myFSE;
1019 std::future<void> future;
1020 };
1021
1022
1023
1024 protected:
1026 Space const* sp;
1027
1028 private:
1029 TransferMe transferMe;
1030 boost::signals2::connection transferConnection;
1031 };
1032
1038 template <class Space, int m, class OutIter>
1039 OutIter vectorToSequence(FunctionSpaceElement<Space,m> const& v, OutIter iter)
1040 {
1041 return vectorToSequence(v.coefficients(),iter);
1042 }
1043
1044 template <class Space, int m, class InIter>
1046 {
1047 return vectorFromSequence(v.coefficients(),in);
1048 }
1049
1050 namespace FunctionSpace_Detail
1051 {
1052 // if an FEFunction is restricted to the boundary transform it in to a new FEFunction over the whole domain,
1053 // otherwise leave it unchanged. Used by writeVTK.
1054 template <class FEFunction>
1056 public:
1057 ToDomainRepresentation(FEFunction const& f_) : f(f_){}
1058
1059 FEFunction const& get() const {
1060 return f;
1061 }
1062
1063 private:
1064 FEFunction const& f;
1065 };
1066
1067 template <template <class, class> class DomainMapper, typename Scalar, typename GridView, int m>
1069 {
1070
1073 using DomainFESpace = typename DomainFEFunction::Space;
1074
1075 public:
1076 ToDomainRepresentation(BoundaryFEFunction const& f_) : space(f_.space().gridManager(),f_.space().gridView(),f_.space().mapper().maxOrder()), f(space) {
1077 f = f_;
1078 }
1079
1080 DomainFEFunction const& get() const {
1081 return f;
1082 }
1083
1084 private:
1085 DomainFESpace space;
1086 DomainFEFunction f;
1087 };
1088 }
1089
1090 //---------------------------------------------------------------------
1091 //---------------------------------------------------------------------
1092
1115 template <class LocalToGlobalMapper>
1117 {
1119
1120 public:
1122 using GridView = typename LocalToGlobalMapper::GridView;
1124 typedef typename GridView::Grid Grid;
1126 typedef typename GridView::IndexSet IndexSet;
1127
1129 typedef typename LocalToGlobalMapper::Scalar Scalar;
1130
1136
1138 typedef typename Grid::ctype ctype;
1139
1141 typedef LocalToGlobalMapper Mapper;
1142
1144 static int const dim = Grid::dimension;
1145
1147 static int const dimworld = Grid::dimensionworld;
1148
1152 static int const sfComponents = Mapper::ShapeFunctionSet::comps;
1153
1161 static int const continuity = Mapper::continuity;
1162
1166 template <int m>
1167 struct [[deprecated]] Element
1168 {
1170 };
1171
1180 template <int m>
1182
1193 {
1194 typedef typename IndexSet::IndexType IndexType;
1195
1197 typedef Self Space;
1198
1203
1207 static int const sfComponents = Mapper::ShapeFunctionSet::comps;
1208
1213
1217 typedef typename Mapper::GlobalIndexRange GlobalIndexRange;
1218
1222 typedef typename Mapper::SortedIndexRange SortedIndexRange;
1223
1233 Evaluator(Self const& space_, ShapeFunctionCache<Grid,Scalar>* cache_=nullptr, int deriv_ = 1) :
1234 space(space_), sf(nullptr), cache(cache_), sfValues(nullptr), combiner_(nullptr),
1235 globIdx(space.mapper().initGlobalIndexRange()), sortedIdx(space.mapper().initSortedIndexRange()),
1236 deriv(deriv_), currentCell(nullptr)
1237 { }
1238
1242 Evaluator(Evaluator const& eval):
1243 evalData(eval.evalData),
1244 space(eval.space), sf(eval.sf), sfSize(eval.sfSize), cache(eval.cache), sfValues(eval.sfValues), lastQr(eval.lastQr), lastSubId(eval.lastSubId), combiner_(nullptr),
1245 globIdx(eval.globIdx), sortedIdx(eval.sortedIdx), deriv(eval.deriv), currentXloc(eval.currentXloc), currentCell(nullptr)
1246 {
1247 if (eval.combiner_)
1248 combiner_ = std::make_unique<typename Mapper::Combiner>(*eval.combiner_);
1249 if (eval.currentCell)
1250 currentCell = std::make_unique<Cell>(*eval.currentCell);
1251 }
1252
1257 {
1258 assert(&space==&eval.space);
1259 sf = eval.sf;
1260 sfSize = eval.sfSize();
1261 cache = eval.cache;
1262 sfValues = eval.sfValues;
1263 lastQr = nullptr;
1264 lastSubId = -1;
1265 converter = eval.converter;
1266 if (eval.combiner_) {
1267 combiner_ = std::make_unique<typename Mapper::Combiner>(*eval.combiner_);
1268 } else {
1269 combiner_.reset();
1270 }
1271 globIdx = eval.globIdx;
1272 sortedIdx = eval.sortedIdx;
1273 evalData = eval.evalData;
1274 deriv = eval.deriv;
1275 currentXloc = eval.currentXloc;
1276 if (eval.currentCell) {
1277 currentCell = std::make_unique<Cell>(*eval.currentCell);
1278 } else {
1279 currentCell.reset();
1280 }
1281
1282 return *this;
1283 }
1284
1297 void moveTo(Cell const& cell, IndexType const index)
1298 {
1299 sf = &space.mapper().shapefunctions(index);
1300 sfSize = sf->size();
1301 assert(sfSize>=0);
1302
1303 currentCell = std::make_unique<Cell>(cell);
1304
1305 converter.moveTo(*currentCell);
1306
1307 combiner_ = std::make_unique<typename Mapper::Combiner>(space.mapper().combiner(*currentCell,index));
1308
1309 globIdx = space.mapper().globalIndices(index);
1310 sortedIdx = space.mapper().sortedIndices(index);
1311 }
1312
1319 void moveTo(Cell const& cell)
1320 {
1321 moveTo(cell,space.indexSet().index(cell));
1322 }
1323
1334 template <int subDim>
1336 {
1337 // reusing data does not work for boundary mapper in its current (non optimal) implementation,
1338 // where every cell has its own restricted shape function set.
1339 // TODO: When the implementation of boundary mapper is improved (i.e. all cells use the
1340 // same shape function set and restriction is handled by the Combiner) remove the following line.
1341 if(FunctionSpace_Detail::isBoundaryMapper<Mapper>())
1342 return;
1343 // check whether we have the data corresponding to the lookup key (qr,subId) already available
1344 if (sfValues && lastQr==&qr && lastSubId==subId)
1345 return;
1346
1347 if (cache)
1348 {
1349 sfValues = &cache->evaluate(*sf,qr,subId); // extract data from cache
1350 lastQr = &qr; // remember extraction key
1351 lastSubId = subId;
1352 }
1353 }
1354
1359 {
1360 currentXloc = xi;
1361 evalData.clear();
1362
1363 converter.setLocalPosition(xi);
1364
1365 evalData.reserve(sfSize);
1366 for (int i=0; i<sfSize; ++i)
1367 {
1369
1370 typename Mapper::ShapeFunctionSet::value_type const& sfun = (*sf)[i];
1371 evalData.push_back( derivatives()<=1?
1372 converter.global(SfArg(sfun.evaluateFunction(xi),sfun.evaluateDerivative(xi)),1) :
1373 converter.global(SfArg(sfun.evaluateFunction(xi),sfun.evaluateDerivative(xi),sfun.evaluate2ndDerivative(xi)),2) );
1374 }
1375 combiner_->rightTransform(evalData);
1376 }
1377
1386 template <int subDim>
1388 Dune::QuadratureRule<typename Grid::ctype,subDim> const& qr, int ip, int subId)
1389 {
1390 if (cache)
1391 {
1392 currentXloc = x;
1393 evalData.clear();
1394 converter.setLocalPosition(x);
1395
1396 if (sfValues)
1397 for (int i=0; i<sfSize; ++i)
1398 evalData.push_back( converter.global((*sfValues)[ip][i],derivatives()) );
1399 else
1400 {
1401 auto const& localData = cache->evaluate(*sf,qr,ip,subId);
1402
1403 for (int i=0; i<sfSize; ++i)
1404 evalData.push_back( converter.global(localData[i],derivatives()) );
1405 }
1406
1407 combiner_->rightTransform(evalData);
1408 }
1409 else
1410 evaluateAt(x);
1411 }
1412
1414 GlobalIndexRange globalIndices() const { return globIdx; }
1415
1419 SortedIndexRange sortedIndices() const { return sortedIdx; }
1420
1425 int size() const
1426 {
1427 return globalIndices().size();
1428 }
1429
1430
1432 int order() const { return sf->order(); }
1433
1435 typename Mapper::ShapeFunctionSet const& shapeFunctions() const { return *sf; }
1436
1438 typename Mapper::Combiner const& combiner() const { return *combiner_; }
1439
1445 std::vector<VarArg> evalData;
1446
1450 GridView const& gridView() const
1451 {
1452 return space.gridView();
1453 }
1454
1455 LocalToGlobalMapper const& mapper() const
1456 {
1457 return space.mapper();
1458 }
1459
1463 Cell const& cell() const
1464 {
1465 assert(currentCell);
1466 return *currentCell;
1467 }
1468
1472 Dune::FieldVector<ctype,dim> const& xloc() const { return currentXloc; }
1473
1477 int derivatives() const { return deriv; }
1478
1479 private:
1480 Self const& space;
1481 typename Mapper::ShapeFunctionSet const* sf;
1482 int sfSize;
1484 typename ShapeFunctionCache<Grid,Scalar>::template DataType<sfComponents>::type const* sfValues;
1485 void const* lastQr; // lookup key for cached shape function values
1486 int lastSubId; // lookup key for cached shape function values
1487 typename Mapper::Converter converter;
1488 std::unique_ptr<typename Mapper::Combiner> combiner_; // TODO: why held by pointer? Wouldn't a member variable make more sense and simplify things? (For this, something like a default constructor would be needed)
1489 GlobalIndexRange globIdx;
1490 SortedIndexRange sortedIdx;
1491 int deriv; // number of derivatives to evaluate
1492 Dune::FieldVector<ctype,dim> currentXloc; // local coordinates of current evaluation point
1493 std::unique_ptr<Cell> currentCell; // cell containing current evaluation point (want Evaluator to store its own Entity object
1494 // (previously it only stored a raw pointer),
1495 // unfortunately not all grid implementations (especially AluGrid) provide a
1496 // default constructor for Entity, so we cannot hold it by value.
1497 }; // end of class Evaluator
1498
1503
1521 template <typename... Args>
1523 GridView const& gridView_,
1524 Args... args)
1525 : gridman(gridMan)
1526 , m_gridView(gridView_)
1527 , mapper_(m_gridView,args...)
1528 , rtf(*this,gridman)
1529 {
1530 refConnection = gridman.signals.informAboutRefinement.connect(int(GridSignals::allocResources),rtf);
1531 }
1532
1545 : gridman(gridman_)
1546 , m_gridView(m.gridView())
1547 , mapper_(m)
1548 , rtf(*this,gridman)
1549 {
1550 refConnection = gridman.signals.informAboutRefinement.connect(int(GridSignals::allocResources),rtf);
1551 }
1552
1557 gridman(fs.gridman),
1558 m_gridView(fs.m_gridView),
1559 mapper_(fs.mapper()),
1560 rtf(*this,gridman)
1561 {
1562 refConnection = gridman.signals.informAboutRefinement.connect(int(GridSignals::allocResources),rtf);
1563 }
1564
1566 {
1567 refConnection.disconnect();
1568 }
1569
1574 size_t degreesOfFreedom() const { return mapper_.size(); }
1575
1576
1580 Grid const& grid() const { return gridman.grid(); }
1581
1586 GridManagerBase<Grid>& gridManager() const { return gridman; }
1587
1591 IndexSet const& indexSet() const { return m_gridView.indexSet(); }
1592
1596 GridView const& gridView() const { return m_gridView; }
1597
1601 LocalToGlobalMapper const & mapper() const { return mapper_; }
1602
1606 LocalToGlobalMapper /* const */ & mapper() /* const */ { return mapper_; }
1607
1613 Evaluator evaluator(ShapeFunctionCache<Grid,Scalar>* cache=nullptr, int deriv = 1) const { return Evaluator(*this,cache,deriv); }
1614
1620 template <int m>
1622 {
1623 return Element_t<m>(*this);
1624 }
1625
1638 std::vector<std::pair<size_t,SfValueType>> linearCombination(Evaluator const& evaluator) const
1639 {
1640 std::vector<std::pair<size_t,SfValueType>> ic;
1641
1642 size_t esize = evaluator.size();
1643 ic.reserve(esize);
1644
1645 for (size_t j=0; j<esize; ++j)
1646 {
1647 size_t i = evaluator.globalIndices()[j];
1648 auto const& c = evaluator.evalData[j].value;
1649 ic.push_back(std::make_pair(i,c));
1650 }
1651
1652 return ic;
1653 }
1654
1666 std::vector<std::pair<size_t,SfValueType>>
1668 {
1669 Evaluator eval(*this);
1670 eval.moveTo(cell);
1671 eval.evaluateAt(xi);
1672
1673 return linearCombination(eval);
1674 }
1675
1688 std::vector<std::pair<size_t,SfValueType>>
1690 {
1691 auto cell = findCell(gridView(),x); // throws LookupException if no cell is found
1692 auto xi = cell.geometry().local(x); // may end up slightly outside of reference element
1693
1694 return linearCombination(cell,xi);
1695 }
1696
1697 private:
1698
1699 // The slot class that connects to the grid manager signal to be informed about the
1700 // state of the refinement process.
1701 struct ReactToRefinement
1702 {
1703 ReactToRefinement(Self & space, GridManagerBase<Grid>& gm_)
1704 : mySpace(space), gm(gm_) {};
1705
1706 ReactToRefinement(ReactToRefinement const& rtr)
1707 : mySpace(rtr.mySpace)
1708 , gm(rtr.gm)
1709 {}
1710
1711 void operator()(typename GridSignals::Status const ref)
1712 {
1713 switch (ref)
1714 {
1716 assert(!future.valid());
1717 if (!mySpace.requestToRefine.empty()) // no functions registered -> nothing to do
1718 future = std::async(std::launch::async, // otherwise create transfer matrix data
1719 [&]() { transferData.reset(new TransferData<Self>(mySpace)); });
1720 break;
1721
1722 case GridSignals::BeforeRefinementComplete: // Now we need to have the data ready
1723 if (future.valid()) // (if there is any).
1724 future.get(); // Block execution until the data is complete.
1725 break;
1726
1728 mySpace.mapper().update(); // new grid available -> new indexing
1729 if(!mySpace.requestToRefine.empty()) // no functions registered -> nothing to do
1730 {
1731 assert(transferData!=0);
1732 assert(!future.valid());
1733 future = std::async(std::launch::async,
1734 [&]() {
1735 transferMatrix = transferData->transferMatrix();
1736 transferData.reset();
1737 mySpace.requestToRefine(transferMatrix.get());
1738 });
1739 }
1740 break;
1741
1743 if (future.valid())
1744 future.get();
1745 mySpace.requestToRefine(nullptr);
1746 transferMatrix.reset();
1747 }
1748 }
1749
1750 private:
1751 Self& mySpace;
1752 GridManagerBase<Grid>& gm;
1753 std::unique_ptr<TransferData<Self>> transferData;
1754 std::unique_ptr<typename TransferData<Self>::TransferMatrix> transferMatrix;
1755 std::future<void> future;
1756 };
1757
1758 GridManagerBase<Grid>& gridman;
1759 GridView m_gridView;
1760 LocalToGlobalMapper mapper_;
1761 ReactToRefinement rtf;
1762 boost::signals2::connection refConnection;
1763
1764 public:
1774 mutable typename boost::signals2::signal<void (typename TransferData<Self>::TransferMatrix const*) > requestToRefine;
1775
1776 };
1777
1778
1779
1780 //---------------------------------------------------------------------
1781 //---------------------------------------------------------------------
1782
1792 template <class Cache>
1794 {
1795 public:
1796 GetEvaluators(Cache* cache_, std::map<void const*,int> const& deriv_ = std::map<void const*,int>()):
1797 cache(cache_), deriv(deriv_)
1798 {}
1799
1800 template <class Space>
1801 typename Space::Evaluator operator()(Space const* space) const
1802 {
1803 auto it = deriv.find(space);
1804 int derivatives = it==deriv.end()? 1: it->second; // defaults to first derivatives
1805 return typename Space::Evaluator(*space,cache,derivatives);
1806 }
1807
1808 private:
1809 Cache* cache;
1810 std::map<void const*,int> const& deriv;
1811 };
1812
1820 {
1821 public:
1822 template <class Space>
1823 typename Space::Evaluator operator()(Space const*);
1824 };
1825
1837 template <class Spaces, class ShapeFunctionCache>
1838 auto getEvaluators(Spaces const& spaces, ShapeFunctionCache* cache,
1839 std::map<void const*,int> const& deriv = std::map<void const*,int>())
1840 {
1841// return boost::fusion::as_vector(boost::fusion::transform(spaces,GetEvaluators<ShapeFunctionCache>(cache,deriv)));
1842 return boost::fusion::as_vector(boost::fusion::transform(spaces,[&](auto const* space)
1843 {
1844 auto it = deriv.find(space);
1845 int derivatives = it==deriv.end()? 1: it->second; // defaults to first derivatives
1846 return space->evaluator(cache,derivatives);
1847 }));
1848 }
1849
1855 template <class Spaces>
1856 using Evaluators = typename boost::fusion::result_of::as_vector<
1857 typename boost::fusion::result_of::transform<Spaces,GetEvaluatorTypes>::type
1858 >::type;
1859
1860 //---------------------------------------------------------------------
1868 template<class Evaluators>
1869 class [[deprecated]] GetVarArgs
1870 {
1871 public:
1872 template <class T> struct result {};
1873
1874 template <class VD>
1875 struct result<GetVarArgs(VD)>
1876 {
1877 static int const sidx = VD::spaceIndex;
1878 typedef typename boost::fusion::result_of::value_at_c<Evaluators, sidx>::type::VarArg type;
1879 };
1880 };
1881
1882 //---------------------------------------------------------------------
1883
1887 template <class Evaluators, class Cell>
1888 void moveEvaluatorsToCell(Evaluators& evals, Cell const& cell)
1889 {
1890 boost::fusion::for_each(evals,[&cell](auto& eval) { eval.moveTo(cell); });
1891 }
1892
1899 template <class Evaluators, class Cell, class Index>
1900 void moveEvaluatorsToCell(Evaluators& evals, Cell const& cell, Index idx)
1901 {
1902 boost::fusion::for_each(evals,[&cell,idx](auto& eval) { eval.moveTo(cell,idx); });
1903 }
1904
1905//---------------------------------------------------------------------
1906
1911 template <class Evaluator, class QuadratureRule>
1912 void useQuadratureRuleInEvaluators(Evaluator& evals, QuadratureRule const& qr, int subId)
1913 {
1914 boost::fusion::for_each(evals,[&qr,subId](auto& eval) { eval.useQuadratureRule(qr,subId); });
1915 }
1916
1917 //---------------------------------------------------------------------
1918
1928 template <class Evaluators, class CoordType, int dim, int subDim>
1930 Dune::QuadratureRule<CoordType,subDim> const& qr, int ip, int subId)
1931 {
1932 boost::fusion::for_each(evals,[&x,&qr,ip,subId](auto& eval) { eval.evaluateAt(x,qr,ip,subId); });
1933 }
1934
1941 template <class Evaluators, class CoordType, int dim>
1943 {
1944 boost::fusion::for_each(evals,[&x](auto& eval) { eval.evaluateAt(x); });
1945 }
1946
1947 //---------------------------------------------------------------------
1948
1953 template <class Evaluators>
1954 int maxOrder(Evaluators const& evals)
1955 {
1956 auto getOrder = [](auto const& eval) -> int { return eval.order(); };
1957 auto max = [](auto a, auto b) -> int { return std::max(a,b); };
1958 return boost::fusion::fold(boost::fusion::transform(evals,getOrder),0,max);
1959 }
1960
1961} /* end of namespace Kaskade */
1962
1963#endif
A local to global mapper implementation for boundary spaces, with functions defined on the domain bou...
A representation of a finite element function space defined over a domain covered by a grid.
FEFunctionSpace(GridManagerBase< Grid > &gridman_, Mapper &&m)
Constructs a finite element space from a directly given mapper.
std::vector< std::pair< size_t, SfValueType > > linearCombination(Cell< GridView > const &cell, LocalPosition< GridView > const &xi) const
Returns the coefficients of the linear combination of global DoFs that define the value at the given ...
GridView::Grid Grid
Type of grid.
static int const continuity
Tells how often elements are globally continuously differentiable.
GridManagerBase< Grid > & gridManager() const
Access to the GridManager.
GridView::IndexSet IndexSet
Type of IndexSet.
LocalToGlobalMapper::Scalar Scalar
typename Evaluator::VarArg::ValueType SfValueType
type of shape function values
LocalToGlobalMapper Mapper
corresponding mapper
Element_t< m > element() const
Creates a new function in this function space.
typename LocalToGlobalMapper::GridView GridView
Type of grid view.
size_t degreesOfFreedom() const
Returns the dimension of the function space, i.e. the number of degrees of freedom of a one-component...
Evaluator evaluator(ShapeFunctionCache< Grid, Scalar > *cache=nullptr, int deriv=1) const
Creates a new evaluator for this space.
std::vector< std::pair< size_t, SfValueType > > linearCombination(Evaluator const &evaluator) const
Returns the coefficients of the linear combination of global DoFs that define the value at the positi...
Grid const & grid() const
Provides access to the grid on which this finite element space is defined.
FEFunctionSpace(GridManagerBase< Grid > &gridMan, GridView const &gridView_, Args... args)
Constructs a finite element space from a GridManager, a grid view, and possibly extra arguments passe...
GridView const & gridView() const
Provides access to the index set defining the potential support of the space.
static int const dim
Grid dimension.
Scalar field_type
The scalar field type on which the linear (function) space is based. This is provided for consistency...
boost::signals2::signal< void(typename TransferData< Self >::TransferMatrix const *) > requestToRefine
Signal for refinement.
Grid::ctype ctype
Coordinate Type.
static int const sfComponents
The number of components of shape functions.
FEFunctionSpace(FEFunctionSpace< LocalToGlobalMapper > const &fs)
Copy constructor.
std::vector< std::pair< size_t, SfValueType > > linearCombination(GlobalPosition< GridView > const &x) const
Returns the coefficients of the linear combination of global DoFs that define the value at the given ...
static int const dimworld
spatial dimension
IndexSet const & indexSet() const
Provides access to the index set defining the part of the grid on which the space is defined.
LocalToGlobalMapper & mapper()
Provides read-write access to the node manager.
LocalToGlobalMapper const & mapper() const
Provides read access to the node manager.
A class for representing finite element functions.
int order(SFS const &sfs) const
Self & axpy(Scalar a, StorageType const &v)
Computes for coefficient vectors.
Self & operator+=(Self const &f)
Addition of a function from the same (type of) space. Note that despite the same type the function sp...
Dune::BlockVector< StorageValueType > data
Self & operator=(Scalar val)
Sets all coefficients to the given value.
FunctionSpaceElement(Space const &fs)
Constructor.
Self & operator+=(StorageType const &v)
Addition of coefficient vectors.
Self & operator=(FunctionSpaceElement< FEFunctionSpace< BoundaryMapper< DomainMapper, Scalar, typename Space::GridView > >, m > const &bf)
Assignment from an FE function which is restricted to the boundary to a suitable FE function.
DerivativeType derivative(Cell< GridView > const &cell, LocalPosition< GridView > const &local) const
Evaluates the derivative of the FE function at the given local position inside the given cell.
Self & operator+=(Scalar val)
Addition of a constant value to the coefficient vector. Note that this does in general not add a cons...
ValueType value(Cell< GridView > const &cell, LocalPosition< GridView > const &local) const
Evaluates the FE function at the specified local position in the given cell.
Self & operator=(FunctionSpaceElement< OtherSpace, m > const &f)
Assignment from functions belonging to other function spaces.
int order(Cell< GridView > const &cell) const
The polynomial order of the function on the provided cell.
HessianType hessian(GlobalPosition< GridView > const &global) const
Evaluates the FE function's Hessian at the specified global position.
typename Space::field_type field_type
scalar field type
Self & operator=(FunctionViewAdaptor< Space, Functor > const &f)
Assignment from a function view adaptor.
StorageValueType const & operator[](size_t i) const
EXPERIMENTAL Provides read-only access to the coefficients of the finite element basis functions.
FunctionSpaceElement(Self const &fse)
Copy constructor.
Self & operator=(Self &&fse)
Move assignment.
HessianType hessian(Cell< GridView > const &cell, LocalPosition< GridView > const &local) const
Evaluates the Hessian of the FE function at the given local position inside the given cell.
std::enable_if_t< std::is_same< Mapper, FunctionSpace_Detail::ChooseDomainMapper< typename Space::Mapper > >::value, Self & > operator=(FunctionSpaceElement< FEFunctionSpace< Mapper >, m > const &f)
Assignment from a suitable FE function to an FE function which is restricted to the boundary.
StorageType const & coefficients() const
Provides read-only access to the coefficients of the finite element basis functions.
Self & operator-=(StorageType const &v)
Subtraction of coefficient vectors.
Dune::FieldVector< Scalar, m > StorageValueType
type of the elements of the data vector
Self & operator+=(FunctionSpaceElement< OtherSpace, m > const &f)
Addition of a function from a different function space, but with the same number of components.
static int const components
components at each point of evaluation
Self & operator=(StorageType const &v)
Assignment from vector of coefficients.
ValueType value(GlobalPosition< GridView > const &x) const
Evaluates the FE function at the specified global position.
DerivativeType derivative(GlobalPosition< GridView > const &global) const
Evaluates the FE function's gradient at the specified global position.
Self & operator=(Self const &fse)
Copy assignment.
DerivativeType derivative(typename FunctionSpace::Evaluator const &evaluator) const
Evaluates the derivative of the FE function wrt global coordinates at the position used to construct ...
FunctionSpaceElement< Space, m > Self
own type
Self & axpy(Scalar a, FunctionSpaceElement< OtherSpace, m > const &f)
Computes for a function x from a different function space, but with the same number of components.
typename GridView::ctype ctype
the scalar type used for spatial coordinates
Self & operator=(WeakFunctionViewAdaptor< Functor > const &f)
Assignment from a weak function view adaptor.
Self & operator-=(FunctionSpaceElement< OtherSpace, m > const &f)
Subtraction of a function from a different function space, but with the same number of components.
HessianType hessian(typename FunctionSpace::Evaluator const &evaluator) const
Evaluates the Hessian of the FE function at the position used to construct the evaluator.
Self & operator=(StorageValueType const &a)
Sets all coefficients to the given value. As StorageValueType is a vector one value for each componen...
Dune::FieldMatrix< Scalar, components, Space::dimworld > DerivativeType
return type of the function derivative (...)
void transfer(typename TransferData< Space >::TransferMatrix const &transferMatrix)
typename Space::GridView GridView
the grid view this function is defined on
StorageValueType & operator[](size_t i)
EXPERIMENTAL Provides access to the coefficients of the finite element basis functions.
Space const & space() const
Provides access to the FEFunctionSpace to which this function belongs.
ValueType value(typename Space::Evaluator const &evaluator) const
Evaluates the FE function at the position used to construct the evaluator.
Dune::FieldVector< Scalar, components > ValueType
return type of the function value(...)
typename Space::SfValueType SfValueType
type of shape function values
Dune::BlockVector< StorageValueType > StorageType
type of the data vector
int size() const
Number of coefficient blocks.
FunctionSpace Space
FEFunctionSpace, this function is an element of.
Space::Scalar Scalar
scalar field type
Self & axpy(Scalar a, Self const &f)
Computes for a function x from the same (type of) space. Note that despite the same type the functio...
int dim() const
Number of scalar degrees of freedom.
Self & operator-=(Self const &f)
Subtraction of a function from the same (type of) space.
Self & operator*=(Scalar a)
Scaling.
StorageType & coefficients()
Provides access to the coefficients of the finite element basis functions.
An adaptor that allows to turn lambda functions into function views.
Definition: fetransfer.hh:1074
A boost::fusion functor for extracting the evaluator type from a pointer to a FE space....
Space::Evaluator operator()(Space const *)
A boost::fusion functor for creating an evaluator from the space, using a shape function cache that i...
Space::Evaluator operator()(Space const *space) const
GetEvaluators(Cache *cache_, std::map< void const *, int > const &deriv_=std::map< void const *, int >())
A boost::fusion functor for creating a variational arg from the space, using a shape function cache t...
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
An exception that can be thrown whenever a key lookup fails.
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 class for representing tensors of arbitrary static rank and extents.
Definition: tensor.hh:86
Matrix that transforms a data vector v_1 corresponding to the old grid to a data vector v_2 correspon...
Definition: fetransfer.hh:556
std::unique_ptr< Dune::BlockVector< StorageValue > > apply(Dune::BlockVector< StorageValue > const &oldCoeff) const
Transforms oldCoeff, which lives on the old grid to an equivalent vector that lives on the new grid.
Definition: fetransfer.hh:563
std::pair< bool, size_t > unrestrictedToRestrictedIndex(size_t unrestrictedIndex)
Definition: scalarspace.hh:379
An adaptor that turns callables (e.g., lambdas) into weak function views.
Definition: fetransfer.hh:1033
void useQuadratureRuleInEvaluators(Evaluator &evals, QuadratureRule const &qr, int subId)
Tells all evaluators to use the given quadrature rule on the given subentity.
void moveEvaluatorsToIntegrationPoint(Evaluators &evals, Dune::FieldVector< CoordType, dim > const &x, Dune::QuadratureRule< CoordType, subDim > const &qr, int ip, int subId)
Moves all provided evaluators to the given integration point, evaluating the shape functions there.
int maxOrder(Evaluators const &evals)
Computes the maximum ansatz order used in a collection of evaluators.
auto getEvaluators(Spaces const &spaces, ShapeFunctionCache *cache, std::map< void const *, int > const &deriv=std::map< void const *, int >())
returns a heterogeneous sequence of evaluators for the given spaces
OutIter vectorToSequence(FunctionSpaceElement< Space, m > const &v, OutIter iter)
Writes the coefficients into a flat sequence. <Space,m>
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
void interpolateGlobally(FSElement &fse, Function const &fu)
Interpolates FunctionSpaceElement to FunctionSpaceElement.
Definition: fetransfer.hh:855
void interpolateGloballyWeak(Target &target, Source const &fu)
Interpolates WeakFunctionViews to FunctionSpaceElement.
Definition: fetransfer.hh:946
ProblemType
A type for describing the nature of a PDE problem.
@ VariationalFunctional
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
boost::signals2::signal< void(Status)> informAboutRefinement
A signal that is emitted thrice on grid modifications, once before adaptation takes place and twice a...
Definition: gridmanager.hh:74
Status
The argument type of the signal that is emitted before and after grid adaptation.
Definition: gridmanager.hh:64
std::pair< Cell, Dune::FieldVector< ctype, Cell::dimension > > findCellOnLevel(Cell cell, Dune::FieldVector< ctype, Cell::dimension > xi, int level=std::numeric_limits< int >::max())
Returns a descendant or ancestor cell of the given cell containing the specified local coordinate.
Cell< GridView > findCell(GridView const &gv, GlobalPosition< GridView > global)
Returns a cell of the given grid containing the specified global coordinate.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
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
OutIter vectorToSequence(double x, OutIter iter)
Definition: crsutil.hh:30
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
InIter vectorFromSequence(FunctionSpaceElement< Space, m > &v, InIter in)
DEPRECATED use Element_t<m> instead.
FunctionSpaceElement< Self, m > type
A helper class that stores all informations necessary to evaluate FE functions at a certain point.
void evaluateAt(Dune::FieldVector< ctype, dim > const &xi)
Evaluates the shape functions at the given local coordinate.
void useQuadratureRule(Dune::QuadratureRule< typename Grid::ctype, subDim > const &qr, int subId)
Tells the evaluator that subsequent calls to evaluateAt(x,qr,ip,subId) refer to the given quadrature ...
Self Space
The type of function space we belong to.
SortedIndexRange sortedIndices() const
Provides access to (global,local) index pairs sorted ascendingly by global index.
VariationalArg< Scalar, dimworld, sfComponents > VarArg
The type of variational test/ansatz arguments storing value and derivatives/hessians of restricted an...
int derivatives() const
The number of derivatives that can be evaluated.
int order() const
Returns the polynomial order of the shape functions.
static int const sfComponents
The number of components of the shape functions.
Evaluator(Self const &space_, ShapeFunctionCache< Grid, Scalar > *cache_=nullptr, int deriv_=1)
Construct a shape function evaluator for a given space, possibly using the given shape function cache...
Mapper::Combiner const & combiner() const
Returns the algebraic combiner associated to the cell.
Mapper::SortedIndexRange SortedIndexRange
A range of sorted (global index, local index) pairs.
Dune::FieldVector< ctype, dim > const & xloc() const
Returns the local coordinates of the current evaluation point.
GridView const & gridView() const
The grid view on which the space is defined.
Mapper::ShapeFunctionSet const & shapeFunctions() const
Returns the shape function set.
void moveTo(Cell const &cell)
A convenience overload, looking up the cell index itself.
Cell const & cell() const
Returns the cell containing the current evaluation point.
Mapper::GlobalIndexRange GlobalIndexRange
The type of ranges of global indices.
Kaskade::Cell< GridView > Cell
The type of cells in the grid.
LocalToGlobalMapper const & mapper() const
GlobalIndexRange globalIndices() const
Provides access to the global indices.
std::vector< VarArg > evalData
The container holding values and gradients of the global ansatz functions at the evaluation point.
Evaluator & operator=(Evaluator const &eval)
Assignment.
void evaluateAt(Dune::FieldVector< ctype, dim > const &x, Dune::QuadratureRule< typename Grid::ctype, subDim > const &qr, int ip, int subId)
Evaluates the shape functions at the given integration point of the given quadrature rule....
Evaluator(Evaluator const &eval)
Copy constructor.
void moveTo(Cell const &cell, IndexType const index)
Tells the evaluator that subsequent calls refer to the given cell.
boost::fusion::result_of::value_at_c< Evaluators, sidx >::type::VarArg type
Extracts the type of FE space with given index from set of spaces.
std::remove_pointer_t< typename boost::fusion::result_of::value_at_c< Spaces, Idx >::type > type
A class that stores values, gradients, and Hessians of evaluated shape functions.
Dune::FieldVector< Scalar, components > ValueType
type of variational argument's value