From: Peter Munch Date: Sun, 11 Dec 2022 15:15:47 +0000 (+0100) Subject: ParameterHandler::add_parameter(): do not call action X-Git-Tag: v9.5.0-rc1~487^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bbb1a228aa87ea1225f33acf61e129f0e7e0bf31;p=dealii.git ParameterHandler::add_parameter(): do not call action --- diff --git a/doc/news/changes/incompatibilities/20221211Munch b/doc/news/changes/incompatibilities/20221211Munch new file mode 100644 index 0000000000..5c6f5448e1 --- /dev/null +++ b/doc/news/changes/incompatibilities/20221211Munch @@ -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. +
+(Peter Munch, Magdalena Schreter, 2022/12/11) diff --git a/include/deal.II/base/parameter_handler.h b/include/deal.II/base/parameter_handler.h index f9935bb0e2..119f251dc7 100644 --- a/include/deal.II/base/parameter_handler.h +++ b/include/deal.II/base/parameter_handler.h @@ -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 &action); + const std::function &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::to_value( val, *patterns[pattern_index]); }; - add_action(entry, action); + add_action(entry, action, false); } DEAL_II_NAMESPACE_CLOSE diff --git a/source/base/parameter_handler.cc b/source/base/parameter_handler.cc index 7da508bf49..39f9507e4a 100644 --- a/source/base/parameter_handler.cc +++ b/source/base/parameter_handler.cc @@ -874,7 +874,8 @@ ParameterHandler::declare_entry(const std::string & entry, void ParameterHandler::add_action( const std::string & entry, - const std::function &action) + const std::function &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( - get_current_full_path(entry) + path_separator + "default_value"); - action(default_value); + if (execute_action) + { + const std::string default_value = entries->get( + 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 index 0000000000..96f1409f99 --- /dev/null +++ b/tests/parameter_handler/add_parameter_01.cc @@ -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 + +#include "../tests.h" + +using namespace dealii; + +int +main() +{ + initlog(); + + double a = std::numeric_limits::lowest(); + + AssertThrow(a == std::numeric_limits::lowest(), ExcInternalError()); + + ParameterHandler prm; + prm.add_parameter("test", a); + + AssertThrow(a == std::numeric_limits::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 index 0000000000..5cfb783b8f --- /dev/null +++ b/tests/parameter_handler/add_parameter_01.output @@ -0,0 +1,2 @@ + +DEAL::OK!