17 #include <deal.II/base/function_parser.h> 18 #include <deal.II/base/patterns.h> 19 #include <deal.II/base/thread_management.h> 20 #include <deal.II/base/utilities.h> 22 #include <deal.II/lac/vector.h> 24 #include <boost/math/special_functions/erf.hpp> 25 #include <boost/random.hpp> 30 #ifdef DEAL_II_WITH_MUPARSER 31 # include <muParser.h> 43 DEAL_II_NAMESPACE_OPEN
49 const double initial_time,
60 const std::string &variable_names,
64 Utilities::split_string_list(expression,
';').size())
92 #ifdef DEAL_II_WITH_MUPARSER 98 const std::map<std::string, double> &
constants,
99 const bool time_dependent)
154 return static_cast<int>(val + ((val >= 0.0) ? 0.5 : -0.5));
158 mu_if(
double condition,
double thenvalue,
double elsevalue)
160 if (mu_round(condition))
167 mu_or(
double left,
double right)
169 return (mu_round(left)) || (mu_round(right));
173 mu_and(
double left,
double right)
175 return (mu_round(left)) && (mu_round(right));
181 return static_cast<double>(mu_round(value));
185 mu_ceil(
double value)
191 mu_floor(
double value)
199 return 1.0 / tan(value);
205 return 1.0 / sin(value);
211 return 1.0 / cos(value);
221 mu_pow(
double a,
double b)
223 return std::pow(a, b);
227 mu_erfc(
double value)
229 return boost::math::erfc(value);
235 mu_rand_seed(
double seed)
240 static boost::random::uniform_real_distribution<> uniform_distribution(0,
245 static std::map<double, boost::random::mt19937> rng_map;
247 if (rng_map.find(seed) == rng_map.end())
248 rng_map[seed] = boost::random::mt19937(static_cast<unsigned int>(seed));
250 return uniform_distribution(rng_map[seed]);
259 static boost::random::uniform_real_distribution<> uniform_distribution(0,
261 static boost::random::mt19937 rng(
262 static_cast<unsigned long>(std::time(
nullptr)));
263 return uniform_distribution(rng);
283 for (
unsigned int component = 0; component < this->
n_components; ++component)
285 fp.
get().emplace_back(
new mu::Parser());
287 for (std::map<std::string, double>::const_iterator constant =
292 fp.
get()[component]->DefineConst(constant->first.c_str(),
296 for (
unsigned int iv = 0; iv <
var_names.size(); ++iv)
300 fp.
get()[component]->DefineFun(
"if", internal::mu_if,
true);
301 fp.
get()[component]->DefineOprt(
"|", internal::mu_or, 1);
302 fp.
get()[component]->DefineOprt(
"&", internal::mu_and, 2);
303 fp.
get()[component]->DefineFun(
"int", internal::mu_int,
true);
304 fp.
get()[component]->DefineFun(
"ceil", internal::mu_ceil,
true);
305 fp.
get()[component]->DefineFun(
"cot", internal::mu_cot,
true);
306 fp.
get()[component]->DefineFun(
"csc", internal::mu_csc,
true);
307 fp.
get()[component]->DefineFun(
"floor", internal::mu_floor,
true);
308 fp.
get()[component]->DefineFun(
"sec", internal::mu_sec,
true);
309 fp.
get()[component]->DefineFun(
"log", internal::mu_log,
true);
310 fp.
get()[component]->DefineFun(
"pow", internal::mu_pow,
true);
311 fp.
get()[component]->DefineFun(
"erfc", internal::mu_erfc,
true);
312 fp.
get()[component]->DefineFun(
"rand_seed", internal::mu_rand_seed,
true);
313 fp.
get()[component]->DefineFun(
"rand", internal::mu_rand,
true);
324 std::string transformed_expression =
expressions[component];
326 const char *function_names[] = {
365 for (
unsigned int f = 0;
366 f <
sizeof(function_names) /
sizeof(function_names[0]);
369 const std::string function_name = function_names[f];
370 const unsigned int function_name_length = function_name.size();
372 std::string::size_type pos = 0;
376 pos = transformed_expression.find(function_name, pos);
377 if (pos == std::string::npos)
381 while ((pos + function_name_length <
382 transformed_expression.size()) &&
383 ((transformed_expression[pos + function_name_length] ==
385 (transformed_expression[pos + function_name_length] ==
387 transformed_expression.erase(
388 transformed_expression.begin() + pos +
389 function_name_length);
393 pos += function_name_length;
398 fp.
get()[component]->SetExpr(transformed_expression);
400 catch (mu::ParserError &e)
402 std::cerr <<
"Message: <" << e.GetMsg() <<
">\n";
403 std::cerr <<
"Formula: <" << e.GetExpr() <<
">\n";
404 std::cerr <<
"Token: <" << e.GetToken() <<
">\n";
405 std::cerr <<
"Position: <" << e.GetPos() <<
">\n";
406 std::cerr <<
"Errc: <" << e.GetCode() <<
">" << std::endl;
417 const std::string & expression,
418 const std::map<std::string, double> &
constants,
419 const bool time_dependent)
432 const unsigned int component)
const 439 if (
fp.
get().size() == 0)
442 for (
unsigned int i = 0; i < dim; ++i)
449 return fp.
get()[component]->Eval();
451 catch (mu::ParserError &e)
453 std::cerr <<
"Message: <" << e.GetMsg() <<
">\n";
454 std::cerr <<
"Formula: <" << e.GetExpr() <<
">\n";
455 std::cerr <<
"Token: <" << e.GetToken() <<
">\n";
456 std::cerr <<
"Position: <" << e.GetPos() <<
">\n";
457 std::cerr <<
"Errc: <" << e.GetCode() <<
">" << std::endl;
476 if (
fp.
get().size() == 0)
479 for (
unsigned int i = 0; i < dim; ++i)
484 for (
unsigned int component = 0; component < this->
n_components; ++component)
485 values(component) =
fp.
get()[component]->Eval();
494 const std::vector<std::string> &,
495 const std::map<std::string, double> &,
505 const std::map<std::string, double> &,
538 DEAL_II_NAMESPACE_CLOSE
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
static::ExceptionBase & ExcNeedsFunctionparser()
FunctionParser(const unsigned int n_components=1, const double initial_time=0.0, const double h=1e-8)
Threads::ThreadLocalStorage< std::vector< std::shared_ptr< mu::Parser > > > fp
const unsigned int n_components
static const unsigned int max_int_value
static::ExceptionBase & ExcParseError(int arg1, std::string arg2)
void init_muparser() const
static::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static::ExceptionBase & ExcMessage(std::string arg1)
virtual void vector_value(const Point< dim > &p, Vector< double > &values) const override
#define Assert(cond, exc)
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Threads::ThreadLocalStorage< std::vector< double > > vars
static::ExceptionBase & ExcInvalidExpressionSize(int arg1, int arg2)
std::vector< std::string > var_names
void initialize(const std::string &vars, const std::vector< std::string > &expressions, const ConstMap &constants, const bool time_dependent=false)
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
std::vector< std::string > expressions
~FunctionParser() override
std::map< std::string, double > constants
static::ExceptionBase & ExcInternalError()