libMesh::ParsedFunction< Output, OutputGradient > Class Template Reference

A Function defined by a std::string. More...

#include <parsed_function.h>

Inheritance diagram for libMesh::ParsedFunction< Output, OutputGradient >:

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
 
 ParsedFunction (const ParsedFunction &)=default
 
 ParsedFunction (ParsedFunction &&)=default
 
ParsedFunctionoperator= (ParsedFunction &&)=default
 
virtual ~ParsedFunction ()=default
 
void reparse (const std::string &expression)
 
virtual Output operator() (const Point &p, const Real time=0) override
 
virtual bool has_derivatives ()
 
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
 
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)
 
 ParsedFunction (const std::string &, const std::vector< std::string > *=nullptr, const std::vector< Output > *=nullptr)
 
 ParsedFunction (ParsedFunction &&)=delete
 
 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 > &)
 
virtual void init ()
 
virtual void clear ()
 
virtual Output & getVarAddress (const std::string &)
 
virtual std::unique_ptr< FunctionBase< Output > > clone () const
 
void operator() (const Point &p, DenseVector< Output > &output)
 
bool initialized () const
 
void set_is_time_dependent (bool is_time_dependent)
 
bool is_time_dependent () const
 

Protected Member Functions

void partial_reparse (const std::string &expression)
 
std::size_t find_name (const std::string &varname, const std::string &expr) const
 
bool expression_is_time_dependent (const std::string &expression) const
 

Protected Attributes

const FunctionBase_master
 
bool _initialized
 
bool _is_time_dependent
 

Private Member Functions

void set_spacetime (const Point &p, const Real time=0)
 
Output eval (FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
 

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 defined by a std::string.

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

Definition at line 59 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 210 of file parsed_function.h.

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

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

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

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

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

743 {}

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

358 {
359  return libmesh_make_unique<ParsedFunction>(_expression,
361  &_initial_vals);
362 }
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 745 of file parsed_function.h.

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

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

325 {
326  set_spacetime(p, time);
327  libmesh_assert_less (i, parsers.size());
328 
329  // The remaining locations in _spacetime are currently fixed at construction
330  // but could potentially be made dynamic
331  libmesh_assert_less(i, parsers.size());
332  return eval(parsers[i], "f", i);
333 }
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const

◆ dot()

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

Definition at line 270 of file parsed_function.h.

271 {
272  set_spacetime(p, time);
273  return eval(dt_parsers[0], "df/dt", 0);
274 }
std::vector< FunctionParserADBase< Output > > dt_parsers
void set_spacetime(const Point &p, const Real time=0)
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const

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

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

◆ expression()

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

Definition at line 120 of file parsed_function.h.

120 { 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 617 of file parsed_function.h.

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

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

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

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

Referenced by libMesh::ParsedFunctionParameter< T >::get().

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

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

Definition at line 744 of file parsed_function.h.

744 { 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 279 of file parsed_function.h.

280 {
281  OutputGradient grad;
282  set_spacetime(p, time);
283 
284  grad(0) = eval(dx_parsers[0], "df/dx", 0);
285 #if LIBMESH_DIM > 1
286  grad(1) = eval(dy_parsers[0], "df/dy", 0);
287 #endif
288 #if LIBMESH_DIM > 2
289  grad(2) = eval(dz_parsers[0], "df/dz", 0);
290 #endif
291 
292  return grad;
293 }
void set_spacetime(const Point &p, const Real time=0)
std::vector< FunctionParserADBase< Output > > dz_parsers
std::vector< FunctionParserADBase< Output > > dx_parsers
std::vector< FunctionParserADBase< Output > > dy_parsers
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const

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

742 {}

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

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

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

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

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

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

262 {
263  set_spacetime(p, time);
264  return eval(parsers[0], "f", 0);
265 }
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const

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

302 {
303  set_spacetime(p, time);
304 
305  unsigned int size = output.size();
306 
307  libmesh_assert_equal_to (size, parsers.size());
308 
309  // The remaining locations in _spacetime are currently fixed at construction
310  // but could potentially be made dynamic
311  for (unsigned int i=0; i != size; ++i)
312  output(i) = eval(parsers[i], "f", i);
313 }
virtual unsigned int size() const override
Definition: dense_vector.h:92
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const

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

243 {
244  // Call the time-dependent function with t=0.
245  this->operator()(p, 0., output);
246 }
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 734 of file parsed_function.h.

736  { 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 738 of file parsed_function.h.

740  {}

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

Re-parse with minor changes to expression.

Definition at line 505 of file parsed_function.h.

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

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

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

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

Referenced by libMesh::ParsedFunctionParameter< T >::set().

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

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

214 {
216 }
bool is_time_dependent() const

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

635 {
636  _spacetime[0] = p(0);
637 #if LIBMESH_DIM > 1
638  _spacetime[1] = p(1);
639 #endif
640 #if LIBMESH_DIM > 2
641  _spacetime[2] = p(2);
642 #endif
643  _spacetime[LIBMESH_DIM] = time;
644 
645  // The remaining locations in _spacetime are currently fixed at construction
646  // but could potentially be made dynamic
647 }
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 201 of file parsed_function.h.

◆ _dummy

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

Definition at line 750 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 183 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 202 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 180 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 185 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 174 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 186 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 184 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 197 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 196 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 189 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 191 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 194 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 185 of file parsed_function.h.

◆ variables

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

Definition at line 200 of file parsed_function.h.


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