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=libmesh_nullptr, const std::vector< Output > *initial_vals=libmesh_nullptr)
 
void reparse (const std::string &expression)
 
virtual Output operator() (const Point &p, const Real time=0) libmesh_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) libmesh_override
 
virtual Output component (unsigned int i, const Point &p, Real time) libmesh_override
 
const std::string & expression ()
 
virtual Output & getVarAddress (const std::string &variable_name)
 
virtual std::unique_ptr< FunctionBase< Output > > clone () const libmesh_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 > *=libmesh_nullptr, const std::vector< Output > *=libmesh_nullptr)
 
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

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

Definition at line 184 of file parsed_function.h.

References libMesh::FunctionBase< Output >::_initialized, and libMesh::ParsedFunction< Output, OutputGradient >::reparse().

186  :
187  _expression (), // overridden by parse()
188  // Size the spacetime vector to account for space, time, and any additional
189  // variables passed
190  _spacetime (LIBMESH_DIM+1 + (additional_vars ? additional_vars->size() : 0)),
191  _valid_derivatives (true),
192  _additional_vars (additional_vars ? *additional_vars : std::vector<std::string>()),
193  _initial_vals (initial_vals ? *initial_vals : std::vector<Output>())
194 {
195  // time-dependence established in reparse function
196  this->reparse(expression);
197  this->_initialized = true;
198 }
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()
template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const std::string &  ,
const std::vector< std::string > *  = libmesh_nullptr,
const std::vector< Output > *  = libmesh_nullptr 
)
inline

Definition at line 693 of file parsed_function.h.

695  : _dummy(0)
696  {
697  libmesh_not_implemented();
698  }

Member Function Documentation

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

709 {}
template<typename Output , typename OutputGradient >
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 331 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_additional_vars, libMesh::ParsedFunction< Output, OutputGradient >::_expression, and libMesh::ParsedFunction< Output, OutputGradient >::_initial_vals.

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

332 {
333  return libmesh_make_unique<ParsedFunction>(_expression,
335  &_initial_vals);
336 }
std::vector< std::string > _additional_vars
std::vector< Output > _initial_vals
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 711 of file parsed_function.h.

712  {
713  return libmesh_make_unique<ParsedFunction<Output>>("");
714  }
template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::component ( unsigned int  i,
const Point p,
Real  time 
)
inlinevirtual
Returns
The vector component i at coordinate p and time time.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 296 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::eval(), libMesh::ParsedFunction< Output, OutputGradient >::parsers, and libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime().

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

299 {
300  set_spacetime(p, time);
301  libmesh_assert_less (i, parsers.size());
302 
303  // The remaining locations in _spacetime are currently fixed at construction
304  // but could potentially be made dynamic
305  libmesh_assert_less(i, parsers.size());
306  return eval(parsers[i], "f", i);
307 }
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
template<typename Output , typename OutputGradient >
Output libMesh::ParsedFunction< Output, OutputGradient >::dot ( const Point p,
const Real  time = 0 
)
inlinevirtual

Definition at line 244 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::dt_parsers, libMesh::ParsedFunction< Output, OutputGradient >::eval(), and libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime().

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

245 {
246  set_spacetime(p, time);
247  return eval(dt_parsers[0], "df/dt", 0);
248 }
std::vector< FunctionParserADBase< Output > > dt_parsers
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
void set_spacetime(const Point &p, const Real time=0)
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 629 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_spacetime, and libMesh::err.

Referenced by libMesh::ParsedFunction< Output, OutputGradient >::component(), libMesh::ParsedFunction< Output, OutputGradient >::dot(), libMesh::ParsedFunction< T >::expression(), libMesh::ParsedFunction< Output, OutputGradient >::get_inline_value(), libMesh::ParsedFunction< Output, OutputGradient >::gradient(), and libMesh::ParsedFunction< Output, OutputGradient >::operator()().

632 {
633 #ifndef NDEBUG
634  Output result = parser.Eval(&_spacetime[0]);
635  int error_code = parser.EvalError();
636  if (error_code)
637  {
638  libMesh::err << "ERROR: FunctionParser is unable to evaluate component "
639  << component_idx
640  << " of expression '"
641  << function_name
642  << "' with arguments:\n";
643  for (std::size_t j=0; j<_spacetime.size(); ++j)
644  libMesh::err << '\t' << _spacetime[j] << '\n';
645  libMesh::err << '\n';
646 
647  // Currently no API to report error messages, we'll do it manually
648  std::string error_message = "Reason: ";
649 
650  switch (error_code)
651  {
652  case 1:
653  error_message += "Division by zero";
654  break;
655  case 2:
656  error_message += "Square Root error (negative value)";
657  break;
658  case 3:
659  error_message += "Log error (negative value)";
660  break;
661  case 4:
662  error_message += "Trigonometric error (asin or acos of illegal value)";
663  break;
664  case 5:
665  error_message += "Maximum recursion level reached";
666  break;
667  default:
668  error_message += "Unknown";
669  break;
670  }
671  libmesh_error_msg(error_message);
672  }
673 
674  return result;
675 #else
676  return parser.Eval(&_spacetime[0]);
677 #endif
678 }
std::vector< Output > _spacetime
OStreamProxy err(std::cerr)
template<typename Output = Number, typename OutputGradient = Gradient>
const std::string& libMesh::ParsedFunction< Output, OutputGradient >::expression ( )
inline
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 593 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::find_name(), and libMesh::FunctionBase< Output >::is_time_dependent().

Referenced by libMesh::ParsedFunction< T >::expression(), and libMesh::ParsedFunction< Output, OutputGradient >::reparse().

594 {
595  bool is_time_dependent = false;
596 
597  // By definition, time is "t" for FunctionBase-based objects, so we just need to
598  // see if this expression has the variable "t" in it.
599  if (this->find_name(std::string("t"), expression) != std::string::npos)
600  is_time_dependent = true;
601 
602  return is_time_dependent;
603 }
bool is_time_dependent() const
std::size_t find_name(const std::string &varname, const std::string &expr) const
const std::string & expression()
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 571 of file parsed_function.h.

Referenced by libMesh::ParsedFunction< T >::expression(), libMesh::ParsedFunction< Output, OutputGradient >::expression_is_time_dependent(), libMesh::ParsedFunction< Output, OutputGradient >::get_inline_value(), and libMesh::ParsedFunction< Output, OutputGradient >::set_inline_value().

573 {
574  const std::size_t namesize = varname.size();
575  std::size_t varname_i = expr.find(varname);
576 
577  while ((varname_i != std::string::npos) &&
578  (((varname_i > 0) &&
579  (std::isalnum(expr[varname_i-1]) ||
580  (expr[varname_i-1] == '_'))) ||
581  ((varname_i+namesize < expr.size()) &&
582  (std::isalnum(expr[varname_i+namesize]) ||
583  (expr[varname_i+namesize] == '_')))))
584  {
585  varname_i = expr.find(varname, varname_i+1);
586  }
587 
588  return varname_i;
589 }
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 341 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_subexpressions, libMesh::ParsedFunction< Output, OutputGradient >::eval(), libMesh::ParsedFunction< Output, OutputGradient >::find_name(), libMesh::Real, and libMesh::ParsedFunction< Output, OutputGradient >::variables.

Referenced by libMesh::ParsedFunction< T >::expression(), and libMesh::ParsedFunctionParameter< T >::get().

342 {
343  libmesh_assert_greater (_subexpressions.size(), 0);
344 
345 #ifndef NDEBUG
346  bool found_var_name = false;
347 #endif
348  Output old_var_value(0.);
349 
350  for (std::size_t s=0; s != _subexpressions.size(); ++s)
351  {
352  const std::string & subexpression = _subexpressions[s];
353  const std::size_t varname_i =
354  find_name(inline_var_name, subexpression);
355  if (varname_i == std::string::npos)
356  continue;
357 
358  const std::size_t assignment_i =
359  subexpression.find(":", varname_i+1);
360 
361  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
362 
363  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
364  for (unsigned int i = varname_i+1; i != assignment_i; ++i)
365  libmesh_assert_equal_to(subexpression[i], ' ');
366 
367  std::size_t end_assignment_i =
368  subexpression.find(";", assignment_i+1);
369 
370  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
371 
372  std::string new_subexpression =
373  subexpression.substr(0, end_assignment_i+1) +
374  inline_var_name;
375 
376 #ifdef LIBMESH_HAVE_FPARSER
377  // Parse and evaluate the new subexpression.
378  // Add the same constants as we used originally.
379  FunctionParserADBase<Output> fp;
380  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
381  fp.AddConstant("pi", std::acos(Real(-1)));
382  fp.AddConstant("e", std::exp(Real(1)));
383  if (fp.Parse(new_subexpression, variables) != -1) // -1 for success
384  libmesh_error_msg
385  ("ERROR: FunctionParser is unable to parse modified expression: "
386  << new_subexpression << '\n' << fp.ErrorMsg());
387 
388  Output new_var_value = this->eval(fp, new_subexpression, 0);
389 #ifdef NDEBUG
390  return new_var_value;
391 #else
392  if (found_var_name)
393  {
394  libmesh_assert_equal_to(old_var_value, new_var_value);
395  }
396  else
397  {
398  old_var_value = new_var_value;
399  found_var_name = true;
400  }
401 #endif
402 
403 #else
404  libmesh_error_msg("ERROR: This functionality requires fparser!");
405 #endif
406  }
407 
408  libmesh_assert(found_var_name);
409  return old_var_value;
410 }
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
std::vector< std::string > _subexpressions
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::size_t find_name(const std::string &varname, const std::string &expr) const
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 315 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_additional_vars, and libMesh::ParsedFunction< Output, OutputGradient >::_spacetime.

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

316 {
317  const std::vector<std::string>::iterator it =
318  std::find(_additional_vars.begin(), _additional_vars.end(), variable_name);
319 
320  if (it == _additional_vars.end())
321  libmesh_error_msg("ERROR: Requested variable not found in parsed function");
322 
323  // Iterator Arithmetic (How far from the end of the array is our target address?)
324  return _spacetime[_spacetime.size() - (_additional_vars.end() - it)];
325 }
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output& libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( const std::string &  )
inlinevirtual

Definition at line 710 of file parsed_function.h.

710 { return _dummy; }
template<typename Output , typename OutputGradient >
OutputGradient libMesh::ParsedFunction< Output, OutputGradient >::gradient ( const Point p,
const Real  time = 0 
)
inlinevirtual

Definition at line 253 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::dx_parsers, libMesh::ParsedFunction< Output, OutputGradient >::dy_parsers, libMesh::ParsedFunction< Output, OutputGradient >::dz_parsers, libMesh::ParsedFunction< Output, OutputGradient >::eval(), and libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime().

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

254 {
255  OutputGradient grad;
256  set_spacetime(p, time);
257 
258  grad(0) = eval(dx_parsers[0], "df/dx", 0);
259 #if LIBMESH_DIM > 1
260  grad(1) = eval(dy_parsers[0], "df/dy", 0);
261 #endif
262 #if LIBMESH_DIM > 2
263  grad(2) = eval(dz_parsers[0], "df/dz", 0);
264 #endif
265 
266  return grad;
267 }
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
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
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 78 of file parsed_function.h.

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

708 {}
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 209 of file function_base.h.

References libMesh::FunctionBase< Output >::_initialized.

Referenced by libMesh::FunctionBase< Real >::clear(), and libMesh::AnalyticFunction< Output >::operator()().

210 {
211  return (this->_initialized);
212 }
template<typename Output >
bool libMesh::FunctionBase< Output >::is_time_dependent ( ) const
inlineinherited
template<typename Output , typename OutputGradient >
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 235 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::eval(), libMesh::ParsedFunction< Output, OutputGradient >::parsers, and libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime().

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

236 {
237  set_spacetime(p, time);
238  return eval(parsers[0], "f", 0);
239 }
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
template<typename Output, typename OutputGradient >
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 273 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::eval(), libMesh::ParsedFunction< Output, OutputGradient >::parsers, and libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime().

276 {
277  set_spacetime(p, time);
278 
279  unsigned int size = output.size();
280 
281  libmesh_assert_equal_to (size, parsers.size());
282 
283  // The remaining locations in _spacetime are currently fixed at construction
284  // but could potentially be made dynamic
285  for (unsigned int i=0; i != size; ++i)
286  output(i) = eval(parsers[i], "f", i);
287 }
Output eval(FunctionParserADBase< Output > &parser, const std::string &libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
std::vector< FunctionParserADBase< Output > > parsers
void set_spacetime(const Point &p, const Real time=0)
virtual unsigned int size() const libmesh_override
Definition: dense_vector.h:87
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 244 of file function_base.h.

References libMesh::FunctionBase< Output >::operator()().

246 {
247  // Call the time-dependent function with t=0.
248  this->operator()(p, 0., output);
249 }
virtual Output operator()(const Point &p, const Real time=0.)=0
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 700 of file parsed_function.h.

702  { return 0.; }
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 704 of file parsed_function.h.

706  {}
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 481 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_expression, libMesh::ParsedFunction< Output, OutputGradient >::_subexpressions, libMesh::ParsedFunction< Output, OutputGradient >::_valid_derivatives, libMesh::ParsedFunction< Output, OutputGradient >::dt_parsers, libMesh::ParsedFunction< Output, OutputGradient >::dx_parsers, libMesh::ParsedFunction< Output, OutputGradient >::dy_parsers, libMesh::ParsedFunction< Output, OutputGradient >::dz_parsers, end, libMesh::ParsedFunction< Output, OutputGradient >::expression(), libMesh::ParsedFunction< Output, OutputGradient >::parsers, libMesh::Real, and libMesh::ParsedFunction< Output, OutputGradient >::variables.

Referenced by libMesh::ParsedFunction< T >::expression(), libMesh::ParsedFunction< Output, OutputGradient >::reparse(), and libMesh::ParsedFunction< Output, OutputGradient >::set_inline_value().

482 {
484  _subexpressions.clear();
485  parsers.clear();
486 
487  size_t nextstart = 0, end = 0;
488 
489  while (end != std::string::npos)
490  {
491  // If we're past the end of the string, we can't make any more
492  // subparsers
493  if (nextstart >= expression.size())
494  break;
495 
496  // If we're at the start of a brace delimited section, then we
497  // parse just that section:
498  if (expression[nextstart] == '{')
499  {
500  nextstart++;
501  end = expression.find('}', nextstart);
502  }
503  // otherwise we parse the whole thing
504  else
505  end = std::string::npos;
506 
507  // We either want the whole end of the string (end == npos) or
508  // a substring in the middle.
509  _subexpressions.push_back
510  (expression.substr(nextstart, (end == std::string::npos) ?
511  std::string::npos : end - nextstart));
512 
513  // fparser can crash on empty expressions
514  if (_subexpressions.back().empty())
515  libmesh_error_msg("ERROR: FunctionParser is unable to parse empty expression.\n");
516 
517  // Parse (and optimize if possible) the subexpression.
518  // Add some basic constants, to Real precision.
519  FunctionParserADBase<Output> fp;
520  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
521  fp.AddConstant("pi", std::acos(Real(-1)));
522  fp.AddConstant("e", std::exp(Real(1)));
523  if (fp.Parse(_subexpressions.back(), variables) != -1) // -1 for success
524  libmesh_error_msg
525  ("ERROR: FunctionParser is unable to parse expression: "
526  << _subexpressions.back() << '\n' << fp.ErrorMsg());
527 
528  // use of derivatives is optional. suppress error output on the console
529  // use the has_derivatives() method to check if AutoDiff was successful.
530  // also enable immediate optimization
531  fp.SetADFlags(FunctionParserADBase<Output>::ADSilenceErrors |
532  FunctionParserADBase<Output>::ADAutoOptimize);
533 
534  // optimize original function
535  fp.Optimize();
536  parsers.push_back(fp);
537 
538  // generate derivatives through automatic differentiation
539  FunctionParserADBase<Output> dx_fp(fp);
540  if (dx_fp.AutoDiff("x") != -1) // -1 for success
541  _valid_derivatives = false;
542  dx_parsers.push_back(dx_fp);
543 #if LIBMESH_DIM > 1
544  FunctionParserADBase<Output> dy_fp(fp);
545  if (dy_fp.AutoDiff("y") != -1) // -1 for success
546  _valid_derivatives = false;
547  dy_parsers.push_back(dy_fp);
548 #endif
549 #if LIBMESH_DIM > 2
550  FunctionParserADBase<Output> dz_fp(fp);
551  if (dz_fp.AutoDiff("z") != -1) // -1 for success
552  _valid_derivatives = false;
553  dz_parsers.push_back(dz_fp);
554 #endif
555  FunctionParserADBase<Output> dt_fp(fp);
556  if (dt_fp.AutoDiff("t") != -1) // -1 for success
557  _valid_derivatives = false;
558  dt_parsers.push_back(dt_fp);
559 
560  // If at end, use nextstart=maxSize. Else start at next
561  // character.
562  nextstart = (end == std::string::npos) ?
563  std::string::npos : end + 1;
564  }
565 }
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()
template<typename Output , typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::reparse ( const std::string &  expression)
inline

Re-parse with new expression.

Definition at line 204 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_additional_vars, libMesh::ParsedFunction< Output, OutputGradient >::_initial_vals, libMesh::FunctionBase< Output >::_is_time_dependent, libMesh::ParsedFunction< Output, OutputGradient >::_spacetime, libMesh::ParsedFunction< Output, OutputGradient >::expression_is_time_dependent(), libMesh::ParsedFunction< Output, OutputGradient >::partial_reparse(), and libMesh::ParsedFunction< Output, OutputGradient >::variables.

Referenced by libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction().

205 {
206  variables = "x";
207 #if LIBMESH_DIM > 1
208  variables += ",y";
209 #endif
210 #if LIBMESH_DIM > 2
211  variables += ",z";
212 #endif
213  variables += ",t";
214 
215  // If additional vars were passed, append them to the string
216  // that we send to the function parser. Also add them to the
217  // end of our spacetime vector
218  for (std::size_t i=0; i < _additional_vars.size(); ++i)
219  {
220  variables += "," + _additional_vars[i];
221  // Initialize extra variables to the vector passed in or zero
222  // Note: The initial_vals vector can be shorter than the additional_vars vector
223  _spacetime[LIBMESH_DIM+1 + i] =
224  (i < _initial_vals.size()) ? _initial_vals[i] : 0;
225  }
226 
228 
230 }
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()
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 416 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_subexpressions, libMesh::ParsedFunction< Output, OutputGradient >::find_name(), and libMesh::ParsedFunction< Output, OutputGradient >::partial_reparse().

Referenced by libMesh::ParsedFunction< T >::expression(), and libMesh::ParsedFunctionParameter< T >::set().

418 {
419  libmesh_assert_greater (_subexpressions.size(), 0);
420 
421 #ifndef NDEBUG
422  bool found_var_name = false;
423 #endif
424  for (std::size_t s=0; s != _subexpressions.size(); ++s)
425  {
426  const std::string & subexpression = _subexpressions[s];
427  const std::size_t varname_i =
428  find_name(inline_var_name, subexpression);
429  if (varname_i == std::string::npos)
430  continue;
431 
432 #ifndef NDEBUG
433  found_var_name = true;
434 #endif
435  const std::size_t assignment_i =
436  subexpression.find(":", varname_i+1);
437 
438  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
439 
440  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
441  for (unsigned int i = varname_i+1; i != assignment_i; ++i)
442  libmesh_assert_equal_to(subexpression[i], ' ');
443 
444  std::size_t end_assignment_i =
445  subexpression.find(";", assignment_i+1);
446 
447  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
448 
449  std::ostringstream new_subexpression;
450  new_subexpression << subexpression.substr(0, assignment_i+2)
451  << std::setprecision(std::numeric_limits<Output>::digits10+2)
452 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
453  << '(' << newval.real() << '+'
454  << newval.imag() << 'i' << ')'
455 #else
456  << newval
457 #endif
458  << subexpression.substr(end_assignment_i,
459  std::string::npos);
460  _subexpressions[s] = new_subexpression.str();
461  }
462 
463  libmesh_assert(found_var_name);
464 
465  std::string new_expression;
466 
467  for (std::size_t s=0; s != _subexpressions.size(); ++s)
468  {
469  new_expression += '{';
470  new_expression += _subexpressions[s];
471  new_expression += '}';
472  }
473 
474  this->partial_reparse(new_expression);
475 }
std::vector< std::string > _subexpressions
void partial_reparse(const std::string &expression)
std::size_t find_name(const std::string &varname, const std::string &expr) const
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 216 of file function_base.h.

References libMesh::FunctionBase< Output >::_is_time_dependent, and libMesh::FunctionBase< Output >::is_time_dependent().

Referenced by libMesh::FunctionBase< Real >::clear().

217 {
219 }
bool is_time_dependent() const
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 609 of file parsed_function.h.

References libMesh::ParsedFunction< Output, OutputGradient >::_spacetime.

Referenced by libMesh::ParsedFunction< Output, OutputGradient >::component(), libMesh::ParsedFunction< Output, OutputGradient >::dot(), libMesh::ParsedFunction< T >::expression(), libMesh::ParsedFunction< Output, OutputGradient >::gradient(), and libMesh::ParsedFunction< Output, OutputGradient >::operator()().

611 {
612  _spacetime[0] = p(0);
613 #if LIBMESH_DIM > 1
614  _spacetime[1] = p(1);
615 #endif
616 #if LIBMESH_DIM > 2
617  _spacetime[2] = p(2);
618 #endif
619  _spacetime[LIBMESH_DIM] = time;
620 
621  // The remaining locations in _spacetime are currently fixed at construction
622  // but could potentially be made dynamic
623 }
std::vector< Output > _spacetime

Member Data Documentation

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

Definition at line 716 of file parsed_function.h.

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

template<typename Output = Number, typename OutputGradient = Gradient>
std::string libMesh::ParsedFunction< Output, OutputGradient >::_expression
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<Output> libMesh::ParsedFunction< Output, OutputGradient >::_initial_vals
private
template<typename Output = Number>
bool libMesh::FunctionBase< Output >::_is_time_dependent
protectedinherited
template<typename Output = Number>
const FunctionBase* libMesh::FunctionBase< Output >::_master
protectedinherited

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

Definition at line 169 of file function_base.h.

template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<Output> libMesh::ParsedFunction< Output, OutputGradient >::_spacetime
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<std::string> libMesh::ParsedFunction< Output, OutputGradient >::_subexpressions
private
template<typename Output = Number, typename OutputGradient = Gradient>
bool libMesh::ParsedFunction< Output, OutputGradient >::_valid_derivatives
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dt_parsers
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dx_parsers
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dy_parsers
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::dz_parsers
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::vector<FunctionParserADBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::parsers
private
template<typename Output = Number, typename OutputGradient = Gradient>
std::string libMesh::ParsedFunction< Output, OutputGradient >::variables
private

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