Skip to content

Commit cd058c1

Browse files
James CraigJames Craig
authored andcommitted
v521 [BENCHMARKED] - added :TimeOfConcentrationMethod support
new :TimeOfConcentrationMethod - parse support (ParseInput.cpp) - new enum added to Options (RavenInclude.h) - new subbasin _basin_length and _mean_slope members (SubBasin.h/.cpp) - new routine CSubBasin::CalculateTOC (SubBasin.h/.cpp) bug fixes: added QA/QC for bad HRU index in reservoir parsing (ParseHRUFile.cpp) fixed destructor bug in CustomOutput.cpp
1 parent e6f5c82 commit cd058c1

File tree

6 files changed

+88
-8
lines changed

6 files changed

+88
-8
lines changed

src/CustomOutput.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ CCustomOutput::CCustomOutput( const diagnostic variable,
6262
_spaceAggStr ="UNKNOWN";
6363
_filename =filename_spec;
6464

65-
_nData =1;
65+
_nData =0;
6666
_aData =NULL; // pointer to data storage for aggregation
6767
_nDataItems =1;
6868

src/ParseHRUFile.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ bool ParseHRUPropsFile(CModel *&pModel, const optStruct &Options, bool terrain_r
361361
}
362362
pRes=ReservoirParse(pp,s[1],pModel,HRUID,Options);
363363
pSB=pModel->GetSubBasinByID(pRes->GetSubbasinID());
364-
if (HRUID!=DOESNT_EXIST){
364+
if ((HRUID!=DOESNT_EXIST) && (pModel->GetHRUByID(HRUID)!=NULL)){
365365
pRes->SetHRU(pModel->GetHRUByID(HRUID));
366366
}
367367
if (pSB!=NULL){pSB->AddReservoir(pRes);}
@@ -1937,10 +1937,15 @@ CReservoir *ReservoirParse(CParser *p,string name,const CModel *pModel,long long
19371937
ExitGracefullyIf(max_depth==DOESNT_EXIST,"CReservoir::Parse: :LakeDepth must be specified for lake-type reservoirs",BAD_DATA_WARN);
19381938

19391939
if (HRUID != DOESNT_EXIST) {
1940-
double HRUarea =pModel->GetHRUByID(HRUID)->GetArea() * M2_PER_KM2;
1941-
if (fabs((HRUarea - lakearea) / lakearea) > 0.2) {
1942-
string warn="CReservoirParse: specified :LakeArea and corresponding HRU area (in .rvh file) do not seem to agree for reservoir in subbasin "+to_string(SBID);
1943-
WriteWarning(warn.c_str(), Options.noisy);
1940+
if (pModel->GetHRUByID(HRUID)!=NULL){
1941+
double HRUarea =pModel->GetHRUByID(HRUID)->GetArea() * M2_PER_KM2;
1942+
if (fabs((HRUarea - lakearea) / lakearea) > 0.2) {
1943+
string warn="CReservoirParse: specified :LakeArea and corresponding HRU area (in .rvh file) do not seem to agree for reservoir in subbasin "+to_string(SBID);
1944+
WriteWarning(warn.c_str(), Options.noisy);
1945+
}
1946+
}
1947+
else {
1948+
ExitGracefullyIf(max_depth==DOESNT_EXIST,"CReservoir::Parse: invalid HRU ID in :Reservoir command",BAD_DATA_WARN);
19441949
}
19451950
}
19461951

src/ParseInput.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ bool ParseMainInputFile (CModel *&pModel,
276276
Options.interception_factor =PRECIP_ICEPT_USER;
277277
Options.recharge =RECHARGE_NONE;
278278
Options.snow_depletion =SNOWCOV_NONE;
279+
Options.TOC_method =TOC_MCDERMOTT_PILGRIM;
279280
Options.direct_evap =false;
280281
Options.keepUBCWMbugs =false;
281282
Options.suppressCompetitiveET =false;
@@ -486,6 +487,7 @@ bool ParseMainInputFile (CModel *&pModel,
486487
else if (!strcmp(s[0],":FEWSStateInfoFile" )){code=110;}
487488
else if (!strcmp(s[0],":FEWSParamInfoFile" )){code=111;}
488489
else if (!strcmp(s[0],":FEWSBasinStateInfoFile" )){code=112;}
490+
else if (!strcmp(s[0],":TimeOfConcentrationMethod" )){code=113;}
489491

490492
else if (!strcmp(s[0],":WriteGroundwaterHeads" )){code=510;}//GWMIGRATE -TO REMOVE
491493
else if (!strcmp(s[0],":WriteGroundwaterFlows" )){code=511;}//GWMIGRATE -TO REMOVE
@@ -1946,6 +1948,17 @@ bool ParseMainInputFile (CModel *&pModel,
19461948
Options.flowinfo_filename = CorrectForRelativePath(s[1], Options.rvi_filename);//with .nc extension!
19471949
break;
19481950
}
1951+
case(113): //
1952+
{/*:TimeOfConcentrationMethod [method]*/
1953+
if (Options.noisy) { cout << " Time of concentration method" << endl; }
1954+
if (Len<2){ImproperFormatWarning(":TimeOfConcentrationMethod",p,Options.noisy); break;}
1955+
if (!strcmp(s[1],"TOC_MCDERMOTT_PILGRIM")){Options.TOC_method=TOC_MCDERMOTT_PILGRIM;}
1956+
else if (!strcmp(s[1],"TOC_AIRPORT" )){Options.TOC_method=TOC_AIRPORT;}
1957+
else if (!strcmp(s[1],"TOC_BRANSBY_WILLIAMS" )){Options.TOC_method=TOC_BRANSBY_WILLIAMS;}
1958+
else if (!strcmp(s[1],"TOC_WILLIAMS_1922" )){Options.TOC_method=TOC_WILLIAMS_1922;}
1959+
else {ExitGracefully("ParseInput :TimeOfConcentrationMethod: Unrecognized method",BAD_DATA_WARN);}
1960+
break;
1961+
}
19491962
case(160): //--------------------------------------------
19501963
{/*:rvh_Filename [filename.rvh]*/
19511964
if(Options.noisy) { cout <<"rvh filename: "<<s[1]<<endl; }
@@ -2501,7 +2514,7 @@ bool ParseMainInputFile (CModel *&pModel,
25012514
}
25022515
case(215): //----------------------------------------------
25032516
{/*Flush
2504-
:Flush RAVEN_DEFAULT [state_var from] [state_var to] {Optional percentage}*/
2517+
:Flush RAVEN_DEFAULT [state_var from] [state_var to] {Optional percentage}*/
25052518
if (Options.noisy){cout <<"Flushing Process"<<endl;}
25062519
double pct=1.0;
25072520
if (Len<4){ImproperFormatWarning(":Flush",p,Options.noisy); break;}

src/RavenInclude.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ const double CM3_PER_METER3 =1e6;
126126
const double METER_PER_CM =0.01; ///< [cm] to [m]
127127
const double M2_PER_KM2 =1e6; ///< [km2] to [m2]
128128
const double MM2_PER_M2 =1e6; ///< [m2] to [mm2]
129+
const double HECTARE_PER_KM2 =100; ///< [km2] to [ha]
129130
const double M_PER_KM =1000; ///< [km] to [m]
130131
const double GRAMS_PER_KG =1000; ///< [kg] to [g]
131132
const double MG_PER_KG =1000000; ///< [kg] to [mg]
@@ -836,6 +837,15 @@ enum overflowmode
836837
OVERFLOW_NATURAL ///< uses stage discharge curve to calculate Q
837838
};
838839

840+
enum toc_method
841+
{
842+
TOC_MCDERMOTT_PILGRIM,///< uses Austrailian Rainfall and runoff guidelines [McDermott and Pilgrim (1982)] [DEFAULT]
843+
TOC_WILLIAMS_1922, ///< uses Williams (1922) [DEFAULT]
844+
TOC_AIRPORT, ///< uses Airport equation (MTO Drainage Management Manual, 1997)
845+
TOC_BRANSBY_WILLIAMS, ///< uses Bransby-Williams equation (MTO Drainage Management Manual, 1997)
846+
TOC_TEMEZ ///< uses Temez (1978)
847+
};
848+
839849
enum assimtype
840850
{
841851
DA_RAVEN_DEFAULT, ///< multiplicative scaling assimilation upstream propagation
@@ -1111,6 +1121,7 @@ struct optStruct
11111121
recharge_method recharge; ///< aquifer/soil recharge method
11121122
bool direct_evap; ///< true if PET is used to directly reduce precipitation
11131123
snowcov_method snow_depletion; ///< method for handling snowcover depletion curve
1124+
toc_method TOC_method; ///< method for calculating time of concentration
11141125

11151126
precip_icept_method interception_factor; ///< method for calculating canopy interception factor
11161127

src/SubBasin.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ CSubBasin::CSubBasin( const long long Identifier,
4848
_drainage_area =0.0;
4949
_reach_length =reach_len;
5050
_reach_length2 =reach_len;
51+
_basin_length =AUTO_COMPUTE;
5152
_is_headwater =true;
5253
_reach_HRUindex =DOESNT_EXIST; //default
5354
_hyporheic_flux =0.0; //default
@@ -1596,7 +1597,37 @@ double CSubBasin::CalculateBasinArea()
15961597

15971598
return _basin_area;
15981599
}
1600+
//////////////////////////////////////////////////////////////////
1601+
/// \brief Calculates time of concentration, in days
1602+
//
1603+
double CSubBasin::CalculateTOC(const toc_method method)
1604+
{
1605+
double slope_pct=tan(_mean_slope)*100;
1606+
double A=max(_basin_area,0.001); //to handle zero area issues
15991607

1608+
if (method==TOC_MCDERMOTT_PILGRIM) // Austrailian Rainfall and runoff guidelines [McDermott and Pilgrim (1982)]
1609+
{
1610+
return 0.76*pow(A,0.38)/HR_PER_DAY; //[d]
1611+
}
1612+
else if (method==TOC_AIRPORT) // MTO Drainage Manual 1997
1613+
{
1614+
double C=0.3; //TMP DEBUG - cant have a single rational coeff for entire basin
1615+
return 3.26*(1.1-C)*sqrt(_basin_length*M_PER_KM)*pow(slope_pct,-0.33)/MIN_PER_DAY;
1616+
}
1617+
else if (method == TOC_BRANSBY_WILLIAMS) //MTO Drainage Manual 1997
1618+
{
1619+
return 0.057*(_basin_length*M_PER_KM)*pow(slope_pct,-0.2)*pow(A*HECTARE_PER_KM2,-0.1);
1620+
}
1621+
else if (method == TOC_WILLIAMS_1922)
1622+
{
1623+
return 0.2426*_reach_length*pow(A,-0.1)*pow(slope_pct/100,-0.2)/HR_PER_DAY;
1624+
}
1625+
else if (method == TOC_TEMEZ)
1626+
{
1627+
return 0.3*pow(_reach_length,0.76)*pow(slope_pct/100,-0.19)/HR_PER_DAY;
1628+
}
1629+
return 0.0;
1630+
}
16001631
//////////////////////////////////////////////////////////////////
16011632
/// \brief Initializes SB attributes
16021633
/// \details Calculates total subbasin area; initializes _basin_area, _drainage_area,
@@ -1652,6 +1683,20 @@ void CSubBasin::Initialize(const double &Qin_avg, //[m3/s] from upst
16521683
if(_pChannel!=NULL) {
16531684
_pChannel->CheckReferenceFlow(_Q_ref,_slope,_mannings_n,_ID);
16541685
}
1686+
1687+
//Calculate mean slope from HRUs
1688+
//------------------------------------------------------------------------
1689+
double area;
1690+
for (int k=0;k<_nHydroUnits;k++){
1691+
area=_pHydroUnits[k]->GetArea();
1692+
_mean_slope = (_pHydroUnits[k]->GetSlope()) * area / _basin_area; //[radians]
1693+
}
1694+
1695+
//Estimate basin length from area if not provided
1696+
//------------------------------------------------------------------------
1697+
if (_basin_length == AUTO_COMPUTE) {
1698+
_basin_length = 0.5*sqrt(_basin_area); //[km] assume square watershed
1699+
}
16551700

16561701
//Estimate reach length from area if not provided
16571702
//------------------------------------------------------------------------
@@ -1665,7 +1710,8 @@ void CSubBasin::Initialize(const double &Qin_avg, //[m3/s] from upst
16651710
///< \ref from Williams (1922), as cited in Handbook of Hydrology, eqn. 9.4.3 \cite williams1922
16661711
if (_t_conc==AUTO_COMPUTE)
16671712
{
1668-
_t_conc=0.76*pow(max(_basin_area,0.001),0.38)/HR_PER_DAY;// [d] \ref Austrailian Rainfall and runoff guidelines [McDermott and Pilgrim (1982)]
1713+
_t_conc=CalculateTOC(Options.TOC_method);
1714+
16691715
_t_conc *= _pModel->GetGlobalParams()->GetParams()->TOC_multiplier;
16701716
}
16711717
if(Options.catchment_routing==ROUTE_GAMMA_CONVOLUTION ){_t_peak=AUTO_COMPUTE;}

src/SubBasin.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class CSubBasin
6060
bool _assimilate; ///< true if observed data in this basin should be assimilated.
6161
const CSubBasin *_pDownSB; ///< pointer to downstream subbasin instance
6262

63+
double _mean_slope; ///< mean slope of basin [rad]
64+
double _basin_length; ///< watershed length (travel distance to reach) [km]
65+
6366
//catchment routing properties
6467
double _t_conc; ///< basin time of concentration [d]
6568
double _t_peak; ///< basin time to peak [d] (<=_t_conc)
@@ -161,6 +164,8 @@ class CSubBasin
161164
double TVDTheta(double In_old,double In_new,double Out_old,double Out_new,double th_in,double dx,double tstep) const;
162165

163166
void UpdateRoutingHydro(const double &tstep);
167+
168+
double CalculateTOC(const toc_method method);
164169
public:/*-------------------------------------------------------*/
165170
//Constructors:
166171
CSubBasin(const long long ID,

0 commit comments

Comments
 (0)