@@ -279,25 +279,6 @@ int CDemandOptimizer::GetNumUserDVs() const
279279// ////////////////////////////////////////////////////////////////
280280// / \brief enum to string routines
281281//
282- string TermTypeToString (termtype t)
283- {
284- if (t==TERM_DV ){return " TERM_DV" ; }
285- if (t==TERM_TS ){return " TERM_TS" ; }
286- if (t==TERM_LT ){return " TERM_LT" ; }
287- if (t==TERM_HRU ){return " TERM_HRU" ;}
288- if (t==TERM_SB ){return " TERM_SB" ; }
289- if (t==TERM_CONST ){return " TERM_CONST" ; }
290- if (t==TERM_WORKFLOW){return " TERM_WORKFLOW" ; }
291- if (t==TERM_HISTORY ){return " TERM_HISTORY" ; }
292- if (t==TERM_ITER ){return " TERM_ITER" ; }
293- if (t==TERM_MAX ){return " TERM_MAX" ; }
294- if (t==TERM_MIN ){return " TERM_MIN" ; }
295- if (t==TERM_POW ){return " TERM_POW" ; }
296- if (t==TERM_CUMUL ){return " TERM_CUMUL" ;}
297- if (t==TERM_CUMUL_TS){return " TERM_CUMUL_TS" ;}
298- if (t==TERM_UNKNOWN ){return " TERM_UNKNOWN" ; }
299- return " TERM_UNKNOWN" ;
300- }
301282string DVTypeToString (dv_type t)
302283{
303284 if (t==DV_QOUT ){return " DV_QOUT" ; }
@@ -321,6 +302,7 @@ string expTypeToString(termtype &typ){
321302 case (TERM_DV): return " TERM_DV" ; break ;
322303 case (TERM_TS): return " TERM_TS" ; break ;
323304 case (TERM_LT): return " TERM_LT" ; break ;
305+ case (TERM_DLT): return " TERM_DLT" ; break ;
324306 case (TERM_CONST): return " TERM_CONST" ; break ;
325307 case (TERM_HRU): return " TERM_HRU" ; break ;
326308 case (TERM_SB): return " TERM_SB" ; break ;
@@ -333,7 +315,7 @@ string expTypeToString(termtype &typ){
333315 case (TERM_CUMUL): return " TERM_CUMUL" ; break ;
334316 case (TERM_UNKNOWN): return " TERM_UNKNOWN" ; break ;
335317 }
336- return " ? " ;
318+ return " TERM_UNKNOWN " ;
337319}
338320// ////////////////////////////////////////////////////////////////
339321// / \brief parses individual expression string and converts to expression term structure
@@ -644,6 +626,43 @@ bool CDemandOptimizer::ConvertToExpressionTerm(const string s, expressionTerm* t
644626 }
645627 }
646628 }
629+ // ----------------------------------------------------------------------
630+ else if (s.substr (0 , 9 ) == " @dlookup(" )// derivative of lookup table (e.g., @dlookup(my_table,EXPRESSION))
631+ {
632+ string name;
633+ string x_in;
634+ size_t is = s.find (" @dlookup(" );
635+ size_t ie = s.find (" ," ,is);
636+ size_t ip = s.find_last_of (" )" );
637+ if (ie == NPOS) {
638+ warn=" ConvertToExpressionTerm: missing comma in @dlookup expression" +warnstring;
639+ ExitGracefully (warn.c_str (),BAD_DATA_WARN);
640+ }
641+ if (ip == NPOS) {
642+ warn=" ConvertToExpressionTerm: missing end parentheses in @dlookup expression" +warnstring;
643+ ExitGracefully (warn.c_str (), BAD_DATA_WARN);
644+ }
645+ if ((is != NPOS) && (ie != NPOS))
646+ {
647+ bool found=false ;
648+ name = s.substr (is+9 ,ie-(is+9 ));
649+ x_in = s.substr (ie+1 ,ip-(ie+1 ));
650+ term->pLT =NULL ;
651+ for (int i = 0 ; i < _nUserLookupTables; i++) {
652+ if (StringToUppercase (_pUserLookupTables[i]->GetName ()) == StringToUppercase (name)) {
653+ term->pLT = _pUserLookupTables[i];
654+ found=true ;
655+ }
656+ }
657+ term->nested_exp1 =x_in;
658+ term->type =TERM_DLT;
659+ if (!found) {
660+ warn=" ConvertToExpression: unrecognized lookup table name in @dlookup command" +warnstring;
661+ ExitGracefully (warn.c_str (), BAD_DATA_WARN);
662+ return false ;
663+ }
664+ }
665+ }
647666 // ----------------------------------------------------------------------
648667 else if (s.substr (0 , 9 ) == " @HRU_var(" ) // HRU state var (e.g., @HRU_var(SNOW,[id])
649668 {
@@ -922,7 +941,7 @@ expressionStruct *CDemandOptimizer::ParseExpression(const char **s,
922941 if (!valid){return NULL ; }
923942
924943 // TMP DEBUG
925- // cout<<" TERM["<<k<<" in "<< j << "]: " << s[i] << " : type = " << TermTypeToString (terms[j][k]->type) << " index : " << terms[j][k]->DV_ind << endl;
944+ // cout<<" TERM["<<k<<" in "<< j << "]: " << s[i] << " : type = " << expTypeToString (terms[j][k]->type) << " index : " << terms[j][k]->DV_ind << endl;
926945
927946 if ((i>rhs_ind) && (k==0 )){terms[j][k]->mult *=-1.0 ; } // only multiply leading term by -1 to move to LHS
928947 if ((s[i-1 ][0 ]==' -' ) && (k==0 )){terms[j][k]->mult *=-1.0 ; } // and reverse if preceded with minus sign
@@ -1492,6 +1511,12 @@ double CDemandOptimizer::EvaluateTerm(expressionTerm **pTerms,const int k, const
14921511 x=EvaluateTerm (pTerms,kk,t);
14931512 return pT->pLT ->GetValue (x); // decision variable can't be in lookup table
14941513 }
1514+ else if (pT->type == TERM_DLT)
1515+ {
1516+ kk=pT->nested_ind1 ;
1517+ x=EvaluateTerm (pTerms,kk,t);
1518+ return pT->pLT ->GetSlope (x); // decision variable can't be in lookup table
1519+ }
14951520 else if (pT->type == TERM_HRU)
14961521 {
14971522 int i=pT->SV_index ;
@@ -1533,7 +1558,7 @@ double CDemandOptimizer::EvaluateTerm(expressionTerm **pTerms,const int k, const
15331558 else if (tmp==' h' ){return _ahhist[_aSBIndices[p]][nshift]; }
15341559 else if (tmp==' D' ){return _aDhist[_aSBIndices[p]][nshift]; }
15351560 else if (tmp==' I' ){return _aIhist[_aSBIndices[p]][nshift]; }
1536- else if (tmp==' B' ){return _pModel->GetSubBasin (p)->GetSpecifiedInflow (t+pT->timeshift *1.0 ); } // ASSUMES DAILY TIMESTEP!
1561+ else if (tmp==' B' ){return _pModel->GetSubBasin (p)->GetSpecifiedInflow (t+pT->timeshift *1.0 ); } // ASSUMES DAILY TIMESTEP! \todo[funct] should be Options.timestep
15371562 else if (tmp==' E' ){return _pModel->GetSubBasin (p)->GetEnviroMinFlow (t+pT->timeshift *1.0 ); } // ASSUMES DAILY TIMESTEP!
15381563 else {
15391564 ExitGracefully (" CDemandOptimizer::EvaluateTerm: Invalid history variable " ,BAD_DATA);
0 commit comments