Skip to content

Commit 900dff0

Browse files
author
Dilawar Singh
committed
If a symbol already exists, do not add it again. Fixed typo.
1 parent c4b221e commit 900dff0

File tree

4 files changed

+314
-261
lines changed

4 files changed

+314
-261
lines changed

builtins/Function.cpp

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ const Cinfo * Function::initCinfo()
115115
&Function::getDoEvalAtReinit
116116
);
117117

118+
static ValueFinfo< Function, bool > allowUnknownVariable(
119+
"allowUnknownVariable",
120+
"When *false*, expression can only have ci, xi, yi and t."
121+
"When set to *true*, expression can have arbitrary names."
122+
"Defaults to *true*. \n",
123+
&Function::setAllowUnknownVariable,
124+
&Function::getAllowUnknowVariable
125+
);
126+
118127
static ElementValueFinfo< Function, string > expr(
119128
"expr",
120129
"Mathematical expression defining the function. The underlying parser\n"
@@ -258,6 +267,7 @@ const Cinfo * Function::initCinfo()
258267
&mode,
259268
&useTrigger,
260269
&doEvalAtReinit,
270+
&allowUnknownVariable,
261271
&expr,
262272
&numVars,
263273
&inputs,
@@ -324,8 +334,9 @@ Function::Function():
324334
, mode_(1)
325335
, useTrigger_(false)
326336
, doEvalAtReinit_(false)
337+
, allowUnknownVar_(true)
327338
, t_(0.0)
328-
, independent_("x0")
339+
, independent_("t")
329340
, stoich_(nullptr)
330341
, parser_(shared_ptr<moose::MooseParser>(new moose::MooseParser()))
331342
{
@@ -345,6 +356,8 @@ Function& Function::operator=(const Function& rhs)
345356
value_ = rhs.value_;
346357
mode_ = rhs.mode_;
347358
useTrigger_ = rhs.useTrigger_;
359+
doEvalAtReinit_ = rhs.doEvalAtReinit_;
360+
allowUnknownVar_ = rhs.allowUnknownVar_;
348361
t_ = rhs.t_;
349362
rate_ = rhs.rate_;
350363

@@ -357,16 +370,18 @@ Function& Function::operator=(const Function& rhs)
357370
parser_->ClearAll();
358371
if(rhs.parser_->GetExpr().size() > 0)
359372
{
373+
// These are alreay indexed. So its OK to add them by name.
360374
for(auto x: rhs.xs_)
361-
addXByName(x->getName());
375+
{
376+
xs_.push_back(shared_ptr<Variable>(new Variable(x->getName())));
377+
varIndex_[x->getName()] = xs_.size()-1;
378+
}
379+
// Add all the Ys now.
362380
for(size_t i=0; i < rhs.ys_.size(); i++)
363-
addY(i);
364-
parser_->DefineVar("t", &t_);
381+
ys_.push_back(shared_ptr<double>(new double(0.0)));
382+
parser_->LinkVariables(xs_, ys_, &t_);
365383
parser_->SetExpr(rhs.parser_->GetExpr());
366384
}
367-
368-
numVar_ = rhs.numVar_;
369-
370385
return *this;
371386
}
372387

@@ -388,6 +403,9 @@ void Function::addXByIndex(const unsigned int index)
388403
{
389404
// We have only xi's in xs_.
390405
string name = 'x'+to_string(index);
406+
if(symbolExists(name))
407+
return;
408+
391409
if(index >= xs_.size())
392410
{
393411
for(size_t i = xs_.size(); i <= index; i++)
@@ -403,20 +421,14 @@ void Function::addXByIndex(const unsigned int index)
403421

404422
void Function::addXByName(const string& name)
405423
{
424+
if(symbolExists(name))
425+
return;
406426
xs_.push_back(shared_ptr<Variable>(new Variable(name)));
407427
parser_->DefineVar(name, xs_.back()->ref());
408428
varIndex_[name] = xs_.size()-1;
409429
numVar_ = varIndex_.size();
410430
}
411431

412-
void Function::addCustomVariable(const string& name)
413-
{
414-
if(name == "t")
415-
parser_->DefineVar("t", &t_);
416-
else
417-
addXByName(name);
418-
}
419-
420432
void Function::addY(const unsigned int index)
421433
{
422434
string name = 'y'+to_string(index);
@@ -446,20 +458,18 @@ void Function::addVariable(const string& name)
446458

447459
if(XVAR_INDEX == vtype)
448460
{
449-
addXByName(name);
461+
addXByIndex(stoul(name.substr(1)));
450462
return;
451463
}
452-
453464
if(XVAR_NAMED == vtype)
454465
{
455-
addCustomVariable(name);
466+
addXByName(name);
456467
return;
457468
}
458469

459470
if(YVAR == vtype)
460471
{
461-
size_t index = (size_t)stoull(name.substr(1).c_str());
462-
addY(index);
472+
addY(stoul(name.substr(1)));
463473
return;
464474
}
465475

@@ -471,7 +481,8 @@ void Function::addVariable(const string& name)
471481

472482
if(CONSTVAR == vtype)
473483
{
474-
// These are constants. Don't add them.
484+
// These are constants. Don't add them. We don't know there value just
485+
// yet.
475486
return;
476487
}
477488

@@ -533,7 +544,7 @@ void Function::setExpr(const Eref& eref, const string expression)
533544

534545
try
535546
{
536-
valid_ = innerSetExpr(eref, expr, true);
547+
valid_ = innerSetExpr(eref, expr);
537548
}
538549
catch(moose::Parser::ParserException& e)
539550
{
@@ -547,7 +558,7 @@ void Function::setExpr(const Eref& eref, const string expression)
547558
/* --------------------------------------------------------------------------*/
548559
/**
549560
* @Synopsis Set expression in the parser. This function support two mode:
550-
* with dynamic lookup and without it. When `dynamicLookup` is set to true,
561+
* with dynamic lookup and without it. When `dynamicLookup_` is set to true,
551562
* unknown variables are created at the compile time. Otherwise, an error is
552563
* raised.
553564
*
@@ -559,10 +570,18 @@ void Function::setExpr(const Eref& eref, const string expression)
559570
* @Returns True if compilation was successful.
560571
*/
561572
/* ----------------------------------------------------------------------------*/
562-
bool Function::innerSetExpr(const Eref& eref, const string expr, bool dynamicLookup)
573+
bool Function::innerSetExpr(const Eref& eref, const string expr)
563574
{
564575
ASSERT_FALSE(expr.empty(), "Empty expression not allowed here.");
565576

577+
// NOTE: Don't clear the expression here. Sometime the user extend the
578+
// expression by calling this function agian. For example:
579+
//
580+
// >>> f.expr = 'x0+x2'
581+
// >>> # connect x0 and x2
582+
// >>> f.expr += '+ 100+y0'
583+
// >>> # connect more etc.
584+
566585
// First, set the xi, yi and t to the symbol table.
567586
set<string> xs;
568587
set<string> ys;
@@ -571,7 +590,7 @@ bool Function::innerSetExpr(const Eref& eref, const string expr, bool dynamicLoo
571590
for(auto &y : ys) addY(std::stoul(y.substr(1)));
572591
addVariable("t");
573592

574-
if(dynamicLookup)
593+
if(allowUnknownVar_)
575594
return parser_->SetExprWithUnknown(expr, this);
576595

577596
// If we are here that mean we have only xi, yi and t in the expression.
@@ -620,6 +639,17 @@ bool Function::getDoEvalAtReinit() const
620639
return doEvalAtReinit_;
621640
}
622641

642+
void Function::setAllowUnknownVariable(bool value )
643+
{
644+
allowUnknownVar_ = value;
645+
}
646+
647+
bool Function::getAllowUnknowVariable() const
648+
{
649+
return allowUnknownVar_;
650+
}
651+
652+
623653
double Function::getValue() const
624654
{
625655
return parser_->Eval( );
@@ -728,6 +758,11 @@ unsigned int Function::getVarIndex(string name) const
728758
return varIndex_.at(name);
729759
}
730760

761+
bool Function::symbolExists(const string& name) const
762+
{
763+
return varIndex_.find(name) != varIndex_.end();
764+
}
765+
731766
void Function::process(const Eref &e, ProcPtr p)
732767
{
733768
if(! valid_)
@@ -822,3 +857,11 @@ void Function::reinit(const Eref &e, ProcPtr p)
822857
return;
823858
}
824859
}
860+
861+
862+
void Function::clearAll()
863+
{
864+
xs_.clear();
865+
ys_.clear();
866+
varIndex_.clear();
867+
}

builtins/Function.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Function
3535
static const Cinfo * initCinfo();
3636

3737
void setExpr(const Eref& e, const string expr);
38-
bool innerSetExpr(const Eref& e, const string expr, bool dynamicLookup=true);
38+
bool innerSetExpr(const Eref& e, const string expr);
3939

4040
string getExpr(const Eref& e) const;
4141

@@ -64,6 +64,9 @@ class Function
6464
void setDoEvalAtReinit(bool doEvalAtReinit);
6565
bool getDoEvalAtReinit() const;
6666

67+
void setAllowUnknownVariable(bool value);
68+
bool getAllowUnknowVariable() const;
69+
6770
void setNumVar(unsigned int num);
6871
unsigned int getNumVar() const;
6972

@@ -94,15 +97,17 @@ class Function
9497
// Add unknown variable.
9598
void callbackAddSymbol(const string& name);
9699

100+
bool symbolExists(const string& name) const;
101+
97102
void addXByIndex(const unsigned int index);
98103
void addXByName(const string& name);
99104

100105
void addY(const unsigned int index);
101106

102-
void addCustomVariable(const string& name);
103-
104107
VarType getVarType(const string& name) const;
105108

109+
void clearAll();
110+
106111
protected:
107112

108113
bool valid_;
@@ -113,6 +118,7 @@ class Function
113118
unsigned int mode_;
114119
bool useTrigger_;
115120
bool doEvalAtReinit_;
121+
bool allowUnknownVar_;
116122

117123
double t_; // local storage for current time
118124
string independent_; // To take derivative.

kinetics/ReadKkit.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,12 @@ Id makeStandardElements( Id pa, const string& modelname )
132132
if ( mgr == Id() )
133133
mgr = shell->doCreate( "Neutral", pa, modelname, 1, MooseGlobal );
134134
Id kinetics( modelPath + "/kinetics" );
135-
if ( kinetics == Id() ) {
136-
kinetics = shell->doCreate( "CubeMesh", mgr, "kinetics", 1, MooseGlobal );
135+
if ( kinetics == Id() )
136+
{
137+
kinetics = shell->doCreate( "CubeMesh", mgr, "kinetics", 1, MooseGlobal );
137138
SetGet2< double, unsigned int >::set( kinetics, "buildDefaultMesh", 1e-15, 1 );
138-
Id cInfo = shell->doCreate( "Annotator", kinetics, "info", 1 );
139-
assert( cInfo != Id() );
139+
Id cInfo = shell->doCreate( "Annotator", kinetics, "info", 1 );
140+
assert( cInfo != Id() );
140141
}
141142
assert( kinetics != Id() );
142143

@@ -1167,6 +1168,8 @@ void ReadKkit::buildSumTotal( const string& src, const string& dest )
11671168
if ( destId.element()->cinfo()->name() == "Pool" )
11681169
{
11691170
sumId = shell_->doCreate( "Function", destId, "func", 1 );
1171+
Field< bool >::set( sumId, "allowUnknownVariable", false );
1172+
11701173
// Turn dest into a FuncPool.
11711174
destId.element()->zombieSwap( BufPool::initCinfo() );
11721175

@@ -1255,12 +1258,12 @@ Id ReadKkit::buildChan( const vector< string >& args )
12551258
//
12561259
double permeability = atof( args[ chanMap_["perm"] ].c_str() );
12571260
Id chan = shell_->doCreate( "ConcChan", pa, tail, 1 );
1258-
// Convert from perm in uM in GENESIS, to mM for MOOSE.
1259-
Field< double >::set( chan, "permeability", permeability *1000.0 );
1261+
// Convert from perm in uM in GENESIS, to mM for MOOSE.
1262+
Field< double >::set( chan, "permeability", permeability *1000.0 );
12601263
assert( chan != Id() );
12611264
string chanPath = clean.substr( 10 );
12621265
chanIds_[ chanPath ] = chan;
1263-
Id info = buildInfo( chan, chanMap_, args );
1266+
Id info = buildInfo( chan, chanMap_, args );
12641267
return chan;
12651268
}
12661269

0 commit comments

Comments
 (0)