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

#include <parsed_function.h>

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

List of all members.

Public Member Functions

 ParsedFunction (const std::string &expression, const std::vector< std::string > *additional_vars=NULL, const std::vector< Output > *initial_vals=NULL)
virtual Output operator() (const Point &p, const Real time=0)
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)
virtual Output component (unsigned int i, const Point &p, Real time)
virtual Output & getVarAddress (const std::string &variable_name)
virtual UniquePtr
< FunctionBase< Output > > 
clone () const
 ParsedFunction (std::string)
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 UniquePtr
< FunctionBase< Output > > 
clone () const
void operator() (const Point &p, DenseVector< Output > &output)
bool initialized () const

Protected Attributes

const FunctionBase_master
bool _initialized

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))

Private Attributes

std::string _expression
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::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 >

Definition at line 45 of file parsed_function.h.


Constructor & Destructor Documentation

template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( const std::string &  expression,
const std::vector< std::string > *  additional_vars = NULL,
const std::vector< Output > *  initial_vals = NULL 
) [inline, explicit]

Definition at line 49 of file parsed_function.h.

References libMesh::FunctionBase< Output >::_initialized, libMesh::ParsedFunction< Output, OutputGradient >::_spacetime, 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 >::parsers, and libMesh::Real.

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

                                                              :
    _expression (expression),
    _spacetime (LIBMESH_DIM+1 + (additional_vars ?
                                 additional_vars->size() : 0)),
    _valid_derivatives (true),
    _additional_vars (additional_vars ? *additional_vars :
                      std::vector<std::string>()),
    _initial_vals (initial_vals ? *initial_vals :
                   std::vector<Output>())
    // Size the spacetime vector to account for space, time, and any additional
    // variables passed
    //_spacetime(LIBMESH_DIM+1 + (additional_vars ? additional_vars->size() : 0)),
  {
    std::string variables = "x";
#if LIBMESH_DIM > 1
    variables += ",y";
#endif
#if LIBMESH_DIM > 2
    variables += ",z";
#endif
    variables += ",t";

    // If additional vars were passed, append them to the string
    // that we send to the function parser. Also add them to the
    // end of our spacetime vector
    if (additional_vars)
      {
        for (unsigned int i=0; i < additional_vars->size(); ++i)
          {
            variables += "," + (*additional_vars)[i];
            // Initialize extra variables to the vector passed in or zero
            // Note: The initial_vals vector can be shorter than the additional_vars vector
            _spacetime[LIBMESH_DIM+1 + i] = (initial_vals && i < initial_vals->size()) ? (*initial_vals)[i] : 0;
          }
      }

    size_t nextstart = 0, end = 0;

    while (end != std::string::npos)
      {
        // If we're past the end of the string, we can't make any more
        // subparsers
        if (nextstart >= expression.size())
          break;

        // If we're at the start of a brace delimited section, then we
        // parse just that section:
        if (expression[nextstart] == '{')
          {
            nextstart++;
            end = expression.find('}', nextstart);
          }
        // otherwise we parse the whole thing
        else
          end = std::string::npos;

        // We either want the whole end of the string (end == npos) or
        // a substring in the middle.
        std::string subexpression =
          expression.substr(nextstart, (end == std::string::npos) ?
                            std::string::npos : end - nextstart);

        // fparser can crash on empty expressions
        if (subexpression.empty())
          libmesh_error_msg("ERROR: FunctionParser is unable to parse empty expression.\n");

        // Parse (and optimize if possible) the subexpression.
        // Add some basic constants, to Real precision.
        FunctionParserADBase<Output> fp;
        fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
        fp.AddConstant("pi", std::acos(Real(-1)));
        fp.AddConstant("e", std::exp(Real(1)));
        if (fp.Parse(subexpression, variables) != -1) // -1 for success
          libmesh_error_msg("ERROR: FunctionParser is unable to parse expression: " << subexpression << '\n' << fp.ErrorMsg());

        // use of derivatives is optional. suppress error output on the console
        // use the has_derivatives() method to check if AutoDiff was successful.
        fp.silenceAutoDiffErrors();

        // generate derivatives through automatic differentiation
        FunctionParserADBase<Output> dx_fp(fp);
        if (dx_fp.AutoDiff("x") != -1) // -1 for success
          _valid_derivatives = false;
        dx_fp.Optimize();
        dx_parsers.push_back(dx_fp);
#if LIBMESH_DIM > 1
        FunctionParserADBase<Output> dy_fp(fp);
        if (dy_fp.AutoDiff("y") != -1) // -1 for success
          _valid_derivatives = false;
        dy_fp.Optimize();
        dy_parsers.push_back(dy_fp);
#endif
#if LIBMESH_DIM > 2
        FunctionParserADBase<Output> dz_fp(fp);
        if (dz_fp.AutoDiff("z") != -1) // -1 for success
          _valid_derivatives = false;
        dz_fp.Optimize();
        dz_parsers.push_back(dz_fp);
#endif
        FunctionParserADBase<Output> dt_fp(fp);
        if (dt_fp.AutoDiff("t") != -1) // -1 for success
          _valid_derivatives = false;
        dt_fp.Optimize();
        dt_parsers.push_back(dt_fp);

        // now optimise original function (after derivatives are taken)
        fp.Optimize();
        parsers.push_back(fp);

        // If at end, use nextstart=maxSize.  Else start at next
        // character.
        nextstart = (end == std::string::npos) ?
          std::string::npos : end + 1;
      }

    this->_initialized = true;
  }
template<typename Output = Number, typename OutputGradient = Gradient>
libMesh::ParsedFunction< Output, OutputGradient >::ParsedFunction ( std::string  ) [inline]

Definition at line 360 of file parsed_function.h.

                               : _dummy(0)
  {
    libmesh_not_implemented();
  }

Member Function Documentation

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

Clears the function.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 374 of file parsed_function.h.

{}
template<typename Output = Number, typename OutputGradient = Gradient>
virtual UniquePtr<FunctionBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::clone ( ) const [inline, virtual]

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

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

                                                         {
    return UniquePtr<FunctionBase<Output> >
      (new ParsedFunction(_expression, &_additional_vars, &_initial_vals));
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual UniquePtr<FunctionBase<Output> > libMesh::ParsedFunction< Output, OutputGradient >::clone ( ) const [inline, virtual]

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

                                                         {
    return UniquePtr<FunctionBase<Output> >
      (new ParsedFunction<Output>(""));
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::component ( unsigned int  i,
const Point p,
Real  time 
) [inline, virtual]
Returns:
the vector component i at coordinate p and time time.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 222 of file parsed_function.h.

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

  {
    set_spacetime(p, time);
    libmesh_assert_less (i, parsers.size());

    // The remaining locations in _spacetime are currently fixed at construction
    // but could potentially be made dynamic
    libmesh_assert_less(i, parsers.size());
    return eval(parsers[i], "f", i);
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::dot ( const Point p,
const Real  time = 0 
) [inline, virtual]
template<typename Output = Number, typename OutputGradient = Gradient>
Output libMesh::ParsedFunction< Output, OutputGradient >::eval ( FunctionParserADBase< Output > &  parser,
const std::string &  libmesh_dbg_varfunction_name,
unsigned int   libmesh_dbg_varcomponent_idx 
) [inline, private]

Definition at line 275 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< Output, OutputGradient >::gradient(), and libMesh::ParsedFunction< Output, OutputGradient >::operator()().

  {
#ifndef NDEBUG
    Output result = parser.Eval(&_spacetime[0]);
    int error_code = parser.EvalError();
    if (error_code)
      {
        libMesh::err << "ERROR: FunctionParser is unable to evaluate component "
                     << component_idx
                     << " of expression '"
                     << function_name
                     << "' with arguments:\n";
        for (unsigned int j=0; j<_spacetime.size(); ++j)
          libMesh::err << '\t' << _spacetime[j] << '\n';
        libMesh::err << '\n';

        // Currently no API to report error messages, we'll do it manually
        std::string error_message = "Reason: ";

        switch (error_code)
          {
          case 1:
            error_message += "Division by zero";
            break;
          case 2:
            error_message += "Square Root error (negative value)";
            break;
          case 3:
            error_message += "Log error (negative value)";
            break;
          case 4:
            error_message += "Trigonometric error (asin or acos of illegal value)";
            break;
          case 5:
            error_message += "Maximum recursion level reached";
            break;
          default:
            error_message += "Unknown";
            break;
          }
        libmesh_error_msg(error_message);
      }

    return result;
#else
    return parser.Eval(&_spacetime[0]);
#endif
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output& libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( const std::string &  variable_name) [inline, virtual]
Returns:
the address of a parsed variable so you can supply a parameterized value

Definition at line 238 of file parsed_function.h.

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

  {
    const std::vector<std::string>::iterator it =
      std::find(_additional_vars.begin(), _additional_vars.end(), variable_name);

    if (it == _additional_vars.end())
      libmesh_error_msg("ERROR: Requested variable not found in parsed function");

    // Iterator Arithmetic (How far from the end of the array is our target address?)
    return _spacetime[_spacetime.size() - (_additional_vars.end() - it)];
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output& libMesh::ParsedFunction< Output, OutputGradient >::getVarAddress ( const std::string &  ) [inline, virtual]

Definition at line 375 of file parsed_function.h.

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

{ return _dummy; }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual OutputGradient libMesh::ParsedFunction< Output, OutputGradient >::gradient ( const Point p,
const Real  time = 0 
) [inline, virtual]
template<typename Output = Number, typename OutputGradient = Gradient>
virtual bool libMesh::ParsedFunction< Output, OutputGradient >::has_derivatives ( ) [inline, virtual]
template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::init ( ) [inline, virtual]

The actual initialization process.

Reimplemented from libMesh::FunctionBase< Output >.

Definition at line 373 of file parsed_function.h.

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

Definition at line 198 of file function_base.h.

{
  return (this->_initialized);
}
template<typename Output>
void libMesh::FunctionBase< Output >::operator() ( const Point p,
DenseVector< Output > &  output 
) [inline, inherited]

Return function for vectors. Returns in output the values of the data at the coordinate p.

Definition at line 220 of file function_base.h.

{
  // Call the time-dependent function with t=0.
  this->operator()(p, 0., output);
}
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  time = 0 
) [inline, virtual]
Returns:
the scalar value at coordinate p and time time, which defaults to zero. Purely virtual, so you have to overload it. Note that this cannot be a const method, check MeshFunction.

Implements libMesh::FunctionBase< Output >.

Definition at line 168 of file parsed_function.h.

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

  {
    set_spacetime(p, time);
    return eval(parsers[0], "f", 0);
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual void libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  time,
DenseVector< Output > &  output 
) [inline, virtual]

Return function for vectors. Returns in output the values of the data at the coordinate p and for time time. Purely virtual, so you have to overload it. Note that this cannot be a const method, check MeshFunction. Can optionally provide subdomain_ids which will restrict the function to operate on elements with subdomain id contained in the set. This is useful in cases where there are multiple dimensioned elements, for example.

Implements libMesh::FunctionBase< Output >.

Definition at line 202 of file parsed_function.h.

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

  {
    set_spacetime(p, time);

    unsigned int size = output.size();

    libmesh_assert_equal_to (size, parsers.size());

    // The remaining locations in _spacetime are currently fixed at construction
    // but could potentially be made dynamic
    for (unsigned int i=0; i != size; ++i)
      output(i) = eval(parsers[i], "f", i);
  }
template<typename Output = Number, typename OutputGradient = Gradient>
virtual Output libMesh::ParsedFunction< Output, OutputGradient >::operator() ( const Point p,
const Real  time = 0 
) [inline, virtual]
Returns:
the scalar value at coordinate p and time time, which defaults to zero. Purely virtual, so you have to overload it. Note that this cannot be a const method, check MeshFunction.

Implements libMesh::FunctionBase< Output >.

Definition at line 365 of file parsed_function.h.

  { 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 
) [inline, virtual]

Return function for vectors. Returns in output the values of the data at the coordinate p and for time time. Purely virtual, so you have to overload it. Note that this cannot be a const method, check MeshFunction. Can optionally provide subdomain_ids which will restrict the function to operate on elements with subdomain id contained in the set. This is useful in cases where there are multiple dimensioned elements, for example.

Implements libMesh::FunctionBase< Output >.

Definition at line 369 of file parsed_function.h.

                                                   {}
template<typename Output = Number, typename OutputGradient = Gradient>
void libMesh::ParsedFunction< Output, OutputGradient >::set_spacetime ( const Point p,
const Real  time = 0 
) [inline, private]

Definition at line 258 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< Output, OutputGradient >::gradient(), and libMesh::ParsedFunction< Output, OutputGradient >::operator()().

  {
    _spacetime[0] = p(0);
#if LIBMESH_DIM > 1
    _spacetime[1] = p(1);
#endif
#if LIBMESH_DIM > 2
    _spacetime[2] = p(2);
#endif
    _spacetime[LIBMESH_DIM] = time;

    // The remaining locations in _spacetime are currently fixed at construction
    // but could potentially be made dynamic
  }

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]
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 >::_initialized [protected, inherited]
template<typename Output = Number>
const FunctionBase* libMesh::FunctionBase< Output >::_master [protected, inherited]

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

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]

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