libMesh
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
libMesh::ParsedFunction< Output, OutputGradient > Class Template Reference

A Function generated (via FParser) by parsing a mathematical expression. More...

#include <parsed_function.h>

Inheritance diagram for libMesh::ParsedFunction< Output, OutputGradient >:
[legend]

Public Member Functions

 ParsedFunction (const std::string &expression, const std::vector< std::string > *additional_vars=nullptr, const std::vector< Output > *initial_vals=nullptr)
 
ParsedFunctionoperator= (const ParsedFunction &)=delete
 This class cannot be (default) copy assigned because the underlying FunctionParserADBase class does not define a custom copy assignment operator, and manually manages memory. More...
 
 ParsedFunction (const ParsedFunction &)=default
 The remaining special functions can be defaulted for this class. More...
 
 ParsedFunction (ParsedFunction &&)=default
 
ParsedFunctionoperator= (ParsedFunction &&)=default
 
virtual ~ParsedFunction ()=default
 
void reparse (const std::string &expression)
 Re-parse with new expression. More...
 
virtual Output operator() (const Point &p, const Real time=0) override
 
virtual bool has_derivatives ()
 Query if the automatic derivative generation was successful. More...
 
virtual Output dot (const Point &p, const Real time=0)
 
virtual OutputGradient gradient (const Point &p, const Real time=0)
 
virtual void operator() (const Point &p, const Real time, DenseVector< Output > &output) override
 Evaluation function for time-dependent vector-valued functions. More...
 
virtual Output component (unsigned int i, const Point &p, Real time) override
 
const std::string & expression ()
 
virtual Output & getVarAddress (const std::string &variable_name)
 
virtual std::unique_ptr< FunctionBase< Output > > clone () const override
 
Output get_inline_value (const std::string &inline_var_name) const
 
void set_inline_value (const std::string &inline_var_name, Output newval)
 Changes the value of an inline variable. More...
 
 ParsedFunction (const std::string &, const std::vector< std::string > *=nullptr, const std::vector< Output > *=nullptr)
 
 ParsedFunction (ParsedFunction &&)=delete
 When !LIBMESH_HAVE_FPARSER, this class is not implemented, so let's make that explicit by deleting the special functions. More...
 
 ParsedFunction (const ParsedFunction &)=delete
 
ParsedFunctionoperator= (const ParsedFunction &)=delete
 
ParsedFunctionoperator= (ParsedFunction &&)=delete
 
virtual ~ParsedFunction ()=default
 
virtual Output operator() (const Point &, const Real=0)
 
virtual void operator() (const Point &, const Real, DenseVector< Output > &)
 Evaluation function for time-dependent vector-valued functions. More...
 
virtual void init ()
 The actual initialization process. More...
 
virtual void clear ()
 Clears the function. More...
 
virtual Output & getVarAddress (const std::string &)
 
virtual std::unique_ptr< FunctionBase< Output > > clone () const
 
void operator() (const Point &p, DenseVector< Output > &output)
 Evaluation function for time-independent vector-valued functions. More...
 
bool initialized () const
 
void set_is_time_dependent (bool is_time_dependent)
 Function to set whether this is a time-dependent function or not. More...
 
bool is_time_dependent () const
 

Protected Member Functions

void partial_reparse (const std::string &expression)
 Re-parse with minor changes to expression. More...
 
std::size_t find_name (const std::string &varname, const std::string &expr) const
 Helper function for parsing out variable names. More...
 
bool expression_is_time_dependent (const std::string &expression) const
 

Protected Attributes

const FunctionBase_master
 Const pointer to our master, initialized to nullptr. More...
 
bool _initialized
 When init() was called so that everything is ready for calls to operator() (...), then this bool is true. More...
 
bool _is_time_dependent
 Cache whether or not this function is actually time-dependent. More...
 

Private Member Functions

void set_spacetime (const Point &p, const Real time=0)
 Set the _spacetime argument vector. More...
 
Output eval (FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
 Evaluate the ith FunctionParser and check the result. More...
 

Private Attributes

std::string _expression
 
std::vector< std::string > _subexpressions
 
std::vector< FunctionParserADBase< Output > > parsers
 
std::vector< Output > _spacetime
 
std::vector< FunctionParserADBase< Output > > dx_parsers
 
std::vector< FunctionParserADBase< Output > > dy_parsers
 
std::vector< FunctionParserADBase< Output > > dz_parsers
 
std::vector< FunctionParserADBase< Output > > dt_parsers
 
bool _valid_derivatives
 
std::string variables
 
std::vector< std::string > _additional_vars
 
std::vector< Output > _initial_vals
 
Output _dummy
 

Detailed Description

template<typename Output = Number, typename OutputGradient = Gradient>
class libMesh::ParsedFunction< Output, OutputGradient >

A Function generated (via FParser) by parsing a mathematical expression.

All overridden virtual functions are documented in function_base.h.

Author
Roy Stogner
Date
2012

A Function defined by a std::string.

Definition at line 60 of file parsed_function.h.

Constructor & Destructor Documentation

◆ ParsedFunction() [1/6]

template<typename Output, typename OutputGradient >
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const std::string &  expression,
const std::vector< std::string > *  additional_vars = nullptr,
const std::vector< Output > *  initial_vals = nullptr 
)
inlineexplicit

Definition at line 211 of file parsed_function.h.

213  :
214  _expression (), // overridden by parse()
215  // Size the spacetime vector to account for space, time, and any additional
216  // variables passed
217  _spacetime (LIBMESH_DIM+1 + (additional_vars ? additional_vars->size() : 0)),
218  _valid_derivatives (true),
219  _additional_vars (additional_vars ? *additional_vars : std::vector<std::string>()),
220  _initial_vals (initial_vals ? *initial_vals : std::vector<Output>())
221 {
222  // time-dependence established in reparse function
223  this->reparse(expression);
224  this->_initialized = true;
225 }

◆ ParsedFunction() [2/6]

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const ParsedFunction< Output, OutputGradient > &  )
default

The remaining special functions can be defaulted for this class.

Note
Despite the fact that the underlying FunctionParserADBase class is not move-assignable or move-constructible, it is still possible for this class to be move-assigned and move-constructed, because FunctionParserADBase objects only appear within std::vectors in this class, and std::vectors can generally still be move-assigned and move-constructed even when their contents cannot. There are some allocator-specific exceptions to this, but it should be guaranteed to work for std::allocator in C++14 and beyond. See also: https://stackoverflow.com/q/42051917/659433

◆ ParsedFunction() [3/6]

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( ParsedFunction< Output, OutputGradient > &&  )
default

◆ ~ParsedFunction() [1/2]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual libMesh::ParsedFunction< Output, OutputGradient >::~ParsedFunction ( )
virtualdefault

◆ ParsedFunction() [4/6]

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const std::string &  ,
const std::vector< std::string > *  = nullptr,
const std::vector< Output > *  = nullptr 
)
inline

Definition at line 718 of file parsed_function.h.

720  : _dummy(0)
721  {
722  libmesh_not_implemented();
723  }

◆ ParsedFunction() [5/6]

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( ParsedFunction< Output, OutputGradient > &&  )
delete

When !LIBMESH_HAVE_FPARSER, this class is not implemented, so let's make that explicit by deleting the special functions.

◆ ParsedFunction() [6/6]

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const ParsedFunction< Output, OutputGradient > &  )
delete

◆ ~ParsedFunction() [2/2]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual libMesh::ParsedFunction< Output, OutputGradient >::~ParsedFunction ( )
virtualdefault

Member Function Documentation

◆ clear()

template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::clear ( )
inlinevirtual

Clears the function.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 744 of file parsed_function.h.

744 {}

Referenced by libMesh::ParsedFunction< T >::partial_reparse().

◆ clone() [1/2]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual std::unique_ptr<FunctionBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::clone ( ) const
inlinevirtual
Returns
A new copy of the function.

The new copy should be as "deep" as necessary to allow independent destruction and simultaneous evaluations of the copies in different threads.

Implements libMesh::FunctionBase< Output >.

Definition at line 746 of file parsed_function.h.

747  {
748  return libmesh_make_unique<ParsedFunction<Output>>("");
749  }

◆ clone() [2/2]

template<typename Output , typename OutputGradient >
std::unique_ptr< FunctionBase< Output > > libMesh::ParsedFunction< Output, OutputGradient >::clone ( ) const
inlineoverridevirtual
Returns
A new copy of the function.

The new copy should be as "deep" as necessary to allow independent destruction and simultaneous evaluations of the copies in different threads.

Implements libMesh::FunctionBase< Output >.

Definition at line 358 of file parsed_function.h.

359 {
360  return libmesh_make_unique<ParsedFunction>(_expression,
362  &_initial_vals);
363 }

◆ component()

template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::component ( unsigned int  i,
const Point p,
Real  time 
)
inlineoverridevirtual
Returns
The vector component i at coordinate p and time time.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 323 of file parsed_function.h.

326 {
327  set_spacetime(p, time);
328  libmesh_assert_less (i, parsers.size());
329 
330  // The remaining locations in _spacetime are currently fixed at construction
331  // but could potentially be made dynamic
332  libmesh_assert_less(i, parsers.size());
333  return eval(parsers[i], "f", i);
334 }

◆ dot()

template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::dot ( const Point p,
const Real  time = 0 
)
inlinevirtual

Definition at line 271 of file parsed_function.h.

272 {
273  set_spacetime(p, time);
274  return eval(dt_parsers[0], "df/dt", 0);
275 }

◆ eval()

template<typename Output, typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::eval ( FunctionParserADBase< Output > &  parser,
const std::string &  libmesh_dbg_varfunction_name,
unsigned int   libmesh_dbg_varcomponent_idx 
) const
inlineprivate

Evaluate the ith FunctionParser and check the result.

Definition at line 654 of file parsed_function.h.

657 {
658 #ifndef NDEBUG
659  Output result = parser.Eval(_spacetime.data());
660  int error_code = parser.EvalError();
661  if (error_code)
662  {
663  libMesh::err << "ERROR: FunctionParser is unable to evaluate component "
664  << component_idx
665  << " of expression '"
666  << function_name
667  << "' with arguments:\n";
668  for (const auto & item : _spacetime)
669  libMesh::err << '\t' << item << '\n';
670  libMesh::err << '\n';
671 
672  // Currently no API to report error messages, we'll do it manually
673  std::string error_message = "Reason: ";
674 
675  switch (error_code)
676  {
677  case 1:
678  error_message += "Division by zero";
679  break;
680  case 2:
681  error_message += "Square Root error (negative value)";
682  break;
683  case 3:
684  error_message += "Log error (negative value)";
685  break;
686  case 4:
687  error_message += "Trigonometric error (asin or acos of illegal value)";
688  break;
689  case 5:
690  error_message += "Maximum recursion level reached";
691  break;
692  default:
693  error_message += "Unknown";
694  break;
695  }
696  libmesh_error_msg(error_message);
697  }
698 
699  return result;
700 #else
701  return parser.Eval(_spacetime.data());
702 #endif
703 }

◆ expression()

template<typename Output = Number, typename OutputGradient = Gradient>
const std::string& libMesh::ParsedFunction< Output, OutputGradient >::expression ( )
inline

Definition at line 121 of file parsed_function.h.

121 { return _expression; }

◆ expression_is_time_dependent()

template<typename Output , typename OutputGradient >
bool libMesh::ParsedFunction< Output, OutputGradient >::expression_is_time_dependent ( const std::string &  expression) const
inlineprotected
Returns
true if the expression is time-dependent, false otherwise.

Definition at line 618 of file parsed_function.h.

619 {
620  bool is_time_dependent = false;
621 
622  // By definition, time is "t" for FunctionBase-based objects, so we just need to
623  // see if this expression has the variable "t" in it.
624  if (this->find_name(std::string("t"), expression) != std::string::npos)
625  is_time_dependent = true;
626 
627  return is_time_dependent;
628 }

◆ find_name()

template<typename Output , typename OutputGradient >
std::size_t libMesh::ParsedFunction< Output, OutputGradient >::find_name ( const std::string &  varname,
const std::string &  expr 
) const
inlineprotected

Helper function for parsing out variable names.

Definition at line 596 of file parsed_function.h.

598 {
599  const std::size_t namesize = varname.size();
600  std::size_t varname_i = expr.find(varname);
601 
602  while ((varname_i != std::string::npos) &&
603  (((varname_i > 0) &&
604  (std::isalnum(expr[varname_i-1]) ||
605  (expr[varname_i-1] == '_'))) ||
606  ((varname_i+namesize < expr.size()) &&
607  (std::isalnum(expr[varname_i+namesize]) ||
608  (expr[varname_i+namesize] == '_')))))
609  {
610  varname_i = expr.find(varname, varname_i+1);
611  }
612 
613  return varname_i;
614 }

◆ get_inline_value()

template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::get_inline_value ( const std::string &  inline_var_name) const
inline
Returns
The value of an inline variable.
Note
Will only be correct if the inline variable value is independent of input variables, if the inline variable is not redefined within any subexpression, and if the inline variable takes the same value within any subexpressions where it appears.

Definition at line 368 of file parsed_function.h.

369 {
370  libmesh_assert_greater (_subexpressions.size(), 0);
371 
372 #ifndef NDEBUG
373  bool found_var_name = false;
374 #endif
375  Output old_var_value(0.);
376 
377  for (const auto & subexpression : _subexpressions)
378  {
379  const std::size_t varname_i =
380  find_name(inline_var_name, subexpression);
381  if (varname_i == std::string::npos)
382  continue;
383 
384  const std::size_t assignment_i =
385  subexpression.find(":", varname_i+1);
386 
387  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
388 
389  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
390  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
391  libmesh_assert_equal_to(subexpression[i], ' ');
392 
393  std::size_t end_assignment_i =
394  subexpression.find(";", assignment_i+1);
395 
396  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
397 
398  std::string new_subexpression =
399  subexpression.substr(0, end_assignment_i+1) +
400  inline_var_name;
401 
402 #ifdef LIBMESH_HAVE_FPARSER
403  // Parse and evaluate the new subexpression.
404  // Add the same constants as we used originally.
405  FunctionParserADBase<Output> fp;
406  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
407  fp.AddConstant("pi", std::acos(Real(-1)));
408  fp.AddConstant("e", std::exp(Real(1)));
409  if (fp.Parse(new_subexpression, variables) != -1) // -1 for success
410  libmesh_error_msg
411  ("ERROR: FunctionParser is unable to parse modified expression: "
412  << new_subexpression << '\n' << fp.ErrorMsg());
413 
414  Output new_var_value = this->eval(fp, new_subexpression, 0);
415 #ifdef NDEBUG
416  return new_var_value;
417 #else
418  if (found_var_name)
419  {
420  libmesh_assert_equal_to(old_var_value, new_var_value);
421  }
422  else
423  {
424  old_var_value = new_var_value;
425  found_var_name = true;
426  }
427 #endif
428 
429 #else
430  libmesh_error_msg("ERROR: This functionality requires fparser!");
431 #endif
432  }
433 
434  libmesh_assert(found_var_name);
435  return old_var_value;
436 }

Referenced by libMesh::ParsedFunctionParameter< T >::get(), ParsedFunctionTest::testInlineGetter(), and ParsedFunctionTest::testInlineSetter().

◆ getVarAddress() [1/2]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output& libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( const std::string &  )
inlinevirtual

Definition at line 745 of file parsed_function.h.

745 { return _dummy; }

◆ getVarAddress() [2/2]

template<typename Output , typename OutputGradient >
Output & libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( const std::string &  variable_name)
inlinevirtual
Returns
The address of a parsed variable so you can supply a parameterized value.
The address of a parsed variable so you can supply a parameterized value

Definition at line 342 of file parsed_function.h.

343 {
344  const std::vector<std::string>::iterator it =
345  std::find(_additional_vars.begin(), _additional_vars.end(), variable_name);
346 
347  if (it == _additional_vars.end())
348  libmesh_error_msg("ERROR: Requested variable not found in parsed function");
349 
350  // Iterator Arithmetic (How far from the end of the array is our target address?)
351  return _spacetime[_spacetime.size() - (_additional_vars.end() - it)];
352 }

◆ gradient()

template<typename Output , typename OutputGradient >
OutputGradient libMesh::ParsedFunction< Output, OutputGradient >::gradient ( const Point p,
const Real  time = 0 
)
inlinevirtual

Definition at line 280 of file parsed_function.h.

281 {
282  OutputGradient grad;
283  set_spacetime(p, time);
284 
285  grad(0) = eval(dx_parsers[0], "df/dx", 0);
286 #if LIBMESH_DIM > 1
287  grad(1) = eval(dy_parsers[0], "df/dy", 0);
288 #endif
289 #if LIBMESH_DIM > 2
290  grad(2) = eval(dz_parsers[0], "df/dz", 0);
291 #endif
292 
293  return grad;
294 }

◆ has_derivatives()

template<typename Output = Number, typename OutputGradient = Gradient>
virtual bool libMesh::ParsedFunction< Output, OutputGradient >::has_derivatives ( )
inlinevirtual

Query if the automatic derivative generation was successful.

Definition at line 105 of file parsed_function.h.

105 { return _valid_derivatives; }

◆ init()

template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::init ( )
inlinevirtual

The actual initialization process.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 743 of file parsed_function.h.

743 {}

◆ initialized()

template<typename Output >
bool libMesh::FunctionBase< Output >::initialized ( ) const
inlineinherited
Returns
true when this object is properly initialized and ready for use, false otherwise.

Definition at line 205 of file function_base.h.

206 {
207  return (this->_initialized);
208 }

◆ is_time_dependent()

template<typename Output >
bool libMesh::FunctionBase< Output >::is_time_dependent ( ) const
inlineinherited
Returns
true when the function this object represents is actually time-dependent, false otherwise.

Definition at line 219 of file function_base.h.

220 {
221  return (this->_is_time_dependent);
222 }

Referenced by libMesh::CompositeFunction< Output >::attach_subfunction(), ParsedFunctionTest::testTimeDependence(), and CompositeFunctionTest::testTimeDependence().

◆ operator()() [1/5]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const  time,
DenseVector< Output > &  output 
)
inlinevirtual

Evaluation function for time-dependent vector-valued functions.

Sets output values in the passed-in output DenseVector.

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 739 of file parsed_function.h.

741  {}

◆ operator()() [2/5]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const  time = 0 
)
inlinevirtual
Returns
The scalar function value at coordinate p and time time, which defaults to zero.

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 735 of file parsed_function.h.

737  { return 0.; }

◆ operator()() [3/5]

template<typename Output, typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  time,
DenseVector< Output > &  output 
)
inlineoverridevirtual

Evaluation function for time-dependent vector-valued functions.

Sets output values in the passed-in output DenseVector.

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 300 of file parsed_function.h.

303 {
304  set_spacetime(p, time);
305 
306  unsigned int size = output.size();
307 
308  libmesh_assert_equal_to (size, parsers.size());
309 
310  // The remaining locations in _spacetime are currently fixed at construction
311  // but could potentially be made dynamic
312  for (unsigned int i=0; i != size; ++i)
313  output(i) = eval(parsers[i], "f", i);
314 }

◆ operator()() [4/5]

template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  time = 0 
)
inlineoverridevirtual
Returns
The scalar function value at coordinate p and time time, which defaults to zero.

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 262 of file parsed_function.h.

263 {
264  set_spacetime(p, time);
265  return eval(parsers[0], "f", 0);
266 }

◆ operator()() [5/5]

template<typename Output>
void libMesh::FunctionBase< Output >::operator() ( const Point p,
DenseVector< Output > &  output 
)
inlineinherited

Evaluation function for time-independent vector-valued functions.

Sets output values in the passed-in output DenseVector.

Definition at line 240 of file function_base.h.

242 {
243  // Call the time-dependent function with t=0.
244  this->operator()(p, 0., output);
245 }

◆ operator=() [1/4]

template<typename Output = Number, typename OutputGradient = Gradient>
ParsedFunction& libMesh::ParsedFunction< Output, OutputGradient >::operator= ( const ParsedFunction< Output, OutputGradient > &  )
delete

This class cannot be (default) copy assigned because the underlying FunctionParserADBase class does not define a custom copy assignment operator, and manually manages memory.

◆ operator=() [2/4]

template<typename Output = Number, typename OutputGradient = Gradient>
ParsedFunction& libMesh::ParsedFunction< Output, OutputGradient >::operator= ( const ParsedFunction< Output, OutputGradient > &  )
delete

◆ operator=() [3/4]

template<typename Output = Number, typename OutputGradient = Gradient>
ParsedFunction& libMesh::ParsedFunction< Output, OutputGradient >::operator= ( ParsedFunction< Output, OutputGradient > &&  )
default

◆ operator=() [4/4]

template<typename Output = Number, typename OutputGradient = Gradient>
ParsedFunction& libMesh::ParsedFunction< Output, OutputGradient >::operator= ( ParsedFunction< Output, OutputGradient > &&  )
delete

◆ partial_reparse()

template<typename Output , typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::partial_reparse ( const std::string &  expression)
inlineprotected

Re-parse with minor changes to expression.

Definition at line 506 of file parsed_function.h.

507 {
509  _subexpressions.clear();
510  parsers.clear();
511 
512  size_t nextstart = 0, end = 0;
513 
514  while (end != std::string::npos)
515  {
516  // If we're past the end of the string, we can't make any more
517  // subparsers
518  if (nextstart >= expression.size())
519  break;
520 
521  // If we're at the start of a brace delimited section, then we
522  // parse just that section:
523  if (expression[nextstart] == '{')
524  {
525  nextstart++;
526  end = expression.find('}', nextstart);
527  }
528  // otherwise we parse the whole thing
529  else
530  end = std::string::npos;
531 
532  // We either want the whole end of the string (end == npos) or
533  // a substring in the middle.
534  _subexpressions.push_back
535  (expression.substr(nextstart, (end == std::string::npos) ?
536  std::string::npos : end - nextstart));
537 
538  // fparser can crash on empty expressions
539  if (_subexpressions.back().empty())
540  libmesh_error_msg("ERROR: FunctionParser is unable to parse empty expression.\n");
541 
542  // Parse (and optimize if possible) the subexpression.
543  // Add some basic constants, to Real precision.
544  FunctionParserADBase<Output> fp;
545  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
546  fp.AddConstant("pi", std::acos(Real(-1)));
547  fp.AddConstant("e", std::exp(Real(1)));
548  if (fp.Parse(_subexpressions.back(), variables) != -1) // -1 for success
549  libmesh_error_msg
550  ("ERROR: FunctionParser is unable to parse expression: "
551  << _subexpressions.back() << '\n' << fp.ErrorMsg());
552 
553  // use of derivatives is optional. suppress error output on the console
554  // use the has_derivatives() method to check if AutoDiff was successful.
555  // also enable immediate optimization
556  fp.SetADFlags(FunctionParserADBase<Output>::ADSilenceErrors |
557  FunctionParserADBase<Output>::ADAutoOptimize);
558 
559  // optimize original function
560  fp.Optimize();
561  parsers.push_back(fp);
562 
563  // generate derivatives through automatic differentiation
564  FunctionParserADBase<Output> dx_fp(fp);
565  if (dx_fp.AutoDiff("x") != -1) // -1 for success
566  _valid_derivatives = false;
567  dx_parsers.push_back(dx_fp);
568 #if LIBMESH_DIM > 1
569  FunctionParserADBase<Output> dy_fp(fp);
570  if (dy_fp.AutoDiff("y") != -1) // -1 for success
571  _valid_derivatives = false;
572  dy_parsers.push_back(dy_fp);
573 #endif
574 #if LIBMESH_DIM > 2
575  FunctionParserADBase<Output> dz_fp(fp);
576  if (dz_fp.AutoDiff("z") != -1) // -1 for success
577  _valid_derivatives = false;
578  dz_parsers.push_back(dz_fp);
579 #endif
580  FunctionParserADBase<Output> dt_fp(fp);
581  if (dt_fp.AutoDiff("t") != -1) // -1 for success
582  _valid_derivatives = false;
583  dt_parsers.push_back(dt_fp);
584 
585  // If at end, use nextstart=maxSize. Else start at next
586  // character.
587  nextstart = (end == std::string::npos) ?
588  std::string::npos : end + 1;
589  }
590 }

◆ reparse()

template<typename Output , typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::reparse ( const std::string &  expression)
inline

Re-parse with new expression.

Definition at line 231 of file parsed_function.h.

232 {
233  variables = "x";
234 #if LIBMESH_DIM > 1
235  variables += ",y";
236 #endif
237 #if LIBMESH_DIM > 2
238  variables += ",z";
239 #endif
240  variables += ",t";
241 
242  // If additional vars were passed, append them to the string
243  // that we send to the function parser. Also add them to the
244  // end of our spacetime vector
245  for (auto i : index_range(_additional_vars))
246  {
247  variables += "," + _additional_vars[i];
248  // Initialize extra variables to the vector passed in or zero
249  // Note: The initial_vals vector can be shorter than the additional_vars vector
250  _spacetime[LIBMESH_DIM+1 + i] =
251  (i < _initial_vals.size()) ? _initial_vals[i] : 0;
252  }
253 
255 
257 }

◆ set_inline_value()

template<typename Output, typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::set_inline_value ( const std::string &  inline_var_name,
Output  newval 
)
inline

Changes the value of an inline variable.

Note
Forever after, the variable value will take the given constant, independent of input variables, in every subexpression where it is already defined.
Currently only works if the inline variable is not redefined within any one subexpression.

Definition at line 442 of file parsed_function.h.

444 {
445  libmesh_assert_greater (_subexpressions.size(), 0);
446 
447 #ifndef NDEBUG
448  bool found_var_name = false;
449 #endif
450  for (auto & subexpression : _subexpressions)
451  {
452  const std::size_t varname_i =
453  find_name(inline_var_name, subexpression);
454  if (varname_i == std::string::npos)
455  continue;
456 
457 #ifndef NDEBUG
458  found_var_name = true;
459 #endif
460  const std::size_t assignment_i =
461  subexpression.find(":", varname_i+1);
462 
463  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
464 
465  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
466  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
467  libmesh_assert_equal_to(subexpression[i], ' ');
468 
469  std::size_t end_assignment_i =
470  subexpression.find(";", assignment_i+1);
471 
472  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
473 
474  std::ostringstream new_subexpression;
475  new_subexpression << subexpression.substr(0, assignment_i+2)
476  << std::setprecision(std::numeric_limits<Output>::digits10+2)
477 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
478  << '(' << newval.real() << '+'
479  << newval.imag() << 'i' << ')'
480 #else
481  << newval
482 #endif
483  << subexpression.substr(end_assignment_i,
484  std::string::npos);
485  subexpression = new_subexpression.str();
486  }
487 
488  libmesh_assert(found_var_name);
489 
490  std::string new_expression;
491 
492  for (const auto & subexpression : _subexpressions)
493  {
494  new_expression += '{';
495  new_expression += subexpression;
496  new_expression += '}';
497  }
498 
499  this->partial_reparse(new_expression);
500 }

Referenced by libMesh::ParsedFunctionParameter< T >::set(), and ParsedFunctionTest::testInlineSetter().

◆ set_is_time_dependent()

template<typename Output >
void libMesh::FunctionBase< Output >::set_is_time_dependent ( bool  is_time_dependent)
inlineinherited

Function to set whether this is a time-dependent function or not.

This is intended to be only used by subclasses who cannot natively determine time-dependence. In such a case, this function should be used immediately following construction.

Definition at line 212 of file function_base.h.

213 {
215 }

◆ set_spacetime()

template<typename Output , typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime ( const Point p,
const Real  time = 0 
)
inlineprivate

Set the _spacetime argument vector.

Definition at line 634 of file parsed_function.h.

636 {
637  _spacetime[0] = p(0);
638 #if LIBMESH_DIM > 1
639  _spacetime[1] = p(1);
640 #endif
641 #if LIBMESH_DIM > 2
642  _spacetime[2] = p(2);
643 #endif
644  _spacetime[LIBMESH_DIM] = time;
645 
646  // The remaining locations in _spacetime are currently fixed at construction
647  // but could potentially be made dynamic
648 }

Member Data Documentation

◆ _additional_vars

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<std::string> libMesh::ParsedFunction< Output, OutputGradient >::_additional_vars
private

Definition at line 202 of file parsed_function.h.

◆ _dummy

template<typename Output = Number, typename OutputGradient = Gradient>
Output libMesh::ParsedFunction< Output, OutputGradient >::_dummy
private

Definition at line 751 of file parsed_function.h.

Referenced by libMesh::ParsedFunction< T >::getVarAddress().

◆ _expression

template<typename Output = Number, typename OutputGradient = Gradient>
std::string libMesh::ParsedFunction< Output, OutputGradient >::_expression
private

Definition at line 184 of file parsed_function.h.

Referenced by libMesh::ParsedFunction< T >::expression().

◆ _initial_vals

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<Output> libMesh::ParsedFunction< Output, OutputGradient >::_initial_vals
private

Definition at line 203 of file parsed_function.h.

◆ _initialized

template<typename Output = Number>
bool libMesh::FunctionBase< Output >::_initialized
protectedinherited

When init() was called so that everything is ready for calls to operator() (...), then this bool is true.

Definition at line 179 of file function_base.h.

Referenced by libMesh::AnalyticFunction< Output >::AnalyticFunction(), libMesh::ConstFunction< Output >::ConstFunction(), and libMesh::WrappedFunction< Output >::WrappedFunction().

◆ _is_time_dependent

template<typename Output = Number>
bool libMesh::FunctionBase< Output >::_is_time_dependent
protectedinherited

Cache whether or not this function is actually time-dependent.

Definition at line 184 of file function_base.h.

Referenced by libMesh::CompositeFunction< Output >::attach_subfunction(), and libMesh::ConstFunction< Output >::ConstFunction().

◆ _master

template<typename Output = Number>
const FunctionBase* libMesh::FunctionBase< Output >::_master
protectedinherited

Const pointer to our master, initialized to nullptr.

There may be cases where multiple functions are required, but to save memory, one master handles some centralized data.

Definition at line 173 of file function_base.h.

◆ _spacetime

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<Output> libMesh::ParsedFunction< Output, OutputGradient >::_spacetime
private

Definition at line 187 of file parsed_function.h.

◆ _subexpressions

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<std::string> libMesh::ParsedFunction< Output, OutputGradient >::_subexpressions
private

Definition at line 185 of file parsed_function.h.

◆ _valid_derivatives

template<typename Output = Number, typename OutputGradient = Gradient>
bool libMesh::ParsedFunction< Output, OutputGradient >::_valid_derivatives
private

Definition at line 198 of file parsed_function.h.

Referenced by libMesh::ParsedFunction< T >::has_derivatives().

◆ dt_parsers

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dt_parsers
private

Definition at line 197 of file parsed_function.h.

◆ dx_parsers

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dx_parsers
private

Definition at line 190 of file parsed_function.h.

◆ dy_parsers

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dy_parsers
private

Definition at line 192 of file parsed_function.h.

◆ dz_parsers

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dz_parsers
private

Definition at line 195 of file parsed_function.h.

◆ parsers

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::parsers
private

Definition at line 186 of file parsed_function.h.

◆ variables

template<typename Output = Number, typename OutputGradient = Gradient>
std::string libMesh::ParsedFunction< Output, OutputGradient >::variables
private

Definition at line 201 of file parsed_function.h.


The documentation for this class was generated from the following file:
libMesh::ParsedFunction::find_name
std::size_t find_name(const std::string &varname, const std::string &expr) const
Helper function for parsing out variable names.
Definition: parsed_function.h:596
libMesh::ParsedFunction::dy_parsers
std::vector< FunctionParserADBase< Output > > dy_parsers
Definition: parsed_function.h:192
libMesh::ParsedFunction::_valid_derivatives
bool _valid_derivatives
Definition: parsed_function.h:198
libMesh::ParsedFunction::_initial_vals
std::vector< Output > _initial_vals
Definition: parsed_function.h:203
libMesh::ParsedFunction::eval
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
Definition: parsed_function.h:654
libMesh::FunctionBase::is_time_dependent
bool is_time_dependent() const
Definition: function_base.h:219
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh::FunctionBase::_is_time_dependent
bool _is_time_dependent
Cache whether or not this function is actually time-dependent.
Definition: function_base.h:184
libMesh::ParsedFunction::dx_parsers
std::vector< FunctionParserADBase< Output > > dx_parsers
Definition: parsed_function.h:190
libMesh::ParsedFunction::dt_parsers
std::vector< FunctionParserADBase< Output > > dt_parsers
Definition: parsed_function.h:197
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::ParsedFunction::_subexpressions
std::vector< std::string > _subexpressions
Definition: parsed_function.h:185
libMesh::ParsedFunction::variables
std::string variables
Definition: parsed_function.h:201
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::FunctionBase::_initialized
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
Definition: function_base.h:179
libMesh::ParsedFunction::expression
const std::string & expression()
Definition: parsed_function.h:121
libMesh::ParsedFunction::partial_reparse
void partial_reparse(const std::string &expression)
Re-parse with minor changes to expression.
Definition: parsed_function.h:506
libMesh::ParsedFunction::set_spacetime
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.
Definition: parsed_function.h:634
libMesh::DenseVector::size
virtual unsigned int size() const override
Definition: dense_vector.h:92
libMesh::ParsedFunction::_dummy
Output _dummy
Definition: parsed_function.h:751
libMesh::ParsedFunction::parsers
std::vector< FunctionParserADBase< Output > > parsers
Definition: parsed_function.h:186
libMesh::FunctionBase::operator()
virtual Output operator()(const Point &p, const Real time=0.)=0
libMesh::ParsedFunction::dz_parsers
std::vector< FunctionParserADBase< Output > > dz_parsers
Definition: parsed_function.h:195
libMesh::ParsedFunction::expression_is_time_dependent
bool expression_is_time_dependent(const std::string &expression) const
Definition: parsed_function.h:618
libMesh::ParsedFunction::_spacetime
std::vector< Output > _spacetime
Definition: parsed_function.h:187
libMesh::err
OStreamProxy err
libMesh::ParsedFunction::_additional_vars
std::vector< std::string > _additional_vars
Definition: parsed_function.h:202
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::ParsedFunction::_expression
std::string _expression
Definition: parsed_function.h:184
libMesh::ParsedFunction::reparse
void reparse(const std::string &expression)
Re-parse with new expression.
Definition: parsed_function.h:231