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 (std::string expression, const std::vector< std::string > *additional_vars=nullptr, const std::vector< Output > *initial_vals=nullptr)
 
 ParsedFunction (const ParsedFunction &)
 Constructors. More...
 
ParsedFunctionoperator= (const ParsedFunction &)
 
 ParsedFunction (ParsedFunction &&)=default
 
ParsedFunctionoperator= (ParsedFunction &&)=default
 
virtual ~ParsedFunction ()=default
 
void reparse (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 (std::string_view variable_name)
 
virtual std::unique_ptr< FunctionBase< Output > > clone () const override
 
Output get_inline_value (std::string_view inline_var_name) const
 
void set_inline_value (std::string_view inline_var_name, Output newval)
 Changes the value of an inline variable. More...
 
 ParsedFunction (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 (std::string_view)
 
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 (std::string expression)
 Re-parse with minor changes to expression. More...
 
std::size_t find_name (std::string_view varname, std::string_view expr) const
 Helper function for parsing out variable names. More...
 
bool expression_is_time_dependent (std::string_view 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, std::string_view 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< std::unique_ptr< FunctionParserADBase< Output > > > parsers
 
std::vector< Output > _spacetime
 
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dx_parsers
 
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dy_parsers
 
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dz_parsers
 
std::vector< std::unique_ptr< 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 ( std::string  expression,
const std::vector< std::string > *  additional_vars = nullptr,
const std::vector< Output > *  initial_vals = nullptr 
)
inlineexplicit

Definition at line 197 of file parsed_function.h.

199  :
200  _expression (), // overridden by parse()
201  // Size the spacetime vector to account for space, time, and any additional
202  // variables passed
203  _spacetime (LIBMESH_DIM+1 + (additional_vars ? additional_vars->size() : 0)),
204  _valid_derivatives (true),
205  _additional_vars (additional_vars ? *additional_vars : std::vector<std::string>()),
206  _initial_vals (initial_vals ? *initial_vals : std::vector<Output>())
207 {
208  // time-dependence established in reparse function
209  this->reparse(std::move(expression));
210  this->_initialized = true;
211 }
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
void reparse(std::string expression)
Re-parse with new expression.
std::vector< Output > _initial_vals
const std::string & expression()

◆ ParsedFunction() [2/6]

template<typename Output, typename OutputGradient >
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const ParsedFunction< Output, OutputGradient > &  other)
inline

Constructors.

  • This class contains unique_ptrs so it can't be default copy constructed or assigned, only default moved and deleted.

Definition at line 216 of file parsed_function.h.

216  :
217  FunctionBase<Output>(other),
218  _expression(other._expression),
219  _subexpressions(other._subexpressions),
220  _spacetime(other._spacetime),
221  _valid_derivatives(other._valid_derivatives),
222  variables(other.variables),
223  _additional_vars(other._additional_vars),
224  _initial_vals(other._initial_vals)
225 {
226  // parsers can be generated from scratch by reparsing expression
227  this->reparse(this->_expression);
228  this->_initialized = true;
229 }
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
std::vector< std::string > _subexpressions
void reparse(std::string expression)
Re-parse with new expression.
std::vector< Output > _initial_vals

◆ 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 ( std::string  ,
const std::vector< std::string > *  = nullptr,
const std::vector< Output > *  = nullptr 
)
inline

Definition at line 738 of file parsed_function.h.

740  : _dummy(0)
741  {
742  libmesh_not_implemented();
743  }

◆ 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 764 of file parsed_function.h.

764 {}

◆ clone() [1/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 375 of file parsed_function.h.

376 {
377  return std::make_unique<ParsedFunction>(_expression,
379  &_initial_vals);
380 }
std::vector< std::string > _additional_vars
std::vector< Output > _initial_vals

◆ clone() [2/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 766 of file parsed_function.h.

767  {
768  return std::make_unique<ParsedFunction<Output>>("");
769  }

◆ 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 340 of file parsed_function.h.

343 {
344  set_spacetime(p, time);
345  libmesh_assert_less (i, parsers.size());
346 
347  // The remaining locations in _spacetime are currently fixed at construction
348  // but could potentially be made dynamic
349  libmesh_assert_less(i, parsers.size());
350  return eval(*parsers[i], "f", i);
351 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > parsers
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.

◆ dot()

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

Definition at line 288 of file parsed_function.h.

289 {
290  set_spacetime(p, time);
291  return eval(*dt_parsers[0], "df/dt", 0);
292 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dt_parsers

◆ eval()

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

Evaluate the ith FunctionParser and check the result.

Definition at line 672 of file parsed_function.h.

675 {
676  Output result = parser.Eval(_spacetime.data());
677  int error_code = parser.EvalError();
678  if (error_code)
679  {
680  libMesh::err << "ERROR: FunctionParser is unable to evaluate component "
681  << component_idx
682  << " for '"
683  << function_name;
684 
685  for (auto i : index_range(parsers))
686  if (parsers[i].get() == &parser)
687  libMesh::err << "' of expression '"
688  << _subexpressions[i];
689 
690  libMesh::err << "' with arguments:\n";
691  for (const auto & item : _spacetime)
692  libMesh::err << '\t' << item << '\n';
693  libMesh::err << '\n';
694 
695  // Currently no API to report error messages, we'll do it manually
696  std::string error_message = "Reason: ";
697 
698  switch (error_code)
699  {
700  case 1:
701  error_message += "Division by zero";
702  break;
703  case 2:
704  error_message += "Square Root error (negative value)";
705  break;
706  case 3:
707  error_message += "Log error (negative value)";
708  break;
709  case 4:
710  error_message += "Trigonometric error (asin or acos of illegal value)";
711  break;
712  case 5:
713  error_message += "Maximum recursion level reached";
714  break;
715  default:
716  error_message += "Unknown";
717  break;
718  }
719  libmesh_error_msg(error_message);
720  }
721 
722  return result;
723 }
OStreamProxy err
std::vector< Output > _spacetime
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > parsers
std::vector< std::string > _subexpressions
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111

◆ expression()

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

Definition at line 107 of file parsed_function.h.

107 { return _expression; }

◆ expression_is_time_dependent()

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

Definition at line 636 of file parsed_function.h.

637 {
638  bool is_time_dependent = false;
639 
640  // By definition, time is "t" for FunctionBase-based objects, so we just need to
641  // see if this expression has the variable "t" in it.
642  if (this->find_name(std::string("t"), expression) != std::string::npos)
643  is_time_dependent = true;
644 
645  return is_time_dependent;
646 }
std::size_t find_name(std::string_view varname, std::string_view expr) const
Helper function for parsing out variable names.
bool is_time_dependent() const
const std::string & expression()

◆ find_name()

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

Helper function for parsing out variable names.

Definition at line 614 of file parsed_function.h.

616 {
617  const std::size_t namesize = varname.size();
618  std::size_t varname_i = expr.find(varname);
619 
620  while ((varname_i != std::string::npos) &&
621  (((varname_i > 0) &&
622  (std::isalnum(expr[varname_i-1]) ||
623  (expr[varname_i-1] == '_'))) ||
624  ((varname_i+namesize < expr.size()) &&
625  (std::isalnum(expr[varname_i+namesize]) ||
626  (expr[varname_i+namesize] == '_')))))
627  {
628  varname_i = expr.find(varname, varname_i+1);
629  }
630 
631  return varname_i;
632 }

◆ get_inline_value()

template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::get_inline_value ( std::string_view  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 385 of file parsed_function.h.

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

386 {
387  libmesh_assert_greater (_subexpressions.size(), 0);
388 
389 #ifndef NDEBUG
390  bool found_var_name = false;
391 #endif
392  Output old_var_value(0.);
393 
394  for (const auto & subexpression : _subexpressions)
395  {
396  const std::size_t varname_i =
397  find_name(inline_var_name, subexpression);
398  if (varname_i == std::string::npos)
399  continue;
400 
401  const std::size_t assignment_i =
402  subexpression.find(":", varname_i+1);
403 
404  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
405 
406  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
407  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
408  libmesh_assert_equal_to(subexpression[i], ' ');
409 
410  std::size_t end_assignment_i =
411  subexpression.find(";", assignment_i+1);
412 
413  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
414 
415  std::string new_subexpression =
416  subexpression.substr(0, end_assignment_i+1).append(inline_var_name);
417 
418 #ifdef LIBMESH_HAVE_FPARSER
419  // Parse and evaluate the new subexpression.
420  // Add the same constants as we used originally.
421  FunctionParserADBase<Output> fp;
422  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
423  fp.AddConstant("pi", std::acos(Real(-1)));
424  fp.AddConstant("e", std::exp(Real(1)));
425  libmesh_error_msg_if
426  (fp.Parse(new_subexpression, variables) != -1, // -1 for success
427  "ERROR: FunctionParser is unable to parse modified expression: "
428  << new_subexpression << '\n' << fp.ErrorMsg());
429 
430  Output new_var_value = this->eval(fp, new_subexpression, 0);
431 #ifdef NDEBUG
432  return new_var_value;
433 #else
434  if (found_var_name)
435  {
436  libmesh_assert_equal_to(old_var_value, new_var_value);
437  }
438  else
439  {
440  old_var_value = new_var_value;
441  found_var_name = true;
442  }
443 #endif
444 
445 #else
446  libmesh_error_msg("ERROR: This functionality requires fparser!");
447 #endif
448  }
449 
450  libmesh_assert(found_var_name);
451  return old_var_value;
452 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
std::vector< std::string > _subexpressions
std::size_t find_name(std::string_view varname, std::string_view expr) const
Helper function for parsing out variable names.
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ getVarAddress() [1/2]

template<typename Output , typename OutputGradient >
Output & libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( std::string_view  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 359 of file parsed_function.h.

360 {
361  const std::vector<std::string>::iterator it =
362  std::find(_additional_vars.begin(), _additional_vars.end(), variable_name);
363 
364  libmesh_error_msg_if(it == _additional_vars.end(),
365  "ERROR: Requested variable not found in parsed function");
366 
367  // Iterator Arithmetic (How far from the end of the array is our target address?)
368  return _spacetime[_spacetime.size() - (_additional_vars.end() - it)];
369 }
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars

◆ getVarAddress() [2/2]

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

Definition at line 765 of file parsed_function.h.

765 { return _dummy; }

◆ gradient()

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

Definition at line 297 of file parsed_function.h.

298 {
299  OutputGradient grad;
300  set_spacetime(p, time);
301 
302  grad(0) = eval(*dx_parsers[0], "df/dx", 0);
303 #if LIBMESH_DIM > 1
304  grad(1) = eval(*dy_parsers[0], "df/dy", 0);
305 #endif
306 #if LIBMESH_DIM > 2
307  grad(2) = eval(*dz_parsers[0], "df/dz", 0);
308 #endif
309 
310  return grad;
311 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dy_parsers
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dx_parsers
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dz_parsers

◆ 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 91 of file parsed_function.h.

◆ 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 763 of file parsed_function.h.

763 {}

◆ 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 210 of file function_base.h.

Referenced by libMesh::MeshFunction::MeshFunction().

211 {
212  return (this->_initialized);
213 }
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...

◆ 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 224 of file function_base.h.

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

225 {
226  return (this->_is_time_dependent);
227 }
bool _is_time_dependent
Cache whether or not this function is actually time-dependent.

◆ operator()() [1/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 279 of file parsed_function.h.

280 {
281  set_spacetime(p, time);
282  return eval(*parsers[0], "f", 0);
283 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > parsers
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.

◆ operator()() [2/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 317 of file parsed_function.h.

320 {
321  set_spacetime(p, time);
322 
323  unsigned int size = output.size();
324 
325  libmesh_assert_equal_to (size, parsers.size());
326 
327  // The remaining locations in _spacetime are currently fixed at construction
328  // but could potentially be made dynamic
329  for (unsigned int i=0; i != size; ++i)
330  output(i) = eval(*parsers[i], "f", i);
331 }
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
Evaluate the ith FunctionParser and check the result.
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > parsers
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.
virtual unsigned int size() const override final
Definition: dense_vector.h:104

◆ operator()() [3/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 245 of file function_base.h.

247 {
248  // Call the time-dependent function with t=0.
249  this->operator()(p, 0., output);
250 }
virtual Output operator()(const Point &p, const Real time=0.)=0

◆ operator()() [4/5]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  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 755 of file parsed_function.h.

757  { return 0.; }

◆ operator()() [5/5]

template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  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 759 of file parsed_function.h.

761  {}

◆ operator=() [1/4]

template<typename Output , typename OutputGradient >
ParsedFunction< Output, OutputGradient > & libMesh::ParsedFunction< Output, OutputGradient >::operator= ( const ParsedFunction< Output, OutputGradient > &  other)
inline

Definition at line 236 of file parsed_function.h.

237 {
238  // Use copy-and-swap idiom
239  ParsedFunction<Output,OutputGradient> tmp(other);
240  std::swap(tmp, *this);
241  return *this;
242 }

◆ operator=() [2/4]

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

◆ operator=() [3/4]

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

◆ 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 ( std::string  expression)
inlineprotected

Re-parse with minor changes to expression.

Definition at line 522 of file parsed_function.h.

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

◆ reparse()

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

Re-parse with new expression.

Definition at line 248 of file parsed_function.h.

249 {
250  variables = "x";
251 #if LIBMESH_DIM > 1
252  variables += ",y";
253 #endif
254 #if LIBMESH_DIM > 2
255  variables += ",z";
256 #endif
257  variables += ",t";
258 
259  // If additional vars were passed, append them to the string
260  // that we send to the function parser. Also add them to the
261  // end of our spacetime vector
262  for (auto i : index_range(_additional_vars))
263  {
264  variables += "," + _additional_vars[i];
265  // Initialize extra variables to the vector passed in or zero
266  // Note: The initial_vals vector can be shorter than the additional_vars vector
267  _spacetime[LIBMESH_DIM+1 + i] =
268  (i < _initial_vals.size()) ? _initial_vals[i] : 0;
269  }
270 
272 
273  this->partial_reparse(std::move(expression));
274 }
void partial_reparse(std::string expression)
Re-parse with minor changes to expression.
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars
bool expression_is_time_dependent(std::string_view expression) const
bool _is_time_dependent
Cache whether or not this function is actually time-dependent.
std::vector< Output > _initial_vals
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
const std::string & expression()

◆ set_inline_value()

template<typename Output, typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::set_inline_value ( std::string_view  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 458 of file parsed_function.h.

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

460 {
461  libmesh_assert_greater (_subexpressions.size(), 0);
462 
463 #ifndef NDEBUG
464  bool found_var_name = false;
465 #endif
466  for (auto & subexpression : _subexpressions)
467  {
468  const std::size_t varname_i =
469  find_name(inline_var_name, subexpression);
470  if (varname_i == std::string::npos)
471  continue;
472 
473 #ifndef NDEBUG
474  found_var_name = true;
475 #endif
476  const std::size_t assignment_i =
477  subexpression.find(":", varname_i+1);
478 
479  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
480 
481  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
482  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
483  libmesh_assert_equal_to(subexpression[i], ' ');
484 
485  std::size_t end_assignment_i =
486  subexpression.find(";", assignment_i+1);
487 
488  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
489 
490  std::ostringstream new_subexpression;
491  new_subexpression << subexpression.substr(0, assignment_i+2)
492  << std::setprecision(std::numeric_limits<Output>::digits10+2)
493 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
494  << '(' << newval.real() << '+'
495  << newval.imag() << 'i' << ')'
496 #else
497  << newval
498 #endif
499  << subexpression.substr(end_assignment_i,
500  std::string::npos);
501  subexpression = new_subexpression.str();
502  }
503 
504  libmesh_assert(found_var_name);
505 
506  std::string new_expression;
507 
508  for (const auto & subexpression : _subexpressions)
509  {
510  new_expression += '{';
511  new_expression += subexpression;
512  new_expression += '}';
513  }
514 
515  this->partial_reparse(new_expression);
516 }
void partial_reparse(std::string expression)
Re-parse with minor changes to expression.
std::vector< std::string > _subexpressions
std::size_t find_name(std::string_view varname, std::string_view expr) const
Helper function for parsing out variable names.
libmesh_assert(ctx)

◆ 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 217 of file function_base.h.

218 {
220 }
bool is_time_dependent() const
bool _is_time_dependent
Cache whether or not this function is actually time-dependent.

◆ 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 652 of file parsed_function.h.

654 {
655  _spacetime[0] = p(0);
656 #if LIBMESH_DIM > 1
657  _spacetime[1] = p(1);
658 #endif
659 #if LIBMESH_DIM > 2
660  _spacetime[2] = p(2);
661 #endif
662  _spacetime[LIBMESH_DIM] = time;
663 
664  // The remaining locations in _spacetime are currently fixed at construction
665  // but could potentially be made dynamic
666 }
std::vector< Output > _spacetime

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 188 of file parsed_function.h.

◆ _dummy

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

Definition at line 771 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 170 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 189 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 184 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 189 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 178 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 173 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 171 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 184 of file parsed_function.h.

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

◆ dt_parsers

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

Definition at line 183 of file parsed_function.h.

◆ dx_parsers

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

Definition at line 176 of file parsed_function.h.

◆ dy_parsers

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

Definition at line 178 of file parsed_function.h.

◆ dz_parsers

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

Definition at line 181 of file parsed_function.h.

◆ parsers

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

Definition at line 172 of file parsed_function.h.

◆ variables

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

Definition at line 187 of file parsed_function.h.


The documentation for this class was generated from the following file: