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/random.hpp> 29 #ifdef DEAL_II_WITH_MUPARSER 30 # include <muParser.h> 42 DEAL_II_NAMESPACE_OPEN
46 const std::vector<std::string> &
56 const double initial_time,
66 const std::string &constants,
67 const std::string &variable_names,
71 Utilities::split_string_list(expression,
';').size())
98 #ifdef DEAL_II_WITH_MUPARSER 103 const std::vector<std::string> &expressions,
104 const std::map<std::string, double> &constants,
105 const bool time_dependent)
109 this->constants = constants;
111 this->expressions = expressions;
112 AssertThrow(((time_dependent) ? dim + 1 : dim) == var_names.size(),
121 ExcInvalidExpressionSize(this->
n_components, expressions.size()));
160 return static_cast<int>(val + ((val >= 0.0) ? 0.5 : -0.5));
164 mu_if(
double condition,
double thenvalue,
double elsevalue)
166 if (mu_round(condition))
173 mu_or(
double left,
double right)
175 return (mu_round(left)) || (mu_round(right));
179 mu_and(
double left,
double right)
181 return (mu_round(left)) && (mu_round(right));
187 return static_cast<double>(mu_round(value));
191 mu_ceil(
double value)
193 return std::ceil(value);
197 mu_floor(
double value)
199 return std::floor(value);
205 return 1.0 / std::tan(value);
211 return 1.0 / std::sin(value);
217 return 1.0 / std::cos(value);
223 return std::log(value);
227 mu_pow(
double a,
double b)
229 return std::pow(a, b);
233 mu_erfc(
double value)
235 return std::erfc(value);
241 mu_rand_seed(
double seed)
244 std::lock_guard<std::mutex> lock(rand_mutex);
246 static boost::random::uniform_real_distribution<> uniform_distribution(0,
251 static std::map<double, boost::random::mt19937> rng_map;
253 if (rng_map.find(seed) == rng_map.end())
254 rng_map[seed] = boost::random::mt19937(static_cast<unsigned int>(seed));
256 return uniform_distribution(rng_map[seed]);
264 std::lock_guard<std::mutex> lock(rand_mutex);
265 static boost::random::uniform_real_distribution<> uniform_distribution(0,
267 static boost::random::mt19937 rng(
268 static_cast<unsigned long>(std::time(
nullptr)));
269 return uniform_distribution(rng);
288 vars.get().resize(var_names.size());
289 for (
unsigned int component = 0; component < this->
n_components; ++component)
291 fp.get().emplace_back(
new mu::Parser());
293 for (std::map<std::string, double>::const_iterator constant =
295 constant != constants.end();
298 fp.get()[component]->DefineConst(constant->first, constant->second);
301 for (
unsigned int iv = 0; iv < var_names.size(); ++iv)
302 fp.get()[component]->DefineVar(var_names[iv], &vars.get()[iv]);
305 fp.get()[component]->DefineFun(
"if", internal::mu_if,
true);
306 fp.get()[component]->DefineOprt(
"|", internal::mu_or, 1);
307 fp.get()[component]->DefineOprt(
"&", internal::mu_and, 2);
308 fp.get()[component]->DefineFun(
"int", internal::mu_int,
true);
309 fp.get()[component]->DefineFun(
"ceil", internal::mu_ceil,
true);
310 fp.get()[component]->DefineFun(
"cot", internal::mu_cot,
true);
311 fp.get()[component]->DefineFun(
"csc", internal::mu_csc,
true);
312 fp.get()[component]->DefineFun(
"floor", internal::mu_floor,
true);
313 fp.get()[component]->DefineFun(
"sec", internal::mu_sec,
true);
314 fp.get()[component]->DefineFun(
"log", internal::mu_log,
true);
315 fp.get()[component]->DefineFun(
"pow", internal::mu_pow,
true);
316 fp.get()[component]->DefineFun(
"erfc", internal::mu_erfc,
true);
317 fp.get()[component]->DefineFun(
"rand_seed", internal::mu_rand_seed,
true);
318 fp.get()[component]->DefineFun(
"rand", internal::mu_rand,
true);
329 std::string transformed_expression = expressions[component];
331 const char *function_names[] = {
370 for (
const auto &function_name_c_string : function_names)
372 const std::string function_name = function_name_c_string;
373 const unsigned int function_name_length = function_name.size();
375 std::string::size_type pos = 0;
379 pos = transformed_expression.find(function_name, pos);
380 if (pos == std::string::npos)
384 while ((pos + function_name_length <
385 transformed_expression.size()) &&
386 ((transformed_expression[pos + function_name_length] ==
388 (transformed_expression[pos + function_name_length] ==
390 transformed_expression.erase(
391 transformed_expression.begin() + pos +
392 function_name_length);
396 pos += function_name_length;
401 fp.get()[component]->SetExpr(transformed_expression);
403 catch (mu::ParserError &e)
405 std::cerr <<
"Message: <" << e.GetMsg() <<
">\n";
406 std::cerr <<
"Formula: <" << e.GetExpr() <<
">\n";
407 std::cerr <<
"Token: <" << e.GetToken() <<
">\n";
408 std::cerr <<
"Position: <" << e.GetPos() <<
">\n";
409 std::cerr <<
"Errc: <" << e.GetCode() <<
">" << std::endl;
410 AssertThrow(
false, ExcParseError(e.GetCode(), e.GetMsg()));
420 const std::string & expression,
421 const std::map<std::string, double> &constants,
422 const bool time_dependent)
435 const unsigned int component)
const 442 if (fp.get().size() == 0)
445 for (
unsigned int i = 0; i < dim; ++i)
446 vars.get()[i] = p(i);
448 vars.get()[dim] = this->get_time();
452 return fp.get()[component]->Eval();
454 catch (mu::ParserError &e)
456 std::cerr <<
"Message: <" << e.GetMsg() <<
">\n";
457 std::cerr <<
"Formula: <" << e.GetExpr() <<
">\n";
458 std::cerr <<
"Token: <" << e.GetToken() <<
">\n";
459 std::cerr <<
"Position: <" << e.GetPos() <<
">\n";
460 std::cerr <<
"Errc: <" << e.GetCode() <<
">" << std::endl;
461 AssertThrow(
false, ExcParseError(e.GetCode(), e.GetMsg()));
479 if (fp.get().size() == 0)
482 for (
unsigned int i = 0; i < dim; ++i)
483 vars.get()[i] = p(i);
485 vars.get()[dim] = this->get_time();
487 for (
unsigned int component = 0; component < this->
n_components; ++component)
488 values(component) = fp.get()[component]->Eval();
497 const std::vector<std::string> &,
498 const std::map<std::string, double> &,
508 const std::map<std::string, double> &,
541 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)
static const unsigned int max_int_value
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)
void init_muparser() const
const std::vector< std::string > & get_expressions() const
void initialize(const std::string &vars, const std::vector< std::string > &expressions, const ConstMap &constants, const bool time_dependent=false)
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
~FunctionParser() override
std::map< std::string, double > constants
static ::ExceptionBase & ExcInternalError()