Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to state file i/o problems and refactoring of initialization #464

Merged
merged 11 commits into from
Apr 14, 2016
7 changes: 6 additions & 1 deletion docs/Development/ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -74,7 +74,12 @@ This is a major update from VIC 4. The VIC 5.0.0 release aims to have nearly ide
- `BINARY_STATE_FILE` (TRUE or FALSE) has been changed to `STATE_FORMAT` (BINARY or ASCII)
- `BINARY_OUTPUT` (TRUE or FALSE) has been changed to `OUT_FORMAT` (BINARY or ASCII)

3. Classic Driver Output Variables ([GH#352](https://github.com/UW-Hydro/VIC/pull/352))
3. State files now include seconds ([GH#464] (https://github.com/UW-Hydro/VIC/pull/464))

- There is a new global parameter option, `STATESEC`. This specifies the time step at the end of which state will be saved, in units of seconds. In other words, if you have an hourly time step (3600 sec) and you want to save state at the end of the final time step of the day (which is 86400 seconds long), subtract 3600 from 86400 to get a STATESEC of 82800. This corresponds to the first second of the final time step. State will be saved at the end of that time step.
- When the state save date is appended to state filenames, STATESEC will be included so that the date will have the format YYYYMMDD_SSSSS.

4. Classic Driver Output Variables ([GH#352](https://github.com/UW-Hydro/VIC/pull/352))

Computation of potential evapotranspiration (PET) has been simplified, reducing the number of output variables from 6 to 1. The following output variables have been removed:

3 changes: 2 additions & 1 deletion samples/global.param.sample.classic.txt
Original file line number Diff line number Diff line change
@@ -97,10 +97,11 @@ FROZEN_SOIL FALSE # TRUE = calculate frozen soils. Default = FALSE.
# State Files and Parameters
#######################################################################
#INIT_STATE (put the initial state path/filename here) # Initial state path/file
#STATENAME (put the path/prefix of output state file here) # Output state file path/prefix. The date (STATEYEAR,STATEMONTH,STATEDAY) will be appended to the prefix automatically in the format yyyymmdd.
#STATENAME (put the path/prefix of output state file here) # Output state file path/prefix. The date (STATEYEAR,STATEMONTH,STATEDAY,STATESEC) will be appended to the prefix automatically in the format yyyymmdd_sssss.
#STATEYEAR 2000 # year to save model state
#STATEMONTH 12 # month to save model state
#STATEDAY 31 # day to save model state
#STATESEC 75600 # second of day to save model state; numbering begins at 0 and STATESEC must be the second of the day corresponding to the beginning of the timestep whose state will be saved
#STATE_FORMAT ASCII # BINARY OR ASCII

#######################################################################
3 changes: 2 additions & 1 deletion samples/global.param.sample.image.txt
Original file line number Diff line number Diff line change
@@ -108,10 +108,11 @@ FROZEN_SOIL FALSE # TRUE = calculate frozen soils. Default = FALSE.
# State Files and Parameters
#######################################################################
#INIT_STATE (put the initial state path/filename here) # Initial state path/file
#STATENAME (put the path/prefix of output state file here) # Output state file path/prefix. The date (STATEYEAR,STATEMONTH,STATEDAY) will be appended to the prefix automatically in the format yyyymmdd.
#STATENAME (put the path/prefix of output state file here) # Output state file path/prefix. The date (STATEYEAR,STATEMONTH,STATEDAY,STATESEC) will be appended to the prefix automatically in the format yyyymmdd_sssss.
#STATEYEAR 2000 # year to save model state
#STATEMONTH 12 # month to save model state
#STATEDAY 31 # day to save model state
#STATESEC 75600 # second of day to save model state; numbering begins at 0 and STATESEC must be the second of the day corresponding to the beginning of the timestep whose state will be saved
#STATE_FORMAT NETCDF4_CLASSIC # State file format, valid options: NETCDF3_CLASSIC, NETCDF3_64BIT_OFFSET, NETCDF4_CLASSIC, NETCDF4

#######################################################################
28 changes: 16 additions & 12 deletions vic/drivers/cesm/src/vic_populate_model_state.c
Original file line number Diff line number Diff line change
@@ -33,26 +33,21 @@ void
vic_populate_model_state(char *runtype_str)
{
extern all_vars_struct *all_vars;
extern lake_con_struct *lake_con;
extern domain_struct local_domain;
extern option_struct options;
extern soil_con_struct *soil_con;
extern veg_con_struct **veg_con;
extern filenames_struct filenames;


double surf_temp;
size_t i;
size_t nveg;
unsigned short int runtype;

debug("In vic_restore");
debug("In vic_populate_model_state");

runtype = start_type_from_char(runtype_str);

// read first forcing timestep (used in restoring model state)
// reset the forcing offset to what it was before
vic_force();

// read the model state from the netcdf file if there is one
if (runtype == CESM_RUNTYPE_RESTART || runtype == CESM_RUNTYPE_BRANCH) {
// Get restart file from rpointer file
@@ -64,11 +59,20 @@ vic_populate_model_state(char *runtype_str)
else if (runtype == CESM_RUNTYPE_CLEANSTART) {
// run type is clean start
for (i = 0; i < local_domain.ncells_active; i++) {
// TBD: do something sensible for surf_temp
surf_temp = 0.;
nveg = veg_con[i][0].vegetat_type_num;
initialize_model_state(&(all_vars[i]), nveg, options.Nnode,
surf_temp, &(soil_con[i]), veg_con[i]);
generate_default_state(&(all_vars[i]), &(soil_con[i]), veg_con[i]);
if (options.LAKES) {
generate_default_lake_state(&(all_vars[i]), &(soil_con[i]),
lake_con[i]);
}
}
}

// compute those state variables that are derived from the others
for (i = 0; i < local_domain.ncells_active; i++) {
compute_derived_state_vars(&(all_vars[i]), &(soil_con[i]), veg_con[i]);
if (options.LAKES) {
compute_derived_lake_dimensions(&(all_vars[i].lake_var),
lake_con[i]);
}
}
}
10 changes: 5 additions & 5 deletions vic/drivers/classic/include/vic_driver_classic.h
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ void alloc_veg_hist(int nrecs, int nveg, veg_hist_struct ***veg_hist);
void calc_netlongwave(double *, double, double, double);
double calc_netshort(double, int, double, double *);
void check_files(filep_struct *, filenames_struct *);
bool check_save_state_flag(dmy_struct *, size_t);
FILE *check_state_file(char *, size_t, size_t, int *);
void close_files(filep_struct *, out_data_file_struct *, filenames_struct *);
size_t count_n_outfiles(FILE *gp);
@@ -53,10 +54,6 @@ void get_force_type(char *, int, int *);
void get_global_param(FILE *);
void init_output_list(out_data_struct *, int, char *, int, double);
void initialize_forcing_files(void);
int initialize_model_state(all_vars_struct *, global_param_struct *,
filep_struct, size_t, size_t, size_t, double,
soil_con_struct *, veg_con_struct *,
lake_con_struct);
void make_in_and_outfiles(filep_struct *, filenames_struct *, soil_con_struct *,
out_data_file_struct *);
FILE *open_state_file(global_param_struct *, filenames_struct, int, int);
@@ -66,7 +63,7 @@ void read_atmos_data(FILE *, global_param_struct, int, int, double **,
double ***);
double **read_forcing_data(FILE **, global_param_struct, double ****);
void read_initial_model_state(FILE *, all_vars_struct *, int, int, int,
soil_con_struct *);
soil_con_struct *, lake_con_struct);
lake_con_struct read_lakeparam(FILE *, soil_con_struct, veg_con_struct *);
void read_snowband(FILE *, soil_con_struct *);
soil_con_struct read_soilparam(FILE *, char *, char *);
@@ -75,6 +72,9 @@ veg_con_struct *read_vegparam(FILE *, int, size_t);
out_data_file_struct *set_output_defaults(out_data_struct *);
void vic_force(atmos_data_struct *, dmy_struct *, FILE **, veg_con_struct *,
veg_hist_struct **, soil_con_struct *);
void vic_populate_model_state(all_vars_struct *, filep_struct, size_t,
soil_con_struct *, veg_con_struct *,
lake_con_struct);
void write_data(out_data_file_struct *, out_data_struct *, dmy_struct *,
double);
void write_forcing_file(atmos_data_struct *, int, out_data_file_struct *,
49 changes: 49 additions & 0 deletions vic/drivers/classic/src/check_save_state_flag.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/******************************************************************************
* @section DESCRIPTION
*
* Function to check whether model state should be saved for the current
* time step
*
* @section LICENSE
*
* The Variable Infiltration Capacity (VIC) macroscale hydrological model
* Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil
* and Environmental Engineering, University of Washington.
*
* The VIC model is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*****************************************************************************/

#include <vic_driver_classic.h>

/******************************************************************************
* @brief Function to check whether model state should be saved for the
* current time step
*****************************************************************************/
bool
check_save_state_flag(dmy_struct *dmy,
size_t current)
{
extern global_param_struct global_param;

if (dmy[current].year == global_param.stateyear &&
dmy[current].month == global_param.statemonth &&
dmy[current].day == global_param.stateday &&
dmy[current].dayseconds == global_param.statesec) {
return true;
}
else {
return false;
}
}
1 change: 1 addition & 0 deletions vic/drivers/classic/src/display_current_settings.c
Original file line number Diff line number Diff line change
@@ -417,6 +417,7 @@ display_current_settings(int mode)
fprintf(LOG_DEST, "STATEYEAR\t\t%d\n", global_param.stateyear);
fprintf(LOG_DEST, "STATEMONTH\t\t%d\n", global_param.statemonth);
fprintf(LOG_DEST, "STATEDAY\t\t%d\n", global_param.stateday);
fprintf(LOG_DEST, "STATESEC\t\t%u\n", global_param.statesec);
if (options.STATE_FORMAT == BINARY) {
fprintf(LOG_DEST, "STATE_FORMAT\tBINARY\n");
}
37 changes: 22 additions & 15 deletions vic/drivers/classic/src/get_global_param.c
Original file line number Diff line number Diff line change
@@ -416,6 +416,9 @@ get_global_param(FILE *gp)
else if (strcasecmp("STATEDAY", optstr) == 0) {
sscanf(cmdstr, "%*s %hu", &global_param.stateday);
}
else if (strcasecmp("STATESEC", optstr) == 0) {
sscanf(cmdstr, "%*s %u", &global_param.statesec);
}
else if (strcasecmp("STATE_FORMAT", optstr) == 0) {
sscanf(cmdstr, "%*s %s", flgstr);
if (strcasecmp("BINARY", flgstr) == 0) {
@@ -1397,32 +1400,36 @@ get_global_param(FILE *gp)
if (global_param.stateyear == 0 || global_param.statemonth == 0 ||
global_param.stateday == 0) {
log_err("Incomplete specification of the date to save state "
"for state file (%s). Specified date (yyyy-mm-dd): "
"%04d-%02d-%02d Make sure STATEYEAR, STATEMONTH, and "
"STATEDAY are set correctly in your global parameter "
"for state file (%s).\nSpecified date (yyyy-mm-dd-sssss): "
"%04d-%02d-%02d-%05u\nMake sure STATEYEAR, STATEMONTH, "
"and STATEDAY are set correctly in your global parameter "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have -hh but this is seconds here. Maybe -sssss is better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

"file.", filenames.statefile, global_param.stateyear,
global_param.statemonth, global_param.stateday);
global_param.statemonth, global_param.stateday,
global_param.statesec);
}
// Check for month, day in range
make_lastday(global_param.stateyear, global_param.calendar,
lastday);
if (global_param.stateday > lastday[global_param.statemonth - 1] ||
global_param.statemonth > MONTHS_PER_YEAR ||
global_param.statemonth < 1 ||
global_param.stateday < 1) {
log_err("Unusual specification of the date to save state for "
"state file (%s). Specified date (yyyy-mm-dd): "
"%04d-%02d-%02d Make sure STATEYEAR, STATEMONTH, and "
"STATEDAY are set correctly in your global parameter "
"file.", filenames.statefile, global_param.stateyear,
global_param.statemonth, global_param.stateday);
global_param.statemonth > MONTHS_PER_YEAR ||
global_param.stateday < 1 || global_param.stateday > 31 ||
global_param.statesec > SEC_PER_DAY) {
log_err("Unusual specification of the date to save state "
"for state file (%s).\nSpecified date (yyyy-mm-dd-sssss): "
"%04d-%02d-%02d-%05u\nMake sure STATEYEAR, STATEMONTH, "
"STATEDAY and STATESEC are set correctly in your global "
"parameter file.", filenames.statefile,
global_param.stateyear, global_param.statemonth,
global_param.stateday, global_param.statesec);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above on seconds vs. hours.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

}
}
// Set the statename here to be able to compare with INIT_STATE name
if (options.SAVE_STATE) {
sprintf(filenames.statefile, "%s_%04i%02i%02i", filenames.statefile,
global_param.stateyear, global_param.statemonth,
global_param.stateday);
sprintf(filenames.statefile, "%s_%04i%02i%02i_%05u",
filenames.statefile, global_param.stateyear,
global_param.statemonth, global_param.stateday,
global_param.statesec);
}
if (options.INIT_STATE && options.SAVE_STATE &&
(strcmp(filenames.init_state, filenames.statefile) == 0)) {
Loading