diff --git a/dumux/common/quad.hh b/dumux/common/quad.hh new file mode 100644 index 0000000000000000000000000000000000000000..89d6b7b95a43df51aa7549126ada9b5390520d01 --- /dev/null +++ b/dumux/common/quad.hh @@ -0,0 +1,84 @@ +/***************************************************************************** + * Copyright (C) 2011 by Andreas Lauser * + * Institute of Hydraulic Engineering * + * University of Stuttgart, Germany * + * email: <givenname>.<name>@iws.uni-stuttgart.de * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \brief This file provides the infrastructure to use quad-precision + * floating point values in the numerical models. + */ +#ifndef DUMUX_QUAD_HH +#define DUMUX_QUAD_HH + +#if ! HAVE_QUAD +#error "Quad precision floating point values must be enabled to use this file" +#endif + +#include <iostream> +#include <cmath> +#include <quadmath.h> + +typedef __float128 quad; + +namespace std +{ + +inline std::ostream& operator<<(std::ostream& os, const quad &val) +{ + return (os << double(val)); +} + +inline std::istream& operator>>(std::istream& is, quad &val) +{ + double tmp; + std::istream &ret = (is >> tmp); + val = tmp; + return ret; +} + +inline quad abs(quad val) +{ return (val < 0)?-val:val; } + +inline quad max(quad a, quad b) +{ return (a>b)?a:b; }; + +inline quad min(quad a, quad b) +{ return (a<b)?a:b; }; + +inline quad sqrt(quad val) +{ return sqrtq(val); }; + +template <class ExpType> +inline quad pow(quad base, ExpType exp) +{ return powq(base, exp); }; + +inline quad exp(quad val) +{ return expq(val); }; + +inline bool isfinite(quad val) +{ return !isnanq(val) && !isinfq(val); }; + +inline bool isnan(quad val) +{ return isnanq(val); }; + +inline bool isinf(quad val) +{ return isinfq(val); }; + +} // namespace std + + +#endif // DUMUX_QUAD_HH diff --git a/m4/dumux.m4 b/m4/dumux.m4 index 8631e99487714d41c01560ff1f6793d20670cc3e..4634cba9154daee5b075f0b8b2b765ac70c73c5f 100644 --- a/m4/dumux.m4 +++ b/m4/dumux.m4 @@ -76,6 +76,8 @@ AC_DEFUN([DUMUX_CHECKS], else DUNE_ADD_SUMMARY_ENTRY([Valgrind client requests],["no"]) fi + + DUMUX_CHECK_QUAD # check whether the constexpr keyword is present AC_REQUIRE([CONSTEXPR_CHECK]) diff --git a/m4/dumux_quad.m4 b/m4/dumux_quad.m4 new file mode 100644 index 0000000000000000000000000000000000000000..eecb3819e56527c8df35841677c41284b26eceeb --- /dev/null +++ b/m4/dumux_quad.m4 @@ -0,0 +1,69 @@ +AC_DEFUN([DUMUX_CHECK_QUAD], +[ +AC_ARG_WITH([quad], + AS_HELP_STRING([--with-quad@<:@=yes|no@:>@], [enable quad-precision floating point math (default is no)]), + [ + if test "$withval" = "no"; then + want_quad="no" + elif test "$withval" = "yes"; then + want_quad="yes" + else + want_quad="no" + fi + ], + [want_quad="no"]) + + # store old values + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LIBS="$LIBS" + + if test "x$want_quad" = "xyes"; then + QUADMATH_LIB_PATH="" + QUADMATH_INCLUDE_PATH="" + + QUAD_LIBS="-lquadmath" + QUAD_CPPFLAGS="" + + dnl overwrite ld flags if we have required special directory with + dnl --with-quad-libdir parameter + dnl if test "$ac_quad_lib_path" != ""; then + dnl QUAD_LDFLAGS="-L$ac_quad_lib_path -lquadmath" + dnl fi + LIBS="$LIBS -L/usr/lib64" + AC_LANG_PUSH(C++) + AC_SEARCH_LIBS([sqrtq], [quadmath], + [ + HAVE_QUAD="1" + QUAD_LIBS="$QUAD_LIBS" + ],[ + HAVE_QUAD="0" + AC_MSG_ERROR([libquadmath not found!]) + ]) + AC_LANG_POP([C++]) + + AC_SUBST(QUAD_LIBS, $QUAD_LIBS) + AC_SUBST(QUAD_LDFLAGS, $QUAD_LDFLAGS) + AC_SUBST(QUAD_CPPFLAGS, $QUAD_CPPFLAGS) + AC_MSG_RESULT(ok) + + # add to global list + DUNE_PKG_LIBS="$QUAD_LIBS $DUNE_PKG_LIBS" + DUNE_PKG_LDFLAGS="$DUNE_PKG_LDFLAGS $QUAD_LDFLAGS" + DUNE_PKG_CPPFLAGS="$DUNE_PKG_CPPFLAGS $QUAD_CPPFLAGS" + + AC_DEFINE([HAVE_QUAD],1,[Are quad-precision floating point values usable?]) + with_quad="yes" + else + with_quad="no" + fi + + # tell automake + AM_CONDITIONAL(QUAD, test "x$HAVE_QUAD" = "x1") + + # restore variables + LDFLAGS="$ac_save_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS" + LIBS="$ac_save_LIBS" + + DUNE_ADD_SUMMARY_ENTRY([quadruple precision math],[$with_quad]) +])