From 85d33d4c7e750ebbb3891282819d9ba222d64dda Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Mon, 24 Mar 2014 15:48:08 +0000 Subject: [PATCH] New interpolation function that interpolates in a Euclidean space and projects onto the manifold [[Imported from SVN: r9682]] --- dune/gfe/Makefile.am | 1 + dune/gfe/localprojectedfefunction.hh | 128 +++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 dune/gfe/localprojectedfefunction.hh diff --git a/dune/gfe/Makefile.am b/dune/gfe/Makefile.am index ad63f329..97b5f27c 100644 --- a/dune/gfe/Makefile.am +++ b/dune/gfe/Makefile.am @@ -21,6 +21,7 @@ srcinclude_HEADERS = adolcnamespaceinjections.hh \ localgeodesicfefunction.hh \ localgeodesicfestiffness.hh \ localgfetestfunctionbasis.hh \ + localprojectedfefunction.hh \ maxnormtrustregion.hh \ orthogonalmatrix.hh \ pktop1mgtransfer.hh \ diff --git a/dune/gfe/localprojectedfefunction.hh b/dune/gfe/localprojectedfefunction.hh new file mode 100644 index 00000000..5971b33d --- /dev/null +++ b/dune/gfe/localprojectedfefunction.hh @@ -0,0 +1,128 @@ +#ifndef DUNE_GFE_LOCALPROJECTEDFEFUNCTION_HH +#define DUNE_GFE_LOCALPROJECTEDFEFUNCTION_HH + +#include <vector> + +#include <dune/common/fvector.hh> + +#include <dune/geometry/type.hh> + +namespace Dune { + + namespace GFE { + + /** \brief Interpolate in an embedding Euclidean space, and project back onto the Riemannian manifold + * + * \tparam dim Dimension of the reference element + * \tparam ctype Type used for coordinates on the reference element + * \tparam LocalFiniteElement A Lagrangian finite element whose shape functions define the interpolation weights + * \tparam TargetSpace The manifold that the function takes its values in + */ + template <int dim, class ctype, class LocalFiniteElement, class TargetSpace> + class LocalProjectedFEFunction + { + typedef typename TargetSpace::ctype RT; + + typedef typename TargetSpace::EmbeddedTangentVector EmbeddedTangentVector; + static const int embeddedDim = EmbeddedTangentVector::dimension; + + static const int spaceDim = TargetSpace::TangentVector::dimension; + + public: + + /** \brief The type used for derivatives */ + typedef Dune::FieldMatrix<RT, embeddedDim, dim> DerivativeType; + + /** \brief Constructor + * \param localFiniteElement A Lagrangian finite element that provides the interpolation points + * \param coefficients Values of the function at the Lagrange points + */ + LocalProjectedFEFunction(const LocalFiniteElement& localFiniteElement, + const std::vector<TargetSpace>& coefficients) + : localFiniteElement_(localFiniteElement), + coefficients_(coefficients) + { + assert(localFiniteElement_.localBasis().size() == coefficients_.size()); + } + + /** \brief The number of Lagrange points */ + unsigned int size() const + { + return localFiniteElement_.localBasis().size(); + } + + /** \brief The type of the reference element */ + Dune::GeometryType type() const + { + return localFiniteElement_.type(); + } + + /** \brief Evaluate the function */ + TargetSpace evaluate(const Dune::FieldVector<ctype, dim>& local) const; + + /** \brief Evaluate the derivative of the function */ + DerivativeType evaluateDerivative(const Dune::FieldVector<ctype, dim>& local) const; + + /** \brief Evaluate the derivative of the function, if you happen to know the function value (much faster!) + * \param local Local coordinates in the reference element where to evaluate the derivative + * \param q Value of the local gfe function at 'local'. If you provide something wrong here the result will be wrong, too! + */ + DerivativeType evaluateDerivative(const Dune::FieldVector<ctype, dim>& local, + const TargetSpace& q) const; + + /** \brief Get the i'th base coefficient. */ + TargetSpace coefficient(int i) const + { + return coefficients_[i]; + } + private: + + /** \brief The scalar local finite element, which provides the weighting factors + * \todo We really only need the local basis + */ + const LocalFiniteElement& localFiniteElement_; + + /** \brief The coefficient vector */ + std::vector<TargetSpace> coefficients_; + + }; + + template <int dim, class ctype, class LocalFiniteElement, class TargetSpace> + TargetSpace LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,TargetSpace>:: + evaluate(const Dune::FieldVector<ctype, dim>& local) const + { + // Evaluate the weighting factors---these are the Lagrangian shape function values at 'local' + std::vector<Dune::FieldVector<ctype,1> > w; + localFiniteElement_.localBasis().evaluateFunction(local,w); + + typename TargetSpace::CoordinateType c(0); + for (size_t i=0; i<coefficients_.size(); i++) + c.axpy(w[i][0], coefficients_[i].globalCoordinates()); + + return TargetSpace(c); + } + + template <int dim, class ctype, class LocalFiniteElement, class TargetSpace> + typename LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,TargetSpace>::DerivativeType + LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,TargetSpace>:: + evaluateDerivative(const Dune::FieldVector<ctype, dim>& local) const + { + // the function value at the point where we are evaluating the derivative + TargetSpace q = evaluate(local); + + // Actually compute the derivative + return evaluateDerivative(local,q); + } + + template <int dim, class ctype, class LocalFiniteElement, class TargetSpace> + typename LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,TargetSpace>::DerivativeType + LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,TargetSpace>:: + evaluateDerivative(const Dune::FieldVector<ctype, dim>& local, const TargetSpace& q) const + { + DUNE_THROW(NotImplemented, "Not implemented yet!"); + } + + } + +} +#endif -- GitLab