@@ -270,17 +270,21 @@ double CEnthalpyModel::GetEnergyLossesFromLake(const int p, double &Q_sens, doub
270270 double A_new = pRes->GetSurfaceArea ();
271271 double A_old = pRes->GetOldSurfaceArea ();
272272 double A_avg = 0.5 * (A_new + A_old);
273+ double V_h_new = pRes->GetHypolimnionStorage ();
274+ double V_h_old = pRes->GetOldHypolimnionStorage ();
273275
274276 CHydroUnit* pHRU=_pModel->GetHydroUnit (pRes->GetHRUIndex ());
275277
276278 double Acorr=1.0 ;
277279
278280 double SW (0 ), LW (0 ), LW_in (0 ), temp_air (0 ), AET (0 );
281+
279282 double hstar (0 ),ksed (0 ),Vsed=0.001 ;
280283 double T_new =ConvertVolumetricEnthalpyToTemperature (_aMres[p] / V_new);
281284 double T_old =ConvertVolumetricEnthalpyToTemperature (_aMres_last[p] / V_old);
282285 double Ts_new=ConvertVolumetricEnthalpyToTemperature (_aMsed[p] / Vsed );
283286 double Ts_old=ConvertVolumetricEnthalpyToTemperature (_aMsed_last[p] / Vsed );
287+
284288
285289 if (pHRU!=NULL ) { // otherwise only simulate advective mixing+ rain input
286290
@@ -300,7 +304,7 @@ double CEnthalpyModel::GetEnergyLossesFromLake(const int p, double &Q_sens, doub
300304 }
301305
302306 Q_sens =hstar* A_avg * (temp_air -0.5 *(T_new+T_old));
303- Q_cond =ksed * A_avg * (0.5 *(Ts_new+Ts_old)- 0.5 *(T_new+T_old));
307+ Q_cond =kdiff * A_avg * (0.5 *(Ts_new+Ts_old)- 0.5 *(T_new+T_old));
304308 Q_sw_in =(SW )*A_avg;
305309 Q_lw_in =(LW_in )*A_avg;
306310 Q_lw_out=(LW )*A_avg;
@@ -340,15 +344,27 @@ void CEnthalpyModel::RouteMassInReservoir (const int p, //
340344 double tstep=Options.timestep ;
341345
342346 if ((V_old<=0.0 ) || (V_new<=0.0 )) { Res_mass=ResSedMass=0.0 ; return ;} // handles dried out reservoir/lake
343-
347+
348+ double V_h_new = pRes->GetHypolimnionStorage ();
349+ double V_h_old = pRes->GetOldHypolimnionStorage ();
350+ double V_e_new = V_new-V_h_new;
351+ double V_e_old = V_old-V_h_old;
352+ double Q_dn_new = 0 ;
353+ double Q_dn_old = 0 ;
354+ double Q_up_new = 0 ;
355+ double Q_up_old = 0 ;
356+ double A_h_new = pRes->GetMixingArea ();
357+ double A_h_old = pRes->GetOldMixingArea ();
358+ double A_h_avg = 0.5 * (A_h_new + A_h_old);
359+
344360 CHydroUnit* pHRU=_pModel->GetHydroUnit (pRes->GetHRUIndex ());
345361
346362 double Acorr=1.0 ;
347363
348- double T_old =ConvertVolumetricEnthalpyToTemperature (_aMres_last[p]/V_old );
364+ double T_old =ConvertVolumetricEnthalpyToTemperature (_aMres_last[p]/V_e_old );
349365
350366 double SW (0 ), LW (0 ), LW_in (0 ), temp_air (0 ), AET (0 );
351- double hstar (0 ), ksed ( 0 ), Vsed= 0.001 ;
367+ double hstar (0 );
352368 if (pHRU!=NULL ) { // otherwise only simulate advective mixing+ rain input
353369 Acorr =pHRU->GetArea ()*M2_PER_KM2/A_avg; // handles the fact that GetAET() returns mm/d normalized by HRU area, not actual area
354370
@@ -359,14 +375,38 @@ void CEnthalpyModel::RouteMassInReservoir (const int p, //
359375 LW =-STEFAN_BOLTZ*EMISS_WATER*pow (T_old+ZERO_CELSIUS,4 ); // [MJ/m2/d] //TMP DEBUG -time-lagged - should include in the N-R formulation
360376
361377 AET =pRes->GetAET ()*Acorr/ MM_PER_METER ; // [m/d]
362-
363- Vsed =pRes->GetLakebedThickness () * pHRU->GetArea ()*M2_PER_KM2;
378+ // Vsed =pRes->GetLakebedThickness() * pHRU->GetArea()*M2_PER_KM2;
364379 hstar =pRes->GetLakeConvectionCoeff (); // [MJ/m2/d/K]
365- ksed =pRes->GetLakebedConductivity ()/0.5 / pRes->GetLakebedThickness ();// [MJ/m2/d/K]
380+ // ksed =pRes->GetLakebedConductivity()/0.5/ pRes->GetLakebedThickness();//[MJ/m2/d/K]
366381 }
367382
368- double T_sed_old=ConvertVolumetricEnthalpyToTemperature (_aMsed_last[p]/Vsed);
369-
383+ double Ts_old=ConvertVolumetricEnthalpyToTemperature (_aMsed_last[p]/V_h_old);
384+
385+
386+ double dens_e,dens_h,vdiff,kdiff;
387+
388+ double a0= 999.842594 ;
389+ double a1= 6.793952e-2 ;
390+ double a2=-9.095290e-3 ;
391+ double a3= 1.001685e-4 ;
392+ double a4=-1.120083e-6 ;
393+ double a5= 6.536332e-9 ;
394+
395+ dens_e = a0+a1*T_old + a2*pow (T_old,2 ) + a3*pow (T_old,3 ) +a4*pow (T_old,4 )+a5*pow (T_old,5 );
396+ dens_h = a0+a1*Ts_old + a2*pow (Ts_old,2 ) + a3*pow (Ts_old,3 ) +a4*pow (Ts_old,4 )+a5*pow (Ts_old,5 );
397+
398+ double N2;
399+
400+ if (dens_e<dens_h){
401+ N2 = -1 *GRAVITY/dens_e*(dens_e-dens_h)/1.0 ;
402+ }
403+ double m = -0.65 ;
404+ double b = -3.1 ;
405+
406+ vdiff = pow (10 ,m*log10 (N2)+b)/100 /100 ;
407+ kdiff = vdiff*HCP_WATER*SEC_PER_DAY;
408+
409+
370410 // N-R solution of Crank-nicolson problem as set of two non-linear algebraic equations
371411 // -----------------------------------------------------------------------------------------
372412 // dE /dt=Qh_in-Qh_out+(Rnet*A+P*hrain*A)-ET*rho*LH*A+k*(Tair-T(E))*A+ksed*(Tsed-T(E))*A //[MJ/d]
@@ -393,11 +433,11 @@ void CEnthalpyModel::RouteMassInReservoir (const int p, //
393433
394434 B[0 ]+=(1.0 -0.5 *tstep/V_old*Q_old)*_aMres_last[p];
395435 B[0 ]-=0.5 *tstep*hstar*A_old*T_old;
396- B[0 ]-=0.5 *tstep*ksed *A_avg*T_old;
397- B[0 ]+=0.5 *tstep*ksed *A_avg*T_sed_old ;
436+ B[0 ]-=0.5 *tstep*kdiff *A_avg*T_old;
437+ B[0 ]+=0.5 *tstep*kdiff *A_avg*Ts_old ;
398438
399- B[1 ] =0.5 *tstep*ksed *A_avg*T_old;
400- B[1 ]+=_aMsed_last[p]-0.5 *tstep*ksed *A_avg*T_sed_old ;
439+ B[1 ] =0.5 *tstep*kdiff *A_avg*T_old;
440+ B[1 ]+=_aMsed_last[p]-0.5 *tstep*kdiff *A_avg*Ts_old ;
401441
402442 int iter=0 ;
403443 double change=ALMOST_INF;
@@ -409,28 +449,28 @@ void CEnthalpyModel::RouteMassInReservoir (const int p, //
409449
410450 while (change > tolerance)
411451 {
412- T_guess = ConvertVolumetricEnthalpyToTemperature (E_guess/V_new );
413- Ts_guess= ConvertVolumetricEnthalpyToTemperature (Es_guess/Vsed );
452+ T_guess = ConvertVolumetricEnthalpyToTemperature (E_guess/V_e_new );
453+ Ts_guess= ConvertVolumetricEnthalpyToTemperature (Es_guess/V_h_new );
414454
415455 A[0 ][0 ] = 1.0 + 0.5 * tstep * Q_new/V_new;
416456 A[1 ][1 ] = 1.0 ;
417457 A[1 ][0 ] = 0.0 ;
418458 A[0 ][1 ] = 0.0 ;
419459 if (E_guess!=0.0 ){
420460 A[0 ][0 ]+= 0.5 *tstep*hstar*A_new*T_guess/E_guess;
421- A[0 ][0 ]+= 0.5 *tstep*ksed *A_avg*T_guess/E_guess; // [MJ/m2/d/K]*[m2]/[MJ/m3/K] = [m3/d]
422- A[1 ][0 ]-= 0.5 *tstep*ksed *A_avg*T_guess/E_guess;
461+ A[0 ][0 ]+= 0.5 *tstep*kdiff *A_avg*T_guess/E_guess; // [MJ/m2/d/K]*[m2]/[MJ/m3/K] = [m3/d]
462+ A[1 ][0 ]-= 0.5 *tstep*kdiff *A_avg*T_guess/E_guess;
423463 }
424464 if (Es_guess!=0.0 ){
425- A[0 ][1 ]-= 0.5 *tstep*ksed *A_avg*Ts_guess/Es_guess;
426- A[1 ][1 ]+= 0.5 *tstep*ksed *A_avg*Ts_guess/Es_guess;
465+ A[0 ][1 ]-= 0.5 *tstep*kdiff *A_avg*Ts_guess/Es_guess;
466+ A[1 ][1 ]+= 0.5 *tstep*kdiff *A_avg*Ts_guess/Es_guess;
427467 }
428468
429469 // J_ij=A_ij+E*dA_ij/dE = Jacobian
430- J[0 ][0 ]=A[0 ][0 ]+0.5 *tstep*(hstar*A_new+ksed *A_avg) * (TemperatureEnthalpyDerivative (E_guess /V_new )/ V_new );
431- J[0 ][1 ]=A[0 ][1 ]-0.5 *tstep*( ksed *A_avg) * (TemperatureEnthalpyDerivative (Es_guess/Vsed )/ Vsed );
432- J[1 ][0 ]=A[1 ][0 ]-0.5 *tstep*( ksed *A_avg) * (TemperatureEnthalpyDerivative (E_guess /V_new )/ V_new );
433- J[1 ][1 ]=A[1 ][1 ]+0.5 *tstep*( ksed *A_avg) * (TemperatureEnthalpyDerivative (Es_guess/Vsed )/ Vsed );
470+ J[0 ][0 ]=A[0 ][0 ]+0.5 *tstep*(hstar*A_new+kdiff *A_avg) * (TemperatureEnthalpyDerivative (E_guess /V_e_new )/ V_e_new );
471+ J[0 ][1 ]=A[0 ][1 ]-0.5 *tstep*( kdiff *A_avg) * (TemperatureEnthalpyDerivative (Es_guess/V_h_new )/ V_h_new );
472+ J[1 ][0 ]=A[1 ][0 ]-0.5 *tstep*( kdiff *A_avg) * (TemperatureEnthalpyDerivative (E_guess /V_e_new )/ V_e_new );
473+ J[1 ][1 ]=A[1 ][1 ]+0.5 *tstep*( kdiff *A_avg) * (TemperatureEnthalpyDerivative (Es_guess/V_h_new )/ V_h_new );
434474
435475 R[0 ] =-A[0 ][0 ]*E_guess-A[0 ][1 ]*Es_guess+B[0 ];
436476 R[1 ] =-A[1 ][0 ]*E_guess-A[1 ][1 ]*Es_guess+B[1 ];
@@ -440,7 +480,7 @@ void CEnthalpyModel::RouteMassInReservoir (const int p, //
440480 dE = (J[0 ][1 ]*R[1 ]-J[1 ][1 ]*R[0 ])/den;
441481 dEs = (J[1 ][0 ]*R[0 ]-J[0 ][0 ]*R[1 ])/den;
442482
443- change =sqrt (dE*dE+dEs*dEs)/ V_new / HCP_WATER; // convert to approx temp difference (for >0C water)
483+ change =sqrt (dE*dE+dEs*dEs)/ V_e_new / HCP_WATER; // convert to approx temp difference (for >0C water)
444484
445485 E_guess +=dE;
446486 Es_guess +=dEs;
0 commit comments