]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Check for long double accuracy in QGauss constructor.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Tue, 21 Feb 2006 21:36:35 +0000 (21:36 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Tue, 21 Feb 2006 21:36:35 +0000 (21:36 +0000)
git-svn-id: https://svn.dealii.org/trunk@12451 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/source/quadrature_lib.cc
deal.II/doc/news/changes.html

index 2e267d5c7d7bccdef03eb6077efe7b77eb8ac7fb..8bbbd276d04ddb30f96fc7b65b34f85b2d281106 100644 (file)
@@ -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<long double>(std::numeric_limits<double>::epsilon() / 100),
-                static_cast<long double>(std::numeric_limits<long double>::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<long double>(std::numeric_limits<long double>::epsilon()),
+    double_eps      = static_cast<long double>(std::numeric_limits<double>::epsilon());
 #else
-                                  // well, if there is no <limits>
-                                  // 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<long double>(1.0) + long_double_eps != static_cast<long double>(1.0)
+       ?
+       std::max (double_eps / 100, long_double_eps * 5)
+       :
+       double_eps * 5
+       );
+
   
   for (unsigned int i=1; i<=m; ++i)
     {
index 4b804575d94efe77422817bbb71ae69c4a83261b..6b96d045ed41307b361fde52cd68a460da96f3e9 100644 (file)
@@ -247,6 +247,22 @@ inconvenience this causes.
 <h3>base</h3>
 
 <ol>
+  <li> <p>Fixed: The <code class="member">QGauss</code> 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.
+       <br>
+       (Christian Kamm, WB 2006/02/21)
+       </p>
+
   <li> <p>Fixed: The <code class="member">ParameterHandler::get_integer</code>
        had an erroneous check that the value given for a parameter really
        represented an integer. This check always succeeded, even in face of an

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.