libMesh
Loading...
Searching...
No Matches
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.
 
ParsedFunctionoperator= (const ParsedFunction &)
 
 ParsedFunction (ParsedFunction &&)=default
 
ParsedFunctionoperator= (ParsedFunction &&)=default
 
virtual ~ParsedFunction ()=default
 
void reparse (std::string expression)
 Re-parse with new expression.
 
virtual Output operator() (const Point &p, const Real time=0) override
 
virtual bool has_derivatives ()
 Query if the automatic derivative generation was successful.
 
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.
 
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.
 
 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.
 
 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.
 
virtual void init ()
 The actual initialization process.
 
virtual void clear ()
 Clears the function.
 
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.
 
bool initialized () const
 
void set_is_time_dependent (bool is_time_dependent)
 Function to set whether this is a time-dependent function or not.
 
bool is_time_dependent () const
 

Protected Member Functions

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

Protected Attributes

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

Private Member Functions

void set_spacetime (const Point &p, const Real time=0)
 Set the _spacetime argument vector.
 
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.
 

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}
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
const std::string & expression()
void reparse(std::string expression)
Re-parse with new expression.
std::vector< Output > _initial_vals
std::vector< std::string > _additional_vars
std::vector< Output > _spacetime

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

◆ 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< std::string > _subexpressions

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

◆ 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 = 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 }

◆ clone() [2/2]

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

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

Implements libMesh::FunctionBase< Output >.

Definition at line 375 of file parsed_function.h.

376{
377 return std::make_unique<ParsedFunction>(_expression,
380}

◆ 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}
void set_spacetime(const Point &p, const Real time=0)
Set the _spacetime argument vector.
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

◆ 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}
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}
const Elem & get(const ElemType type_in)
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
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:153

References libMesh::err, and libMesh::index_range().

◆ expression()

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

◆ 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}
bool is_time_dependent() const
std::size_t find_name(std::string_view varname, std::string_view expr) const
Helper function for parsing out variable names.

◆ 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.

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}
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::libmesh_assert(), and libMesh::Real.

Referenced by ParsedFunctionTest::testInlineGetter(), and ParsedFunctionTest::testInlineSetter().

◆ 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}

◆ 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; }

References libMesh::ParsedFunction< Output, OutputGradient >::_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}
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dz_parsers
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dy_parsers
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dx_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.

91{ return _valid_derivatives; }

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

◆ init()

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

The actual initialization process.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 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.

211{
212 return (this->_initialized);
213}

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

◆ 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.

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

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

◆ operator()() [1/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()() [2/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()() [3/5]

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

Evaluation function for time-dependent vector-valued functions.

Sets output values in the passed-in output DenseVector.

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 316 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}

◆ operator()() [4/5]

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

Pure virtual, so you have to override it.

Implements libMesh::FunctionBase< Output >.

Definition at line 279 of file parsed_function.h.

280{
281 set_spacetime(p, time);
282 return eval(*parsers[0], "f", 0);
283}

◆ operator()() [5/5]

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

Evaluation function for time-independent vector-valued functions.

Sets output values in the passed-in output DenseVector.

Definition at line 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=() [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= ( const ParsedFunction< Output, OutputGradient > &  )
delete

◆ operator=() [3/4]

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

◆ operator=() [4/4]

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

◆ partial_reparse()

template<typename Output , typename OutputGradient >
void libMesh::ParsedFunction< Output, OutputGradient >::partial_reparse ( 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}

References libMesh::Real.

◆ 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.
bool expression_is_time_dependent(std::string_view expression) const

References libMesh::index_range().

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

◆ 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.

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}

References libMesh::libmesh_assert().

Referenced by ParsedFunctionTest::testInlineSetter().

◆ set_is_time_dependent()

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

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

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

Definition at line 217 of file function_base.h.

218{
220}

◆ 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}

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

◆ _expression

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

◆ _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

◆ _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

◆ 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: