From 216f6b1c5e676b86ff560f1a0356daa3983220a9 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 21 Feb 2006 21:36:35 +0000 Subject: [PATCH] Check for long double accuracy in QGauss constructor. git-svn-id: https://svn.dealii.org/trunk@12451 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/source/quadrature_lib.cc | 48 +++++++++++++++++++-------- deal.II/doc/news/changes.html | 16 +++++++++ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/deal.II/base/source/quadrature_lib.cc b/deal.II/base/source/quadrature_lib.cc index 2e267d5c7d..8bbbd276d0 100644 --- a/deal.II/base/source/quadrature_lib.cc +++ b/deal.II/base/source/quadrature_lib.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -66,21 +66,43 @@ QGauss<1>::QGauss (const unsigned int n) // of the accuracy of double there, // while on other machines we'd // like to go further down -#ifdef HAVE_STD_NUMERIC_LIMITS - const long double tolerance - = std::max (static_cast(std::numeric_limits::epsilon() / 100), - static_cast(std::numeric_limits::epsilon() * 5)); + // + // the situation is complicated by + // the fact that even if long + // double exists and is described + // by std::numeric_limits, we may + // not actually get the additional + // precission. One case where this + // happens is on x86, where one can + // set hardware flags that disable + // long double precision even for + // long double variables. these + // flags are not usually set, but + // for example matlab sets them and + // this then breaks deal.II code + // that is run as a subroutine to + // matlab... +#ifdef HAVE_STD_NUMERIC_LIMITS + const long double + long_double_eps = static_cast(std::numeric_limits::epsilon()), + double_eps = static_cast(std::numeric_limits::epsilon()); #else - // well, if there is no - // header, then we can do not much - // better than just checking by - // hand that long double is not the - // same as double and set some - // values by hand - const long double tolerance - = (sizeof(long double) != sizeof(double) ? 1.e-19 : 5e-16); + const long double + long_double_eps = 1.09-19L, + double_eps = 2.23-16; #endif + // now check whether long double is + // more accurate than double, and + // set tolerances accordingly + const long double tolerance + = (static_cast(1.0) + long_double_eps != static_cast(1.0) + ? + std::max (double_eps / 100, long_double_eps * 5) + : + double_eps * 5 + ); + for (unsigned int i=1; i<=m; ++i) { diff --git a/deal.II/doc/news/changes.html b/deal.II/doc/news/changes.html index 4b804575d9..6b96d045ed 100644 --- a/deal.II/doc/news/changes.html +++ b/deal.II/doc/news/changes.html @@ -247,6 +247,22 @@ inconvenience this causes.

base

    +
  1. Fixed: The QGauss constructor + hangs on x86 linux systems when deal.II is run from inside + MATLAB. The reason is that while the processor offers long + double accuracy, MATLAB switches off support for that inside + the CPU. It therefore leaves codes that expect the additional + accuracy high and dry. Annoyingly, these codes of course run + just fine outside of MATLAB's environment. This behavior leads + to an infinite loop inside the QGauss constructor, where we + want to use the additional accuracy to compute quadrature + points to high precision. To avoid the infinite loop, we now + check during runtime whether the extra precision is available, + not only at compile time. +
    + (Christian Kamm, WB 2006/02/21) +

    +
  2. Fixed: The ParameterHandler::get_integer had an erroneous check that the value given for a parameter really represented an integer. This check always succeeded, even in face of an -- 2.39.5