From: Denis Davydov Date: Wed, 19 Sep 2018 21:11:58 +0000 (+0200) Subject: extend Patterns::Tools::Convert to understand ComponentMask and FunctionParser X-Git-Tag: v9.1.0-rc1~700^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3facf92c17615a4c789208df719f6b7b484730c;p=dealii.git extend Patterns::Tools::Convert to understand ComponentMask and FunctionParser --- diff --git a/include/deal.II/base/function_parser.h b/include/deal.II/base/function_parser.h index 31de68488f..b1d4c1c574 100644 --- a/include/deal.II/base/function_parser.h +++ b/include/deal.II/base/function_parser.h @@ -341,6 +341,13 @@ public: virtual void vector_value(const Point &p, Vector &values) const override; + /** + * Return an array of function expressions (one per component), used to + * initialize this function. + */ + const std::vector & + get_expressions() const; + /** * @addtogroup Exceptions * @{ diff --git a/include/deal.II/base/patterns.h b/include/deal.II/base/patterns.h index 9414567e8a..3b30fcfa3b 100644 --- a/include/deal.II/base/patterns.h +++ b/include/deal.II/base/patterns.h @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -52,6 +54,8 @@ DEAL_II_NAMESPACE_OPEN // forward declarations for interfaces and friendship class LogStream; class MultipleParameterLoop; +template +class FunctionParser; /** * Namespace for a few classes that act as patterns for the ParameterHandler @@ -1715,6 +1719,23 @@ namespace Patterns static constexpr int map_rank = RankInfo::map_rank; }; + // Rank of FunctionParser + template + struct RankInfo>> + { + static constexpr int list_rank = 1; + static constexpr int map_rank = 0; + }; + + // Rank of ComponentMask + template <> + struct RankInfo + { + static constexpr int list_rank = 1; + static constexpr int map_rank = 0; + }; + + // Rank of std::pair template struct RankInfo> { @@ -1982,6 +2003,106 @@ namespace Patterns } }; + // Functions::FunctionParser + template + struct Convert>> + { + using T = std::unique_ptr>; + + static std::unique_ptr + to_pattern() + { + static_assert(internal::RankInfo::list_rank > 0, + "Cannot use this class for non List-compatible types."); + + return std_cxx14::make_unique( + Patterns::Anything(), + 1, + Patterns::List::max_int_value, + internal::default_list_separator[internal::RankInfo::list_rank - + 1]); + } + + static std::string + to_string(const T & t, + const std::unique_ptr &pattern = + Convert::to_pattern()) + { + auto p = dynamic_cast(pattern.get()); + AssertThrow(p, + ExcMessage("I need a List pattern to convert a string " + "to a List compatbile type.")); + + const auto &expressions = t->get_expressions(); + if (expressions.size() == 0) + return std::string(); + + std::string s = expressions[0]; + for (unsigned int i = 1; i < expressions.size(); ++i) + s = s + p->get_separator() + expressions[i]; + + AssertThrow(pattern->match(s), ExcNoMatch(s, p)); + return s; + } + + static T + to_value(const std::string & s, + const std::unique_ptr &pattern = + Convert::to_pattern()) + { + AssertThrow(pattern->match(s), ExcNoMatch(s, pattern.get())); + + auto p = dynamic_cast(pattern.get()); + AssertThrow(p, + ExcMessage("I need a List pattern to convert a string " + "to a List compatbile type.")); + + const auto expressions = + Utilities::split_string_list(s, p->get_separator()); + + T t = std_cxx14::make_unique>(expressions.size()); + const std::string var = + FunctionParser::default_variable_names() + ",t"; + const typename FunctionParser::ConstMap constants; + t->initialize(var, expressions, constants, true); + return t; + } + }; + + // ComponentMask + template <> + struct Convert + { + using T = ComponentMask; + + static std::unique_ptr + to_pattern() + { + return Convert>::to_pattern(); + } + + static std::string + to_string(const T & t, + const std::unique_ptr &pattern = + Convert::to_pattern()) + { + std::vector mask(t.size()); + for (unsigned int i = 0; i < t.size(); ++i) + mask[i] = t[i]; + + return Convert>::to_string(mask, pattern); + } + + static T + to_value(const std::string & s, + const std::unique_ptr &pattern = + Convert::to_pattern()) + { + const auto mask = Convert>::to_value(s, pattern); + return ComponentMask(mask); + } + }; + // Complex numbers template struct Convert> diff --git a/source/base/function_parser.cc b/source/base/function_parser.cc index 754887ba1d..24a63b19d5 100644 --- a/source/base/function_parser.cc +++ b/source/base/function_parser.cc @@ -42,6 +42,14 @@ namespace fparser DEAL_II_NAMESPACE_OPEN +template +const std::vector & +FunctionParser::get_expressions() const +{ + return expressions; +} + + template FunctionParser::FunctionParser(const unsigned int n_components, diff --git a/tests/parameter_handler/patterns_14.cc b/tests/parameter_handler/patterns_14.cc new file mode 100644 index 0000000000..20e4e68bfe --- /dev/null +++ b/tests/parameter_handler/patterns_14.cc @@ -0,0 +1,56 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2005 - 2017 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. +// +// --------------------------------------------------------------------- + +// test add_parameters with ParsedFunction. + +#include +#include +#include + +#include + +#include "../tests.h" + +using namespace Patterns; +using namespace Patterns::Tools; + +int +main() +{ + initlog(); + + typedef std::unique_ptr> T; + + T a; + a = Convert::to_value("x*y,y-t"); + + ParameterHandler prm; + prm.add_parameter("A function", a); + + prm.log_parameters(deallog); + + prm.set("A function", "x*4,y*y*x+t*24"); + + deallog << "After ParameterHandler::set ==========================" + << std::endl + << std::endl; + prm.log_parameters(deallog); + + deallog << "Actual variables ==========================" + << std::endl + << std::endl; + + deallog << Convert::to_string(a) << std::endl; +} diff --git a/tests/parameter_handler/patterns_14.output b/tests/parameter_handler/patterns_14.output new file mode 100644 index 0000000000..67a3766836 --- /dev/null +++ b/tests/parameter_handler/patterns_14.output @@ -0,0 +1,8 @@ + +DEAL:parameters::A function: x*y,y-t +DEAL::After ParameterHandler::set ========================== +DEAL:: +DEAL:parameters::A function: x*4,y*y*x+t*24 +DEAL::Actual variables ========================== +DEAL:: +DEAL::x*4,y*y*x+t*24 diff --git a/tests/parameter_handler/patterns_15.cc b/tests/parameter_handler/patterns_15.cc new file mode 100644 index 0000000000..ff52373c5a --- /dev/null +++ b/tests/parameter_handler/patterns_15.cc @@ -0,0 +1,57 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2005 - 2017 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. +// +// --------------------------------------------------------------------- + +// test add_parameters with ComponentMask. + +#include +#include + +#include + +#include + +#include "../tests.h" + +using namespace Patterns; +using namespace Patterns::Tools; + +int +main() +{ + initlog(); + + typedef ComponentMask T; + + T a; + a = Convert::to_value("true,false,true"); + + ParameterHandler prm; + prm.add_parameter("A mask", a); + + prm.log_parameters(deallog); + + prm.set("A mask", "false,false,true"); + + deallog << "After ParameterHandler::set ==========================" + << std::endl + << std::endl; + prm.log_parameters(deallog); + + deallog << "Actual variables ==========================" + << std::endl + << std::endl; + + deallog << Convert::to_string(a) << std::endl; +} diff --git a/tests/parameter_handler/patterns_15.output b/tests/parameter_handler/patterns_15.output new file mode 100644 index 0000000000..91f8e92fb4 --- /dev/null +++ b/tests/parameter_handler/patterns_15.output @@ -0,0 +1,8 @@ + +DEAL:parameters::A mask: true, false, true +DEAL::After ParameterHandler::set ========================== +DEAL:: +DEAL:parameters::A mask: false,false,true +DEAL::Actual variables ========================== +DEAL:: +DEAL::false, false, true diff --git a/tests/parameter_handler/patterns_16.cc b/tests/parameter_handler/patterns_16.cc new file mode 100644 index 0000000000..f89e409bb4 --- /dev/null +++ b/tests/parameter_handler/patterns_16.cc @@ -0,0 +1,58 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2005 - 2017 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. +// +// --------------------------------------------------------------------- + +// test add_parameters with std::map + +#include +#include +#include + +#include + +#include + +#include "../tests.h" + +using namespace Patterns; +using namespace Patterns::Tools; + +int +main() +{ + initlog(); + + typedef std::map>> T; + + T a; + a = Convert::to_value("0:x,y,z*t"); + + ParameterHandler prm; + prm.add_parameter("Boundary conditions", a); + + prm.log_parameters(deallog); + + prm.set("Boundary conditions", "0:x*x*x,y*y*y,z*z*z*t;1:0,x*y,t"); + + deallog << "After ParameterHandler::set ==========================" + << std::endl + << std::endl; + prm.log_parameters(deallog); + + deallog << "Actual variables ==========================" + << std::endl + << std::endl; + + deallog << Convert::to_string(a) << std::endl; +} diff --git a/tests/parameter_handler/patterns_16.output b/tests/parameter_handler/patterns_16.output new file mode 100644 index 0000000000..9a822a8868 --- /dev/null +++ b/tests/parameter_handler/patterns_16.output @@ -0,0 +1,8 @@ + +DEAL:parameters::Boundary conditions: 0:x,y,z*t +DEAL::After ParameterHandler::set ========================== +DEAL:: +DEAL:parameters::Boundary conditions: 0:x*x*x,y*y*y,z*z*z*t;1:0,x*y,t +DEAL::Actual variables ========================== +DEAL:: +DEAL::0:x*x*x,y*y*y,z*z*z*t; 1:0,x*y,t