Skip to content

Commit b768a9b

Browse files
James CraigJames Craig
authored andcommitted
v514 - Isotope transport up and running!
Isotopes: -Updated arguments needed for GetAdvectionCorrection() (Advection.cpp; ConstituentModel.cpp;Transport.cpp/h) -blanks for zero volume concentrations (ConstituentModel.cpp) -New routine UpdateInitialConditions(), member _initSWConc (IsotopeTransport.cpp/h;ParseInitialConditionsFile.cpp;Transport.cpp/h) -Proper handling of isotopic composition and drying out stores (IsotopeTransport.cpp) -Handle isotopic specified fluxes (MAssRouting.cpp) -New rvc command :InitialSurfaceWaterConcentration (ParseInitialConditionsFile.cpp) -new overloaded Transport routine GetConcentration() (Transport.cpp/.h) bug fix: reading snow composition (ParseInput.cpp) cleaned up IsDirichlet() routine (ConstituentModel.cpp)
1 parent 88f27a0 commit b768a9b

12 files changed

+228
-112
lines changed

src/Advection.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,25 +187,28 @@ void CmvAdvection::GetRatesOfChange(const double *state_vars,
187187
vol =sv[iToWater];
188188
iF=iToWater;iT=iFromWater;
189189
}
190-
if (vol>1e-6)//note: otherwise Q should generally be constrained to be <vol/tstep & 0.0<rates[q]<(m/tstep*corr)
190+
if ((vol>1e-6) && (Q[q]!=0))//note: otherwise Q should generally be constrained to be <vol/tstep & 0.0<rates[q]<(m/tstep*corr)
191191
{
192-
corr=pTransModel->GetAdvectionCorrection(_constit_ind,pHRU,iF,iT,mass/vol*MM_PER_METER/LITER_PER_M3);//mg/m2/mm->mg/L
192+
corr=pTransModel->GetAdvectionCorrection(_constit_ind,pHRU,iF,iT,mass,vol,Q[q]);
193193

194194
rates[q]=Q[q]*mass/vol*corr; //[mg/m2/d] or [MJ/m2/d]
195195
if(fabs(rates[q])>mass/tstep) { rates[q]=(Q[q]/fabs(Q[q]))*mass/tstep; }//emptying out compartment
196196

197-
if ((!isEnthalpy) && (!isIsotope)){ //negative enthalpy/temperature/isotopic composition allowed
197+
if ((!isEnthalpy)){ //negative enthalpy/temperature allowed
198198
if(mass<-1e-9) { ExitGracefully("CmvAdvection - negative mass",RUNTIME_ERR); }
199199
}
200200
}
201+
else {
202+
rates[q]=0.0;
203+
}
201204

202205
//special consideration - atmospheric precip can have negative storage but still specified concentration or temperature
203206
//----------------------------------------------------------------------
204207
if((pModel->GetStateVarType(iF)==ATMOS_PRECIP) &&
205208
(pConstit->IsDirichlet(iF,k,tt,Cs,1.0-pHRU->GetForcingFunctions()->snow_frac)))
206209
{
207210
if(!isEnthalpy) {
208-
Cs=pConstit->ConvertConcentration(Cs);
211+
Cs=pConstit->ConvertConcentration(Cs);//[mg/L]->[mg/mm-m2] or [o/oo]->[mg/mm-m2]
209212
}
210213
else {
211214
Cs=pTransModel->GetEnthalpyModel()->GetDirichletEnthalpy(pHRU,Cs);
@@ -227,7 +230,7 @@ void CmvAdvection::GetRatesOfChange(const double *state_vars,
227230
if(pConstit->IsDirichlet(iFromWater,k,tt,Cs))
228231
{
229232
if(!isEnthalpy) {
230-
Cs=pConstit->ConvertConcentration(Cs);//[mg/L]->[mg/mm-m2]
233+
Cs=pConstit->ConvertConcentration(Cs);//[mg/L]->[mg/mm-m2] or [o/oo]->[mg/mm-m2]
231234
}
232235
else{
233236
Cs=pTransModel->GetEnthalpyModel()->GetDirichletEnthalpy(pHRU,Cs);
@@ -244,7 +247,7 @@ void CmvAdvection::GetRatesOfChange(const double *state_vars,
244247
if(pConstit->IsDirichlet(iToWater,k,tt,Cs))
245248
{
246249
if(!isEnthalpy) {
247-
Cs=pConstit->ConvertConcentration(Cs);
250+
Cs=pConstit->ConvertConcentration(Cs);//[mg/L]->[mg/mm-m2] or [o/oo]->[mg/mm-m2]
248251
}
249252
else{
250253
Cs=pTransModel->GetEnthalpyModel()->GetDirichletEnthalpy(pHRU,Cs);

src/ConstituentModel.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ bool CConstituentModel::IsPassive() const {
9999
/// \param iToWater [in] index of "to" water storage state variable
100100
/// \param Cs [in] RAW constituent concentration (mg/L or MJ/L or L/L, not mg/L or C or o/oo)
101101
//
102-
double CConstituentModel::GetAdvectionCorrection(const CHydroUnit* pHRU,const int iFromWater,const int iToWater,const double& Cs) const
102+
double CConstituentModel::GetAdvectionCorrection(const CHydroUnit* pHRU,const int iFromWater,const int iToWater,const double& mass, const double &vol, const double &Q) const
103103
{
104104
/*sv_type fromType=_pModel->GetStateVarType(iFromWater);
105105
sv_type toType =_pModel->GetStateVarType(iToWater);
@@ -171,17 +171,18 @@ double CConstituentModel::GetCatchmentTransitLosses(const int p) const
171171
bool CConstituentModel::IsDirichlet(const int i_stor,const int k,const time_struct &tt,double &Cs,const double blend) const
172172
{
173173
Cs=0.0;
174+
double Cs2=0.0;
174175
int i_source=_aSourceIndices[i_stor][k];
175176
if(i_source==DOESNT_EXIST) { return false; }
176177
if(!_pSources[i_source]->dirichlet) { return false; }
177-
Cs = _pSources[i_source]->concentration;
178-
if (blend!=1.0){Cs=Cs*blend+(1-blend)*_pSources[i_source]->concentration2;}
179178

180-
if(Cs != DOESNT_EXIST) { return true; }
181-
else {//time series
182-
Cs = _pSources[i_source]->pTS->GetValue(tt.model_time);
183-
return true;
184-
}
179+
Cs =_pSources[i_source]->concentration;
180+
Cs2=_pSources[i_source]->concentration2;
181+
if (blend!=1.0){Cs=(blend)*Cs+(1-blend)*Cs2; }
182+
183+
if(Cs == DOESNT_EXIST) {Cs = _pSources[i_source]->pTS->GetValue(tt.model_time);}//time series
184+
185+
return true;
185186
}
186187
//////////////////////////////////////////////////////////////////
187188
/// \brief returns specified mass flux for given constitutent and water storage unit at time tt
@@ -668,6 +669,13 @@ void GetUnitNames(constit_type type,bool writemass,string &kg,string &kgd,string
668669
}
669670
}
670671
//////////////////////////////////////////////////////////////////
672+
/// \brief update initial conditions
673+
/// \details Called prior to simulation (but after initialization) from CModel::Initialize()
674+
//
675+
void CConstituentModel::UpdateInitialConditions(const optStruct& Options) {
676+
//default: does nothing
677+
}
678+
//////////////////////////////////////////////////////////////////
671679
/// \brief Write transport output file headers
672680
/// \details Called prior to simulation (but after initialization) from CModel::Initialize()
673681
/// \param &Options [in] Global model options information
@@ -1325,7 +1333,12 @@ void CConstituentModel::WriteMinorOutput(const optStruct &Options,const time_str
13251333

13261334
if(_pTransModel->GetStorWaterIndex(ii)!=iCumPrecip)
13271335
{
1328-
_OUTPUT<<","<<concentration; //print column entry
1336+
if ((V < 1e-6) && (_type == ISOTOPE)) {
1337+
_OUTPUT<<",";
1338+
}
1339+
else {
1340+
_OUTPUT<<","<<concentration; //print column entry
1341+
}
13291342
currentMass+=M*(area*M2_PER_KM2); //[mg] or [MJ] //increment total mass in system
13301343
}
13311344
else {

src/DemandOptimization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ void CDemandOptimizer::AddNonLinVariable(const string name, const string targetD
412412
nonlin_var *pNonLinVar=new nonlin_var(name,targetDV);
413413

414414
if(!DynArrayAppend((void**&)(_pNonLinVars),(void*)(pNonLinVar),_nNonLinVars)) {
415-
ExitGracefully("CConstituentModel::AddDirichletCompartment: adding NULL source",BAD_DATA);
415+
ExitGracefully("CDemandOptimizer::AddNonLinVariable: adding NULL source",BAD_DATA);
416416
}
417417
}
418418
//////////////////////////////////////////////////////////////////

src/EnergyTransport.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ double CEnthalpyModel::CalculateReportingConcentration(const double &M,const dou
6868
//
6969
double CEnthalpyModel::ConvertConcentration(const double &T) const
7070
{
71-
//specified in C, convert to MJ/m2
71+
//specified in degrees C, convert to MJ/mm/m2
7272
double pctfroz=0.0;
7373
if (T<0.0){pctfroz=1.0;} //treats all 0 degree water as unfrozen
7474
return ConvertTemperatureToVolumetricEnthalpy(T,pctfroz)/MM_PER_METER; //[C]->[MJ/m3]*[M/mm]=[MJ/mm-m2]
@@ -546,12 +546,14 @@ void CEnthalpyModel::Initialize(const optStruct& Options)
546546
for(int p=0;p<_pModel->GetNumSubBasins();p++)
547547
{
548548
pBasin=_pModel->GetSubBasin(p);
549-
const double *aQin=pBasin->GetInflowHistory();
549+
550550
for(int i=0; i<pBasin->GetNumSegments(); i++)
551551
{
552552
_aMout[p][i]=pBasin->GetOutflowArray()[_pModel->GetSubBasin(p)->GetNumSegments()-1] * SEC_PER_DAY * hv; //not really - requires outflow rate from all segments in general case. Don't have access to this. assumes nSegs=1
553553
}
554554
_aMout_last[p]=_aMout[p][0];
555+
556+
const double *aQin=pBasin->GetInflowHistory();
555557
for(int i=0; i<_nMinHist[p]; i++)
556558
{
557559
_aMinHist[p][i]=aQin[i]*SEC_PER_DAY*hv;

0 commit comments

Comments
 (0)