]> https://gitweb.dealii.org/ - dealii.git/commitdiff
ParameterHandler::add_parameter(): do not call action 14562/head
authorPeter Munch <peterrmuench@gmail.com>
Sun, 11 Dec 2022 15:15:47 +0000 (16:15 +0100)
committerMagdalena Schreter <schreter.magdalena@gmail.com>
Sat, 11 Feb 2023 00:08:57 +0000 (01:08 +0100)
doc/news/changes/incompatibilities/20221211Munch [new file with mode: 0644]
include/deal.II/base/parameter_handler.h
source/base/parameter_handler.cc
tests/parameter_handler/add_parameter_01.cc [new file with mode: 0644]
tests/parameter_handler/add_parameter_01.output [new file with mode: 0644]

diff --git a/doc/news/changes/incompatibilities/20221211Munch b/doc/news/changes/incompatibilities/20221211Munch
new file mode 100644 (file)
index 0000000..5c6f544
--- /dev/null
@@ -0,0 +1,9 @@
+Fixed: The function ParamerHandler::add_parameter() used to
+call the internal action. Within that step, the action
+converts the default value to a string and back afterwards.
+This can lead to round-off errors so that the default
+values might change in the case of floating-point numbers.
+The action is not called any more during ParamerHandler::add_parameter(),
+fixing the problem.
+<br>
+(Peter Munch, Magdalena Schreter, 2022/12/11)
index f9935bb0e2e9a1b398bf4522696f5eac8d341860..119f251dc72cf784e7dbb25505ac386650535744 100644 (file)
@@ -1137,10 +1137,14 @@ public:
    *
    * The action is executed in three different circumstances:
    * - With the default value of the parameter with name @p name, at
-   *   the end of the current function. This is useful because it allows
-   *   for the action to execute whatever it needs to do at least once
-   *   for each parameter, even those that are not actually specified in
-   *   the input file (and thus remain at their default values).
+   *   the end of the current function if @p execute_action is set to
+   *   true. This is useful because it allows for the action to execute
+   *   whatever it needs to do at least once for each parameter, even
+   *   those that are not actually specified in the input file (and
+   *   thus remain at their default values). Note that if the action
+   *   is executed, it converts the default value to a string and back
+   *   afterwards. This can lead to round-off errors so that the default
+   *   values might change in the case of floating-point numbers.
    * - Within the ParameterHandler::set() functions that explicitly
    *   set a value for a parameter.
    * - Within the parse_input() function and similar functions such
@@ -1173,7 +1177,8 @@ public:
    */
   void
   add_action(const std::string &                                  entry,
-             const std::function<void(const std::string &value)> &action);
+             const std::function<void(const std::string &value)> &action,
+             const bool execute_action = true);
 
   /**
    * Declare a new entry name @p entry, set its default value to the content of
@@ -2353,7 +2358,7 @@ ParameterHandler::add_parameter(const std::string &          entry,
     parameter = Patterns::Tools::Convert<ParameterType>::to_value(
       val, *patterns[pattern_index]);
   };
-  add_action(entry, action);
+  add_action(entry, action, false);
 }
 
 DEAL_II_NAMESPACE_CLOSE
index 7da508bf4987d407a12fe20f094f75936e417a9d..39f9507e4a009c6d03f04b5e6c5a348288669811 100644 (file)
@@ -874,7 +874,8 @@ ParameterHandler::declare_entry(const std::string &          entry,
 void
 ParameterHandler::add_action(
   const std::string &                             entry,
-  const std::function<void(const std::string &)> &action)
+  const std::function<void(const std::string &)> &action,
+  const bool                                      execute_action)
 {
   actions.push_back(action);
 
@@ -898,11 +899,12 @@ ParameterHandler::add_action(
     entries->put(get_current_full_path(entry) + path_separator + "actions",
                  Utilities::int_to_string(actions.size() - 1));
 
-
-  // as documented, run the action on the default value at the very end
-  const std::string default_value = entries->get<std::string>(
-    get_current_full_path(entry) + path_separator + "default_value");
-  action(default_value);
+  if (execute_action)
+    {
+      const std::string default_value = entries->get<std::string>(
+        get_current_full_path(entry) + path_separator + "default_value");
+      action(default_value);
+    }
 }
 
 
diff --git a/tests/parameter_handler/add_parameter_01.cc b/tests/parameter_handler/add_parameter_01.cc
new file mode 100644 (file)
index 0000000..96f1409
--- /dev/null
@@ -0,0 +1,42 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2022 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// check that ParameterHandler::add_parameter() does not modify the
+// default value
+
+#include <deal.II/base/parameter_handler.h>
+
+#include "../tests.h"
+
+using namespace dealii;
+
+int
+main()
+{
+  initlog();
+
+  double a = std::numeric_limits<double>::lowest();
+
+  AssertThrow(a == std::numeric_limits<double>::lowest(), ExcInternalError());
+
+  ParameterHandler prm;
+  prm.add_parameter("test", a);
+
+  AssertThrow(a == std::numeric_limits<double>::lowest(), ExcInternalError());
+
+  deallog << "OK!" << std::endl;
+}
diff --git a/tests/parameter_handler/add_parameter_01.output b/tests/parameter_handler/add_parameter_01.output
new file mode 100644 (file)
index 0000000..5cfb783
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK!

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.