[Dune-devel] [Dune-Commit] [Commit] dune-localfunctions - 13481f3: Implement second derivatives for PK2d shape functions

Carsten Gräser graeser at mi.fu-berlin.de
Tue May 5 13:09:14 CEST 2015


Hi,
I'd like to merge this feature to 2.4, but it seems that this
is incomplete, because we guarantee up to 2nd order partial
derivatives while throwing if 1st order is requested.

Is someone working on the implementation of 1st order partial
derivatives? Otherwise I'll drop this for 2.4.

Best,
Carsten



Am 29.04.2015 um 17:13 schrieb Oliver Sander:
> New commit, appeared at Wed Apr 29 17:13:30 2015 +0200
> as part of the following ref changes:
> 
>     branch refs/heads/master    updated from d127aad -> 13481f3
> 
> Browsable version: http://cgit.dune-project.org/repositories/dune-localfunctions/commit/?id=13481f3bb3d4ab1e033967bd9c0a8f28f3b3fe9a
> 
> ======================================================================
> 
> commit 13481f3bb3d4ab1e033967bd9c0a8f28f3b3fe9a
> Author:     Elisa Friebel <friebel at igpm.rwth-aachen.de>
> AuthorDate: Wed Apr 29 17:10:36 2015 +0200
> Commit:     Oliver Sander <sander at igpm.rwth-aachen.de>
> CommitDate: Wed Apr 29 17:10:36 2015 +0200
> 
>     Implement second derivatives for PK2d shape functions
> 
>  COPYING                                            |  1 +
>  .../localfunctions/lagrange/pk2d/pk2dlocalbasis.hh | 79 +++++++++++++++++++++-
>  2 files changed, 79 insertions(+), 1 deletion(-)
> 
> 
> 
> diff --git a/COPYING b/COPYING
> index 4ec1a66..308b0a1 100644
> --- a/COPYING
> +++ b/COPYING
> @@ -10,6 +10,7 @@ Copyright holders:
>  2008--2015    Christian Engwer
>  2008--2012    Jorrit Fahlke
>  2011--2013    Bernd Flemisch
> +2015          Elisa Friebel
>  2012          Christoph Gersbacher
>  2009--2014    Carsten Gräser
>  2015          Felix Gruber
> diff --git a/dune/localfunctions/lagrange/pk2d/pk2dlocalbasis.hh b/dune/localfunctions/lagrange/pk2d/pk2dlocalbasis.hh
> index 8286e19..0ccea9c 100644
> --- a/dune/localfunctions/lagrange/pk2d/pk2dlocalbasis.hh
> +++ b/dune/localfunctions/lagrange/pk2d/pk2dlocalbasis.hh
> @@ -35,7 +35,7 @@ namespace Dune
>      enum {O = k};
>  
>      typedef LocalBasisTraits<D,2,Dune::FieldVector<D,2>,R,1,Dune::FieldVector<R,1>,
> -        Dune::FieldMatrix<R,1,2> > Traits;
> +        Dune::FieldMatrix<R,1,2>, 2 > Traits;
>  
>      //! \brief Standard constructor
>      Pk2DLocalBasis ()
> @@ -158,6 +158,59 @@ namespace Dune
>  
>      }
>  
> +    //! \brief Evaluate higher derivatives of all shape functions
> +    template<unsigned int order> //order of derivative
> +    inline void evaluate(const std::array<int,order>& directions, //direction of derivative
> +                         const typename Traits::DomainType& in,  //position
> +                         std::vector<typename Traits::RangeType>& out) const //return value
> +    {
> +      out.resize(N);
> +
> +      if (order > Traits::diffOrder)
> +        DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
> +
> +      if (order==0)
> +        evaluateFunction(in, out);
> +      else if (order==1)
> +        DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
> +      else if (order==2)
> +      {
> +        // specialization for k<2, not clear whether that is needed
> +        if (k<2) {
> +          std::fill(out.begin(), out.end(), 0.0);
> +        return;
> +      }
> +
> +      //f = prod_{i} f_i -> dxa dxb f = sum_{i} {dxa f_i sum_{k \neq i} dxb f_k prod_{l \neq k,i} f_l
> +      int n=0;
> +      for (unsigned int j=0; j<=k; j++)
> +        for (unsigned int i=0; i<=k-j; i++, n++)
> +        {
> +          R res = 0.0;
> +
> +          for (unsigned int no1=0; no1 < k; no1++)
> +          {
> +            R factor1 = lagrangianFactorDerivative(directions[0], no1, i, j, in);
> +            for (unsigned int no2=0; no2 < k; no2++)
> +            {
> +              if (no1 == no2)
> +                continue;
> +              R factor2 = factor1*lagrangianFactorDerivative(directions[1], no2, i, j, in);
> +              for (unsigned int no3=0; no3 < k; no3++)
> +              {
> +                if (no3 == no1 || no3 == no2)
> +                  continue;
> +                factor2 *= lagrangianFactor(no3, i, j, in);
> +              }
> +              res += factor2;
> +            }
> +
> +          }
> +          out[n] = res;
> +        }
> +      }
> +    }
> +
>      //! \brief Polynomial order of the shape functions
>      unsigned int order () const
>      {
> @@ -165,6 +218,30 @@ namespace Dune
>      }
>  
>    private:
> +  /** \brief Returns a single Lagrangian factor of l_ij evaluated at x */
> +  typename Traits::RangeType lagrangianFactor(const int no, const int i, const int j, const typename Traits::DomainType& x) const
> +  {
> +    if ( no < i)
> +      return (x[0]-pos[no])/(pos[i]-pos[no]);
> +    if (no < i+j)
> +      return (x[1]-pos[no-i])/(pos[j]-pos[no-i]);
> +    return (pos[no+1]-x[0]-x[1])/(pos[no+1]-pos[i]-pos[j]);
> +  }
> +
> +  /** \brief Returns the derivative of a single Lagrangian factor of l_ij evaluated at x
> +   * \param direction Derive in x-direction if this is 0, otherwise derive in y direction
> +   */
> +  typename Traits::RangeType lagrangianFactorDerivative(const int direction, const int no, const int i, const int j, const typename Traits::DomainType& x) const
> +  {
> +    if ( no < i)
> +      return (direction == 0) ? 1.0/(pos[i]-pos[no]) : 0;
> +
> +    if (no < i+j)
> +      return (direction == 0) ? 0: 1.0/(pos[j]-pos[no-i]);
> +
> +    return -1.0/(pos[no+1]-pos[i]-pos[j]);
> +  }
> +
>      R pos[k+1]; // positions on the interval
>    };

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.dune-project.org/pipermail/dune-devel/attachments/20150505/60565da7/attachment.sig>


More information about the Dune-devel mailing list