[Dune-devel] [PATCH] Use unqualified calls to allow ADL.

Christian Engwer christian.engwer at uni-muenster.de
Tue Sep 1 15:06:43 CEST 2015


Hi Carsten,

(a) the double cast is only used, if K is an integer type.
(b) fvmeta is one of the ancient artifacts that are there from the
    (nearly) very beginning and the design is far from nice
(c) I guess Peter was the inital author, but this will be kind of
    tricky to find out, as the content was moved around quite often.
(d) I currently don't see where the current code fails with user
    defined types.
(e) the ADL is here quite new (from june), perhaps it isn't in the
    release branch?

Hi Atgeirr,

if it fails this is definitely a bug and must be fixed. Could you
please send a test example.

Ciao
Christian

On Tue, Sep 01, 2015 at 02:45:48PM +0200, Carsten Gräser wrote:
> Dear Atgeirr,
> thanks for the patch. To in corporate it in dune 2.4 I'd first
> like to see it in the master and then merge from there. Hence
> I'd prefer a patch against master. However, I'm unclear if we should
> merge this.
> 
> It seems to me that fvmeta already uses proper adl internally.
> So there seems to be no need to add this on top. The only place
> that does not seem to be fully generic is the square root, that
> does first cast to double for non-complex types and hence be
> inexact if your type has higher precision. The latter might
> just be an error.
> 
> But even for this you could customize by spezializing the
> struct fvmeta:Sqrt. The question is if this is the "official"
> customization point, which is an interface decision that
> I'd like to have discussed before. Perhaps the inventor of
> fvmeta (Christian?) can comment on what he had in mind.
> 
> Best,
> Carsten
> 
> 
> 
> 
> 
> What exactly would you like to customize?
> Am 01.09.2015 um 11:22 schrieb Atgeirr Rasmussen:
> > From 476d7e2e9ac446568ded32e41e5d9e2265eded85 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= <atgeirr at sintef.no>
> > Date: Tue, 1 Sep 2015 10:53:25 +0200
> > Subject: [PATCH] Use unqualified calls to allow ADL.
> > 
> > In order to have argument-dependent-lookup for calls to absreal()
> > and the other functions defined in the fvmeta namespace, the calls
> > must be unqualified.
> > 
> > This makes it easier to use FieldVector/FieldMatrix with user-defined types.
> > 
> > I posted this to the developer list, if I should have used another channel, please
> > tell me (and sorry!).
> > 
> > I hope it is possible to get this in the release, the patch has been made
> > against the 2.4 branch. Please tell me if you'd prefer a patch against the
> > master branch. Also, the patch contain many repeated comments explaining
> > the reason for the using-statements, if you'd rather be without them I'll change it.
> > 
> > ---
> >  dune/common/densematrix.hh | 20 ++++++++++++--------
> >  dune/common/densevector.hh | 17 +++++++++++------
> >  2 files changed, 23 insertions(+), 14 deletions(-)
> > 
> > diff --git a/dune/common/densematrix.hh b/dune/common/densematrix.hh
> > index d3ed73f..951810c 100644
> > --- a/dune/common/densematrix.hh
> > +++ b/dune/common/densematrix.hh
> > @@ -553,9 +553,10 @@ namespace Dune
> >      //! frobenius norm: sqrt(sum over squared values of entries)
> >      typename FieldTraits<value_type>::real_type frobenius_norm () const
> >      {
> > +      using fvmeta::sqrt; // Must make unqualified calls to allow argument dependent lookup.
> >        typename FieldTraits<value_type>::real_type sum=(0.0);
> >        for (size_type i=0; i<rows(); ++i) sum += (*this)[i].two_norm2();
> > -      return fvmeta::sqrt(sum);
> > +      return sqrt(sum);
> >      }
> >  
> >      //! square of frobenius norm, need for block recursion
> > @@ -815,7 +816,8 @@ namespace Dune
> >      // LU decomposition of A in A
> >      for (size_type i=0; i<rows(); i++)  // loop over all rows
> >      {
> > -      typename FieldTraits<value_type>::real_type pivmax=fvmeta::absreal(A[i][i]);
> > +      using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
> > +      typename FieldTraits<value_type>::real_type pivmax=absreal(A[i][i]);
> >  
> >        // pivoting ?
> >        if (pivmax<pivthres)
> > @@ -824,7 +826,7 @@ namespace Dune
> >          size_type imax=i;
> >          typename FieldTraits<value_type>::real_type abs(0.0);
> >          for (size_type k=i+1; k<rows(); k++)
> > -          if ((abs=fvmeta::absreal(A[k][i]))>pivmax)
> > +          if ((abs=absreal(A[k][i]))>pivmax)
> >            {
> >              pivmax = abs; imax = k;
> >            }
> > @@ -856,6 +858,7 @@ namespace Dune
> >    template <class V>
> >    inline void DenseMatrix<MAT>::solve(V& x, const V& b) const
> >    {
> > +    using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
> >      // never mind those ifs, because they get optimized away
> >      if (rows()!=cols())
> >        DUNE_THROW(FMatrixError, "Can't solve for a " << rows() << "x" << cols() << " matrix!");
> > @@ -863,7 +866,7 @@ namespace Dune
> >      if (rows()==1) {
> >  
> >  #ifdef DUNE_FMatrix_WITH_CHECKING
> > -      if (fvmeta::absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
> > +      if (absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
> >          DUNE_THROW(FMatrixError,"matrix is singular");
> >  #endif
> >        x[0] = b[0]/(*this)[0][0];
> > @@ -873,7 +876,7 @@ namespace Dune
> >  
> >        field_type detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
> >  #ifdef DUNE_FMatrix_WITH_CHECKING
> > -      if (fvmeta::absreal(detinv)<FMatrixPrecision<>::absolute_limit())
> > +      if (absreal(detinv)<FMatrixPrecision<>::absolute_limit())
> >          DUNE_THROW(FMatrixError,"matrix is singular");
> >  #endif
> >        detinv = 1.0/detinv;
> > @@ -886,7 +889,7 @@ namespace Dune
> >  
> >        field_type d = determinant();
> >  #ifdef DUNE_FMatrix_WITH_CHECKING
> > -      if (fvmeta::absreal(d)<FMatrixPrecision<>::absolute_limit())
> > +      if (absreal(d)<FMatrixPrecision<>::absolute_limit())
> >          DUNE_THROW(FMatrixError,"matrix is singular");
> >  #endif
> >  
> > @@ -924,6 +927,7 @@ namespace Dune
> >    template<typename MAT>
> >    inline void DenseMatrix<MAT>::invert()
> >    {
> > +    using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
> >      // never mind those ifs, because they get optimized away
> >      if (rows()!=cols())
> >        DUNE_THROW(FMatrixError, "Can't invert a " << rows() << "x" << cols() << " matrix!");
> > @@ -931,7 +935,7 @@ namespace Dune
> >      if (rows()==1) {
> >  
> >  #ifdef DUNE_FMatrix_WITH_CHECKING
> > -      if (fvmeta::absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
> > +      if (absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
> >          DUNE_THROW(FMatrixError,"matrix is singular");
> >  #endif
> >        (*this)[0][0] = field_type( 1 ) / (*this)[0][0];
> > @@ -941,7 +945,7 @@ namespace Dune
> >  
> >        field_type detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
> >  #ifdef DUNE_FMatrix_WITH_CHECKING
> > -      if (fvmeta::absreal(detinv)<FMatrixPrecision<>::absolute_limit())
> > +      if (absreal(detinv)<FMatrixPrecision<>::absolute_limit())
> >          DUNE_THROW(FMatrixError,"matrix is singular");
> >  #endif
> >        detinv = field_type( 1 ) / detinv;
> > diff --git a/dune/common/densevector.hh b/dune/common/densevector.hh
> > index 6dacfe6..417f6bc 100644
> > --- a/dune/common/densevector.hh
> > +++ b/dune/common/densevector.hh
> > @@ -579,27 +579,31 @@ namespace Dune {
> >      //! simplified one norm (uses Manhattan norm for complex values)
> >      typename FieldTraits<value_type>::real_type one_norm_real () const
> >      {
> > +      using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
> >        typename FieldTraits<value_type>::real_type result( 0 );
> >        for (size_type i=0; i<size(); i++)
> > -        result += fvmeta::absreal((*this)[i]);
> > +        result += absreal((*this)[i]);
> >        return result;
> >      }
> >  
> >      //! two norm sqrt(sum over squared values of entries)
> >      typename FieldTraits<value_type>::real_type two_norm () const
> >      {
> > +      using fvmeta::abs2; // Must make unqualified calls to allow argument dependent lookup.
> > +      using fvmeta::sqrt; // Must make unqualified calls to allow argument dependent lookup.
> >        typename FieldTraits<value_type>::real_type result( 0 );
> >        for (size_type i=0; i<size(); i++)
> > -        result += fvmeta::abs2((*this)[i]);
> > -      return fvmeta::sqrt(result);
> > +        result += abs2((*this)[i]);
> > +      return sqrt(result);
> >      }
> >  
> >      //! square of two norm (sum over squared values of entries), need for block recursion
> >      typename FieldTraits<value_type>::real_type two_norm2 () const
> >      {
> > +      using fvmeta::abs2; // Must make unqualified calls to allow argument dependent lookup.
> >        typename FieldTraits<value_type>::real_type result( 0 );
> >        for (size_type i=0; i<size(); i++)
> > -        result += fvmeta::abs2((*this)[i]);
> > +        result += abs2((*this)[i]);
> >        return result;
> >      }
> >  
> > @@ -625,14 +629,15 @@ namespace Dune {
> >      typename FieldTraits<value_type>::real_type infinity_norm_real () const
> >      {
> >        using std::max;
> > +      using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
> >  
> >        if (size() == 0)
> >          return 0.0;
> >  
> >        ConstIterator it = begin();
> > -      typename FieldTraits<value_type>::real_type max_val = fvmeta::absreal(*it);
> > +      typename FieldTraits<value_type>::real_type max_val = absreal(*it);
> >        for (it = it + 1; it != end(); ++it)
> > -        max_val = max(max_val, fvmeta::absreal(*it));
> > +        max_val = max(max_val, absreal(*it));
> >  
> >        return max_val;
> >      }
> > 
> 
> 
> -- 
> Prof. Dr. Carsten Gräser
> Freie Universität Berlin
> Institut für Mathematik
> Arnimallee 6
> 14195 Berlin, Germany
> phone: +49 30 838 72637
> fax  : +49 30 838 472637
> email: graeser at mi.fu-berlin.de
> URL  : http://page.mi.fu-berlin.de/graeser
> 



> _______________________________________________
> Dune-devel mailing list
> Dune-devel at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-devel


-- 
Prof. Dr. Christian Engwer 
Institut für Numerische und Angewandte Mathematik
Fachbereich Mathematik und Informatik der Universität Münster
Einsteinstrasse 62
48149 Münster

E-Mail  christian.engwer at uni-muenster.de
Telefon +49 251 83-35067
FAX     +49 251 83-32729




More information about the Dune-devel mailing list