MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Function.cpp
Go to the documentation of this file.
1 // Function.cpp ---
2 //
3 // Filename: Function.cpp
4 // Description: Implementation of a wrapper around muParser.
5 // Author: Subhasis Ray
6 // Maintainer: Subhasis Ray
7 // Created: Sat May 25 16:35:17 2013 (+0530)
8 // Version:
9 // Last-Updated: Tue Jun 11 16:49:01 2013 (+0530)
10 // By: subha
11 // Update #: 619
12 // URL:
13 // Keywords:
14 // Compatibility:
15 //
16 //
17 
18 // Commentary:
19 //
20 //
21 //
22 //
23 
24 // Change log:
25 //
26 //
27 //
28 //
29 // This program is free software; you can redistribute it and/or
30 // modify it under the terms of the GNU Lesser General Public License as
31 // published by the Free Software Foundation; either version 3, or
32 // (at your option) any later version.
33 //
34 // This program is distributed in the hope that it will be useful,
35 // but WITHOUT ANY WARRANTY; without even the implied warranty of
36 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 // General Public License for more details.
38 //
39 // You should have received a copy of the GNU Lesser General Public License
40 // along with this program; see the file COPYING. If not, write to
41 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth
42 // Floor, Boston, MA 02110-1301, USA.
43 //
44 //
45 
46 // Code:
47 
48 #include "header.h"
49 #include "../utility/utility.h"
50 #include "../utility/numutil.h"
51 #include "Variable.h"
52 
53 #include "Function.h"
54 #include "ElementValueFinfo.h"
55 
56 #define PARSER_MAXVARS 100
57 
58 
59 static const double TriggerThreshold = 0.0;
60 
62 {
63  static SrcFinfo1<double> valueOut("valueOut",
64  "Evaluated value of the function for the current variable values.");
65  return &valueOut;
66 }
67 
69 {
70  static SrcFinfo1< double > derivativeOut("derivativeOut",
71  "Value of derivative of the function for the current variable values");
72  return &derivativeOut;
73 }
74 
76 {
77  static SrcFinfo1< double > rateOut("rateOut",
78  "Value of time-derivative of the function for the current variable values");
79  return &rateOut;
80 }
81 
83 {
85  "requestOut",
86  "Sends request for input variable from a field on target object");
87  return &requestOut;
88 
89 }
90 
92 {
94  // Value fields
97  "value",
98  "Result of the function evaluation with current variable values.",
100  static ReadOnlyValueFinfo< Function, double > derivative(
101  "derivative",
102  "Derivative of the function at given variable values. This is calulated"
103  " using 5-point stencil "
104  " <http://en.wikipedia.org/wiki/Five-point_stencil> at current value of"
105  " independent variable. Note that unlike hand-calculated derivatives,"
106  " numerical derivatives are not exact.",
109  "rate",
110  "Derivative of the function at given variable values. This is computed"
111  " as the difference of the current and previous value of the function"
112  " divided by the time step.",
115  "mode",
116  "Mode of operation: \n"
117  " 1: only the function value will be sent out.\n"
118  " 2: only the derivative with respect to the independent variable will be sent out.\n"
119  " 3: only rate (time derivative) will be sent out.\n"
120  " anything else: all three, value, derivative and rate will be sent out.\n",
123  static ValueFinfo< Function, bool > useTrigger(
124  "useTrigger",
125  "When *false*, disables event-driven calculation and turns on "
126  "Process-driven calculations. \n"
127  "When *true*, enables event-driven calculation and turns off "
128  "Process-driven calculations. \n"
129  "Defaults to *false*. \n",
132  static ValueFinfo< Function, bool > doEvalAtReinit(
133  "doEvalAtReinit",
134  "When *false*, disables function evaluation at reinit, and "
135  "just emits a value of zero to any message targets. \n"
136  "When *true*, does a function evaluation at reinit and sends "
137  "the computed value to any message targets. \n"
138  "Defaults to *false*. \n",
142  "expr",
143  "Mathematical expression defining the function. The underlying parser\n"
144  "is muParser. In addition to the available functions and operators from\n"
145  "muParser, some more functions are added.\n"
146  "\nFunctions\n"
147  "Name args explanation\n"
148  "sin 1 sine function\n"
149  "cos 1 cosine function\n"
150  "tan 1 tangens function\n"
151  "asin 1 arcus sine function\n"
152  "acos 1 arcus cosine function\n"
153  "atan 1 arcus tangens function\n"
154  "sinh 1 hyperbolic sine function\n"
155  "cosh 1 hyperbolic cosine\n"
156  "tanh 1 hyperbolic tangens function\n"
157  "asinh 1 hyperbolic arcus sine function\n"
158  "acosh 1 hyperbolic arcus tangens function\n"
159  "atanh 1 hyperbolic arcur tangens function\n"
160  "log2 1 logarithm to the base 2\n"
161  "log10 1 logarithm to the base 10\n"
162  "log 1 logarithm to the base 10\n"
163  "ln 1 logarithm to base e (2.71828...)\n"
164  "exp 1 e raised to the power of x\n"
165  "sqrt 1 square root of a value\n"
166  "sign 1 sign function -1 if x<0; 1 if x>0\n"
167  "rint 1 round to nearest integer\n"
168  "abs 1 absolute value\n"
169  "min var. min of all arguments\n"
170  "max var. max of all arguments\n"
171  "sum var. sum of all arguments\n"
172  "avg var. mean value of all arguments\n"
173  "rand 1 rand(seed), random float between 0 and 1, \n"
174  " if seed = -1, then a 'random' seed is created.\n"
175  "rand2 3 rand(a, b, seed), random float between a and b, \n"
176  " if seed = -1, a 'random' seed is created using either\n"
177  " by random_device or by reading system clock\n"
178  "\nOperators\n"
179  "Op meaning priority\n"
180  "= assignment -1\n"
181  "&& logical and 1\n"
182  "|| logical or 2\n"
183  "<= less or equal 4\n"
184  ">= greater or equal 4\n"
185  "!= not equal 4\n"
186  "== equal 4\n"
187  "> greater than 4\n"
188  "< less than 4\n"
189  "+ addition 5\n"
190  "- subtraction 5\n"
191  "* multiplication 6\n"
192  "/ division 6\n"
193  "^ raise x to the power of y 7\n"
194  "% floating point modulo 7\n"
195  "\n"
196  "?: if then else operator C++ style syntax\n",
199  );
200 
202  "numVars",
203  "Number of variables used by Function.",
206  );
207 
209  "x",
210  "Input variables to the function. These can be passed via messages.",
215  );
216 
218  "c",
219  "Constants used in the function. These must be assigned before"
220  " specifying the function expression.",
223 
225  "y",
226  "Variable values received from target fields by requestOut",
227  &Function::getY);
228 
229  static ValueFinfo< Function, string > independent(
230  "independent",
231  "Index of independent variable. Differentiation is done based on this. Defaults"
232  " to the first assigned variable.",
235 
237  // Shared messages
239  static DestFinfo process( "process",
240  "Handles process call, updates internal time stamp.",
242  static DestFinfo reinit( "reinit",
243  "Handles reinit call.",
245  static Finfo* processShared[] = { &process, &reinit };
246 
247  static SharedFinfo proc( "proc",
248  "This is a shared message to receive Process messages "
249  "from the scheduler objects."
250  "The first entry in the shared msg is a MsgDest "
251  "for the Process operation. It has a single argument, "
252  "ProcInfo, which holds lots of information about current "
253  "time, thread, dt and so on. The second entry is a MsgDest "
254  "for the Reinit operation. It also uses ProcInfo. ",
255  processShared, sizeof( processShared ) / sizeof( Finfo* )
256  );
257  /*
258  static DestFinfo trigger( "trigger",
259  "Handles trigger input. Argument is timestamp of event. This is "
260  "compatible with spike events as well as chemical ones. ",
261  new OpFunc1< Function, double >( &Function::trigger ) );
262  */
263 
264  static Finfo *functionFinfos[] =
265  {
266  &value,
267  &rate,
268  &derivative,
269  &mode,
270  &useTrigger,
271  &doEvalAtReinit,
272  &expr,
273  &numVars,
274  &inputs,
275  &constants,
276  &independent,
277  &proc,
278  requestOut(),
279  valueOut(),
280  rateOut(),
281  derivativeOut(),
282  };
283 
284  static string doc[] =
285  {
286  "Name", "Function",
287  "Author", "Subhasis Ray",
288  "Description",
289  "General purpose function calculator using real numbers.\n"
290  "It can parse mathematical expression defining a function and evaluate"
291  " it and/or its derivative for specified variable values."
292  "You can assign expressions of the form::\n"
293  "\n"
294  "f(c0, c1, ..., cM, x0, x1, ..., xN, y0,..., yP ) \n"
295  "\n"
296  " where `ci`'s are constants and `xi`'s and `yi`'s are variables."
297 
298  "The constants must be defined before setting the expression and"
299  " variables are connected via messages. The constants can have any"
300  " name, but the variable names must be of the form x{i} or y{i}"
301  " where i is increasing integer starting from 0.\n"
302  " The variables can be input from other moose objects."
303  " Such variables must be named `x{i}` in the expression and the source"
304  " field is connected to Function.x[i]'s `input` destination field.\n"
305  " In case the input variable is not available as a source field, but is"
306  " a value field, then the value can be requested by connecting the"
307  " `requestOut` message to the `get{Field}` destination on the target"
308  " object. Such variables must be specified in the expression as y{i}"
309  " and connecting the messages should happen in the same order as the"
310  " y indices.\n"
311  " This class handles only real numbers (C-double). Predefined constants"
312  " are: pi=3.141592..., e=2.718281..."
313  };
314 
315  static Dinfo< Function > dinfo;
316  static Cinfo functionCinfo("Function",
318  functionFinfos,
319  sizeof(functionFinfos) / sizeof(Finfo*),
320  &dinfo,
321  doc,
322  sizeof(doc)/sizeof(string));
323  return &functionCinfo;
324 
325 }
326 
328 
329 Function::Function(): _t(0.0), _valid(false), _numVar(0), _lastValue(0.0),
330  _value(0.0), _rate(0.0), _mode(1),
331  _useTrigger( false ), _doEvalAtReinit( false ), _stoich(0)
332 {
333  _parser.SetVarFactory(_functionAddVar, this);
334  _independent = "x0";
335  //extendMuParser( );
336 
337  // Adding this default expression by default to avoid complains from GUI
338  try{
339  _parser.SetExpr("0");
340  } catch (mu::Parser::exception_type &e) {
341  _showError(e);
342  _clearBuffer();
343  return;
344  }
345  _valid = true;
346 }
347 
348 #if 0
349 void Function::extendMuParser( void )
350 {
351  // Adding pi and e, the defaults are `_pi` and `_e`
352  _parser.DefineConst(_T("pi"), (mu::value_type)M_PI);
353  _parser.DefineConst(_T("e"), (mu::value_type)M_E);
354  // Add support
355  _parser.DefineVar( _T("t"), &this->_t );
356  _parser.DefineOprt( _T("%"), &Function::muCallbackFMod, 7, mu::EOprtAssociativity::oaRIGHT, 0);
357 }
358 #endif
359 
360 Function::Function(const Function& rhs): _numVar(rhs._numVar),
361  _lastValue(rhs._lastValue),
362  _value(rhs._value), _rate(rhs._rate),
363  _mode(rhs._mode),
364  _useTrigger( rhs._useTrigger),
365  _stoich(0)
366 {
367  static Eref er;
369 
370  _parser.SetVarFactory(_functionAddVar, this);
371  //extendMuParser( );
372 
373  // Copy the constants
374  mu::valmap_type cmap = rhs._parser.GetConst();
375  if (cmap.size()){
376  mu::valmap_type::const_iterator item = cmap.begin();
377  for (; item!=cmap.end(); ++item){
378  _parser.DefineConst(item->first, item->second);
379  }
380  }
381 
382 
383  setExpr(er, rhs.getExpr( er ));
384  // Copy the values from the var pointers in rhs
385  assert(_varbuf.size() == rhs._varbuf.size());
386  for (unsigned int ii = 0; ii < rhs._varbuf.size(); ++ii){
387  _varbuf[ii]->value = rhs._varbuf[ii]->value;
388  }
389  assert(_pullbuf.size() == rhs._pullbuf.size());
390  for (unsigned int ii = 0; ii < rhs._pullbuf.size(); ++ii){
391  *_pullbuf[ii] = *(rhs._pullbuf[ii]);
392  }
393 }
394 
396 {
397  static Eref er;
398  _clearBuffer();
399  _mode = rhs._mode;
400  _lastValue = rhs._lastValue;
401  _value = rhs._value;
402  _rate = rhs._rate;
404  // Adding pi and e, the defaults are `_pi` and `_e`
405  _parser.DefineConst(_T("pi"), (mu::value_type)M_PI);
406  _parser.DefineConst(_T("e"), (mu::value_type)M_E);
407  // Copy the constants
408  mu::valmap_type cmap = rhs._parser.GetConst();
409  if (cmap.size()){
410  mu::valmap_type::const_iterator item = cmap.begin();
411  for (; item!=cmap.end(); ++item){
412  _parser.DefineConst(item->first, item->second);
413  }
414  }
415  // Copy the values from the var pointers in rhs
416  setExpr(er, rhs.getExpr( er ));
417  assert(_varbuf.size() == rhs._varbuf.size());
418  for (unsigned int ii = 0; ii < rhs._varbuf.size(); ++ii){
419  _varbuf[ii]->value = rhs._varbuf[ii]->value;
420  }
421  assert(_pullbuf.size() == rhs._pullbuf.size());
422  for (unsigned int ii = 0; ii < rhs._pullbuf.size(); ++ii){
423  *_pullbuf[ii] = *(rhs._pullbuf[ii]);
424  }
425  return *this;
426 }
427 
429 {
430  _clearBuffer();
431  }
432 
433 // do not know what to do about Variables that have already been
434 // connected by message.
436 {
437  _numVar = 0;
438  _parser.ClearVar();
439  for (unsigned int ii = 0; ii < _varbuf.size(); ++ii){
440  if ( _varbuf[ii] ){
441  delete _varbuf[ii];
442  }
443  }
444  _varbuf.clear();
445  for (unsigned int ii = 0; ii < _pullbuf.size(); ++ii){
446  if ( _pullbuf[ii] ){
447  delete _pullbuf[ii];
448  }
449  }
450  _pullbuf.clear();
451 }
452 
453 void Function::_showError(mu::Parser::exception_type &e) const
454 {
455  cout << "Error occurred in parser.\n"
456  << "Message: " << e.GetMsg() << "\n"
457  << "Formula: " << e.GetExpr() << "\n"
458  << "Token: " << e.GetToken() << "\n"
459  << "Position: " << e.GetPos() << "\n"
460  << "Error code: " << e.GetCode() << endl;
461 }
462 
482 double * _functionAddVar(const char *name, void *data)
483 {
484  Function* function = reinterpret_cast< Function * >(data);
485  double * ret = NULL;
486  string strname(name);
487  // Names starting with x are variables, everything else is constant.
488  if (strname[0] == 'x'){
489  int index = atoi(strname.substr(1).c_str());
490  if ((unsigned)index >= function->_varbuf.size()){
491  function->_varbuf.resize(index+1, 0);
492  for (int ii = 0; ii <= index; ++ii){
493  if (function->_varbuf[ii] == 0){
494  function->_varbuf[ii] = new Variable();
495  }
496  }
497  function->_numVar = function->_varbuf.size();
498  }
499  ret = &(function->_varbuf[index]->value);
500  } else if (strname[0] == 'y'){
501  int index = atoi(strname.substr(1).c_str());
502  if ((unsigned)index >= function->_pullbuf.size()){
503  function->_pullbuf.resize(index+1, 0 );
504  for (int ii = 0; ii <= index; ++ii){
505  if (function->_pullbuf[ii] == 0){
506  function->_pullbuf[ii] = new double();
507  }
508  }
509  }
510  ret = function->_pullbuf[index];
511  } else if (strname == "t"){
512  ret = &function->_t;
513  } else {
514  cerr << "Got an undefined symbol: " << name << endl
515  << "Variables must be named xi, yi, where i is integer index."
516  << " You must define the constants beforehand using LookupField c: c[name]"
517  " = value"
518  << endl;
519  throw mu::ParserError("Undefined constant.");
520  }
521 
522  return ret;
523 }
524 
539 unsigned int Function::addVar()
540 {
541 // unsigned int newVarIndex = _numVar;
542 // ++_numVar;
543 // stringstream name;
544 // name << "x" << newVarIndex;
545 // _functionAddVar(name.str().c_str(), this);
546  // return newVarIndex;
547  return 0;
548 }
549 
550 // void Function::dropVar(unsigned int msgLookup)
551 // {
552 // // Don't know what this can possibly mean in the context of
553 // // evaluating a set expression.
554 // }
555 
556 void Function::setExpr(const Eref& eref, string expr)
557 {
558  this->innerSetExpr( eref, expr ); // Refer to the virtual function here.
559 }
560 
561 // Virtual function, this does the work.
562 void Function::innerSetExpr(const Eref& eref, string expr)
563 {
564  _valid = false;
565  _clearBuffer();
566  _varbuf.resize(_numVar);
567  // _pullbuf.resize(_num
568  mu::varmap_type vars;
569  try{
570  _parser.SetExpr(expr);
571  } catch (mu::Parser::exception_type &e) {
572  cerr << "Error setting expression on: " << eref.objId().path() << endl;
573  _showError(e);
574  _clearBuffer();
575  return;
576  }
577  // Force variable creation right away. Otherwise numVar does not
578  // get set properly
579  try{
580  _parser.Eval();
581  _valid = true;
582  } catch (mu::Parser::exception_type &e){
583  _showError(e);
584  }
585 }
586 
587 string Function::getExpr( const Eref& e ) const
588 {
589  if (!_valid){
590  cout << "Error: " << e.objId().path() << "::getExpr() - invalid parser state" << endl;
591  return "";
592  }
593  return _parser.GetExpr();
594 }
595 
596 void Function::setMode(unsigned int mode)
597 {
598  _mode = mode;
599 }
600 
601 unsigned int Function::getMode() const
602 {
603  return _mode;
604 }
605 
606 void Function::setUseTrigger(bool useTrigger )
607 {
608  _useTrigger = useTrigger;
609 }
610 
612 {
613  return _useTrigger;
614 }
615 
616 void Function::setDoEvalAtReinit(bool doEvalAtReinit )
617 {
618  _doEvalAtReinit = doEvalAtReinit;
619 }
620 
622 {
623  return _doEvalAtReinit;
624 }
625 
626 double Function::getValue() const
627 {
628  double value = 0.0;
629  if (!_valid){
630  cout << "Error: Function::getValue() - invalid state" << endl;
631  return value;
632  }
633  try{
634  value = _parser.Eval();
635  } catch (mu::Parser::exception_type &e){
636  _showError(e);
637  }
638  return value;
639 }
640 
641 double Function::getRate() const
642 {
643  if (!_valid){
644  cout << "Error: Function::getValue() - invalid state" << endl;
645  }
646  return _rate;
647 }
648 
649 void Function::setIndependent(string var)
650 {
651  _independent = var;
652 }
653 
655 {
656  return _independent;
657 }
658 
659 vector< double > Function::getY() const
660 {
661  vector < double > ret(_pullbuf.size());
662  for (unsigned int ii = 0; ii < ret.size(); ++ii){
663  ret[ii] = *_pullbuf[ii];
664  }
665  return ret;
666 }
667 
669 {
670  double value = 0.0;
671  if (!_valid){
672  cout << "Error: Function::getDerivative() - invalid state" << endl;
673  return value;
674  }
675  mu::varmap_type variables = _parser.GetVar();
676  mu::varmap_type::const_iterator item = variables.find(_independent);
677  if (item != variables.end()){
678  try{
679  value = _parser.Diff(item->second, *(item->second));
680  } catch (mu::Parser::exception_type &e){
681  _showError(e);
682  }
683  }
684  return value;
685 }
686 
687 void Function::setNumVar(const unsigned int num)
688 {
689  _clearBuffer();
690  for (unsigned int ii = 0; ii < num; ++ii){
691  stringstream name;
692  name << "x" << ii;
693  _functionAddVar(name.str().c_str(), this);
694  }
695 }
696 
697 unsigned int Function::getNumVar() const
698 {
699  return _numVar;
700 }
701 
702 void Function::setVar(unsigned int index, double value)
703 {
704  cout << "varbuf[" << index << "]->setValue(" << value << ")\n";
705  if (index < _varbuf.size()){
706  _varbuf[index]->setValue(value);
707  } else {
708  cerr << "Function: index " << index << " out of bounds." << endl;
709  }
710 }
711 
712 Variable * Function::getVar(unsigned int ii)
713 {
714  static Variable dummy;
715  if ( ii < _varbuf.size()){
716  return _varbuf[ii];
717  }
718  cout << "Warning: Function::getVar: index: "
719  << ii << " is out of range: "
720  << _varbuf.size() << endl;
721  return &dummy;
722 }
723 
724 void Function::setConst(string name, double value)
725 {
726  _parser.DefineConst(name, value);
727 }
728 
729 double Function::getConst(string name) const
730 {
731  mu::valmap_type cmap = _parser.GetConst();
732  if (cmap.size()){
733  mu::valmap_type::const_iterator it = cmap.find(name);
734  if (it != cmap.end()){
735  return it->second;
736  }
737  }
738  return 0;
739 }
740 
741 void Function::process(const Eref &e, ProcPtr p)
742 {
743  if (!_valid){
744  return;
745  }
746  vector < double > databuf;
747  requestOut()->send(e, &databuf);
748  for (unsigned int ii = 0;
749  (ii < databuf.size()) && (ii < _pullbuf.size());
750  ++ii){
751  *_pullbuf[ii] = databuf[ii];
752  }
753  _t = p->currTime;
754  _value = getValue();
755  _rate = (_value - _lastValue) / p->dt;
756  if ( _useTrigger && _value < TriggerThreshold ) {
757  _lastValue = _value;
758  return;
759  }
760  switch (_mode){
761  case 1: {
762  valueOut()->send(e, _value);
763  break;
764  }
765  case 2: {
766  derivativeOut()->send(e, getDerivative());
767  break;
768  }
769  case 3: {
770  rateOut()->send(e, _rate);
771  break;
772  }
773  default: {
774  valueOut()->send(e, _value);
775  derivativeOut()->send(e, getDerivative());
776  rateOut()->send(e, _rate);
777  break;
778  }
779  }
780  _lastValue = _value;
781 }
782 
783 void Function::reinit(const Eref &e, ProcPtr p)
784 {
785  if (!_valid){
786  cout << "Error: Function::reinit() - invalid parser state. Will do nothing." << endl;
787  return;
788  }
789  if (moose::trim(_parser.GetExpr(), " \t\n\r").length() == 0){
790  cout << "Error: no expression set. Will do nothing." << endl;
791  setExpr(e, "0.0");
792  _valid = false;
793  }
794  _t = p->currTime;
795  if (_doEvalAtReinit) {
796  _lastValue = _value = getValue();
797  } else {
798  _lastValue = _value = 0.0;
799  }
800  _rate = 0.0;
801  switch (_mode){
802  case 1: {
803  valueOut()->send(e, _value);
804  break;
805  }
806  case 2: {
807  derivativeOut()->send(e, 0.0);
808  break;
809  }
810  case 3: {
811  rateOut()->send(e, _rate);
812  break;
813  }
814  default: {
815  valueOut()->send(e, _value);
816  derivativeOut()->send(e, 0.0);
817  rateOut()->send(e, _rate);
818  break;
819  }
820  }
821 }
822 
823 #if 0
824 mu::value_type Function::muCallbackFMod( mu::value_type a, mu::value_type b)
825 {
826  cerr << "Callback: " << a << " " << b << endl;
827  return fmod(a, b);
828 }
829 #endif
830 
831 //
832 // Function.cpp ends here
bool getDoEvalAtReinit() const
Definition: Function.cpp:621
string _independent
Definition: Function.h:156
uint32_t value
Definition: moosemodule.h:42
virtual void innerSetExpr(const Eref &e, string expr)
Definition: Function.cpp:562
string getIndependent() const
Definition: Function.cpp:654
Function & operator=(const Function rhs)
Definition: Function.cpp:395
void setConst(string name, double value)
Definition: Function.cpp:724
static const double TriggerThreshold
Definition: Function.cpp:59
double _lastValue
Definition: Function.h:145
unsigned int addVar()
Definition: Function.cpp:539
double value_type
static SrcFinfo1< double > * valueOut()
Definition: Function.cpp:61
friend double * _functionAddVar(const char *name, void *data)
Definition: Function.cpp:482
double currTime
Definition: ProcInfo.h:19
Definition: Dinfo.h:60
vector< double * > _pullbuf
Definition: Function.h:154
double getDerivative() const
Definition: Function.cpp:668
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
void setUseTrigger(bool useTrigger)
Definition: Function.cpp:606
double _value
Definition: Function.h:146
void setMode(unsigned int mode)
Definition: Function.cpp:596
double * _functionAddVar(const char *name, void *data)
Definition: Function.cpp:482
void _showError(mu::Parser::exception_type &e) const
Definition: Function.cpp:453
double getRate() const
Definition: Function.cpp:641
double getValue() const
Definition: Function.cpp:626
static SrcFinfo1< double > * derivativeOut()
Definition: Function.cpp:68
#define M_PI
Definition: numutil.h:34
void setIndependent(string index)
Definition: Function.cpp:649
unsigned int getNumVar() const
Definition: Function.cpp:697
void setDoEvalAtReinit(bool doEvalAtReinit)
Definition: Function.cpp:616
void process(const Eref &e, ProcPtr p)
Definition: Function.cpp:741
vector< double > getY() const
Definition: Function.cpp:659
static const Cinfo * initCinfo()
Definition: Function.cpp:91
double _t
Definition: Function.h:142
unsigned int _numVar
Definition: Function.h:144
void _clearBuffer()
Definition: Function.cpp:435
bool _valid
Definition: Function.h:143
void setVar(unsigned int index, double value)
Definition: Function.cpp:702
string getExpr(const Eref &e) const
Definition: Function.cpp:587
string path() const
Definition: ObjId.cpp:119
vector< Variable * > _varbuf
Definition: Function.h:152
double dt
Definition: ProcInfo.h:18
ObjId objId() const
Definition: Eref.cpp:57
Definition: Eref.h:26
static const Cinfo * functionCinfo
Definition: Function.cpp:327
void setExpr(const Eref &e, string expr)
Definition: Function.cpp:556
static const Cinfo * initCinfo()
Definition: Variable.cpp:52
bool _useTrigger
Definition: Function.h:149
unsigned int _mode
Definition: Function.h:148
static char name[]
Definition: mfield.cpp:401
bool _doEvalAtReinit
Definition: Function.h:150
void reinit(const Eref &e, ProcPtr p)
Definition: Function.cpp:783
static SrcFinfo1< double > * rateOut()
Definition: Function.cpp:75
mu::Parser _parser
Definition: Function.h:157
#define M_E
Definition: numutil.h:38
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
std::string trim(const std::string myString, const string &delimiters)
Definition: strutil.cpp:53
Variable * getVar(unsigned int ii)
Definition: Function.cpp:712
unsigned int getMode() const
Definition: Function.cpp:601
double getConst(string name) const
Definition: Function.cpp:729
double _rate
Definition: Function.h:147
Definition: Cinfo.h:18
bool getUseTrigger() const
Definition: Function.cpp:611
void setNumVar(unsigned int num)
Definition: Function.cpp:687
Definition: Finfo.h:12
static SrcFinfo1< vector< double > * > * requestOut()
Definition: Function.cpp:82