Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-2848-g5241f990fb 2025-03-16 19:30:00+00:00
\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}} \newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=} \newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]} \newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
parsed_function.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2007 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
18
20
21namespace Functions
22{
23 template <int dim>
24 ParsedFunction<dim>::ParsedFunction(const unsigned int n_components,
25 const double h)
26 : AutoDerivativeFunction<dim>(h, n_components)
27 , function_object(n_components)
28 {}
29
30
31
32 template <int dim>
33 void
35 const unsigned int n_components,
36 const std::string &input_expr)
37 {
38 Assert(n_components > 0, ExcZero());
39
40 std::string vnames;
41 switch (dim)
42 {
43 case 1:
44 vnames = "x,t";
45 break;
46 case 2:
47 vnames = "x,y,t";
48 break;
49 case 3:
50 vnames = "x,y,z,t";
51 break;
52 default:
54 break;
55 }
56 prm.declare_entry(
57 "Variable names",
58 vnames,
60 "The names of the variables as they will be used in the "
61 "function, separated by commas. By default, the names of variables "
62 "at which the function will be evaluated are `x' (in 1d), `x,y' (in 2d) or "
63 "`x,y,z' (in 3d) for spatial coordinates and `t' for time. You can then "
64 "use these variable names in your function expression and they will be "
65 "replaced by the values of these variables at which the function is "
66 "currently evaluated. However, you can also choose a different set "
67 "of names for the independent variables at which to evaluate your function "
68 "expression. For example, if you work in spherical coordinates, you may "
69 "wish to set this input parameter to `r,phi,theta,t' and then use these "
70 "variable names in your function expression.");
71
72 // The expression of the function
73 // If the string is an empty string, 0 is set for each components.
74 std::string expr = input_expr;
75 if (expr == "")
76 {
77 expr = "0";
78 for (unsigned int i = 1; i < n_components; ++i)
79 expr += "; 0";
80 }
81 else
82 {
83 // If the user specified an input expr, the number of component
84 // specified need to match n_components.
85 AssertDimension((std::count(expr.begin(), expr.end(), ';') + 1),
86 n_components);
87 }
88
89
90 prm.declare_entry(
91 "Function expression",
92 expr,
94 "The formula that denotes the function you want to evaluate for "
95 "particular values of the independent variables. This expression "
96 "may contain any of the usual operations such as addition or "
97 "multiplication, as well as all of the common functions such as "
98 "`sin' or `cos'. In addition, it may contain expressions like "
99 "`if(x>0, 1, -1)' where the expression evaluates to the second "
100 "argument if the first argument is true, and to the third argument "
101 "otherwise. For a full overview of possible expressions accepted "
102 "see the documentation of the muparser library at http://muparser.beltoforion.de/."
103 "\n\n"
104 "If the function you are describing represents a vector-valued "
105 "function with multiple components, then separate the expressions "
106 "for individual components by a semicolon.");
107 prm.declare_entry(
108 "Function constants",
109 "",
111 "Sometimes it is convenient to use symbolic constants in the "
112 "expression that describes the function, rather than having to "
113 "use its numeric value everywhere the constant appears. These "
114 "values can be defined using this parameter, in the form "
115 "`var1=value1, var2=value2, ...'."
116 "\n\n"
117 "A typical example would be to set this runtime parameter to "
118 "`pi=3.1415926536' and then use `pi' in the expression of the "
119 "actual formula. (That said, for convenience this class actually "
120 "defines both `pi' and `Pi' by default, but you get the idea.)");
121 }
122
123
124
125 template <int dim>
126 void
128 {
129 std::string vnames = prm.get("Variable names");
130 std::string expression = prm.get("Function expression");
131 std::string constants_list = prm.get("Function constants");
132
133 std::vector<std::string> const_list =
134 Utilities::split_string_list(constants_list, ',');
135 std::map<std::string, double> constants;
136 for (const auto &constant : const_list)
137 {
138 std::vector<std::string> this_c =
139 Utilities::split_string_list(constant, '=');
140 AssertThrow(this_c.size() == 2,
141 ExcMessage("The list of constants, <" + constants_list +
142 ">, is not a comma-separated list of "
143 "entries of the form 'name=value'."));
144 constants[this_c[0]] = Utilities::string_to_double(this_c[1]);
145 }
146
147 // set pi and Pi as synonyms for the corresponding value. note that
148 // this overrides any value a user may have given
149 constants["pi"] = numbers::PI;
150 constants["Pi"] = numbers::PI;
151
152 const unsigned int nn = (Utilities::split_string_list(vnames)).size();
153 switch (nn)
154 {
155 case dim:
156 // Time independent function
157 function_object.initialize(vnames, expression, constants);
158 break;
159 case dim + 1:
160 // Time dependent function
161 function_object.initialize(vnames, expression, constants, true);
162 break;
163 default:
164 AssertThrow(false,
166 "The list of variables specified is <" + vnames +
167 "> which is a list of length " +
169 " but it has to be a list of length equal to" +
170 " either dim (for a time-independent function)" +
171 " or dim+1 (for a time-dependent function)."));
172 }
173 }
174
175
176
177 template <int dim>
178 void
180 Vector<double> &values) const
181 {
182 function_object.vector_value(p, values);
183 }
184
185
186
187 template <int dim>
188 double
189 ParsedFunction<dim>::value(const Point<dim> &p, unsigned int comp) const
190 {
191 return function_object.value(p, comp);
192 }
193
194
195
196 template <int dim>
197 void
198 ParsedFunction<dim>::set_time(const double newtime)
199 {
200 function_object.set_time(newtime);
202 }
203
204
205 // Explicit instantiations
206 template class ParsedFunction<1>;
207 template class ParsedFunction<2>;
208 template class ParsedFunction<3>;
209} // namespace Functions
virtual void set_time(const Number new_time)
virtual void vector_value(const Point< dim > &p, Vector< double > &values) const override
ParsedFunction(const unsigned int n_components=1, const double h=1e-8)
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
static void declare_parameters(ParameterHandler &prm, const unsigned int n_components=1, const std::string &input_expr="")
virtual void set_time(const double newtime) override
void parse_parameters(ParameterHandler &prm)
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="", const bool has_to_be_set=false)
std::string get(const std::string &entry_string) const
Definition point.h:113
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
static ::ExceptionBase & ExcZero()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::size_t size
Definition mpi.cc:745
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition utilities.cc:699
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition utilities.cc:466
double string_to_double(const std::string &s)
Definition utilities.cc:650
constexpr double PI
Definition numbers.h:239