$extrastylesheet
libMesh::ParsedFEMFunction< Output > Class Template Reference

#include <parsed_fem_function.h>

Inheritance diagram for libMesh::ParsedFEMFunction< Output >:

List of all members.

Public Member Functions

 ParsedFEMFunction (const System &sys, const std::string &expression, const std::vector< std::string > *additional_vars=NULL, const std::vector< Output > *initial_vals=NULL)
virtual ~ParsedFEMFunction ()
virtual void init_context (const FEMContext &c)
virtual UniquePtr
< FEMFunctionBase< Output > > 
clone () const
virtual Output operator() (const FEMContext &c, const Point &p, const Real time=0.)
void operator() (const FEMContext &c, const Point &p, const Real time, DenseVector< Output > &output)
virtual Output component (const FEMContext &c, unsigned int i, const Point &p, Real time=0.)
void operator() (const FEMContext &, const Point &p, DenseVector< Output > &output)

Private Attributes

const System_sys
std::string _expression
unsigned int _n_vars
std::vector
< FunctionParserBase< Output > > 
parsers
std::vector< Output > _spacetime
std::vector< std::string > _additional_vars
std::vector< Output > _initial_vals

Detailed Description

template<typename Output = Number>
class libMesh::ParsedFEMFunction< Output >

Definition at line 43 of file parsed_fem_function.h.


Constructor & Destructor Documentation

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

Constructor.

Definition at line 51 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_additional_vars, libMesh::ParsedFEMFunction< Output >::_initial_vals, libMesh::ParsedFEMFunction< Output >::_n_vars, libMesh::ParsedFEMFunction< Output >::_spacetime, end, libMesh::ParsedFEMFunction< Output >::parsers, libMesh::Real, and libMesh::System::variable_name().

Referenced by libMesh::ParsedFEMFunction< Output >::clone().

    : _sys(sys),
      _expression(expression),
      _n_vars(sys.n_vars())
  {
    std::string variables = "x";
#if LIBMESH_DIM > 1
    variables += ",y";
#endif
#if LIBMESH_DIM > 2
    variables += ",z";
#endif
    variables += ",t";

    _spacetime.resize(LIBMESH_DIM+1 + _n_vars + (additional_vars ? additional_vars->size() : 0));

    for (unsigned int v=0; v != _n_vars; ++v)
      {
        variables += ',';
        variables += sys.variable_name(v);
      }

    // 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)
      {
        if (initial_vals)
          std::copy(initial_vals->begin(), initial_vals->end(), std::back_inserter(_initial_vals));

        std::copy(additional_vars->begin(), additional_vars->end(), std::back_inserter(_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+_n_vars + 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");


#ifdef LIBMESH_HAVE_FPARSER
        // Parse (and optimize if possible) the subexpression.
        // Add some basic constants, to Real precision.
        FunctionParserBase<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());
        fp.Optimize();
        parsers.push_back(fp);
#else
        libmesh_error_msg("ERROR: This functionality requires fparser!");
#endif

        // If at end, use nextstart=maxSize.  Else start at next
        // character.
        nextstart = (end == std::string::npos) ?
          std::string::npos : end + 1;
      }
  }
template<typename Output = Number>
virtual libMesh::ParsedFEMFunction< Output >::~ParsedFEMFunction ( ) [inline, virtual]

Destructor.

Definition at line 151 of file parsed_fem_function.h.

{}

Member Function Documentation

template<typename Output = Number>
virtual UniquePtr<FEMFunctionBase<Output> > libMesh::ParsedFEMFunction< Output >::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::FEMFunctionBase< Output >.

Definition at line 170 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_additional_vars, libMesh::ParsedFEMFunction< Output >::_expression, libMesh::ParsedFEMFunction< Output >::_initial_vals, libMesh::ParsedFEMFunction< Output >::_sys, and libMesh::ParsedFEMFunction< Output >::ParsedFEMFunction().

                                                             {
    return UniquePtr<FEMFunctionBase<Output> >
      (new ParsedFEMFunction
       (_sys, _expression, &_additional_vars, &_initial_vals));
  }
template<typename Output = Number>
virtual Output libMesh::ParsedFEMFunction< Output >::component ( const FEMContext c,
unsigned int  i,
const Point p,
Real  time = 0. 
) [inline, virtual]
Returns:
the vector component i at coordinate p and time time.

Reimplemented from libMesh::FEMFunctionBase< Output >.

Definition at line 255 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_n_vars, libMesh::ParsedFEMFunction< Output >::_spacetime, libMesh::ParsedFEMFunction< Output >::parsers, and libMesh::FEMContext::point_value().

  {
    _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;

    for (unsigned int v=0; v != _n_vars; ++v)
      {
        c.point_value(v, p, _spacetime[LIBMESH_DIM+1+v]);
      }
#ifdef LIBMESH_HAVE_FPARSER
    libmesh_assert_less (i, parsers.size());

    // The remaining locations in _spacetime are currently fixed at construction
    // but could potentially be made dynamic
    return parsers[i].Eval(&_spacetime[0]);
#else
    libmesh_error_msg("ERROR: This functionality requires fparser!");
    return Output(0);
#endif
  }
template<typename Output = Number>
virtual void libMesh::ParsedFEMFunction< Output >::init_context ( const FEMContext c) [inline, virtual]

Prepares a context object for use.

Reimplemented from libMesh::FEMFunctionBase< Output >.

Definition at line 156 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_n_vars, libMesh::FEMContext::get_element_fe(), and libMesh::FEGenericBase< OutputType >::get_phi().

                                                  {
    for (unsigned int v=0; v != _n_vars; ++v)
      {
        FEBase* elem_fe;
        c.get_element_fe(v, elem_fe);
        elem_fe->get_phi();
      }
  }
template<typename Output >
void libMesh::FEMFunctionBase< Output >::operator() ( const FEMContext context,
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 137 of file fem_function_base.h.

{
  // Call the time-dependent function with t=0.
  this->operator()(context, p, 0., output);
}
template<typename Output = Number>
virtual Output libMesh::ParsedFEMFunction< Output >::operator() ( const FEMContext c,
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::FEMFunctionBase< Output >.

Definition at line 184 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_n_vars, libMesh::ParsedFEMFunction< Output >::_spacetime, libMesh::ParsedFEMFunction< Output >::parsers, and libMesh::FEMContext::point_value().

  {
    _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;

    for (unsigned int v=0; v != _n_vars; ++v)
      {
        c.point_value(v, p, _spacetime[LIBMESH_DIM+1+v]);
      }

    // The remaining locations in _spacetime are currently fixed at construction
    // but could potentially be made dynamic
#if LIBMESH_HAVE_FPARSER
    return parsers[0].Eval(&_spacetime[0]);
#else
    libmesh_error_msg("ERROR: This functionality requires fparser!");
    return Output(0);
#endif
  }
template<typename Output = Number>
void libMesh::ParsedFEMFunction< Output >::operator() ( const FEMContext c,
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.

Implements libMesh::FEMFunctionBase< Output >.

Definition at line 218 of file parsed_fem_function.h.

References libMesh::ParsedFEMFunction< Output >::_n_vars, libMesh::ParsedFEMFunction< Output >::_spacetime, libMesh::ParsedFEMFunction< Output >::parsers, libMesh::FEMContext::point_value(), and libMesh::DenseVector< T >::size().

  {
    _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;

    for (unsigned int v=0; v != _n_vars; ++v)
      {
        c.point_value(v, p, _spacetime[LIBMESH_DIM+1+v]);
      }

    unsigned int size = output.size();

#ifdef LIBMESH_HAVE_FPARSER
    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) = parsers[i].Eval(&_spacetime[0]);
#else
    libmesh_error_msg("ERROR: This functionality requires fparser!");
#endif
  }

Member Data Documentation

template<typename Output = Number>
std::vector<std::string> libMesh::ParsedFEMFunction< Output >::_additional_vars [private]
template<typename Output = Number>
std::string libMesh::ParsedFEMFunction< Output >::_expression [private]

Definition at line 286 of file parsed_fem_function.h.

Referenced by libMesh::ParsedFEMFunction< Output >::clone().

template<typename Output = Number>
std::vector<Output> libMesh::ParsedFEMFunction< Output >::_initial_vals [private]
template<typename Output = Number>
const System& libMesh::ParsedFEMFunction< Output >::_sys [private]

Definition at line 285 of file parsed_fem_function.h.

Referenced by libMesh::ParsedFEMFunction< Output >::clone().

template<typename Output = Number>
std::vector<FunctionParserBase<Output> > libMesh::ParsedFEMFunction< Output >::parsers [private]

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