diff --git a/docs/Documentation/VICDisagg.md b/docs/Documentation/VICDisagg.md index 835a7609d..3027e6ac3 100644 --- a/docs/Documentation/VICDisagg.md +++ b/docs/Documentation/VICDisagg.md @@ -15,13 +15,14 @@ Create a [global parameter file](GlobalParam.md). Because VIC will not actually * `STARTYEAR`,` STARTMONTH`, `STARTDAY`, `STARTHOUR`: Set these to the start date for your disaggregated forcings * `ENDYEAR`, `ENDMONTH`, `ENDDAY`: Set these to the end date for your disaggregated forcings * All the variables in the forcing section should be the same as before, i.e. these describe the **input** (daily) forcings that you are **reading**: `FORCING1`, `FORCING2` (if applicable), `FORCE_FORMAT`, `FORCE_ENDIAN`, `N_TYPES`, `FORCE_TYPE` (there must be one of these for each input variable, e.g. PREC, TMAX, TMIN, WIND), `FORCE_DT`, `FORCEYEAR`, `FORCEMONTH`, `FORCEDAY`, `FORCEHOUR`, `GRID_DECIMAL`, `WIND_H`, `MEASURE_H`, and `ALMA_INPUT` +* `VEGLIB`,`VEGLIB_VEGCOVER`,`VEGPARAM`,`ROOT_ZONES`,`VEGPARAM_LAI`,`VEGPARAM_VEGCOVER`,`VEGPARAM_ALB`: Set to the same values as you would for a full VIC simulation * `RESULT_DIR`: Set to the name of the directory where the disaggregated forcings should be written * `OUT_STEP`: Set to 0 * `ALMA_OUTPUT`: For standard VIC forcings, set to FALSE; for ALMA-compliant forcings (often required by other models) set to TRUE * `BINARY_OUTPUT`: Set this to FALSE to produce ASCII forcings, TRUE to produce BINARY forcings * `SKIPYEAR`: We recommend setting this to 0 * `OUTPUT_FORCE`: This must be set to TRUE -* `N_OUTFILES`, `OUTFILE`, `OUTVAR`: These can be omitted; by default, VIC will produce 1 output file per grid cell, names "full_data__lat___lon_," where lat, lon = latitude and longitude of te grid cell's center. These default output files will contain the following variables: +* `N_OUTFILES`, `OUTFILE`, `OUTVAR`: These can be omitted; by default, VIC will produce 1 output file per grid cell, names "full_data_lat_lon_," where lat, lon = latitude and longitude of te grid cell's center. These default output files will contain the following variables: | Name | Units (ALMA_OUTPUT FALSE) | Units (ALMA_OUTPUT TRUE) | |----------- |--------------------------- |-------------------------- | diff --git a/src/check_files.c b/src/check_files.c index 1b7c562db..243b90107 100644 --- a/src/check_files.c +++ b/src/check_files.c @@ -23,9 +23,9 @@ void check_files(filep_struct *filep, extern FILE *open_file(char string[], char type[]); filep->soilparam = open_file(fnames->soil, "r"); + filep->veglib = open_file(fnames->veglib, "r"); + filep->vegparam = open_file(fnames->veg, "r"); if (!options.OUTPUT_FORCE) { - filep->veglib = open_file(fnames->veglib, "r"); - filep->vegparam = open_file(fnames->veg, "r"); if(options.SNOW_BAND>1) filep->snowband = open_file(fnames->snowband, "r"); if ( options.LAKES ) diff --git a/src/initialize_atmos.c b/src/initialize_atmos.c index b82196dfe..faf77b2f9 100644 --- a/src/initialize_atmos.c +++ b/src/initialize_atmos.c @@ -254,11 +254,10 @@ void initialize_atmos(atmos_data_struct *atmos, // nrerror("Input meteorological forcing files must contain either WIND (wind speed) or both WIND_N (north component of wind speed) and WIND_E (east component of wind speed); check input files\n"); /* Assign N_ELEM for veg-dependent forcings */ - if (!options.OUTPUT_FORCE) { - param_set.TYPE[LAI_IN].N_ELEM = veg_con[0].vegetat_type_num; - param_set.TYPE[VEGCOVER].N_ELEM = veg_con[0].vegetat_type_num; - param_set.TYPE[ALBEDO].N_ELEM = veg_con[0].vegetat_type_num; - } + param_set.TYPE[LAI_IN].N_ELEM = veg_con[0].vegetat_type_num; + param_set.TYPE[VEGCOVER].N_ELEM = veg_con[0].vegetat_type_num; + param_set.TYPE[ALBEDO].N_ELEM = veg_con[0].vegetat_type_num; + /* compute number of simulation days */ tmp_starthour = 0; tmp_endhour = 24 - global_param.dt; @@ -1421,174 +1420,172 @@ void initialize_atmos(atmos_data_struct *atmos, } } - if (!options.OUTPUT_FORCE) { - - /**************************************************** - Albedo - ****************************************************/ + /**************************************************** + Albedo + ****************************************************/ - /* First, assign default climatology */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - for (j = 0; j < NF; j++) { - veg_hist[rec][v].albedo[j] = veg_con[v].albedo[dmy[rec].month-1]; - } + /* First, assign default climatology */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + for (j = 0; j < NF; j++) { + veg_hist[rec][v].albedo[j] = veg_con[v].albedo[dmy[rec].month-1]; } } + } - if(param_set.TYPE[ALBEDO].SUPPLIED) { - if(param_set.FORCE_DT[param_set.TYPE[ALBEDO].SUPPLIED-1] == 24) { - /* daily albedo provided */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for (j = 0; j < NF; j++) { - hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; - if (global_param.starthour - hour_offset_int < 0) hour += 24; - idx = (int)((float)hour/24.0); - if (local_veg_hist_data[ALBEDO][v][idx] != NODATA_VH) - veg_hist[rec][v].albedo[j] = local_veg_hist_data[ALBEDO][v][idx]; // assume constant over the day - sum += veg_hist[rec][v].albedo[j]; - } - if(NF>1) veg_hist[rec][v].albedo[NR] = sum / (float)NF; + if(param_set.TYPE[ALBEDO].SUPPLIED) { + if(param_set.FORCE_DT[param_set.TYPE[ALBEDO].SUPPLIED-1] == 24) { + /* daily albedo provided */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for (j = 0; j < NF; j++) { + hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; + if (global_param.starthour - hour_offset_int < 0) hour += 24; + idx = (int)((float)hour/24.0); + if (local_veg_hist_data[ALBEDO][v][idx] != NODATA_VH) + veg_hist[rec][v].albedo[j] = local_veg_hist_data[ALBEDO][v][idx]; // assume constant over the day + sum += veg_hist[rec][v].albedo[j]; } + if(NF>1) veg_hist[rec][v].albedo[NR] = sum / (float)NF; } } - else { - /* sub-daily albedo provided */ - for(rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for(i = 0; i < NF; i++) { - hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; - veg_hist[rec][v].albedo[i] = 0; - while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { - idx = hour; - if (idx < 0) idx += 24; - if (local_veg_hist_data[ALBEDO][v][idx] != NODATA_VH) - veg_hist[rec][v].albedo[i] = local_veg_hist_data[ALBEDO][v][idx]; - hour++; - } - sum += veg_hist[rec][v].albedo[i]; + } + else { + /* sub-daily albedo provided */ + for(rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for(i = 0; i < NF; i++) { + hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; + veg_hist[rec][v].albedo[i] = 0; + while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { + idx = hour; + if (idx < 0) idx += 24; + if (local_veg_hist_data[ALBEDO][v][idx] != NODATA_VH) + veg_hist[rec][v].albedo[i] = local_veg_hist_data[ALBEDO][v][idx]; + hour++; } - if(NF>1) veg_hist[rec][v].albedo[NR] = sum / (float)NF; + sum += veg_hist[rec][v].albedo[i]; } + if(NF>1) veg_hist[rec][v].albedo[NR] = sum / (float)NF; } } } + } - /**************************************************** - Leaf Area Index (LAI) - ****************************************************/ + /**************************************************** + Leaf Area Index (LAI) + ****************************************************/ - /* First, assign default climatology */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - for (j = 0; j < NF; j++) { - veg_hist[rec][v].LAI[j] = veg_con[v].LAI[dmy[rec].month-1]; - } + /* First, assign default climatology */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + for (j = 0; j < NF; j++) { + veg_hist[rec][v].LAI[j] = veg_con[v].LAI[dmy[rec].month-1]; } } + } - if(param_set.TYPE[LAI_IN].SUPPLIED) { - if(param_set.FORCE_DT[param_set.TYPE[LAI_IN].SUPPLIED-1] == 24) { - /* daily LAI provided */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for (j = 0; j < NF; j++) { - hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; - if (global_param.starthour - hour_offset_int < 0) hour += 24; - idx = (int)((float)hour/24.0); - if (local_veg_hist_data[LAI_IN][v][idx] != NODATA_VH) - veg_hist[rec][v].LAI[j] = local_veg_hist_data[LAI_IN][v][idx]; // assume constant over the day - sum += veg_hist[rec][v].LAI[j]; - } - if(NF>1) veg_hist[rec][v].LAI[NR] = sum / (float)NF; + if(param_set.TYPE[LAI_IN].SUPPLIED) { + if(param_set.FORCE_DT[param_set.TYPE[LAI_IN].SUPPLIED-1] == 24) { + /* daily LAI provided */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for (j = 0; j < NF; j++) { + hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; + if (global_param.starthour - hour_offset_int < 0) hour += 24; + idx = (int)((float)hour/24.0); + if (local_veg_hist_data[LAI_IN][v][idx] != NODATA_VH) + veg_hist[rec][v].LAI[j] = local_veg_hist_data[LAI_IN][v][idx]; // assume constant over the day + sum += veg_hist[rec][v].LAI[j]; } + if(NF>1) veg_hist[rec][v].LAI[NR] = sum / (float)NF; } } - else { - /* sub-daily LAI provided */ - for(rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for(i = 0; i < NF; i++) { - hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; - veg_hist[rec][v].LAI[i] = 0; - while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { - idx = hour; - if (idx < 0) idx += 24; - if (local_veg_hist_data[LAI_IN][v][idx] != NODATA_VH) - veg_hist[rec][v].LAI[i] = local_veg_hist_data[LAI_IN][v][idx]; - hour++; - } - sum += veg_hist[rec][v].LAI[i]; + } + else { + /* sub-daily LAI provided */ + for(rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for(i = 0; i < NF; i++) { + hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; + veg_hist[rec][v].LAI[i] = 0; + while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { + idx = hour; + if (idx < 0) idx += 24; + if (local_veg_hist_data[LAI_IN][v][idx] != NODATA_VH) + veg_hist[rec][v].LAI[i] = local_veg_hist_data[LAI_IN][v][idx]; + hour++; } - if(NF>1) veg_hist[rec][v].LAI[NR] = sum / (float)NF; + sum += veg_hist[rec][v].LAI[i]; } + if(NF>1) veg_hist[rec][v].LAI[NR] = sum / (float)NF; } } } + } - /**************************************************** - Fractional Vegetation Cover - ****************************************************/ + /**************************************************** + Fractional Vegetation Cover + ****************************************************/ - /* First, assign default climatology */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - for (j = 0; j < NF; j++) { - veg_hist[rec][v].vegcover[j] = veg_con[v].vegcover[dmy[rec].month-1]; - } + /* First, assign default climatology */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + for (j = 0; j < NF; j++) { + veg_hist[rec][v].vegcover[j] = veg_con[v].vegcover[dmy[rec].month-1]; } } + } - if(param_set.TYPE[VEGCOVER].SUPPLIED) { - if(param_set.FORCE_DT[param_set.TYPE[VEGCOVER].SUPPLIED-1] == 24) { - /* daily vegcover provided */ - for (rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for (j = 0; j < NF; j++) { - hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; - if (global_param.starthour - hour_offset_int < 0) hour += 24; - idx = (int)((float)hour/24.0); - if (local_veg_hist_data[VEGCOVER][v][idx] != NODATA_VH) { - veg_hist[rec][v].vegcover[j] = local_veg_hist_data[VEGCOVER][v][idx]; // assume constant over the day - if (veg_hist[rec][v].vegcover[j] < MIN_VEGCOVER) veg_hist[rec][v].vegcover[j] = MIN_VEGCOVER; - } - sum += veg_hist[rec][v].vegcover[j]; + if(param_set.TYPE[VEGCOVER].SUPPLIED) { + if(param_set.FORCE_DT[param_set.TYPE[VEGCOVER].SUPPLIED-1] == 24) { + /* daily vegcover provided */ + for (rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for (j = 0; j < NF; j++) { + hour = rec*global_param.dt + j*options.SNOW_STEP + global_param.starthour - hour_offset_int; + if (global_param.starthour - hour_offset_int < 0) hour += 24; + idx = (int)((float)hour/24.0); + if (local_veg_hist_data[VEGCOVER][v][idx] != NODATA_VH) { + veg_hist[rec][v].vegcover[j] = local_veg_hist_data[VEGCOVER][v][idx]; // assume constant over the day + if (veg_hist[rec][v].vegcover[j] < MIN_VEGCOVER) veg_hist[rec][v].vegcover[j] = MIN_VEGCOVER; } - if(NF>1) veg_hist[rec][v].vegcover[NR] = sum / (float)NF; + sum += veg_hist[rec][v].vegcover[j]; } + if(NF>1) veg_hist[rec][v].vegcover[NR] = sum / (float)NF; } } - else { - /* sub-daily vegcover provided */ - for(rec = 0; rec < global_param.nrecs; rec++) { - for(v = 0; v < veg_con[0].vegetat_type_num; v++) { - sum = 0; - for(i = 0; i < NF; i++) { - hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; - veg_hist[rec][v].vegcover[i] = 0; - while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { - idx = hour; - if (idx < 0) idx += 24; - if (local_veg_hist_data[VEGCOVER][v][idx] != NODATA_VH) { - veg_hist[rec][v].vegcover[i] = local_veg_hist_data[VEGCOVER][v][idx]; - if (veg_hist[rec][v].vegcover[i] < MIN_VEGCOVER) veg_hist[rec][v].vegcover[i] = MIN_VEGCOVER; - } - hour++; + } + else { + /* sub-daily vegcover provided */ + for(rec = 0; rec < global_param.nrecs; rec++) { + for(v = 0; v < veg_con[0].vegetat_type_num; v++) { + sum = 0; + for(i = 0; i < NF; i++) { + hour = rec*global_param.dt + i*options.SNOW_STEP + global_param.starthour - hour_offset_int; + veg_hist[rec][v].vegcover[i] = 0; + while (hour < rec*global_param.dt + (i+1)*options.SNOW_STEP + global_param.starthour - hour_offset_int) { + idx = hour; + if (idx < 0) idx += 24; + if (local_veg_hist_data[VEGCOVER][v][idx] != NODATA_VH) { + veg_hist[rec][v].vegcover[i] = local_veg_hist_data[VEGCOVER][v][idx]; + if (veg_hist[rec][v].vegcover[i] < MIN_VEGCOVER) veg_hist[rec][v].vegcover[i] = MIN_VEGCOVER; } - sum += veg_hist[rec][v].vegcover[i]; + hour++; } - if(NF>1) veg_hist[rec][v].vegcover[NR] = sum / (float)NF; + sum += veg_hist[rec][v].vegcover[i]; } + if(NF>1) veg_hist[rec][v].vegcover[NR] = sum / (float)NF; } } } } + /************************************************* Cosine of Solar Zenith Angle *************************************************/ diff --git a/src/vicNl.c b/src/vicNl.c index 4a0125db8..eb204b81b 100644 --- a/src/vicNl.c +++ b/src/vicNl.c @@ -161,10 +161,8 @@ int main(int argc, char *argv[]) /** Check and Open Files **/ check_files(&filep, &filenames); - if (!options.OUTPUT_FORCE) { - /** Read Vegetation Library File **/ - veg_lib = read_veglib(filep.veglib,&Nveg_type); - } /* !OUTPUT_FORCE */ + /** Read Vegetation Library File **/ + veg_lib = read_veglib(filep.veglib,&Nveg_type); /** Initialize Parameters **/ cellnum = -1; @@ -205,12 +203,12 @@ int main(int argc, char *argv[]) NEWCELL=TRUE; cellnum++; - if (!options.OUTPUT_FORCE) { + /** Read Grid Cell Vegetation Parameters **/ + veg_con = read_vegparam(filep.vegparam, soil_con.gridcel, + Nveg_type); + calc_root_fractions(veg_con, &soil_con); - /** Read Grid Cell Vegetation Parameters **/ - veg_con = read_vegparam(filep.vegparam, soil_con.gridcel, - Nveg_type); - calc_root_fractions(veg_con, &soil_con); + if (!options.OUTPUT_FORCE) { if ( options.LAKES ) lake_con = read_lakeparam(filep.lakeparam, soil_con, veg_con); @@ -233,11 +231,11 @@ int main(int argc, char *argv[]) /** Make Top-level Control Structure **/ all_vars = make_all_vars(veg_con[0].vegetat_type_num); - /** allocate memory for the veg_hist_struct **/ - alloc_veg_hist(global_param.nrecs, veg_con[0].vegetat_type_num, &veg_hist); - } /* !OUTPUT_FORCE */ + /** allocate memory for the veg_hist_struct **/ + alloc_veg_hist(global_param.nrecs, veg_con[0].vegetat_type_num, &veg_hist); + /************************************************** Initialize Meteological Forcing Values That Have not Been Specifically Set @@ -340,11 +338,12 @@ int main(int argc, char *argv[]) close_files(&filep,out_data_files,&filenames); + free_veg_hist(global_param.nrecs, veg_con[0].vegetat_type_num, &veg_hist); + free_vegcon(&veg_con); + if (!options.OUTPUT_FORCE) { - free_veg_hist(global_param.nrecs, veg_con[0].vegetat_type_num, &veg_hist); free_all_vars(&all_vars,veg_con[0].vegetat_type_num); - free_vegcon(&veg_con); free((char *)soil_con.AreaFract); free((char *)soil_con.BandElev); free((char *)soil_con.Tfactor); @@ -362,10 +361,10 @@ int main(int argc, char *argv[]) free_out_data_files(&out_data_files); free_out_data(&out_data); fclose(filep.soilparam); + free_veglib(&veg_lib); + fclose(filep.vegparam); + fclose(filep.veglib); if (!options.OUTPUT_FORCE) { - free_veglib(&veg_lib); - fclose(filep.vegparam); - fclose(filep.veglib); if (options.SNOW_BAND>1) fclose(filep.snowband); if (options.LAKES)