[Dune-devel] [PATCH] Use unqualified calls to allow ADL.
Carsten Gräser
graeser at mi.fu-berlin.de
Tue Sep 1 14:45:48 CEST 2015
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
-------------- 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/20150901/868e9bce/attachment.sig>
More information about the Dune-devel
mailing list