Skip to content

Commit 709d7d5

Browse files
James CraigJames Craig
authored andcommitted
v505: fix assimilation time lag; @dLookUp()
repair to Assimilate to remove time lag (Assimilate.cpp) new @dLookUp() function (DemandExpressionHandling.cpp;Expression.h) clean up: deleted duplicative TermTypeToSstring() function (DemandExpressionHandling.cpp) use :SeasonalCanopyHeight in Raven .rvp template (ParsePropertyFile.cpp)
1 parent 684cea7 commit 709d7d5

File tree

5 files changed

+69
-35
lines changed

5 files changed

+69
-35
lines changed

src/Assimilate.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,16 @@ void CModel::AssimilationOverride(const int p,const optStruct& Options,const tim
9090
//---------------------------------------------------------------------
9191
if(_aDAoverride[p])
9292
{
93-
double Qobs,Qmod;
93+
double Qobs,Qmod,Qmodlast;
9494
double alpha = _pGlobalParams->GetParams()->assimilation_fact;
9595

9696
Qobs = _aDAobsQ[p];
97-
//Option A: mean flow
98-
//Qmod = _pSubBasins[p]->GetIntegratedOutflow(Options.timestep)/(Options.timestep*SEC_PER_DAY);
99-
//Option B: instantaneous flow
10097
Qmod = _pSubBasins[p]->GetOutflowRate();
98+
Qmodlast= _pSubBasins[p]->GetLastOutflowRate();
10199
if(Qmod>PRETTY_SMALL) {
102100
_aDAscale [p]=1.0+alpha*((Qobs-Qmod)/Qmod); //if alpha = 1, Q=Qobs in observation basin
103-
_aDAQadjust[p]=alpha*(Qobs-Qmod);
101+
//_aDAQadjust[p]=alpha*(Qobs-Qmod);//Option A: instantaneous flow
102+
_aDAQadjust[p]=alpha*(2.0*Qobs-Qmodlast-Qmod);//Option B: mean flow
104103
}
105104
else {
106105
_aDAscale [p]=1.0;
@@ -166,7 +165,7 @@ void CModel::PrepareAssimilation(const optStruct &Options,const time_struct &tt)
166165
{
167166
if(IsContinuousFlowObs2(_pObservedTS[i],_pSubBasins[p]->GetID()))//flow observation is available and linked to this subbasin
168167
{
169-
Qobs = _pObservedTS[i]->GetSampledValue(nn); //end of timestep flow
168+
Qobs = _pObservedTS[i]->GetSampledValue(nn); //mean timestep flow
170169

171170
//bool fakeblank=((tt.model_time>30) && (tt.model_time<40)) || ((tt.model_time>45) && (tt.model_time<47));//TMP DEBUG
172171
//if (fakeblank){Qobs=RAV_BLANK_DATA;}

src/DemandExpressionHandling.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
}
301282
string 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);

src/DemandOptimization.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
void SummarizeExpression(const char **s, const int Len, expressionStruct* exp); //defined in DemandExpressionHandling.cpp
1313
string DVTypeToString(dv_type t);
14-
string TermTypeToString(termtype t);
14+
string expTypeToString(termtype &t);
1515

1616
//////////////////////////////////////////////////////////////////
1717
/// \brief Implementation of the Demand optimization constructor
@@ -880,7 +880,7 @@ void CDemandOptimizer::InitializePostRVMRead(CModel* pModel, const optStruct& Op
880880
expressionTerm* term=new expressionTerm();
881881
if (ConvertToExpressionTerm(_pNonLinVars[i]->target, term, 0, "internal")) {
882882
_pNonLinVars[i]->DV_index=term->DV_ind-1; //using 0 indexing for dv rateher than lp 1 indexing
883-
//cout<<" NONLINEAR TARGET FOUND : "<<term->DV_ind-1<<" "<<term->origexp<<" "<<TermTypeToString(term->type)<<endl;
883+
//cout<<" NONLINEAR TARGET FOUND : "<<term->DV_ind-1<<" "<<term->origexp<<" "<<expTypeToString(term->type)<<endl;
884884
}
885885
else {
886886
string warn="ManagementOptimization:Initialize cannot convert target '"+_pNonLinVars[i]->target+"' of non-linear variable to decision variable";
@@ -2092,7 +2092,8 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
20922092
if (fabs(_aSolverResiduals[j])>REAL_SMALL)
20932093
cout<<" -"<<_aSolverRowNames[j] << " " << _aSolverResiduals[j] << endl;
20942094
}
2095-
2095+
2096+
//lp_lib::print_debugdump(pLinProg, dumpfile.c_str());
20962097
WriteLPSubMatrix(pLinProg,"overconstrained_lp_matrix.csv",Options);
20972098
ExitGracefully("SolveManagementProblem: non-optimal solution found. Problem is over-constrained. Remove or adjust management constraints.",RUNTIME_ERR);
20982099
}

src/Expression.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/*----------------------------------------------------------------
2+
Raven Library Source Code
3+
Copyright (c) 2008-2025 the Raven Development Team
4+
----------------------------------------------------------------
5+
enum termtype
6+
expressionTerm struct
7+
expressionStruct structure
8+
----------------------------------------------------------------*/
19
#include "RavenInclude.h"
210
#include "TimeSeries.h"
311
#include "LookupTable.h"
@@ -11,6 +19,7 @@ enum termtype
1119
TERM_DV, //< decision variable !Q123 or named
1220
TERM_TS, //< time series @ts(name,n)
1321
TERM_LT, //< lookup table @lookup(x)
22+
TERM_DLT, //< lookup table derivative @dlookup(x)
1423
TERM_HRU, //< state variable @HRU_var(SNOW,2345)
1524
TERM_SB, //< state variable @SB_var(SNOW,234)
1625
TERM_CONST, //< constant

src/ParsePropertyFile.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,18 +2059,18 @@ void CreateRVPTemplate(string *aP,class_type *aPC,int &nP,const optStruct &Opti
20592059
for(int ii=0;ii<nP;ii++)
20602060
{
20612061
if((aPC[ii]==CLASS_VEGETATION) && (aP[ii]!="RELATIVE_LAI")){
2062-
TEMPLATE<<":SeasonalRelativeLAI"<<endl;
2062+
TEMPLATE<<":SeasonalCanopyLAI"<<endl;
20632063
TEMPLATE<<" *VEGET_1*, *J*,*F*,*M*,*A*,*M*,*J*,*J*,*A*,*S*,*O*,*N*,*D*"<<endl;
2064-
TEMPLATE<<":EndSeasonalRelativeLAI"<<endl;
2064+
TEMPLATE<<":EndSeasonalCanopyLAI"<<endl;
20652065
break;
20662066
}
20672067
}
20682068
for(int ii=0;ii<nP;ii++)
20692069
{
20702070
if((aPC[ii]==CLASS_VEGETATION) && (aP[ii]!="RELATIVE_HT")){
2071-
TEMPLATE<<":SeasonalRelativeHeight"<<endl;
2071+
TEMPLATE<<":SeasonalCanopyHeight"<<endl;
20722072
TEMPLATE<<" *VEGET_1*, *J*,*F*,*M*,*A*,*M*,*J*,*J*,*A*,*S*,*O*,*N*,*D*"<<endl;
2073-
TEMPLATE<<":EndSeasonalRelativeHeight"<<endl;
2073+
TEMPLATE<<":EndSeasonalCanopyHeight"<<endl;
20742074
break;
20752075
}
20762076
}

0 commit comments

Comments
 (0)