32#include "dune/grid/common/grid.hh"
33#include "dune/istl/bcrsmatrix.hh"
34#include "dune/common/fvector.hh"
35#include "dune/common/fmatrix.hh"
36#include "dune/grid/io/file/dgfparser/dgfparser.hh"
46 template<
class G,
class T>
class CellData;
47 template <
class Space,
class CP>
class TransferData;
48 struct AdaptationCoarseningPolicy ;
68 template <
class Space,
class ShapeFunctionSet>
76 sfValues.setSize(xi.size(),shapeFunctionSet.
size());
80 shapeFunctionSet.
evaluate(xi,sfValues);
83 typename Space::Mapper::Converter psi(cell);
84 for (
int i=0; i<sfValues.N(); ++i)
86 psi.setLocalPosition(xi[i]);
87 for (
int j=0; j<sfValues.M(); ++j)
88 sfValues[i][j] = psi.global(sfValues[i][j]);
92 template <
class Space>
132 template <
class Space,
class ShapeFunctionSet>
134 typename Space::Grid::template Codim<0>::Entity
const& cell,
140 typename Space::Mapper::Converter psi(cell);
144 for (
int i=0; i<globalValues.N(); ++i)
146 psi.setLocalPosition(iNodes[i]);
147 for (
int j=0; j<globalValues.M(); ++j)
148 globalValues[i][j] = psi.local(globalValues[i][j]);
158 template <
class Space>
160 typename Space::Grid::template Codim<0>::Entity
const& cell,
194 template <
class ChildSpace,
class FatherSpace>
197 FatherSpace
const& fatherSpace,
200 typename ChildSpace::Mapper::ShapeFunctionSet
const& childSfs,
201 typename FatherSpace::Mapper::ShapeFunctionSet
const& fatherSfs)
203 using GridView =
typename ChildSpace::GridView;
204 typedef typename ChildSpace::Grid Grid;
205 typedef typename ChildSpace::Scalar Scalar;
206 int const sfComponents = ChildSpace::sfComponents;
209 std::vector<LocalPosition<GridView>> iNodes(childSfs.interpolationNodes());
211 std::vector<int> dummy(iNodes.size());
213 mlGeometry.
local(iNodes,dummy);
214 assert(dummy.size()==iNodes.size());
231 template <
class ChildSpace,
class FatherSpace>
234 FatherSpace
const& fatherSpace,
239 childSpace.mapper().shapefunctions(child),fatherSpace.mapper().shapefunctions(father));
256 template <
class Cell>
259 return cell.isLeaf();
262 template <
class Cell>
265 return cell.mightBeCoarsened();
285 void update(
int level_ ) { level = level_ ; }
287 template <
class Cell>
290 return cell.level()==level;
293 template <
class Cell>
320 template <
class Space,
class CoarseningPolicy=AdaptationCoarseningPolicy>
324 typedef typename Space::Grid
Grid;
327 typedef typename Grid::GlobalIdSet::IdType
Id;
335 using ShapeFunctionSet =
typename Space::Mapper::ShapeFunctionSet;
360 globalIndices = std::forward<std::vector<size_t>>(other.globalIndices);
379 CoarseningPolicy
const& relevancePolicy = CoarseningPolicy())
386 Grid const& grid = space.grid();
387 assert(&grid == &space.grid());
393 std::vector<Cell> children;
394 if ( relevancePolicy.accept(father) )
395 children.push_back(father);
398 auto end = father.hend(grid.maxLevel());
399 for (
auto hi=father.hbegin(grid.maxLevel()); hi!=end; ++hi)
400 if (relevancePolicy.accept(*hi))
401 children.push_back(
Cell(*hi));
405 auto const& fatherShapeFunctions = space.mapper().shapefunctions(father);
409 for (
Cell const& child: children)
411 auto gi = space.mapper().globalIndices(child);
422 typedef typename Space::Mapper::ShapeFunctionSet::SfValueArray SfValueArray;
423 SfValueArray restrictionData;
424 restrictionData.setSize(fatherShapeFunctions.interpolationNodes().size(),
globalIndices.size());
429 std::vector<int> fCount(restrictionData.N(),0);
431 SfValueArray afValues;
432 std::vector<size_t> globIdx;
434 std::vector<Position> iNodes;
435 std::vector<int> nodesInside;
437 for (
Cell const& child: children)
441 auto gi = space.mapper().globalIndices(child);
442 globIdx.resize(gi.size());
443 for (
int j=0; j<gi.size(); ++j)
462 iNodes = fatherShapeFunctions.interpolationNodes();
463 nodesInside.resize(iNodes.size());
464 std::iota(begin(nodesInside),end(nodesInside),0);
465 mlGeometry.
local(iNodes,nodesInside);
471 space.mapper().combiner(child,space.indexSet().index(child)).rightTransform(afValues);
472 assert(afValues.M() == globIdx.size());
474 for (
int k=0; k<afValues.N(); ++k)
476 int rIdx = nodesInside[k];
477 assert(0<=rIdx && rIdx<fCount.size());
479 for (
int i=0; i<afValues.M(); ++i)
481 assert(!std::isnan(restrictionData[rIdx][globIdx[i]]));
482 restrictionData[rIdx][globIdx[i]] += afValues[k][i];
483 assert(!std::isnan(restrictionData[rIdx][globIdx[i]]));
489 for (
int i=0; i<restrictionData.N(); ++i)
492 double avg = 1.0 / fCount[i];
494 for (
int j=0; j<restrictionData.M(); ++j)
496 assert(!std::isnan(restrictionData[i][j]));
497 restrictionData[i][j] *= avg;
530 template <
class Space,
class CoarseningPolicy=AdaptationCoarseningPolicy>
534 typedef typename Space::Grid
Grid;
538 typedef typename Grid::GlobalIdSet::IdType
Id;
540 typedef typename Grid::template Codim<0>::Entity
Cell;
545 typedef std::map<Id, RestrictionData> HistoryMap;
562 template <
class StorageValue>
566 for (
int i=0; i<tm.size(); ++i)
568 StorageValue tmp(0.0);
569 for (
int j=0; j<tm[i].first.size(); ++j)
570 tmp += tm[i].first[j].second * oldCoeff[tm[i].first[j].first];
571 (*newCoeff)[i] = tmp;
577 tm(rows), nrows(rows), ncols(cols)
579 for (
int i=0; i<tm.size(); ++i)
592 template <
class ColIter,
class EntryIter>
593 void storeRow(
int row,
int restrictionLevel, ColIter firstCol, ColIter lastCol,
594 EntryIter firstEntry)
596 if (tm[row].second > restrictionLevel)
598 tm[row].second = restrictionLevel;
599 tm[row].first.clear();
601 while (firstCol != lastCol)
603 if (std::abs(*firstEntry)>1e-14)
604 tm[row].first.push_back(std::make_pair(*firstCol,*firstEntry));
612 void out(std::ostream& o)
const
614 o <<
"shape=[" << nrows <<
' ' << ncols <<
"];\n";
616 for (
int i=0; i<tm.size(); ++i)
617 for (
int j=0; j<tm[i].first.size(); ++j)
618 o << i+1 <<
' ' << tm[i].first[j].first+1 <<
' ' << tm[i].first[j].second <<
'\n';
630 std::vector<std::pair<std::vector<std::pair<int,Scalar> >,
int>> tm;
640 TransferData(Space
const& space_, CoarseningPolicy
const& mightBeCoarsened=CoarseningPolicy())
641 : space(space_), DOFcoarseSpace(space.degreesOfFreedom())
643 auto const& idSet = space.grid().globalIdSet();
645 typename Space::Evaluator evaluator(space);
647 std::set<Id> processedAncestors;
657 auto const& cellRanges = space.gridManager().cellRanges(space.gridView());
661 HistoryMap myHistoryData;
663 std::vector<std::pair<Id,Cell>> ancestors;
665 for (
auto const& cell: cellRanges.range(n,i))
670 myHistoryData.insert(std::pair(idSet.id(cell),
671 RestrictionData(space,cell,mightBeCoarsened)));
677 Cell ancestor = cell;
678 std::lock_guard<std::mutex> lock(mutex);
680 while (ancestor.mightVanish() && ancestor.level()>0)
682 ancestor = ancestor.father();
683 Id id = idSet.id(ancestor);
687 if (processedAncestors.find(id) == processedAncestors.end())
689 processedAncestors.insert(id);
690 ancestors.push_back(std::pair(id,ancestor));
696 for (
auto const& [
id,ancestor]: ancestors)
704 std::lock_guard<std::mutex> lock(mutex);
705 historyData.merge(myHistoryData);
729 typename Grid::GlobalIdSet
const& idSet = space.grid().globalIdSet();
730 auto transfer = std::make_unique<TransferMatrix>(space.degreesOfFreedom(),DOFcoarseSpace);
733 for (
auto cell: elements(space.gridView()))
740 typename HistoryMap::const_iterator restriction;
742 while((restriction=historyData.find(idSet.id(ancestor))) == historyData.end() && ancestor.level()> 0)
745 ancestor = ancestor.father();
747 assert(restriction != historyData.end());
750 auto index = space.indexSet().index(cell);
757 space.mapper().shapefunctions(index),*(restriction->second.shapeFunctionSet));
765 space.mapper().combiner(cell,index).leftPseudoInverse(localTransfer);
770 auto rowIdx = space.mapper().globalIndices(index);
771 std::vector<size_t>
const& columnIdx = restriction->second.globalIndices;
772 for (
int i=0; i<localTransfer.N(); ++i)
774 transfer->storeRow(rowIdx[i], colevel,
775 columnIdx.begin(), columnIdx.end(),
776 localTransfer[i].begin());
785 HistoryMap historyData;
798 template<
class Entity>
799 double operator()(Entity
const& e) {
return 1.0/e.geometry().volume();}
810 template<
class Entity>
811 double operator()(Entity
const& e) {
return e.geometry().volume();}
822 template<
class Entity>
831 template<
class Entity>
854 template<
typename Weighing=PlainAverage,
typename FSElement,
typename Function>
857 typedef typename FSElement::Space ImageSpace;
858 typedef typename ImageSpace::Grid Grid;
862 std::vector<typename Grid::ctype> sumOfWeights(fse.space().degreesOfFreedom(),0.0);
865 fse.coefficients() =
typename FSElement::Scalar(0.0);
867 typename ImageSpace::Evaluator isfs(fse.space());
868 typename Function::Space::Evaluator dsfs(fu.space());
871 using DirectValueType =
decltype(fu.
value(dsfs));
872 using ValueType = std::conditional_t<std::is_arithmetic<DirectValueType>::value,
875 std::vector<ValueType> fuvalue;
878 for (
auto const& cell: elements(fse.space().gridView()))
880 auto index = fse.space().indexSet().index(cell);
885 typename Grid::ctype myWeight = w(cell);
886 for (
int i=0; i<isfs.size(); ++i)
887 sumOfWeights[isfs.globalIndices()[i]] += myWeight;
890 auto const& iNodes(isfs.shapeFunctions().interpolationNodes());
893 globalValues.
setSize(iNodes.size(),1);
894 localCoefficients.
setSize(iNodes.size(),1);
895 fuvalue.resize(iNodes.size());
896 for (
int i=0; i<iNodes.size(); ++i)
898 dsfs.evaluateAt(iNodes[i]);
899 fuvalue[i] = fu.
value(dsfs);
903 for(
int k=0; k<FSElement::components/ImageSpace::sfComponents; ++k)
905 for (
int i=0; i<iNodes.size(); ++i)
906 for(
int j=0; j<ImageSpace::sfComponents; ++j)
907 globalValues[i][0][j][0] = myWeight*fuvalue[i][ImageSpace::sfComponents*k+j];
911 assert(localCoefficients.N() == isfs.globalIndices().size());
914 fse.space().mapper().combiner(cell,index).leftPseudoInverse(localCoefficients);
917 for (
int i=0; i<localCoefficients.N(); ++i)
918 fse.coefficients()[isfs.globalIndices()[i]][k] += localCoefficients[i][0];
924 for(
int i=0; i<sumOfWeights.size(); ++i)
945 template<
typename Weighing=PlainAverage,
typename Target,
typename Source>
948 typedef typename Target::Space ImageSpace;
949 typedef typename ImageSpace::Grid Grid;
950 using Scalar =
typename ImageSpace::Scalar;
952 auto const& space = target.space();
956 std::vector<typename Grid::ctype> sumOfWeights(space.degreesOfFreedom(),0.0);
961 typename ImageSpace::Evaluator isfs(space);
965 using ValueType =
decltype(fu.value(*space.gridView().template end<0>(),
967 static_assert(std::is_same_v<ValueType,typename Target::ValueType>,
968 "return type of the weak function view must agree with the value type of the assignment target");
970 std::vector<ValueType> fuvalue;
972 for (
auto const& cell: elements(space.gridView()))
974 auto index = space.indexSet().index(cell);
977 typename Grid::ctype myWeight = w(cell);
978 for (
int i=0; i<isfs.size(); ++i)
979 sumOfWeights[isfs.globalIndices()[i]] += myWeight;
982 auto const& iNodes(isfs.shapeFunctions().interpolationNodes());
985 globalValues.
setSize(iNodes.size(),1);
986 localCoefficients.
setSize(iNodes.size(),1);
987 fuvalue.resize(iNodes.size());
988 for (
int i=0; i<iNodes.size(); ++i)
989 fuvalue[i] = fu.value(cell,iNodes[i]);
992 for(
int k=0; k<Target::components/ImageSpace::sfComponents; ++k)
994 for (
int i=0; i<iNodes.size(); ++i)
995 for(
int j=0; j<ImageSpace::sfComponents; ++j)
996 globalValues[i][0][j][0] = myWeight*fuvalue[i][ImageSpace::sfComponents*k+j];
1000 if (isfs.globalIndices().size()!=0)
1002 assert(localCoefficients.N() == isfs.globalIndices().size());
1005 space.mapper().combiner(cell,index).leftPseudoInverse(localCoefficients);
1008 for (
int i=0; i<localCoefficients.N(); ++i)
1009 target.coefficients()[isfs.globalIndices()[i]][k]+= localCoefficients[i][0];
1016 for(
int i=0; i<sumOfWeights.size(); ++i)
1031 template <
class Functor>
1039 template <
class ...Args>
1042 return g(std::forward<Args>(args)...);
1058 template <
class Functor>
1072 template <
class Space_,
class Functor>
1086 template <
class ...Args>
1089 return g(std::forward<Args>(args)...);
1106 template <
class Space,
class Functor>
1109 return FunctionViewAdaptor<Space,Functor>(space,g);
1117 template <
class Fu1,
class Fu2>
Function is the interface for evaluatable functions .
ValueType value(Cell const &cell, Dune::FieldVector< typename Cell::Geometry::ctype, Cell::dimension > const &localCoordinate) const
unspecified Space
The type of finite element space the evaluators of which are required for evaluating this FunctionVie...
A LAPACK-compatible dense matrix class with shape specified at runtime.
void setSize(size_type r, size_type c)
Resizes the matrix to r x c, leaving the entries in an undefined state.
An adaptor that allows to turn lambda functions into function views.
Space const & space() const
auto value(Args... args) const
FunctionViewAdaptor(Space const &space, Functor const &g_)
Class that stores for a cell ("this entity" or "father") a local projection matrix.
LocalTransferMatrix restrictionMatrix
LocalTransfer()=default
default constructor leaves the object in a valid but undefined state.
DynamicMatrix< Dune::FieldMatrix< Scalar, 1, 1 > > LocalTransferMatrix
LocalTransfer(LocalTransfer const &other)=default
copy constructor
ShapeFunctionSet const * shapeFunctionSet
LocalTransfer< Space, CoarseningPolicy > & operator=(LocalTransfer &&other)
move assignment
Grid::GlobalIdSet::IdType Id
Kaskade::Cell< Grid > Cell
std::vector< size_t > globalIndices
LocalTransfer(Space const &space, Cell father, CoarseningPolicy const &relevancePolicy=CoarseningPolicy())
constructor
LocalTransfer(LocalTransfer &&other)
move constructor
Dune::FieldVector< Scalar, Space::sfComponents > SfValue
Transformation of coordinates between ancestor and child.
void local(std::vector< Dune::FieldVector< ctype, dim > > &x, std::vector< int > &componentsInside) const
Transformation from global to local.
static NumaThreadPool & instance(int maxThreads=std::numeric_limits< int >::max())
Returns a globally unique thread pool instance.
A set of shape functions.
void evaluate(InterpolationNodes const &iNodes, SfValueArray &phi) const
Evaluate shape function set at a set of points. In notation of the LocalToGlobalMapperConcept,...
InterpolationNodes const & interpolationNodes() const
Interpolation points.
virtual int size() const
Number of shape functions in the set.
virtual void interpolate(SfValueArray const &A, Matrix &IA) const =0
Left-multiplies the provided matrix with the interpolation matrix of the shape function set.
Matrix that transforms a data vector v_1 corresponding to the old grid to a data vector v_2 correspon...
void out(std::ostream &o) const
TransferMatrix(size_t rows, size_t cols)
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.
A class storing data collected before grid adaptation that is necessary to transfer FE functions....
Dune::FieldVector< Scalar, Space::sfComponents > SfValue
Grid::GlobalIdSet::IdType Id
TransferData(Space const &space_, CoarseningPolicy const &mightBeCoarsened=CoarseningPolicy())
Gathers all information that might be lost after the refinement process. To be called after preAdapt(...
std::unique_ptr< TransferMatrix > transferMatrix() const
Create a TransferMatrix.
Grid::template Codim< 0 >::Entity Cell
An adaptor that turns callables (e.g., lambdas) into weak function views.
WeakFunctionViewAdaptor(Functor const &g_)
auto value(Args... args) const
This file contains various utility functions that augment the basic functionality of Dune.
void approximateGlobalValues(Space const &space, typename Space::Grid::template Codim< 0 >::Entity const &cell, DynamicMatrix< Dune::FieldMatrix< typename Space::Scalar, Space::sfComponents, 1 > > &globalValues, DynamicMatrix< Dune::FieldMatrix< typename Space::Scalar, 1, 1 > > &coeff, ShapeFunctionSet const &sfs)
Computes global shape function coefficients such that the given set of global function values at the ...
auto makeFunctionView(Space const &space, Functor const &g)
A convenience functor that supports the easy creation of function view adaptors.
auto makeWeakFunctionView(Functor const &g)
A convenience function turning callables (e.g., lambda functions) into weak function views.
void interpolateGlobally(FSElement &fse, Function const &fu)
Interpolates FunctionSpaceElement to FunctionSpaceElement.
void evaluateGlobalShapeFunctions(Space const &space, Cell< typename Space::GridView > const &cell, std::vector< LocalPosition< typename Space::GridView > > const &xi, DynamicMatrix< Dune::FieldMatrix< typename Space::Scalar, Space::sfComponents, 1 > > &sfValues, ShapeFunctionSet const &shapeFunctionSet)
Computes the values of global shape functions at the given points (which are supposed to be local coo...
void interpolateGloballyWeak(Target &target, Source const &fu)
Interpolates WeakFunctionViews to FunctionSpaceElement.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
void MatMult(MatrixZ &z, Matrix const &x, Matrix const &y)
Computes Z = X*Y. X and Y need to be compatible, i.e. X.M()==Y.N() has to hold. No aliasing may occur...
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
NumaBCRSMatrix< Dune::FieldMatrix< typename FineSpace::Scalar, 1, 1 >, SparseIndex > prolongation(CoarseSpace const &coarseSpace, FineSpace const &fineSpace)
Computes an interpolation-based prolongation matrix from a (supposedly) coarser space to a finer spac...
void parallelFor(Func const &f, int maxTasks=std::numeric_limits< int >::max())
A parallel for loop that executes the given functor in parallel on different CPUs.
Class for transformations between ancestors and their children.
Scalar distance(Point< Scalar, dim > const &first, Point< Scalar, dim > const &second)
void approximateGlobalValues(Space const &space, typename Space::Grid::template Codim< 0 >::Entity const &cell, DynamicMatrix< Dune::FieldMatrix< typename Space::Scalar, Space::sfComponents, 1 > > &globalValues, DynamicMatrix< Dune::FieldMatrix< typename Space::Scalar, 1, 1 > > &coeff)
void localProlongationMatrix(ChildSpace const &childSpace, Cell< typename ChildSpace::Grid > const &child, FatherSpace const &fatherSpace, Cell< typename FatherSpace::Grid > const &father, DynamicMatrix< Dune::FieldMatrix< typename ChildSpace::Scalar, 1, 1 > > &prolongation, typename ChildSpace::Mapper::ShapeFunctionSet const &childSfs, typename FatherSpace::Mapper::ShapeFunctionSet const &fatherSfs)
Computes a local prolongation matrix for global shape functions from father cell to child cell.
void spaceTransfer(Fu1 &f1, Fu2 const &f2)
DEPRECATED. Use interpolateGlobally instead.
policy class for LocalTransfer These two structures are used for determining whether to perform a "no...
bool operator()(Cell const &cell) const
bool accept(Cell const &cell) const
A Weighing that associates to each cell its inverse volume.
double operator()(Entity const &e)
policy class for LocalTransfer These two structures are used for determining whether to perform a "no...
bool accept(Cell const &cell) const
MultilevelCoarseningPolicy(int level_)
bool operator()(Cell const &cell) const
A Weighing that associates to each cell a constant weight of 1.
double operator()(Entity const &e)
double operator()(Entity const &e)
A Weighing that associates to each cell its volume.
double operator()(Entity const &e)
A Weighing is a class that allows to compute weighted averages of values associated to cells of a gri...
double scalingFactor() const
Defines the global scaling factor .
double offset() const
Defines the global offset .