Skip to content

Commit fd1f29e

Browse files
James CraigJames Craig
authored andcommitted
v492 - YEAR in conditions; named constants in FEWS; bug fix
support for YEAR in control structure and water managemetn operating conditions (ControlStructures.cpp;DemandExpressionHandling.cpp) support for named constants and target stage in FEWS runinfo file (ParseFEWSRunInfo.cpp) include version # and build date in Raven_errors.txt (RavenMain.cpp) (B. Tolson suggestion) bug fixes: -Proper check for leap year in DateStringToTimeStruct() (CommonFunctions.cpp) (found by M. Revel) clean up/cosmetic: -renamed GetDemandOptimizer() to GetManagementOptimizer (Model.cpp/.h;ParseManagementFile.cpp;ParseTimeSeriesFile.cpp;Solvers.cpp;WaterDemands.cpp) -advisory for calling :OutputDirectory instead of using -o flag (ParseInput.cpp)
1 parent 0585bf2 commit fd1f29e

15 files changed

+101
-41
lines changed

src/CommonFunctions.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,10 @@ time_struct DateStringToTimeStruct(const string sDate, string sTime, const int c
442442
if (tt.month==12){tt.julian_day+=30;}
443443
if ((tt.leap_yr ) && (tt.month> 2)){tt.julian_day+= 1;}
444444

445-
if (tt.day_of_month > DAYS_PER_MONTH[tt.month - 1]) {
445+
int leap=0;
446+
if (tt.leap_yr){leap=1;}
447+
448+
if (tt.day_of_month > (DAYS_PER_MONTH[tt.month - 1]+leap)) {
446449
ExitGracefully("DateStringToTimeStruct: Invalid time format used - exceeded max day of month",BAD_DATA);
447450
}
448451
if (tt.day_of_month <=0 ) {

src/ControlStructures.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ void COutflowRegime::AddRegimeConstraint(RegimeConstraint* pCond)
210210
//
211211
bool EvaluateCondition(const comparison cond, const double& v, const double& v1, const double& v2)
212212
{
213-
if (cond==COMPARE_IS_EQUAL ){return (v==v1); }
214-
else if (cond==COMPARE_NOT_EQUAL ){return (v!=v1); }
213+
if (cond==COMPARE_IS_EQUAL ){return fabs(v-v1)<REAL_SMALL; }
214+
else if (cond==COMPARE_NOT_EQUAL ){return fabs(v-v1)>REAL_SMALL; }
215215
else if (cond==COMPARE_GREATERTHAN){return (v>v1); }
216216
else if (cond==COMPARE_LESSTHAN ){return (v<v1); }
217-
else if (cond==COMPARE_BETWEEN ){return (v>=v1) && (v<=v2); }
217+
else if (cond==COMPARE_BETWEEN ){return (v>=v1) && (v<=v2); }//inclusive
218218
return false;
219219
}
220220

@@ -236,6 +236,9 @@ bool COutflowRegime::AreConditionsMet(const time_struct& tt) const
236236
if (var == "DATE") {
237237
if (!EvaluateCondition(comp, tt.model_time, v1, v2)) {return false;}
238238
}
239+
else if (var == "YEAR") {
240+
if (!EvaluateCondition(comp, (double)(tt.year), v1, v2)) {return false;}
241+
}
239242
else if ((var == "DOY") || (var=="DAY_OF_YEAR")) {
240243
if (comp!=COMPARE_BETWEEN){
241244
if (!EvaluateCondition(comp, tt.julian_day, v1, v2)) {return false;}

src/DemandExpressionHandling.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,10 @@ bool CDemandOptimizer::CheckOpRegimeConditions(const op_regime *pOperRegime, con
10831083
{
10841084
dv_value=(double)(tt.month);
10851085
}
1086+
else if (pCond->dv_name == "YEAR")
1087+
{
1088+
dv_value = (double)(tt.year);
1089+
}
10861090
else if (pCond->dv_name == "DATE")
10871091
{
10881092
dv_value=0;

src/DemandOptimization.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct decision_var
7979
//
8080
struct exp_condition
8181
{
82-
string dv_name; //< decision variable name (e.g., Q1023) or "MONTH" or "DATE" or "DAY_OF_YEAR"
82+
string dv_name; //< decision variable name (e.g., Q1023) or "MONTH" or "DATE" or "DAY_OF_YEAR" or "YEAR"
8383
double value; //< conditional value
8484
double value2; //< second conditional (if COMPARE_BETWEEN)
8585
string date_string; //< conditional value (if date)

src/ForcingGrid.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ void CForcingGrid::ForcingGridInit(const optStruct &Options)
466466
// -------------------------------
467467
// add time shift to data
468468
// --> only applied when _interval < 1.0 (daily)
469-
// --> otherwise ignored and warning written to RavenErrors.txt
469+
// --> otherwise ignored and warning written to Raven_errors.txt
470470
// -------------------------------
471471
if (_interval >= 1.0) { // data are not sub-daily
472472
if ( ceil(_TimeShift) == _TimeShift) { // time shift of whole days requested

src/Model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ CEnsemble *CModel::GetEnsemble() const { return _pEnsemble; }
976976
/// \brief Returns demand optimizer
977977
/// \return pointer to demand optimizer
978978
//
979-
CDemandOptimizer *CModel::GetDemandOptimizer() const { return _pDO; }
979+
CDemandOptimizer *CModel::GetManagementOptimizer() const { return _pDO; }
980980

981981
/*****************************************************************
982982
Watershed Diagnostic Functions

src/Model.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ class CModel: public CModelABC
439439
CTransportModel *GetTransportModel () const;
440440
CGroundwaterModel *GetGroundwaterModel () const;
441441
CEnsemble *GetEnsemble () const;
442-
CDemandOptimizer *GetDemandOptimizer () const;
442+
CDemandOptimizer *GetManagementOptimizer () const;
443443

444444
void GetParticipatingParamList (string *aP,
445445
class_type *aPC,

src/ParseFEWSRunInfo.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,52 @@ bool ParseNetCDFRunInfoFile(CModel *&pModel, optStruct &Options, bool runname_ov
279279
if(Options.noisy) { cout << "ParseRunInfoFile: read properties:AssimilateStreamflow from NetCDF: " << (!strcmp(boolean,"true")) << endl; }
280280
delete[] boolean;
281281
}
282+
283+
// Other attributes with info embedded in attribute name
284+
int nAttributes;
285+
char att_name[NC_MAX_NAME];
286+
double att_value;
287+
retval = nc_inq_varnatts(ncid,varid_props,&nAttributes);
288+
if (retval==NC_NOERR){
289+
for (int i = 0; i < nAttributes; i++) {
290+
retval=nc_inq_attname(ncid,varid_props,i,att_name);
291+
if (retval==NO_ERROR){
292+
string att_name_s=to_string(att_name);
293+
294+
// NamedConstant(s) ----------------------------------------------------
295+
296+
if (att_name_s.substr(0, 14) == "NamedConstant_") {
297+
string name=att_name_s.substr(14,att_name_s.length());
298+
299+
retval=nc_get_att_double(ncid,varid_props,att_name,&att_value);
300+
301+
cout<<"RUN INFO NAMED CONSTANT = "<<name<<" value = "<<att_value <<endl;
302+
303+
pModel->GetManagementOptimizer()->AddUserConstant(att_name,att_value);
304+
}
305+
306+
// TargetStageSet_ ----------------------------------------------------
307+
308+
if (att_name_s.substr(0, 15) == "TargetStageSet_") {
309+
string SBID_s=att_name_s.substr(15,att_name_s.length());
310+
long long SBID=s_to_ll(SBID_s.c_str());
311+
312+
retval = nc_inq_attlen(ncid, varid_props, att_name, &att_len);
313+
char* boolean = new char[att_len + 1];
314+
retval = nc_get_att_text(ncid,varid_props,att_name,boolean); HandleNetCDFErrors(retval);// read attribute text
315+
boolean[att_len] = '\0';// add string determining character
316+
317+
if (!strcmp(boolean,"true")) {
318+
319+
// LOOK for User Time Series
320+
//pModel->GetManagementOptimizer()->LookForTargetStageInUserTS(SBID);
321+
// creates !hSBID = @ts("TargetStage_SBID",0) management goal , ensures units correction applied
322+
ExitGracefully("RUN INFO FILE - TARGET STAGE SET ",STUB);
323+
}
324+
}
325+
}
326+
}
327+
}
282328
}
283329
else {
284330
WriteWarning("ParseNetCDFRunInfoFile: Properties variable not found",Options.noisy);
@@ -306,7 +352,7 @@ bool ParseNetCDFRunInfoFile(CModel *&pModel, optStruct &Options, bool runname_ov
306352
// The index i of each entry will be the same as that used by the matrix in part 3.
307353
// 3) One or more matrices of size[1:time,1:stations] which includes the state variable being updated,using the
308354
// same indexing[i=1:stations] as the vector of HRUIDs. Blank values will not be updated. Raven model HRUs with IDs
309-
// not in this list will not be updated. HRUIDs in this list but not in Raven model will throw a warning to RavenErrors.txt.
355+
// not in this list will not be updated. HRUIDs in this list but not in Raven model will throw a warning to Raven_errors.txt.
310356
// The naming convention of this attribute is equivalent to the raven state variable tag,e.g.,SNOW,PONDED_WATER,SOIL[0].
311357
// The state variable corresponding to the model start time will be used for initialization; all other values in the time vector are ignored
312358
// Note : this ONLY looks for state variables that are in model, all other state variable arrays will be ignored
@@ -498,7 +544,7 @@ bool ParseNetCDFStateFile(CModel *&pModel,const optStruct &Options)
498544
// The index i of each entry will be the same as that used by the matrix in part 3.
499545
// 3) One or more matrices of size[1:time,1:stations] which includes the flow/stage state variable being initialized,using the
500546
// same indexing[i=1:stations] as the vector of SBIDs. Blank values will not be updated. Raven model subbasins with IDs
501-
// not in this list will not be updated. SBIDs in this list but not in Raven model will throw a warning to RavenErrors.txt.
547+
// not in this list will not be updated. SBIDs in this list but not in Raven model will throw a warning to Raven_errors.txt.
502548
// .The state variable corresponding to the model start time will be used for initialization of flow/stage; all other values in the time vector are ignored
503549
// The naming convention of this attribute is one of: {QOUT, STAGE, }
504550
//

src/ParseInput.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,10 @@ bool ParseMainInputFile (CModel *&pModel,
15101510
Options.main_output_dir=Options.output_dir;
15111511
PrepareOutputdirectory(Options);
15121512

1513-
ofstream WARNINGS((Options.main_output_dir+"Raven_errors.txt").c_str());
1513+
ofstream WARNINGS((Options.main_output_dir+"Raven_errors.txt").c_str()); //This means RavenErrors.txt was also created in default directory
15141514
WARNINGS.close();
1515+
1516+
WriteAdvisory("ParseInput: recommended practice is to specify the output directory from the command line, rather than using the :OutputDirectory command.",Options.noisy);
15151517
}
15161518
else {
15171519
WriteWarning("ParseMainInputFile: :OutputDirectory command was ignored because directory was specified from command line.",Options.noisy);

src/ParseManagementFile.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ bool ParseManagementFile(CModel *&pModel,const optStruct &Options)
9595
}
9696
int nWildcards=0;
9797

98-
CDemandOptimizer *pDO=pModel->GetDemandOptimizer();
98+
CDemandOptimizer *pDO=pModel->GetManagementOptimizer();
9999

100100
pDO->Initialize(pModel,Options); //only requires rvh,.rvt read
101101

@@ -968,7 +968,7 @@ bool ParseManagementFile(CModel *&pModel,const optStruct &Options)
968968
pDemand=new CDemand(demand_ID,demand_name,demandSBID,false,pModel);
969969
pDemand->SetLocalIndex(demand_ind);
970970
pSB->AddWaterDemand(pDemand);
971-
pModel->GetDemandOptimizer()->AddWaterDemand(pDemand);
971+
pModel->GetManagementOptimizer()->AddWaterDemand(pDemand);
972972
}
973973
else {
974974
ExitGracefully("Invalid subbasin ID in :WaterDemand command header.",BAD_DATA_WARN);
@@ -1172,7 +1172,7 @@ bool ParseManagementFile(CModel *&pModel,const optStruct &Options)
11721172
pDemand=new CDemand(demand_ID,demand_name,demandSBID,true,pModel);
11731173
pDemand->SetLocalIndex(demand_ind);
11741174
pSB->GetReservoir()->AddDemand(pDemand);
1175-
pModel->GetDemandOptimizer()->AddWaterDemand(pDemand);
1175+
pModel->GetManagementOptimizer()->AddWaterDemand(pDemand);
11761176
}
11771177
else
11781178
{
@@ -1213,7 +1213,7 @@ bool ParseManagementFile(CModel *&pModel,const optStruct &Options)
12131213
CTimeSeries *pTimeSer;
12141214
if(Options.noisy) { cout <<"User-specified Time Series"<<endl; }
12151215
pTimeSer=CTimeSeries::Parse(pp,true,s[1], DOESNT_EXIST, "none", Options);
1216-
pModel->GetDemandOptimizer()->AddUserTimeSeries(pTimeSer);
1216+
pModel->GetManagementOptimizer()->AddUserTimeSeries(pTimeSer);
12171217
break;
12181218
}
12191219
default://------------------------------------------------

0 commit comments

Comments
 (0)