Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Nektar::LibUtilities::AnalyticExpressionEvaluator Class Reference

This class defines evaluator of analytic (symbolic) mathematical expressions. Expressions are allowed to depend on a number of spatial-time variables and parameters. Pre-processing and evaluation stages are split. At evaluation stage one specifies values for each variable, resulting expression value is returned. Vectorized evaluator (evaluate expression at a set of points) is available. More...

#include <AnalyticExpressionEvaluator.hpp>

Collaboration diagram for Nektar::LibUtilities::AnalyticExpressionEvaluator:
Collaboration graph
[legend]

Classes

class  AnalyticExpression
struct  CopyState
struct  EvalAbs
struct  EvalAcos
struct  EvalAsin
struct  EvalAtan
struct  EvalAWGN
struct  EvalCeil
struct  EvalCos
struct  EvalCosh
struct  EvalDiv
struct  EvalExp
struct  EvalFabs
struct  EvalFloor
struct  EvalLog
struct  EvalLog10
struct  EvalLogicalEqual
struct  EvalLogicalGeq
struct  EvalLogicalGreater
struct  EvalLogicalLeq
struct  EvalLogicalLess
struct  EvalMul
struct  EvalNeg
struct  EvalPow
struct  EvalSign
struct  EvalSin
struct  EvalSinh
struct  EvalSqrt
struct  EvalSub
struct  EvalSum
struct  EvalTan
struct  EvalTanh
struct  EvaluationStep
 Function objects (functors) More...
struct  StoreConst
struct  StorePrm
struct  StoreVar

Public Types

typedef std::map< std::string,
int > 
VariableMap
typedef std::map< std::string,
int > 
ConstantMap
typedef std::map< std::string,
int > 
ParameterMap
typedef std::map< std::string,
int > 
ExpressionMap
typedef std::map< std::string,
int > 
FunctionNameMap
typedef std::vector
< EvaluationStep * > 
ExecutionStack
typedef std::pair< bool,
NekDouble
PrecomputedValue
typedef NekDouble(* OneArgFunc )(NekDouble)
typedef
boost_spirit::tree_parse_info
< std::string::const_iterator,
boost_spirit::node_val_data_factory
< NekDouble > > 
ParsedTreeInfo
typedef
boost_spirit::tree_match
< std::string::const_iterator,
boost_spirit::node_val_data_factory
< NekDouble > >::tree_iterator 
ParsedTreeIterator
typedef std::vector< const
Array< OneD, const NekDouble > * > 
VariableArray
typedef boost::mt19937 RandomGeneratorType

Public Member Functions

 AnalyticExpressionEvaluator (void)
 Initializes the evaluator to a state where it is ready to accept input from the DefineFunction function.
 ~AnalyticExpressionEvaluator (void)
 Destroys the execution stack.
void SetRandomSeed (unsigned int seed=123u)
void AddConstants (std::map< std::string, NekDouble > const &constants)
 Constants are evaluated and inserted into the function at the time it is parsed when calling the DefineFunction function. After parsing, if a constant is changed, it will not be reflected in the function when Evaluate is called. This also means that if a function with an unknown constant is added, and then the constant is added, the function will not see the added constant and through an exception. This function will add all of the constants in the map argument to the global internal constants. If a constant was already loaded previously, it will throw an exception stating which constants in the map had this issue. It will add all of the constants it can and output the constants it couldn't add in the string exception.
int AddConstant (std::string const &name, NekDouble value)
 This function behaves in the same way as AddConstants, but it only adds one constant at a time. If the constant existed previously, an exception will be thrown stating the fact. If it did not exist previously, it will be added to the global constants and will be used the next time DefineFunction is called.
NekDouble GetConstant (std::string const &name)
 If a constant with the specified name exists, it returns the NekDouble value that the constant stores. If the constant doesn't exist, it throws an exception.
void SetParameters (std::map< std::string, NekDouble > const &params)
 Parameters are like constants, but they are inserted into the function at the time Evaluate is called instead of when the function is parsed. This function can be called at any time, and it will take effect in the next call to Evaluate. This function will delete all of the parameters, and replace all of them with only the ones in the map argument.
void SetParameter (std::string const &name, NekDouble value)
 This function behaves in the same way as SetParameters, but it only adds one parameter and it does not delete the others. If the parameter existed previously, it will be overridden and replaced with the new value. If it did not exist previously, it will be added to the current parameters.
NekDouble GetParameter (std::string const &name)
 If a parameter with the specified name exists, it returns the NekDouble value that the parameter stores. If the parameter doesn't exist, it throws an exception.
NekDouble GetTime () const
 Returns the total time spent in evaluation procedures, seconds.
int DefineFunction (const std::string &vlist, const std::string &function)
 This function allows one to define a function to evaluate. The first argument (vlist) is a list of variables (separated by spaces) that the second argument (function) depends on. For example, if function = "x + y", then vlist should most likely be "x y", unless you are defining x or y as parameters with SetParameters. parsed expression ID. You will need this expression id to call evaluation methods below.
NekDouble Evaluate (const int AnalyticExpression_id)
 Evaluation method for expressions depending on parameters only.
NekDouble Evaluate (const int AnalyticExpression_id, const NekDouble, const NekDouble, const NekDouble, const NekDouble)
 Evaluation method for expressions depending on 4 variables (+parameters).
NekDouble EvaluateAtPoint (const int AnalyticExpression_id, std::vector< NekDouble > point)
 Evaluation method for expressions depending on unspecified number of variables. This suitable for expressions depending on more than 4 variables or for the dynamic setting some variables as parameters (there is currently no interface method for removing a variable from parameter map though).
void Evaluate (const int expression_id, const Array< OneD, const NekDouble > &, const Array< OneD, const NekDouble > &, const Array< OneD, const NekDouble > &, const Array< OneD, const NekDouble > &, Array< OneD, NekDouble > &result)
 Vectorized evaluation method for expressions depending on 4 variables.
void EvaluateAtPoints (const int expression_id, const std::vector< Array< OneD, const NekDouble > > points, Array< OneD, NekDouble > &result)
 Vectorized evaluation method for expressions depending on unspecified number of variables.

Private Types

enum  EvaluationStepType {
  E_ABS, E_ASIN, E_ACOS, E_ATAN,
  E_ATAN2, E_CEIL, E_COS, E_COSH,
  E_EXP, E_FABS, E_FLOOR, E_LOG,
  E_LOG10, E_POW, E_SIN, E_SINH,
  E_SQRT, E_TAN, E_TANH, E_SIGN,
  E_AWGN
}
typedef std::vector< NekDouble > & vr
 Short names to minimise the infractructural code mess in defining functors below.
typedef const std::vector
< NekDouble > & 
cvr
typedef const int ci
typedef RandomGeneratorTypergt

Private Member Functions

PrecomputedValue PrepareExecutionAsYouParse (const ParsedTreeIterator &root, ExecutionStack &stack, VariableMap &varMap, int stateIndex)
 This method prepares the execution stack (an ordered sequence of operators that perform the evaluation) for the parsed evaluation tree.
template<typename StepType >
EvaluationStepmakeStep (ci dest, ci src_left=0, ci src_right=0)
 Factory method which makes code little less messy.

Private Attributes

boost_spirit::symbols< NekDoublem_constantsParser
ExpressionMap m_parsedMapExprToExecStackId
 These vector and map store pre-processed evaluation sequences for the analytic expressions. Each ExecutionStack is an ordered container of steps of sequential execution process which evaluates an analytic expression.
std::vector< ExecutionStackm_executionStack
std::vector< VariableMapm_stackVariableMap
 Keeping map of variables individually per each analytic expression allows correctly handling expressions which depend on different number of variables.
ParameterMap m_parameterMapNameToId
 The following data structures hold input data to be used on evaluation stage. There are three types of input data:
ConstantMap m_constantMapNameToId
VariableMap m_expressionVariableMap
std::vector< NekDoublem_parameter
std::vector< NekDoublem_constant
std::vector< NekDoublem_variable
std::vector< NekDoublem_state
 This vector stores the execution state (memory) used by the sequential execution process.
std::vector< int > m_state_sizes
 Vector of state sizes per each.
int m_state_size
 This counter is used by PrepareExecutionAsYouParse for finding the minimal state size necessary for evaluation of function parsed.
Timer m_timer
 Timer and sum of evaluation times.
NekDouble m_total_eval_time
RandomGeneratorType m_generator
FunctionNameMap m_functionMapNameToInstanceType
std::map< int, OneArgFuncm_function

Detailed Description

This class defines evaluator of analytic (symbolic) mathematical expressions. Expressions are allowed to depend on a number of spatial-time variables and parameters. Pre-processing and evaluation stages are split. At evaluation stage one specifies values for each variable, resulting expression value is returned. Vectorized evaluator (evaluate expression at a set of points) is available.

Internally this class uses boost::spirit to parse analytic expressions and unrolls their recursive bracketing structure into a sequence of evaluation steps (aka execution stack) with resolved data dependencies. Once an expression is pre-processed, its execution stack is stored internally in order to be re-used.

Definition at line 98 of file AnalyticExpressionEvaluator.hpp.

Member Typedef Documentation

Definition at line 450 of file AnalyticExpressionEvaluator.hpp.

Definition at line 109 of file AnalyticExpressionEvaluator.hpp.

Definition at line 449 of file AnalyticExpressionEvaluator.hpp.

Definition at line 113 of file AnalyticExpressionEvaluator.hpp.

Definition at line 111 of file AnalyticExpressionEvaluator.hpp.

Definition at line 112 of file AnalyticExpressionEvaluator.hpp.

typedef NekDouble(* Nektar::LibUtilities::AnalyticExpressionEvaluator::OneArgFunc)(NekDouble)

Definition at line 115 of file AnalyticExpressionEvaluator.hpp.

Definition at line 110 of file AnalyticExpressionEvaluator.hpp.

typedef boost_spirit::tree_parse_info< std::string::const_iterator, boost_spirit::node_val_data_factory<NekDouble> > Nektar::LibUtilities::AnalyticExpressionEvaluator::ParsedTreeInfo

Definition at line 120 of file AnalyticExpressionEvaluator.hpp.

typedef boost_spirit::tree_match< std::string::const_iterator, boost_spirit::node_val_data_factory<NekDouble> >::tree_iterator Nektar::LibUtilities::AnalyticExpressionEvaluator::ParsedTreeIterator

Definition at line 124 of file AnalyticExpressionEvaluator.hpp.

Definition at line 114 of file AnalyticExpressionEvaluator.hpp.

Definition at line 128 of file AnalyticExpressionEvaluator.hpp.

Definition at line 451 of file AnalyticExpressionEvaluator.hpp.

Definition at line 126 of file AnalyticExpressionEvaluator.hpp.

Definition at line 103 of file AnalyticExpressionEvaluator.hpp.

Short names to minimise the infractructural code mess in defining functors below.

Definition at line 448 of file AnalyticExpressionEvaluator.hpp.

Member Enumeration Documentation

Enumerator:
E_ABS 
E_ASIN 
E_ACOS 
E_ATAN 
E_ATAN2 
E_CEIL 
E_COS 
E_COSH 
E_EXP 
E_FABS 
E_FLOOR 
E_LOG 
E_LOG10 
E_POW 
E_SIN 
E_SINH 
E_SQRT 
E_TAN 
E_TANH 
E_SIGN 
E_AWGN 

Definition at line 460 of file AnalyticExpressionEvaluator.hpp.

Constructor & Destructor Documentation

Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpressionEvaluator ( void  )

Initializes the evaluator to a state where it is ready to accept input from the DefineFunction function.

Definition at line 218 of file AnalyticExpressionEvaluator.cpp.

References AddConstant(), E_ABS, E_ACOS, E_ASIN, E_ATAN, E_AWGN, E_CEIL, E_COS, E_COSH, E_EXP, E_FABS, E_FLOOR, E_LOG, E_LOG10, E_SIGN, E_SIN, E_SINH, E_SQRT, E_TAN, E_TANH, m_function, m_functionMapNameToInstanceType, m_state_size, and Nektar::LibUtilities::sign().

:
{
AddConstant("MEANINGLESS", 0.0);
AddConstant("E", 2.71828182845904523536); // Natural logarithm
AddConstant("LOG2E", 1.4426950408889634074); // log_2 e
AddConstant("LOG10E", 0.43429448190325182765); // log_10 e
AddConstant("LN2", 0.69314718055994530942); // log_e 2
AddConstant("LN10", 2.30258509299404568402); // log_e 10
AddConstant("PI", 3.14159265358979323846); // pi
AddConstant("PI_2", 1.57079632679489661923); // pi/2
AddConstant("PI_4", 0.78539816339744830962); // pi/4
AddConstant("1_PI", 0.31830988618379067154); // 1/pi
AddConstant("2_PI", 0.63661977236758134308); // 2/pi
AddConstant("2_SQRTPI", 1.12837916709551257390); // 2/sqrt(pi)
AddConstant("SQRT2", 1.41421356237309504880); // sqrt(2)
AddConstant("SQRT1_2", 0.70710678118654752440); // 1/sqrt(2)
AddConstant("GAMMA", 0.57721566490153286060); // Euler
AddConstant("DEG", 57.2957795130823208768); // deg/radian
AddConstant("PHI", 1.61803398874989484820); // golden ratio
m_function[ E_ABS ] = std::abs;
m_function[ E_ASIN ] = asin;
m_function[ E_ACOS ] = acos;
m_function[ E_ATAN ] = atan;
m_function[ E_CEIL ] = ceil;
m_function[ E_COS ] = cos;
m_function[ E_COSH ] = cosh;
m_function[ E_EXP ] = exp;
m_function[ E_FABS ] = fabs;
m_function[ E_FLOOR] = floor;
m_function[ E_LOG ] = log;
m_function[ E_LOG10] = log10;
m_function[ E_SIN ] = sin;
m_function[ E_SINH ] = sinh;
m_function[ E_SQRT ] = sqrt;
m_function[ E_TAN ] = tan;
m_function[ E_TANH ] = tanh;
// there is no entry to m_function that correspond to awgn function.
// this is made in purpose. This function need not be pre-evaluated once!
}
Nektar::LibUtilities::AnalyticExpressionEvaluator::~AnalyticExpressionEvaluator ( void  )

Destroys the execution stack.

Definition at line 285 of file AnalyticExpressionEvaluator.cpp.

References Nektar::iterator, and m_executionStack.

{
for (std::vector<ExecutionStack>::iterator it_es = m_executionStack.begin(); it_es != m_executionStack.end(); ++it_es)
{
for (std::vector<EvaluationStep*>::iterator it = (*it_es).begin(); it != (*it_es).end(); ++it)
{
delete *it;
}
(*it_es).clear();
}
}

Member Function Documentation

int Nektar::LibUtilities::AnalyticExpressionEvaluator::AddConstant ( std::string const &  name,
NekDouble  value 
)

This function behaves in the same way as AddConstants, but it only adds one constant at a time. If the constant existed previously, an exception will be thrown stating the fact. If it did not exist previously, it will be added to the global constants and will be used the next time DefineFunction is called.

Definition at line 313 of file AnalyticExpressionEvaluator.cpp.

References m_constant, m_constantMapNameToId, and m_constantsParser.

Referenced by AddConstants(), AnalyticExpressionEvaluator(), DefineFunction(), and PrepareExecutionAsYouParse().

{
ConstantMap::const_iterator it = m_constantMapNameToId.find(name);
if (it == m_constantMapNameToId.end())
{
// we are trying to avoid duplicating entries in m_constantParser and m_constants
m_constantsParser.add(name.c_str(), value);
int index = m_constant.size();
m_constantMapNameToId[name] = index;
m_constant.push_back(value);
return index;
}
else
{
if(m_constant[it->second] != value)
{
std::string errormsg("Attempt to add numerically different constants under the same name: ");
errormsg += name;
std::cout << errormsg << std::endl;
}
//ASSERTL1(m_constant[it->second] == value, "Attempt to add numerically different constants under the same name: " + name);
}
return it->second;
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::AddConstants ( std::map< std::string, NekDouble > const &  constants)

Constants are evaluated and inserted into the function at the time it is parsed when calling the DefineFunction function. After parsing, if a constant is changed, it will not be reflected in the function when Evaluate is called. This also means that if a function with an unknown constant is added, and then the constant is added, the function will not see the added constant and through an exception. This function will add all of the constants in the map argument to the global internal constants. If a constant was already loaded previously, it will throw an exception stating which constants in the map had this issue. It will add all of the constants it can and output the constants it couldn't add in the string exception.

Definition at line 305 of file AnalyticExpressionEvaluator.cpp.

References AddConstant().

Referenced by Nektar::LibUtilities::Equation::SetConstants().

{
for (std::map<std::string, NekDouble>::const_iterator it = constants.begin(); it != constants.end(); ++it)
{
AddConstant(it->first, it->second);
}
}
int Nektar::LibUtilities::AnalyticExpressionEvaluator::DefineFunction ( const std::string &  vlist,
const std::string &  function 
)

This function allows one to define a function to evaluate. The first argument (vlist) is a list of variables (separated by spaces) that the second argument (function) depends on. For example, if function = "x + y", then vlist should most likely be "x y", unless you are defining x or y as parameters with SetParameters. parsed expression ID. You will need this expression id to call evaluation methods below.

Definition at line 391 of file AnalyticExpressionEvaluator.cpp.

References AddConstant(), ASSERTL1, m_constantsParser, m_executionStack, m_parsedMapExprToExecStackId, m_stackVariableMap, m_state_size, m_state_sizes, and PrepareExecutionAsYouParse().

Referenced by Nektar::LibUtilities::Equation::Equation(), Nektar::SpatialDomains::MeshGraph::ReadCurves(), Nektar::SpatialDomains::MeshGraph::ReadGeometry(), and Replacevertices().

{
// Find the previous parsing.
ExpressionMap::const_iterator it = m_parsedMapExprToExecStackId.find(expr);
{
// if this function is already defined, don't do anything but
// return its ID.
return it->second;
}
// ----------------------------------------------
// Prepare an iterator that allows to walk along
// the string representing an analytic expression in the order
// that respects its recursive structure (thanks to boost::spirit).
// ----------------------------------------------
// Parse the vlist input and separate the variables into ordered entries
// in a vector<string> object. These need to be ordered because this is
// the order the variables will get assigned to in the Map when Evaluate(...)
// is called.
std::vector<std::string> variableNames;
parse((char*) vlist.c_str(), ( *space_p >>
*(
+(+graph_p)[push_back_a(variableNames)]
>> +space_p
)
)
);
// Set up our grammar
AnalyticExpression myGrammar(&m_constantsParser, variableNames);
// Do the actual parsing with boost::spirit and alert the user if there was an error with an exception.
ParsedTreeInfo parseInfo = ast_parse<
node_val_data_factory<NekDouble>,
std::string::const_iterator,
AnalyticExpression,
space_parser
>
(expr.begin(), expr.end(), myGrammar, space_p);
ASSERTL1(parseInfo.full != false, "Unable to fully parse function. Stopped just before: "
+ std::string(parseInfo.stop, parseInfo.stop + 15));
// ----------------------------------------------
// Data parsed, start setting up internal data structures.
// ----------------------------------------------
VariableMap variableMap;
int stackId = m_executionStack.size();
// register all variables declared in the expression
for (int i = 0; i < variableNames.size(); i++)
{
variableMap[variableNames[i]] = i;
}
// then prepare an execution stack.
// this method also calculates a length of internal
// state storage (m_state_size) for this function.
PrecomputedValue v = PrepareExecutionAsYouParse(parseInfo.trees.begin(), stack, variableMap, 0);
// constant expression, fully evaluated
if (true == v.first)
{
ASSERTL1(stack.size() == 0, "Constant expression yeilds non-empty execution stack. Bug in PrepareExecutionAsYouParse()");
int const_index = AddConstant(std::string("EXPRESSION_") + boost::lexical_cast<std::string>(stackId), v.second);
stack.push_back ( makeStep<StoreConst>( 0, const_index ) );
}
// the execution stack and its corresponding variable index map are
// two parallel std::vectors that share their ids. This split helps
// to achieve some performance improvement.
m_executionStack.push_back(stack);
m_stackVariableMap.push_back(variableMap);
return stackId;
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::Evaluate ( const int  AnalyticExpression_id)

Evaluation method for expressions depending on parameters only.

Definition at line 477 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_executionStack, m_state, m_state_sizes, m_timer, m_total_eval_time, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

Referenced by Nektar::LibUtilities::Equation::Evaluate(), Nektar::SpatialDomains::MeshGraph::ReadCurves(), Nektar::SpatialDomains::MeshGraph::ReadGeometry(), and Replacevertices().

{
ASSERTL1(m_executionStack.size() > expression_id, "unknown analytic expression, it must first be defined with DefineFunction(...)");
ExecutionStack &stack = m_executionStack[expression_id];
m_state.resize(m_state_sizes[expression_id]);
for (int i = 0; i < stack.size(); i++)
{
(*stack[i]).run_once();
}
return m_state[0];
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::Evaluate ( const int  AnalyticExpression_id,
const NekDouble  x,
const NekDouble  y,
const NekDouble  z,
const NekDouble  t 
)

Evaluation method for expressions depending on 4 variables (+parameters).

Definition at line 497 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_executionStack, m_state, m_state_sizes, m_timer, m_total_eval_time, m_variable, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

{
ASSERTL1(m_executionStack.size() > expression_id, "unknown analytic expression, it must first be defined with DefineFunction(...)");
ExecutionStack &stack = m_executionStack[expression_id];
// initialise internal vector of variable values
m_state.resize(m_state_sizes[expression_id]);
if (m_variable.size() < 4)
{
m_variable.resize(4);
}
// no flexibility, no change of variable ordering in m_variable
// container depending on their names ordering in the input vlist
// argument of DefineFunction. Ordering convention (x,y,z,t) is assumed.
m_variable[0] = x;
m_variable[1] = y;
m_variable[2] = z;
m_variable[3] = t;
// main execution cycle is hidden here
for (int i = 0; i < stack.size(); i++)
{
(*stack[i]).run_once();
}
return m_state[0];
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::Evaluate ( const int  expression_id,
const Array< OneD, const NekDouble > &  x,
const Array< OneD, const NekDouble > &  y,
const Array< OneD, const NekDouble > &  z,
const Array< OneD, const NekDouble > &  t,
Array< OneD, NekDouble > &  result 
)

Vectorized evaluation method for expressions depending on 4 variables.

If number of points tends to 10^6, one may end up with up to ~0.5Gb data allocated for m_state only. Lets split the work into cache-sized chunks. Ahtung, magic constant!

please don't remove brackets around std::min, it screws up windows compilation

Definition at line 570 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_executionStack, m_state, m_state_sizes, m_timer, m_total_eval_time, m_variable, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

{
const int num_points = x.num_elements();
ASSERTL1(m_executionStack.size() > expression_id, "unknown analytic expression, it must first be defined with DefineFunction(...)");
ASSERTL1(result.num_elements() >= num_points, "destination array must have enough capacity to store expression values at each given point");
ExecutionStack &stack = m_executionStack[expression_id];
/// If number of points tends to 10^6, one may end up
/// with up to ~0.5Gb data allocated for m_state only.
/// Lets split the work into cache-sized chunks.
/// Ahtung, magic constant!
const int max_chunk_size = 1024;
/// please don't remove brackets around std::min, it screws up windows compilation
const int chunk_size = (std::min)(max_chunk_size, num_points);
if (m_state.size() < chunk_size * m_state_sizes[expression_id] )
{
m_state.resize( m_state_sizes[expression_id] * chunk_size, 0.0 );
}
if (m_variable.size() < 4 * chunk_size )
{
m_variable.resize( 4 * chunk_size, 0.0);
}
if (result.num_elements() < num_points)
{
result = Array<OneD, NekDouble>(num_points, 0.0);
}
int offset = 0;
int work_left = num_points;
while(work_left > 0)
{
const int this_chunk_size = (std::min)(work_left, 1024);
for (int i = 0; i < this_chunk_size; i++)
{
m_variable[i+this_chunk_size*0] = x[offset + i];
m_variable[i+this_chunk_size*1] = y[offset + i];
m_variable[i+this_chunk_size*2] = z[offset + i];
m_variable[i+this_chunk_size*3] = t[offset + i];
}
for (int i = 0; i < stack.size(); i++)
{
(*stack[i]).run_many(this_chunk_size);
}
for (int i = 0; i < this_chunk_size; i++)
{
result[offset + i] = m_state[i];
}
work_left -= this_chunk_size;
offset += this_chunk_size;
}
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::EvaluateAtPoint ( const int  AnalyticExpression_id,
std::vector< NekDouble point 
)

Evaluation method for expressions depending on unspecified number of variables. This suitable for expressions depending on more than 4 variables or for the dynamic setting some variables as parameters (there is currently no interface method for removing a variable from parameter map though).

Definition at line 538 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_executionStack, m_stackVariableMap, m_state, m_state_sizes, m_timer, m_total_eval_time, m_variable, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

{
ASSERTL1(m_executionStack.size() > expression_id, "unknown analytic expression, it must first be defined with DefineFunction(...)");
ExecutionStack& stack = m_executionStack[expression_id];
VariableMap& variableMap = m_stackVariableMap[expression_id];
ASSERTL1(point.size() == variableMap.size(), "The number of variables used to define this expression should match the point dimensionality.");
// initialise internal vector of variable values
m_state.resize(m_state_sizes[expression_id]);
m_variable.resize(point.size());
VariableMap::const_iterator it;
for (it = variableMap.begin(); it != variableMap.end(); ++it)
{
m_variable[it->second] = point[it->second];
}
// main execution cycle is hidden here
for (int i = 0; i < stack.size(); i++)
{
(*stack[i]).run_once();
}
return m_state[0];
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::EvaluateAtPoints ( const int  expression_id,
const std::vector< Array< OneD, const NekDouble > >  points,
Array< OneD, NekDouble > &  result 
)

Vectorized evaluation method for expressions depending on unspecified number of variables.

Todo:
test this function properly/update as the method above

Definition at line 635 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_executionStack, m_stackVariableMap, m_state, m_state_sizes, m_timer, m_total_eval_time, m_variable, Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

{
/// \todo test this function properly/update as the method above
ASSERTL1(m_executionStack.size() > expression_id, "unknown analytic expression, it must first be defined with DefineFunction(...)");
ExecutionStack& stack = m_executionStack[expression_id];
VariableMap& variableMap = m_stackVariableMap[expression_id];
const int num = points[0].num_elements();
m_state.resize(m_state_sizes[expression_id]*num);
// assuming all points have same # of coordinates
m_variable.resize(4*num,0.0);
for (int i = 0; i < points.size(); i++)
{
for (VariableMap::const_iterator it = variableMap.begin(); it != variableMap.end(); ++it)
{
m_variable[it->second] = points[i][it->second];
}
}
for (int j = 0; j < stack.size(); j++)
{
(*stack[j]).run_many(num);
}
for (int i = 0; i < num; ++i)
{
result[i] = m_state[i];
}
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::GetConstant ( std::string const &  name)

If a constant with the specified name exists, it returns the NekDouble value that the constant stores. If the constant doesn't exist, it throws an exception.

Definition at line 338 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, Nektar::StdRegions::find(), and m_constantsParser.

{
NekDouble* value = find(m_constantsParser, name.c_str());
ASSERTL1(value != NULL, "Constant variable not found: " + name);
return *value;
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::GetParameter ( std::string const &  name)

If a parameter with the specified name exists, it returns the NekDouble value that the parameter stores. If the parameter doesn't exist, it throws an exception.

Definition at line 371 of file AnalyticExpressionEvaluator.cpp.

References ASSERTL1, m_parameter, and m_parameterMapNameToId.

{
ParameterMap::const_iterator it = m_parameterMapNameToId.find(name);
ASSERTL1(it != m_parameterMapNameToId.end(), "Parameter not found: " + name);
return m_parameter[ it->second ];
}
NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::GetTime ( ) const

Returns the total time spent in evaluation procedures, seconds.

Definition at line 381 of file AnalyticExpressionEvaluator.cpp.

References m_total_eval_time.

Referenced by Nektar::LibUtilities::Equation::GetTime().

{
}
template<typename StepType >
EvaluationStep* Nektar::LibUtilities::AnalyticExpressionEvaluator::makeStep ( ci  dest,
ci  src_left = 0,
ci  src_right = 0 
)
inlineprivate

Factory method which makes code little less messy.

Definition at line 455 of file AnalyticExpressionEvaluator.hpp.

References m_constant, m_generator, m_parameter, m_state, and m_variable.

{
return ( new StepType ( m_generator,m_state,m_constant,m_parameter,m_variable,dest,src_left,src_right ) );
}
AnalyticExpressionEvaluator::PrecomputedValue Nektar::LibUtilities::AnalyticExpressionEvaluator::PrepareExecutionAsYouParse ( const ParsedTreeIterator root,
ExecutionStack stack,
VariableMap varMap,
int  stateIndex 
)
private

This method prepares the execution stack (an ordered sequence of operators that perform the evaluation) for the parsed evaluation tree.

In order to do this, it unrolls binary tree representing the recursive evaluation into an ordered sequence of commands. That ordered sequence of commands is equivalent to bottom-up walk up the evaluation tree, but this allows not to form tree explicitly.

This approach requires to introduce explicitly an execution state (memory) shared by commands in the evaluation sequence: recursively dependent commands need to pass data between each other. Such state for the recursive evaluation is passed via return values of a recursive evaluation function — which is bad if one wants to implement vectorized evaluator.

On the other hand, to run through a sequential container of functors is faster than to walk the tree and at each node to check the node type.

root - iterator generated by boost::spirit; stack - initially empty sequential container of evaluation steps; varMap - maps variable names to their ids; stateIndex - an index in state[] array where an evaluation step corresponding to the current tree node is allowed to write. an std::pair<bool, NekDouble> which encodes fully pre-evaluated NekDouble value as pair <true, value> if all sub-tree down the current node evaluates to constant, or flags the opposite via pair <false,0>.

Definition at line 677 of file AnalyticExpressionEvaluator.cpp.

References AddConstant(), ASSERTL0, ASSERTL1, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::constantID, E_ABS, E_ACOS, E_ASIN, E_ATAN, E_AWGN, E_CEIL, E_COS, E_COSH, E_EXP, E_FABS, E_FLOOR, E_LOG, E_LOG10, E_SIGN, E_SIN, E_SINH, E_SQRT, E_TAN, E_TANH, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::factorID, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::functionID, m_constant, m_constantMapNameToId, m_function, m_functionMapNameToInstanceType, m_parameterMapNameToId, m_state_size, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::numberID, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::operatorID, Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::parameterID, and Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::variableID.

Referenced by DefineFunction().

{
std::string valueStr(location->value.begin(), location->value.end());
boost::algorithm::trim(valueStr);
const parser_id parserID = location->value.id();
#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
const int num_children = location->children.size();
#endif
{
ASSERTL1(num_children == 0, "Illegal children under constant node: " + valueStr);
ConstantMap::const_iterator it = m_constantMapNameToId.find(valueStr);
ASSERTL1(it != m_constantMapNameToId.end(), "Cannot find the value for the specified constant: " + valueStr);
return std::make_pair(true, m_constant[it->second]);
}
else if (parserID == AnalyticExpression::numberID)
{
ASSERTL1(num_children == 0, "Illegal children under number node: " + valueStr);
return std::make_pair(true, boost::lexical_cast<NekDouble>(valueStr.c_str()) );
}
else if (parserID == AnalyticExpression::variableID)
{
ASSERTL1(num_children == 0, "Illegal children under variable node: " + valueStr);
VariableMap::const_iterator it = variableMap.find(valueStr);
ASSERTL1(it != variableMap.end(), "Unknown variable parsed: " + valueStr);
// Variables are not defined at the time of this parse.
stack.push_back ( makeStep<StoreVar>( stateIndex, it->second ) );
return std::make_pair(false, 0);
}
else if (parserID == AnalyticExpression::parameterID)
{
ASSERTL1(num_children == 0, "Illegal children under parameter node: " + valueStr);
ParameterMap::const_iterator it = m_parameterMapNameToId.find(valueStr);
ASSERTL1(it != m_parameterMapNameToId.end(), "Unknown parameter parsed: " + valueStr);
// Parameters may change in between of evalutions.
stack.push_back ( makeStep<StorePrm>( stateIndex, it->second ) );
return std::make_pair(false, 0);
}
else if (parserID == AnalyticExpression::functionID)
{
FunctionNameMap::const_iterator it = m_functionMapNameToInstanceType.find(valueStr);
ASSERTL1(it != m_functionMapNameToInstanceType.end(), "Invalid function specified: " + valueStr);
ASSERTL1(num_children == 1, "Function " + valueStr + " would like to have too few or too many arguments. This is not implemented yet");
PrecomputedValue v = PrepareExecutionAsYouParse(location->children.begin(), stack, variableMap, stateIndex);
// additive white gaussian noise function
if (it->second == E_AWGN)
{
int const_index = AddConstant(std::string("SUB_EXPR_") + boost::lexical_cast<std::string>(m_constant.size()), v.second);
stack.push_back ( makeStep<StoreConst>( stateIndex, const_index ) );
stack.push_back ( makeStep<EvalAWGN>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
}
// if precomputed value is valid, return function(value).
if (true == v.first)
{
return std::make_pair( true, m_function[it->second](v.second) );
}
// if somewhere down the parse tree there is a variable or parameter, set up an
// evaluation sequence.
switch (it->second)
{
case E_ABS:
stack.push_back ( makeStep<EvalAbs>( stateIndex, stateIndex) );
return std::make_pair(false,0);
case E_ASIN:
stack.push_back ( makeStep<EvalAsin>( stateIndex, stateIndex) );
return std::make_pair(false,0);
case E_ACOS:
stack.push_back ( makeStep<EvalAcos>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_ATAN:
stack.push_back ( makeStep<EvalAtan>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_CEIL:
stack.push_back ( makeStep<EvalCeil>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_COS:
stack.push_back ( makeStep<EvalCos>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_COSH:
stack.push_back ( makeStep<EvalCosh>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_EXP:
stack.push_back ( makeStep<EvalExp>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_FABS:
stack.push_back ( makeStep<EvalFabs>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_FLOOR:
stack.push_back ( makeStep<EvalFloor>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_LOG:
stack.push_back ( makeStep<EvalLog>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_LOG10:
stack.push_back ( makeStep<EvalLog10>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_SIN:
stack.push_back ( makeStep<EvalSin>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_SINH:
stack.push_back ( makeStep<EvalSinh>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_SQRT:
stack.push_back ( makeStep<EvalSqrt>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_TAN:
stack.push_back ( makeStep<EvalTan>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_TANH:
stack.push_back ( makeStep<EvalTanh>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
case E_SIGN:
stack.push_back ( makeStep<EvalSign>( stateIndex, stateIndex ) );
return std::make_pair(false,0);
default:
ASSERTL0(false, "Evaluation of " + valueStr + " is not implemented yet");
}
return std::make_pair(false,0);
}
else if (parserID == AnalyticExpression::factorID)
{
ASSERTL1(*valueStr.begin() == '-', "Illegal factor - it can only be '-' and it was: " + valueStr);
ASSERTL1(num_children == 1, "Illegal number of children under factor node: " + valueStr);
PrecomputedValue v = PrepareExecutionAsYouParse(location->children.begin(), stack, variableMap, stateIndex);
// if precomputed value is valid, process it further.
if (true == v.first)
{
return std::make_pair( true, - v.second );
}
stack.push_back (makeStep<EvalNeg>( stateIndex, stateIndex) );
return std::make_pair(false,0);
}
else if (parserID == AnalyticExpression::operatorID)
{
ASSERTL1(num_children == 2, "Too few or too many arguments for mathematical operator: " + valueStr);
PrecomputedValue left = PrepareExecutionAsYouParse(location->children.begin()+0, stack, variableMap, stateIndex);
PrecomputedValue right = PrepareExecutionAsYouParse(location->children.begin()+1, stack, variableMap, stateIndex+1);
// if both precomputed values are valid, process them further.
if ((true == left.first) && (true == right.first))
{
switch(*valueStr.begin())
{
case '+':
return std::make_pair( true, left.second + right.second );
case '-':
return std::make_pair( true, left.second - right.second );
case '*':
return std::make_pair( true, left.second * right.second );
case '/':
return std::make_pair( true, left.second / right.second );
case '^':
return std::make_pair( true, std::pow(left.second, right.second) );
case '=':
return std::make_pair( true, left.second == right.second );
case '<':
if (*(valueStr.end()-1) == '=')
{
return std::make_pair( true, left.second <= right.second );
}
else
{
return std::make_pair( true, left.second < right.second );
}
return std::make_pair(false,0);
case '>':
if (*(valueStr.end()-1) == '=')
{
return std::make_pair( true, left.second >= right.second );
}
else
{
return std::make_pair( true, left.second > right.second );
}
return std::make_pair(false,0);
default:
ASSERTL0(false, "Invalid operator encountered: " + valueStr);
}
return std::make_pair(false,0);
}
// either operator argument is not fully evaluated
// add pre-evaluated value to the contaner of constants
if (true == left.first)
{
int const_index = AddConstant(std::string("SUB_EXPR_") + boost::lexical_cast<std::string>(m_constant.size()), left.second);
stack.push_back ( makeStep<StoreConst>( stateIndex, const_index ) );
}
if (true == right.first)
{
int const_index = AddConstant(std::string("SUB_EXPR_") + boost::lexical_cast<std::string>(m_constant.size()), right.second);
stack.push_back ( makeStep<StoreConst>( stateIndex+1, const_index ) );
}
switch(*valueStr.begin())
{
case '+':
stack.push_back (makeStep<EvalSum>( stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '-':
stack.push_back (makeStep<EvalSub> (stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '*':
stack.push_back (makeStep<EvalMul>( stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '/':
stack.push_back (makeStep<EvalDiv>( stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '^':
stack.push_back (makeStep<EvalPow>( stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '=':
stack.push_back (makeStep<EvalLogicalEqual>( stateIndex, stateIndex, stateIndex+1 ) );
return std::make_pair(false,0);
case '<':
if (*(valueStr.end()-1) == '=')
{
stack.push_back (makeStep<EvalLogicalLeq>( stateIndex, stateIndex, stateIndex+1 ) );
}
else
{
stack.push_back (makeStep<EvalLogicalLess>( stateIndex, stateIndex, stateIndex+1 ) );
}
return std::make_pair(false,0);
case '>':
if (*(valueStr.end()-1) == '=')
{
stack.push_back (makeStep<EvalLogicalGeq>( stateIndex, stateIndex, stateIndex+1 ) );
}
else
{
stack.push_back (makeStep<EvalLogicalGreater>( stateIndex, stateIndex, stateIndex+1 ) );
}
return std::make_pair(false,0);
default:
ASSERTL0(false, "Invalid operator encountered: " + valueStr);
}
return std::make_pair(false,0);
}
ASSERTL0(false, "Illegal expression encountered: " + valueStr);
return std::make_pair(false,0);
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::SetParameter ( std::string const &  name,
NekDouble  value 
)

This function behaves in the same way as SetParameters, but it only adds one parameter and it does not delete the others. If the parameter existed previously, it will be overridden and replaced with the new value. If it did not exist previously, it will be added to the current parameters.

Definition at line 355 of file AnalyticExpressionEvaluator.cpp.

References m_parameter, and m_parameterMapNameToId.

Referenced by Nektar::LibUtilities::Equation::SetParameter(), and SetParameters().

{
ParameterMap::const_iterator it = m_parameterMapNameToId.find(name);
if (it == m_parameterMapNameToId.end())
{
m_parameter.push_back(value);
}
else
{
// if parameter is known, change its value
m_parameter[ it->second ] = value;
}
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::SetParameters ( std::map< std::string, NekDouble > const &  params)

Parameters are like constants, but they are inserted into the function at the time Evaluate is called instead of when the function is parsed. This function can be called at any time, and it will take effect in the next call to Evaluate. This function will delete all of the parameters, and replace all of them with only the ones in the map argument.

Definition at line 347 of file AnalyticExpressionEvaluator.cpp.

References SetParameter().

{
for (std::map<std::string, NekDouble>::const_iterator it = params.begin(); it != params.end(); it++)
{
SetParameter(it->first, it->second);
}
}
void Nektar::LibUtilities::AnalyticExpressionEvaluator::SetRandomSeed ( unsigned int  seed = 123u)

Definition at line 299 of file AnalyticExpressionEvaluator.cpp.

References m_generator.

{
m_generator.seed(seed);
}

Member Data Documentation

std::vector<NekDouble> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_constant
private

Definition at line 407 of file AnalyticExpressionEvaluator.hpp.

Referenced by AddConstant(), makeStep(), and PrepareExecutionAsYouParse().

ConstantMap Nektar::LibUtilities::AnalyticExpressionEvaluator::m_constantMapNameToId
private

Definition at line 403 of file AnalyticExpressionEvaluator.hpp.

Referenced by AddConstant(), and PrepareExecutionAsYouParse().

boost_spirit::symbols<NekDouble> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_constantsParser
private

This is a parser for spirit that parses the CONSTANT values. The default constants are those that are in math.h without the M_ prefix and they are initialized in the AnalyticExpressionEvaluator constructor.

Definition at line 294 of file AnalyticExpressionEvaluator.hpp.

Referenced by AddConstant(), DefineFunction(), and GetConstant().

std::vector<ExecutionStack> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_executionStack
private

Definition at line 377 of file AnalyticExpressionEvaluator.hpp.

Referenced by DefineFunction(), Evaluate(), EvaluateAtPoint(), EvaluateAtPoints(), and ~AnalyticExpressionEvaluator().

VariableMap Nektar::LibUtilities::AnalyticExpressionEvaluator::m_expressionVariableMap
private

Definition at line 404 of file AnalyticExpressionEvaluator.hpp.

std::map<int, OneArgFunc> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_function
private

Definition at line 440 of file AnalyticExpressionEvaluator.hpp.

Referenced by AnalyticExpressionEvaluator(), and PrepareExecutionAsYouParse().

FunctionNameMap Nektar::LibUtilities::AnalyticExpressionEvaluator::m_functionMapNameToInstanceType
private

Definition at line 439 of file AnalyticExpressionEvaluator.hpp.

Referenced by AnalyticExpressionEvaluator(), and PrepareExecutionAsYouParse().

RandomGeneratorType Nektar::LibUtilities::AnalyticExpressionEvaluator::m_generator
private

Definition at line 428 of file AnalyticExpressionEvaluator.hpp.

Referenced by makeStep(), and SetRandomSeed().

std::vector<NekDouble> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_parameter
private

Definition at line 406 of file AnalyticExpressionEvaluator.hpp.

Referenced by GetParameter(), makeStep(), and SetParameter().

ParameterMap Nektar::LibUtilities::AnalyticExpressionEvaluator::m_parameterMapNameToId
private

The following data structures hold input data to be used on evaluation stage. There are three types of input data:

Definition at line 402 of file AnalyticExpressionEvaluator.hpp.

Referenced by GetParameter(), PrepareExecutionAsYouParse(), and SetParameter().

ExpressionMap Nektar::LibUtilities::AnalyticExpressionEvaluator::m_parsedMapExprToExecStackId
private

These vector and map store pre-processed evaluation sequences for the analytic expressions. Each ExecutionStack is an ordered container of steps of sequential execution process which evaluates an analytic expression.

Definition at line 376 of file AnalyticExpressionEvaluator.hpp.

Referenced by DefineFunction().

std::vector<VariableMap> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_stackVariableMap
private

Keeping map of variables individually per each analytic expression allows correctly handling expressions which depend on different number of variables.

Definition at line 383 of file AnalyticExpressionEvaluator.hpp.

Referenced by DefineFunction(), EvaluateAtPoint(), and EvaluateAtPoints().

std::vector<NekDouble> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_state
private

This vector stores the execution state (memory) used by the sequential execution process.

Definition at line 413 of file AnalyticExpressionEvaluator.hpp.

Referenced by Evaluate(), EvaluateAtPoint(), EvaluateAtPoints(), and makeStep().

int Nektar::LibUtilities::AnalyticExpressionEvaluator::m_state_size
private

This counter is used by PrepareExecutionAsYouParse for finding the minimal state size necessary for evaluation of function parsed.

Definition at line 420 of file AnalyticExpressionEvaluator.hpp.

Referenced by AnalyticExpressionEvaluator(), DefineFunction(), and PrepareExecutionAsYouParse().

std::vector<int> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_state_sizes
private

Vector of state sizes per each.

Definition at line 416 of file AnalyticExpressionEvaluator.hpp.

Referenced by DefineFunction(), Evaluate(), EvaluateAtPoint(), and EvaluateAtPoints().

Timer Nektar::LibUtilities::AnalyticExpressionEvaluator::m_timer
private

Timer and sum of evaluation times.

Definition at line 424 of file AnalyticExpressionEvaluator.hpp.

Referenced by Evaluate(), EvaluateAtPoint(), and EvaluateAtPoints().

NekDouble Nektar::LibUtilities::AnalyticExpressionEvaluator::m_total_eval_time
private

Definition at line 425 of file AnalyticExpressionEvaluator.hpp.

Referenced by Evaluate(), EvaluateAtPoint(), EvaluateAtPoints(), and GetTime().

std::vector<NekDouble> Nektar::LibUtilities::AnalyticExpressionEvaluator::m_variable
private

Definition at line 408 of file AnalyticExpressionEvaluator.hpp.

Referenced by Evaluate(), EvaluateAtPoint(), EvaluateAtPoints(), and makeStep().