Skip to content

Commit

Permalink
Feature/clean up esoil (UW-Hydro#777)
Browse files Browse the repository at this point in the history
* Cleaned up esoil logic and changed default value of RARC_SOIL to 250.

* Rolled back the change to SOIL_RARC.

* Added release notes entry.

* Minor edits in response to code review.

* Ran uncrustify.

* Changed formatting of call to calc_water_balance_error(), that had been reformatted by uncrustify in a weird way.
  • Loading branch information
tbohn authored and Joe Hamman committed Apr 25, 2018
1 parent 7d9b6c8 commit 0aed9a1
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 133 deletions.
4 changes: 4 additions & 0 deletions docs/Development/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ To check which release of VIC you are running:
6. Updated names of variables and options for LAI and FCANOPY in documentation to match their new names in the code
7. Removed constants MAX_VEG and MAX_BANDS from code; all arrays that were declared with those lengths were replaced with dynamic allocations. This allowed for specification of veg libraries containing more classes without recompiling the code, and more efficient memory usage.

[GH#766](https://github.com/UW-Hydro/VIC/pull/766)

1. Improved logic in computing soil evaporation (esoil), primarily in func_surf_energy_bal(), by creating explicit terms for transpiration (transp) and esoil in the layer data structure.

#### Bug Fixes:

1. NetCDF forcing files are now closed at the last timestep in stead of after the last timestep. ([GH#774](https://github.com/UW-Hydro/VIC/pull/774))
Expand Down
3 changes: 2 additions & 1 deletion vic/drivers/shared_all/src/initialize_soil.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ initialize_soil(cell_data_struct **cell,
cell[veg][band].RhSlow = 0.0;
cell[veg][band].RhTot = 0.0;
for (lindex = 0; lindex < options.Nlayer; lindex++) {
cell[veg][band].layer[lindex].bare_evap_frac = 0.0;
cell[veg][band].layer[lindex].esoil = 0.0;
cell[veg][band].layer[lindex].transp = 0.0;
cell[veg][band].layer[lindex].evap = 0.0;
}
}
Expand Down
8 changes: 5 additions & 3 deletions vic/drivers/shared_all/src/print_library_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ void
print_layer_data_fluxes(layer_data_struct *ldata)
{
fprintf(LOG_DEST, "layer_data (fluxes):\n");
fprintf(LOG_DEST, "\tbare_evap_frac: %f\n", ldata->evap);
fprintf(LOG_DEST, "\tesoil: %f\n", ldata->esoil);
fprintf(LOG_DEST, "\ttransp: %f\n", ldata->transp);
fprintf(LOG_DEST, "\tevap: %f\n", ldata->evap);
}

Expand Down Expand Up @@ -567,8 +568,9 @@ print_stream(stream_struct *stream,
fprintf(LOG_DEST, "\tngridcells: %zu\n", stream->ngridcells);
fprintf(LOG_DEST, "\tagg_alarm:\n ");
print_alarm(&(stream->agg_alarm));
fprintf(LOG_DEST,
"\t# \tVARID \tVARNAME \tTYPE \tMULT \tFORMAT \tAGGTYPE\n");
fprintf(
LOG_DEST,
"\t# \tVARID \tVARNAME \tTYPE \tMULT \tFORMAT \tAGGTYPE\n");
for (i = 0; i < stream->nvars; i++) {
varid = stream->varid[i];
fprintf(LOG_DEST, "\t%zu \t%u \t%20s \t%hu \t%f \t%10s \t%hu\n",
Expand Down
38 changes: 17 additions & 21 deletions vic/drivers/shared_all/src/put_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,11 @@ put_data(all_vars_struct *all_vars,
ThisTreeAdjust = 1;
}

if (ThisAreaFract > 0. && (veg == veg_con[0].vegetat_type_num ||
(!AboveTreeLine[band] ||
(AboveTreeLine[band] &&
!overstory)))) {
if (ThisAreaFract > 0. &&
(veg == veg_con[0].vegetat_type_num ||
(!AboveTreeLine[band] ||
(AboveTreeLine[band] &&
!overstory)))) {
/** compute running totals of various landcovers **/
if (HasVeg) {
cv_veg += Cv * ThisAreaFract * ThisTreeAdjust;
Expand Down Expand Up @@ -415,7 +416,8 @@ put_data(all_vars_struct *all_vars,
lake_var.runoff_out * MM_PER_M /
soil_con->cell_area; // mm over gridcell
// mm over gridcell
out_data[OUT_LAKE_EVAP][0] = lake_var.evapw * MM_PER_M /
out_data[OUT_LAKE_EVAP][0] = lake_var.evapw *
MM_PER_M /
soil_con->cell_area;
// mm over gridcell
out_data[OUT_LAKE_RCHRG][0] = lake_var.recharge *
Expand Down Expand Up @@ -540,10 +542,12 @@ put_data(all_vars_struct *all_vars,
}
storage += out_data[OUT_SWE][0] + out_data[OUT_SNOW_CANOPY][0] +
out_data[OUT_WDEW][0] + out_data[OUT_SURFSTOR][0];
out_data[OUT_WATER_ERROR][0] = calc_water_balance_error(inflow,
outflow,
storage,
save_data->total_moist_storage);
out_data[OUT_WATER_ERROR][0] = \
calc_water_balance_error(inflow,
outflow,
storage,
save_data->
total_moist_storage);

// Store total storage for next timestep
save_data->total_moist_storage = storage;
Expand Down Expand Up @@ -612,19 +616,11 @@ collect_wb_terms(cell_data_struct cell,
tmp_evap = 0.0;
for (index = 0; index < options.Nlayer; index++) {
tmp_evap += cell.layer[index].evap;
out_data[OUT_EVAP_BARE][0] += cell.layer[index].esoil *
AreaFactor;
if (HasVeg) {
out_data[OUT_EVAP_BARE][0] += cell.layer[index].evap *
cell.layer[index].bare_evap_frac
*
AreaFactor;
out_data[OUT_TRANSP_VEG][0] += cell.layer[index].evap *
(1 -
cell.layer[index].
bare_evap_frac) * AreaFactor;
}
else {
out_data[OUT_EVAP_BARE][0] += cell.layer[index].evap *
AreaFactor;
out_data[OUT_TRANSP_VEG][0] += cell.layer[index].transp *
AreaFactor;
}
}
tmp_evap += snow.vapor_flux * MM_PER_M;
Expand Down
3 changes: 2 additions & 1 deletion vic/vic_run/include/vic_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,9 @@ typedef struct {
double phi; /**< moisture diffusion parameter */
double zwt; /**< water table position relative to soil surface within the layer (cm) */
// Fluxes
double bare_evap_frac; /**< fraction of evapotranspiration coming from bare soil evap, from soil layer (mm) */
double esoil; /**< soil evaporation from soil layer (mm) */
double evap; /**< evapotranspiration from soil layer (mm) */
double transp; /**< transpiration from soil layer (mm) */
} layer_data_struct;

/******************************************************************************
Expand Down
22 changes: 11 additions & 11 deletions vic/vic_run/src/arno_evap.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ arno_evap(layer_data_struct *layer,
double ratio, as;
double Epot; /* potential bare soil evaporation */
double moist;
double evap;
double esoil;
double max_infil;
double Evap;
double tmpsum;
Expand Down Expand Up @@ -115,7 +115,7 @@ arno_evap(layer_data_struct *layer,
/**********************************************************************/

if (tmp >= max_infil) {
evap = Epot;
esoil = Epot;
}
else {
/********************************************************************/
Expand Down Expand Up @@ -159,7 +159,7 @@ arno_evap(layer_data_struct *layer,
}

beta_asp = as + (1.0 - as) * (1.0 - ratio) * dummy;
evap = Epot * beta_asp;
esoil = Epot * beta_asp;
}

/***********************************************************************/
Expand All @@ -168,21 +168,21 @@ arno_evap(layer_data_struct *layer,
/***********************************************************************/

/* only consider positive evaporation; we won't put limits on condensation */
if (evap > 0.0) {
if (esoil > 0.0) {
if (moist > moist_resid * depth1 * MM_PER_M) {
/* there is liquid moisture available; cap evap at available liquid moisture */
if (evap > moist - moist_resid * depth1 * MM_PER_M) {
evap = moist - moist_resid * depth1 * MM_PER_M;
/* there is liquid moisture available; cap esoil at available liquid moisture */
if (esoil > moist - moist_resid * depth1 * MM_PER_M) {
esoil = moist - moist_resid * depth1 * MM_PER_M;
}
}
else {
/* no moisture available; cap evap at 0 */
evap = 0.0;
/* no moisture available; cap esoil at 0 */
esoil = 0.0;
}
}

layer[0].evap = evap;
Evap += evap / MM_PER_M / delta_t;
layer[0].esoil = esoil;
Evap += esoil / MM_PER_M / delta_t;

return(Evap);
}
78 changes: 39 additions & 39 deletions vic/vic_run/src/canopy_evap.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ canopy_evap(layer_data_struct *layer,
double tmp_Evap;
double canopyevap;
double tmp_Wdew;
double layerevap[MAX_LAYERS];
double layertransp[MAX_LAYERS];
double rc;

Evap = 0;

/* Initialize variables */
for (i = 0; i < options.Nlayer; i++) {
layerevap[i] = 0;
layertransp[i] = 0;
}
canopyevap = 0;
throughfall = 0;
Expand Down Expand Up @@ -144,7 +144,7 @@ canopy_evap(layer_data_struct *layer,
if (CALC_EVAP) {
transpiration(layer, veg_var, veg_class, rad, vpd, net_short,
air_temp, ra, *dryFrac, delta_t, elevation, Wmax, Wcr,
Wpwp, layerevap, frost_fract, root, shortwave, Catm,
Wpwp, layertransp, frost_fract, root, shortwave, Catm,
CanopLayerBnd);
}

Expand All @@ -153,8 +153,8 @@ canopy_evap(layer_data_struct *layer,
veg_var->Wdew = tmp_Wdew;
tmp_Evap = canopyevap;
for (i = 0; i < options.Nlayer; i++) {
layer[i].evap = layerevap[i];
tmp_Evap += layerevap[i];
layer[i].transp = layertransp[i];
tmp_Evap += layertransp[i];
}

Evap += tmp_Evap / (MM_PER_M * delta_t);
Expand All @@ -180,7 +180,7 @@ transpiration(layer_data_struct *layer,
double *Wmax,
double *Wcr,
double *Wpwp,
double *layerevap,
double *layertransp,
double *frost_fract,
double *root,
double shortwave,
Expand All @@ -195,10 +195,10 @@ transpiration(layer_data_struct *layer,
size_t frost_area;
double gsm_inv; /* soil moisture stress factor */
double moist1, moist2; /* tmp holding of moisture */
double evap; /* tmp holding for evap total */
double transp; /* tmp holding for transp total */
double Wcr1; /* tmp holding of critical water for upper layers */
double root_sum; /* proportion of roots in moist>Wcr zones */
double spare_evap; /* evap for 2nd distribution */
double spare_transp; /* transp for 2nd distribution */
double avail_moist[MAX_LAYERS]; /* moisture available for trans */
double ice[MAX_LAYERS];
double gc;
Expand Down Expand Up @@ -280,8 +280,8 @@ transpiration(layer_data_struct *layer,
Potential evapotranspiration not hindered by soil dryness. If
layer with less than half the roots is dryer than Wcr, extra
evaporation is taken from the wetter layer. Otherwise layers
contribute to evapotransipration based on root fraction.
transpiration is taken from the wetter layer. Otherwise layers
contribute to transpiration based on root fraction.
******************************************************************/

if (options.SHARE_LAYER_MOIST &&
Expand Down Expand Up @@ -324,17 +324,17 @@ transpiration(layer_data_struct *layer,
}

/* compute transpiration */
evap = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc,
vic_run_veg_lib[veg_class].rarc) *
delta_t / CONST_CDAY * dryFrac;
transp = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc,
vic_run_veg_lib[veg_class].rarc) *
delta_t / CONST_CDAY * dryFrac;

/** divide up evap based on root distribution **/
/** divide up transp based on root distribution **/
/** Note the indexing of the roots **/
root_sum = 1.0;
spare_evap = 0.0;
spare_transp = 0.0;
for (i = 0; i < options.Nlayer; i++) {
if (avail_moist[i] >= Wcr[i]) {
layerevap[i] = evap * (double) root[i];
layertransp[i] = transp * (double) root[i];
}
else {
if (avail_moist[i] >= Wpwp[i]) {
Expand All @@ -345,29 +345,29 @@ transpiration(layer_data_struct *layer,
gsm_inv = 0.0;
}

layerevap[i] = evap * gsm_inv * (double) root[i];
layertransp[i] = transp * gsm_inv * (double) root[i];
root_sum -= root[i];
spare_evap = evap * (double) root[i] * (1.0 - gsm_inv);
spare_transp = transp * (double) root[i] * (1.0 - gsm_inv);
}
}

/** Assign excess evaporation to wetter layer **/
if (spare_evap > 0.0) {
/** Assign excess transpiration to wetter layer **/
if (spare_transp > 0.0) {
for (i = 0; i < options.Nlayer; i++) {
if (avail_moist[i] >= Wcr[i]) {
layerevap[i] += (double) root[i] * spare_evap / root_sum;
layertransp[i] += (double) root[i] *
spare_transp / root_sum;
}
}
}
}

/*********************************************************************
CASE 2: Independent evapotranspirations
CASE 2: Independent transpirations
Evapotranspiration is restricted by low soil moisture. Evaporation
is computed independantly from each soil layer.
*********************************************************************/

else {
/* Initialize conductances for aggregation over soil layers */
gc = 0;
Expand All @@ -380,7 +380,7 @@ transpiration(layer_data_struct *layer,
}

for (i = 0; i < options.Nlayer; i++) {
/** Set evaporation restriction factor **/
/** Set transpiration restriction factor **/
if (avail_moist[i] >= Wcr[i]) {
gsm_inv = 1.0;
}
Expand Down Expand Up @@ -428,11 +428,11 @@ transpiration(layer_data_struct *layer,
}

/* compute transpiration */
layerevap[i] = penman(air_temp, elevation, rad, vpd, ra,
veg_var->rc,
vic_run_veg_lib[veg_class].rarc) *
delta_t / CONST_CDAY * dryFrac *
(double) root[i];
layertransp[i] = penman(air_temp, elevation, rad, vpd, ra,
veg_var->rc,
vic_run_veg_lib[veg_class].rarc) *
delta_t / CONST_CDAY * dryFrac *
(double) root[i];

if (veg_var->rc > 0) {
gc += 1 / (veg_var->rc);
Expand All @@ -453,7 +453,7 @@ transpiration(layer_data_struct *layer,
}
}
else {
layerevap[i] = 0.0;
layertransp[i] = 0.0;
gc += 0;
if (options.CARBON) {
for (cidx = 0; cidx < options.Ncanopy; cidx++) {
Expand Down Expand Up @@ -494,32 +494,32 @@ transpiration(layer_data_struct *layer,
}

/****************************************************************
Check that evapotransipration does not cause soil moisture to
Check that transpiration does not cause soil moisture to
fall below wilting point.
****************************************************************/
for (i = 0; i < options.Nlayer; i++) {
if (ice[i] > 0) {
if (ice[i] >= Wpwp[i]) {
// ice content greater than wilting point can use all unfrozen moist
if (layerevap[i] > avail_moist[i]) {
layerevap[i] = avail_moist[i];
if (layertransp[i] > avail_moist[i]) {
layertransp[i] = avail_moist[i];
}
}
else {
// ice content less than wilting point restrict loss of unfrozen moist
if (layerevap[i] > layer[i].moist - Wpwp[i]) {
layerevap[i] = layer[i].moist - Wpwp[i];
if (layertransp[i] > layer[i].moist - Wpwp[i]) {
layertransp[i] = layer[i].moist - Wpwp[i];
}
}
}
else {
// No ice restrict loss of unfrozen moist
if (layerevap[i] > layer[i].moist - Wpwp[i]) {
layerevap[i] = layer[i].moist - Wpwp[i];
if (layertransp[i] > layer[i].moist - Wpwp[i]) {
layertransp[i] = layer[i].moist - Wpwp[i];
}
}
if (layerevap[i] < 0.0) {
layerevap[i] = 0.0;
if (layertransp[i] < 0.0) {
layertransp[i] = 0.0;
}
}
}
Loading

0 comments on commit 0aed9a1

Please sign in to comment.