From be5563f085ac01604838eaee9f2e4e5b67ae937c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 30 Jul 2015 19:35:16 +0200 Subject: [PATCH 001/294] Routing extension for VIC image driver. Affected files in the original VIC files are: './drivers/image/Makefile' and './drivers/image/src/vic_image.c'. To change the routing scheme once they are implemented, only change the following line in the makefile -> ROUT=rout_stub Still only an empty routing module is implemented (rout_stub). See ./extensions/rout_stub --- vic/drivers/image/Makefile | 19 +++++++-- vic/drivers/image/src/vic_image.c | 22 +++++++++- vic/extensions/rout_stub/include/rout.h | 44 +++++++++++++++++++ vic/extensions/rout_stub/rout.mk | 8 ++++ vic/extensions/rout_stub/src/rout.c | 56 +++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 vic/extensions/rout_stub/include/rout.h create mode 100644 vic/extensions/rout_stub/rout.mk create mode 100644 vic/extensions/rout_stub/src/rout.c diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 091f20b0a..c58739b40 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -37,6 +37,9 @@ SHAREDPATH = ../shared # VIC RUN PATH VICPATH = ../../vic_run +# VIC EXTENTIONS PATH +EXTPATH = ../../extensions + # NETCDF include .. change the path depending on travis or other location ifeq (true, ${TRAVIS}) NETCDFPATH = /usr @@ -65,8 +68,14 @@ else CC = mpicc-mpich-mp endif +# set routing extension here (rout_stub means: no routing) +ROUT=rout_stub +#ROUT=rout_rvic + +include ${EXTPATH}/${ROUT}/rout.mk + # set includes -INCLUDES = -I ${DRIVERPATH}/include -I ${VICPATH}/include -I ${SHAREDPATH}/include -I ${NETCDFPATH}/include -I ${MPIPATH}/include +INCLUDES = -I ${DRIVERPATH}/include -I ${VICPATH}/include -I ${SHAREDPATH}/include -I ${NETCDFPATH}/include -I ${MPIPATH}/include -I ${EXTPATH}/${ROUT}/include # Uncomment for normal optimized code flags (fastest run option) #CFLAGS = -O3 -Wall -Wno-unused @@ -93,7 +102,8 @@ HDRS = ${VICPATH}/include/vic_def.h \ ${DRIVERPATH}/include/vic_driver_image.h \ ${SHAREDPATH}/include/vic_driver_shared.h \ ${VICPATH}/include/vic_physical_constants.h \ - ${VICPATH}/include/vic_log.h + ${VICPATH}/include/vic_log.h \ + ${INCL_ROUT} OBJS = \ ${DRIVERPATH}/src/alloc_atmos.o \ @@ -205,7 +215,8 @@ OBJS = \ ${VICPATH}/src/water_under_ice.o \ ${VICPATH}/src/write_layer.o \ ${VICPATH}/src/write_vegvar.o \ - ${VICPATH}/src/zero_output_list.o + ${VICPATH}/src/zero_output_list.o \ + ${OBJS_ROUT} SRCS = $(OBJS:%.o=%.c) @@ -224,7 +235,7 @@ full: make model clean:: - /bin/rm -f ${DRIVERPATH}/src/*.o ${SHAREDPATH}/src/*.o ${VICPATH}/src/*.o core log ${DRIVERPATH}/src/*~ ${SHAREDPATH}/src/*.~ ${VICPATH}/src/*~ vic_image + /bin/rm -f ${DRIVERPATH}/src/*.o ${SHAREDPATH}/src/*.o ${VICPATH}/src/*.o core ${EXTPATH}/${ROUT}/src/*.o log ${DRIVERPATH}/src/*~ ${SHAREDPATH}/src/*.~ ${VICPATH}/src/*~ ${EXTPATH}/${ROUT}/src/*~ vic_image model: $(OBJS) $(CC) -o vic_image$(EXT) $(OBJS) $(CFLAGS) $(LIBRARY) diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 1843b3e5f..b8708a62a 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -27,6 +27,7 @@ #include #include #include +#include // Routing routine (extension) size_t NF, NR; size_t current; @@ -62,6 +63,7 @@ veg_con_map_struct *veg_con_map = NULL; veg_con_struct **veg_con = NULL; veg_hist_struct **veg_hist = NULL; veg_lib_struct **veg_lib = NULL; +rout_struct rout; // Routing routine (extension) /****************************************************************************** * @brief Stand-alone image mode driver of the VIC model @@ -97,13 +99,22 @@ main(int argc, // read global parameters vic_start(); - + + // read global parameters for routing + rout_start(); // Routing routine (extension) + // allocate memory vic_alloc(); + // allocate memory for routing + rout_alloc(); // Routing routine (extension) + // initialize model parameters from parameter files vic_init(); + // initialize routing parameters from parameter files + rout_init(); // Routing routine (extension) + // restore model state, either using a cold start or from a restart file vic_restore(); @@ -118,9 +129,15 @@ main(int argc, // run vic over the domain vic_image_run(); + // run routing over the domain + rout_run(); // Routing routine (extension) + // if output: vic_write(); + // if output (routing) + rout_write(); // Routing routine (extension) + // if save: TBD needs to be fixed - not working in MPI // if (current == global_param.nrecs - 1) { // vic_store(); @@ -130,6 +147,9 @@ main(int argc, // clean up vic_finalize(); + // clean up routing + rout_finalize(); // Routing routine (extension) + // finalize MPI status = MPI_Finalize(); if (status != MPI_SUCCESS) { diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h new file mode 100644 index 000000000..448247d43 --- /dev/null +++ b/vic/extensions/rout_stub/include/rout.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for rout_stub routines + * + * @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. + *****************************************************************************/ +#ifndef ROUT_STUB_H +#define ROUT_STUB_H + +/****************************************************************************** + * @brief main routing Struct + *****************************************************************************/ +typedef struct { +} rout_struct; + +/****************************************************************************** + * @brief prototypes for dummy functions of the rout_stub extension + *****************************************************************************/ +void rout_start(void); // read global parameters for routing +void rout_alloc(void); // allocate memory +void rout_init(void); // initialize model parameters from parameter files +void rout_run(void); // run routing over the domain +void rout_write(void); // write routine for routing +void rout_finalize(void); // clean up routine for routing +#endif diff --git a/vic/extensions/rout_stub/rout.mk b/vic/extensions/rout_stub/rout.mk new file mode 100644 index 000000000..0eb6ef6f5 --- /dev/null +++ b/vic/extensions/rout_stub/rout.mk @@ -0,0 +1,8 @@ +# make a list of all *.h files in routing folder +INCL_ROUT := $(wildcard ${EXTPATH}/${ROUT}/include/*.h) + +# make a list of all *.c files in routing folder +SRCS_ROUT := $(wildcard ${EXTPATH}/${ROUT}/src/*.c) + +# convert the list of all *.c to a list of *.o files (object files) +OBJS_ROUT = $(SRCS_ROUT:%.o=%.c) diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c new file mode 100644 index 000000000..289fb6f22 --- /dev/null +++ b/vic/extensions/rout_stub/src/rout.c @@ -0,0 +1,56 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * dummy functions for the rout_stub extension + * + * @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. + *****************************************************************************/ + +// read global parameters for routing +void rout_start(void) +{ +// log_info("In Routing Stub Model"); +} + +// allocate memory +void rout_alloc(void) +{ +} + +// initialize model parameters from parameter files +void rout_init(void) +{ +} + +// run routing over the domain +void rout_run(void) +{ +} + +// write routine for routing +void rout_write(void) +{ +} + +// clean up routine for routing +void rout_finalize(void) +{ +} From fef012a955de6dbdbd3cd2f83422846b9f603341 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 30 Jul 2015 21:43:29 +0200 Subject: [PATCH 002/294] First attempt to make the RVIC routing extension. Not finished/okay yet. --- vic/extensions/rout_rvic/include/rout.h | 82 +++++++++++++ vic/extensions/rout_rvic/rout.mk | 8 ++ vic/extensions/rout_rvic/src/convolve.c | 47 +++++++ vic/extensions/rout_rvic/src/cshift.c | 16 +++ vic/extensions/rout_rvic/src/rout_alloc.c | 77 ++++++++++++ vic/extensions/rout_rvic/src/rout_finalize.c | 29 +++++ vic/extensions/rout_rvic/src/rout_init.c | 121 +++++++++++++++++++ vic/extensions/rout_rvic/src/rout_run.c | 106 ++++++++++++++++ vic/extensions/rout_rvic/src/rout_start.c | 78 ++++++++++++ vic/extensions/rout_rvic/src/rout_write.c | 32 +++++ 10 files changed, 596 insertions(+) create mode 100644 vic/extensions/rout_rvic/include/rout.h create mode 100644 vic/extensions/rout_rvic/rout.mk create mode 100644 vic/extensions/rout_rvic/src/convolve.c create mode 100644 vic/extensions/rout_rvic/src/cshift.c create mode 100644 vic/extensions/rout_rvic/src/rout_alloc.c create mode 100644 vic/extensions/rout_rvic/src/rout_finalize.c create mode 100644 vic/extensions/rout_rvic/src/rout_init.c create mode 100644 vic/extensions/rout_rvic/src/rout_run.c create mode 100644 vic/extensions/rout_rvic/src/rout_start.c create mode 100644 vic/extensions/rout_rvic/src/rout_write.c diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h new file mode 100644 index 000000000..cba97a5f8 --- /dev/null +++ b/vic/extensions/rout_rvic/include/rout.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for rvic routing routines + * + * @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. + *****************************************************************************/ +#ifndef ROUT_RVIC_H +#define ROUT_RVIC_H + +#include + +/****************************************************************************** + * @brief Routing Structs + *****************************************************************************/ +typedef struct { + size_t iSubsetLength; /*scalar - number of timesteps*/ + size_t iSources; /*scalar - number of sources*/ + size_t iOutlets; /*scalar - length of subset*/ + int *source2outlet_ind; /*1d array - source to outlet mapping*/ + int *source_y_ind ; /*1d array - source y location*/ + int *source_x_ind; /*1d array - source x location*/ + int *source_time_offset; /*1d array - source time offset*/ + double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ + double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ +} rout_param_struct; + +/****************************************************************************** + * @brief main routing Struct + *****************************************************************************/ +typedef struct { + char param_filename[MAXSTRING]; + rout_param_struct rout_param; + double *ring; +} rout_struct; + +/****************************************************************************** + * @brief Function prototypes for the rout_rvic extension + *****************************************************************************/ +void rout_start(void); // read global parameters for routing +void rout_alloc(void); // allocate memory +void rout_init(void); // initialize model parameters from parameter files +void rout_run(void); // run routing over the domain +void rout_write(void); // write routine for routing +void rout_finalize(void); // clean up routine for routing + +/****************************************************************************** + * @brief Convolution function adapted from the RVIC scheme + *****************************************************************************/ +void convolve(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + const size_t x_size, + const int* source2outlet_ind, /*1d array - source to outlet mapping*/ + const int* source_y_ind, /*1d array - source y location*/ + const int* source_x_ind, /*1d array - source x location*/ + const int* source_time_offset, /*1d array - source time offset*/ + const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double* ring); +void get_global_param_rout(FILE *gp); +void cshift(double*, int, int); + +#endif diff --git a/vic/extensions/rout_rvic/rout.mk b/vic/extensions/rout_rvic/rout.mk new file mode 100644 index 000000000..0eb6ef6f5 --- /dev/null +++ b/vic/extensions/rout_rvic/rout.mk @@ -0,0 +1,8 @@ +# make a list of all *.h files in routing folder +INCL_ROUT := $(wildcard ${EXTPATH}/${ROUT}/include/*.h) + +# make a list of all *.c files in routing folder +SRCS_ROUT := $(wildcard ${EXTPATH}/${ROUT}/src/*.c) + +# convert the list of all *.c to a list of *.o files (object files) +OBJS_ROUT = $(SRCS_ROUT:%.o=%.c) diff --git a/vic/extensions/rout_rvic/src/convolve.c b/vic/extensions/rout_rvic/src/convolve.c new file mode 100644 index 000000000..a30aeb425 --- /dev/null +++ b/vic/extensions/rout_rvic/src/convolve.c @@ -0,0 +1,47 @@ +#include +#include +#include + +void convolve(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + const size_t x_size, + const int* source2outlet_ind, /*1d array - source to outlet mapping*/ + const int* source_y_ind, /*1d array - source y location*/ + const int* source_x_ind, /*1d array - source x location*/ + const int* source_time_offset, /*1d array - source time offset*/ + const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double* ring) /*2d array[times][outlets] - convolution ring*/ +{ + log_info("Doing convolution test!"); + size_t s, i, j; /*counters*/ + int y, x, offset, outlet; /*2d indicies*/ + int xyind, rind, uhind; /*1d indicies*/ + + /*Loop through all sources*/ + for (s = 0; s < nsources; s++) { + + outlet = source2outlet_ind[s]; + y = source_y_ind[s]; + x = source_x_ind[s]; + offset = source_time_offset[s]; + + //1d index location + //2d-->1d indexing goes like this: ind = y*x_size + x + xyind = y*x_size + x; + + /* Do the convolution */ + // i is the position in the unit hydrograph + // j is the position in the ring + for (i = 0; i < subset_length; i++) { + j = i + offset; + + //1d index locations + rind = j * noutlets + outlet; + uhind = i * nsources + s; + + ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; + } + } +} diff --git a/vic/extensions/rout_rvic/src/cshift.c b/vic/extensions/rout_rvic/src/cshift.c new file mode 100644 index 000000000..b3a1fa373 --- /dev/null +++ b/vic/extensions/rout_rvic/src/cshift.c @@ -0,0 +1,16 @@ +#include +#include + +void cshift(double *a, int width, int offset) +{ + int i; + double b; + + b=*(a + width*offset); + for (i = 0; i != width - 1; i++) { + *(a + width*offset + i) = *(a + width*offset + i+1); + } + *(a + width*offset + i) = b; + + +} diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c new file mode 100644 index 000000000..f6f6e830a --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -0,0 +1,77 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Allocate memory for Routing structures. + * + * @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 +#include +#include +#include + +/****************************************************************************** + * @brief Allocate memory for Routing structures. + *****************************************************************************/ +void rout_alloc(void) +{ + extern domain_struct local_domain; + extern rout_struct rout; + //char *nc_name="./input/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc"; + + // Get some dimensions + rout.rout_param.iSubsetLength = get_nc_dimension(rout.param_filename, "timesteps"); + rout.rout_param.iOutlets = get_nc_dimension(rout.param_filename, "outlets"); + rout.rout_param.iSources = get_nc_dimension(rout.param_filename, "sources"); + + // Allocate memory in rout param_struct + rout.rout_param.source2outlet_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + if (rout.rout_param.source2outlet_ind == NULL) { + log_err("Memory allocation error in rout.rout_param.source2outlet_ind()."); + } + rout.rout_param.source_time_offset = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + if (rout.rout_param.source_time_offset == NULL) { + log_err("Memory allocation error in rout.rout_param.source_time_offset()."); + } + rout.rout_param.source_x_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + if (rout.rout_param.source_x_ind == NULL) { + log_err("Memory allocation error in rout.rout_param.source_x_ind()."); + } + rout.rout_param.source_y_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + if (rout.rout_param.source_y_ind == NULL) { + log_err("Memory allocation error in rout.rout_param.source_y_ind()."); + } + rout.rout_param.unit_hydrograph = (double *) malloc (rout.rout_param.iSources * rout.rout_param.iSubsetLength * sizeof (double)); + if (rout.rout_param.unit_hydrograph == NULL) { + log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); + } + rout.rout_param.aggrunin = (double *)malloc (local_domain.ncells * sizeof (double)); + if (rout.rout_param.aggrunin == NULL) { + log_err("Memory allocation error in rout.rout_param.aggrunin()."); + } + + // Allocate memory for the ring + rout.ring = (double *)malloc (rout.rout_param.iSubsetLength * rout.rout_param.iOutlets * sizeof (double)); + if (rout.ring == NULL) { + log_err("Memory allocation error in rout.ring()."); + } +} diff --git a/vic/extensions/rout_rvic/src/rout_finalize.c b/vic/extensions/rout_rvic/src/rout_finalize.c new file mode 100644 index 000000000..f84d33450 --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_finalize.c @@ -0,0 +1,29 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * clean up functions for routing extension + * + * @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. + *****************************************************************************/ + +void rout_finalize(void) +{ +} diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c new file mode 100644 index 000000000..8c2268c9f --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -0,0 +1,121 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Initialize routing model parameters + * + * @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 +#include +#include + +#include + +/****************************************************************************** + * @brief Initialize routing model parameters + *****************************************************************************/ +void +rout_init(void) +{ + extern rout_struct rout; + int *ivar = NULL; + double *dvar = NULL; + + size_t i, j; + size_t i1start; + size_t d3count[3]; + size_t d3start[3]; + + i1start = 0; + + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = rout.rout_param.iSubsetLength; + d3count[1] = rout.rout_param.iSources; + d3count[2] = 1; // tracers dimension + + + // allocate memory for variables to be read + ivar = (int *) malloc(sizeof(int) * rout.rout_param.iSources); + if (ivar == NULL) { + log_err("Memory allocation error in vic_init()."); + } + + // allocate memory for variables to be read + dvar = (double *) malloc(rout.rout_param.iSubsetLength * rout.rout_param.iSources * + sizeof(double)); + if (dvar == NULL) { + log_err("Memory allocation error in vic_init()."); + } + + // The Ring + for (j=0;j +#include +#include +#include + +void rout_run(void) +{ + log_info("In Routing Lohmann Model"); + + extern rout_struct rout; + extern domain_struct global_domain; + extern out_data_struct **out_data; + size_t i; + + // even worse stuff here + for (i = 0; i < global_domain.ncells; i++) { + rout.rout_param.aggrunin[i]= out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; + } + + //TODO: Check if nOutlets in ROUTING is the same (same lat lons and same length) as VIC + // completely useless double stuff here + + log_info("Tolkien here"); + size_t j; + size_t ni = rout.rout_param.iSubsetLength; + size_t nj = rout.rout_param.iOutlets; + +// printf("\nThe Ring...\n"); +// for (j=0;j +#include +#include +#include + +/****************************************************************************** + * @brief + *****************************************************************************/ +void rout_start(void) +{ + extern filenames_struct filenames; + extern filep_struct filep; + extern int mpi_rank; + + if (mpi_rank == 0) { + // read global settings + filep.globalparam = open_file(filenames.global, "r"); + get_global_param_rout(filep.globalparam); + } +} + +void get_global_param_rout(FILE *gp) +{ + extern rout_struct rout; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + + /** Read through global control file to find parameters **/ + rewind(gp); + fgets(cmdstr, MAXSTRING, gp); + + while (!feof(gp)) { + if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { + sscanf(cmdstr, "%s", optstr); + + /* Handle case of comment line in which '#' is indented */ + if (optstr[0] == '#') { + fgets(cmdstr, MAXSTRING, gp); + continue; + } + + /************************************* + Get Model Global Parameters + *************************************/ + if (strcasecmp("ROUT_PARAM", optstr) == 0) { + sscanf(cmdstr, "%*s %s", rout.param_filename); + } + + } + fgets(cmdstr, MAXSTRING, gp); + } +} diff --git a/vic/extensions/rout_rvic/src/rout_write.c b/vic/extensions/rout_rvic/src/rout_write.c new file mode 100644 index 000000000..93e4c3d9c --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_write.c @@ -0,0 +1,32 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Write routines for routing. + * + * @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 +#include + +void rout_write() { + log_info("In rout_write"); +} From 058c0c6c3fa05345070429de25ece5cdcef2a1c1 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 26 Aug 2015 11:47:40 +0200 Subject: [PATCH 003/294] Initial commit for lohman routing (dev). --- vic/drivers/classic/src/read_soilparam.c | 2 + vic/drivers/image/src/get_global_domain.c | 6 +- vic/extensions/rout_rvic/include/rout.h | 19 ++- vic/extensions/rout_rvic/src/convolve.c | 78 ++++++++++++ vic/extensions/rout_rvic/src/cshift.c | 141 ++++++++++++++++++++-- vic/extensions/rout_rvic/src/rout_alloc.c | 14 ++- vic/extensions/rout_rvic/src/rout_init.c | 40 ++++++ vic/extensions/rout_rvic/src/rout_run.c | 127 ++++++++++--------- 8 files changed, 351 insertions(+), 76 deletions(-) diff --git a/vic/drivers/classic/src/read_soilparam.c b/vic/drivers/classic/src/read_soilparam.c index 116575a60..2159c9a57 100644 --- a/vic/drivers/classic/src/read_soilparam.c +++ b/vic/drivers/classic/src/read_soilparam.c @@ -98,6 +98,7 @@ read_soilparam(FILE *soilparam, log_err("Can't find values for CELL NUMBER in soil file"); } sscanf(token, "%d", &temp.gridcel); + token = strtok(NULL, delimiters); while (token != NULL && (length = strlen(token)) == 0) { token = strtok(NULL, delimiters); @@ -106,6 +107,7 @@ read_soilparam(FILE *soilparam, log_err("Can't find values for CELL LATITUDE in soil file"); } sscanf(token, "%lf", &temp.lat); + token = strtok(NULL, delimiters); while (token != NULL && (length = strlen(token)) == 0) { token = strtok(NULL, delimiters); diff --git a/vic/drivers/image/src/get_global_domain.c b/vic/drivers/image/src/get_global_domain.c index 087302340..20ad2c33a 100644 --- a/vic/drivers/image/src/get_global_domain.c +++ b/vic/drivers/image/src/get_global_domain.c @@ -112,7 +112,8 @@ get_global_domain(char *nc_name, // get longitude - // TBD: read var id from file - get_nc_field_double(nc_name, "xc", +// get_nc_field_double(nc_name, "xc", + get_nc_field_double(nc_name, "yc", //WF d2start, d2count, var); for (i = 0; i < global_domain->ncells; i++) { // rescale to [-180., 180]. Note that the if statement is not strictly @@ -125,7 +126,8 @@ get_global_domain(char *nc_name, // get latitude // TBD: read var id from file - get_nc_field_double(nc_name, "yc", +// get_nc_field_double(nc_name, "yc", + get_nc_field_double(nc_name, "xc", d2start, d2count, var); for (i = 0; i < global_domain->ncells; i++) { global_domain->locations[i].latitude = (double) var[idx[i]]; diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index cba97a5f8..a6a27f493 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -35,9 +35,12 @@ typedef struct { size_t iSubsetLength; /*scalar - number of timesteps*/ size_t iSources; /*scalar - number of sources*/ size_t iOutlets; /*scalar - length of subset*/ - int *source2outlet_ind; /*1d array - source to outlet mapping*/ + size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ int *source_y_ind ; /*1d array - source y location*/ int *source_x_ind; /*1d array - source x location*/ + double *source_lat; /*1d array - Latitude coordinate of source grid cell*/ + double *source_lon; /*1d array - Longitude coordinate of source grid cell*/ + int *source_VIC_index; /*1d array - mapping of VIC index versus rout lat/lons*/ int *source_time_offset; /*1d array - source time offset*/ double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ @@ -65,6 +68,17 @@ void rout_finalize(void); // clean up routine for routing /****************************************************************************** * @brief Convolution function adapted from the RVIC scheme *****************************************************************************/ +void convolve_new(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + // const size_t x_size, + const int* source2outlet_ind, /*1d array - source to outlet mapping*/ + // const int* source_y_ind, /*1d array - source y location*/ + // const int* source_x_ind, /*1d array - source x location*/ + const int* source_time_offset, /*1d array - source time offset*/ + const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + //const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double* ring); void convolve(const size_t nsources, /*scalar - number of sources*/ const size_t noutlets, /*scalar - length of subset*/ const size_t subset_length, /*scalar - length of subset*/ @@ -77,6 +91,7 @@ void convolve(const size_t nsources, /*scalar - number of sources* const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ double* ring); void get_global_param_rout(FILE *gp); -void cshift(double*, int, int); +void cshift(double *, int, int, int, int); +void print_array(double *, int, int); #endif diff --git a/vic/extensions/rout_rvic/src/convolve.c b/vic/extensions/rout_rvic/src/convolve.c index a30aeb425..6c5a6bd04 100644 --- a/vic/extensions/rout_rvic/src/convolve.c +++ b/vic/extensions/rout_rvic/src/convolve.c @@ -2,6 +2,83 @@ #include #include +//function call: + // convolve_new(rout.rout_param.iSources, /*scalar - number of sources*/ + // rout.rout_param.iOutlets, /*scalar - length of subset*/ + // rout.rout_param.iSubsetLength, /*scalar - length of subset*/ + // global_domain.n_nx, + // rout.rout_param.source2outlet_ind, /*1d array - source to outlet mapping*/ + // rout.rout_param.source_y_ind, /*1d array - source y location*/ + // rout.rout_param.source_x_ind, /*1d array - source x location*/ + // rout.rout_param.source_time_offset, /*1d array - source time offset*/ + // rout.rout_param.unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + // //rout.rout_param.aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + // rout.ring); /*2d array[times][outlets] - convolution ring*/ + + + +void convolve_new(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ +// const size_t x_size, + const int* source2outlet_ind, /*1d array - source to outlet mapping*/ +// const int* source_y_ind, /*1d array - source y location*/ +// const int* source_x_ind, /*1d array - source x location*/ + const int* source_time_offset, /*1d array - source time offset*/ + const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ +// const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double* ring) /*2d array[times][outlets] - convolution ring*/ +{ + log_info("Doing convolution test!"); + size_t s, i, j; /*counters*/ + //int y, x; + int offset, outlet; /*2d indicies*/ +// int xyind; + int rind, uhind; /*1d indicies*/ + extern out_data_struct **out_data; + extern rout_struct rout; + + /*Loop through all sources*/ + for (s = 0; s < nsources; s++) { + + outlet = source2outlet_ind[s]; +// y = source_y_ind[s]; + // x = source_x_ind[s]; + offset = source_time_offset[s]; + + //1d index location + //2d-->1d indexing goes like this: ind = y*x_size + x + // xyind = y*x_size + x; + + //printf("source: %4i: , outlet: %4i: ,x: %4i: ,y: %4i ,offset: %4i ,xyind: %4i\n",s,outlet,x,y,offset,xyind); + + /* Do the convolution */ + // i is the position in the unit hydrograph + // j is the position in the ring + for (i = 0; i < subset_length; i++) { + j = i + offset; + + //1d index locations + rind = j * noutlets + outlet; + uhind = i * nsources + s; + + + // printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); +// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; + // printf(" %4i: ,%4i: ,%4i: ,%4i\n",i,rind,uhind,xyind); + // ring[i] += unit_hydrograph[uhind] * aggrunin[xyind]; // rind = noutlets + outlet + j; + + // uhind = s * subset_length + i; + // printf("new: %4i: , %4i: , %4i: ,%4i: ,%4i: ,%4i\n", s, outlet, i, rind, uhind, xyind); + +// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; +// ring[rind] += unit_hydrograph[uhind]; + //ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; + ring[rind] += (unit_hydrograph[uhind] * (out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0])); + } + } +} + void convolve(const size_t nsources, /*scalar - number of sources*/ const size_t noutlets, /*scalar - length of subset*/ const size_t subset_length, /*scalar - length of subset*/ @@ -40,6 +117,7 @@ void convolve(const size_t nsources, /*scalar - number of sources* //1d index locations rind = j * noutlets + outlet; uhind = i * nsources + s; + printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; } diff --git a/vic/extensions/rout_rvic/src/cshift.c b/vic/extensions/rout_rvic/src/cshift.c index b3a1fa373..a1afb799d 100644 --- a/vic/extensions/rout_rvic/src/cshift.c +++ b/vic/extensions/rout_rvic/src/cshift.c @@ -1,16 +1,133 @@ #include #include -void cshift(double *a, int width, int offset) -{ - int i; - double b; - - b=*(a + width*offset); - for (i = 0; i != width - 1; i++) { - *(a + width*offset + i) = *(a + width*offset + i+1); - } - *(a + width*offset + i) = b; - - +void cshift(double *data, int nx, int ny, int axis, int direction) { + int x, y; + double b; + + if (axis == 0 && direction == 1) { + for (y = 0; y != ny; y++) { + b = *(data + y); + for (x = 0; x != nx - 1; x++) { + *(data + y + ny * x) = *(data + y + ny * (x + 1)); + } + *(data + y + ny * x) = b; + } + } + + if (axis == 0 && direction == -1) { + for (y = 0; y != ny; y++) { + b = *(data + y + ny * (nx - 1)); + for (x = nx - 1; x >= 0; x--) { + *(data + y + ny * (x + 1)) = *(data + y + ny * x); + } + *(data + y) = b; + } + } + + if (axis == 1 && direction == 1) { + for (x = 0; x < nx; x++) { + b = *(data + x * ny); + for (y = 0; y != ny; y++) { + *(data + y + ny * x) = *(data + y + 1 + ny * x); + } + *(data + y - 1 + ny * x) = b; + } + } + + if (axis == 1 && direction == -1) { + for (x = 0; x < nx; x++) { + b = *(data + ny - 1 + ny * x); + for (y = ny - 2; y >= 0; y--) { + *(data + y + 1 + ny * x) = *(data + y + ny * x); + } + *(data + x * ny) = b; + } + } +} + +void print_array(double *data, int nx, int ny) { + int x, y; + for (y = 0; y != ny; y++) { + for (x = 0; x != nx; x++) { + printf("%3i:%9.6f ",(int)(x * ny + y),data[x * ny + y]); + } + printf("\n"); + } +} + +#include /* for CHAR_BIT */ +#include +#include +#include + +#define BITMASK(b) (1 << ((b) % CHAR_BIT)) +#define BITSLOT(b) ((b) / CHAR_BIT) +#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b)) +#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b)) +#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) +#define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT) + +void Print2DArray(double *A, int nr, int nc) { + int r, c; + for (r = 0; r < nr; r++) { + for (c = 0; c < nc; c++) + printf("%7.1f", *(A + r * nc + c)); + + printf("\n"); + } + printf("\n\n"); +} + +// Non-square matrix transpose of matrix of size r x c and base address data + +void MatrixInplaceTranspose(double *data, int r, int c) { + int size = r * c - 1; + double temp1, temp2; // holds element to be replaced, eventually becomes next element to move + int next; // location of 'temp1' to be moved + int cycleBegin; // holds start of cycle + int i; // iterator + + char bitarray[BITNSLOTS(size)]; + memset(bitarray, 0, BITNSLOTS(size)); + + BITSET(bitarray, 0); + BITSET(bitarray, size); + + i = 1; // Note that data[0] and data[size-1] won't move + while (i < size) { + cycleBegin = i; + temp1 = *(data + i); + do { + next = (i * r) % size; + //swap + temp2 = *(data + next); + *(data + next) = temp1; + temp1 = temp2; + BITSET(bitarray, i); + i = next; + } while (i != cycleBegin); + + // Get Next Move + for (i = 1; i < size && BITTEST(bitarray, i); i++); + } +} + +// Driver program to test above function + +int test_matrix(void) { + int r = 5, c = 6; + int size = r*c; + double *A; + int i; + A = (double *) malloc(size * sizeof (double)); + + for (i = 0; i < size; i++) + A[i] = i + 11.1; + + Print2DArray(A, r, c); + MatrixInplaceTranspose(A, r, c); + Print2DArray(A, c, r); + + return 0; } diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index f6f6e830a..97ce93d27 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -44,7 +44,7 @@ void rout_alloc(void) rout.rout_param.iSources = get_nc_dimension(rout.param_filename, "sources"); // Allocate memory in rout param_struct - rout.rout_param.source2outlet_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + rout.rout_param.source2outlet_ind = (size_t *) malloc (rout.rout_param.iSources * sizeof (size_t)); if (rout.rout_param.source2outlet_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source2outlet_ind()."); } @@ -60,6 +60,18 @@ void rout_alloc(void) if (rout.rout_param.source_y_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_y_ind()."); } + rout.rout_param.source_lat = (double *) malloc (rout.rout_param.iSources * sizeof (double)); + if (rout.rout_param.source_lat == NULL) { + log_err("Memory allocation error in rout.rout_param.source_lat()."); + } + rout.rout_param.source_lon = (double *) malloc (rout.rout_param.iSources * sizeof (double)); + if (rout.rout_param.source_lon == NULL) { + log_err("Memory allocation error in rout.rout_param.source_lon()."); + } + rout.rout_param.source_VIC_index = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + if (rout.rout_param.source_VIC_index == NULL) { + log_err("Memory allocation error in rout.rout_param.source_VIC_index()."); + } rout.rout_param.unit_hydrograph = (double *) malloc (rout.rout_param.iSources * rout.rout_param.iSubsetLength * sizeof (double)); if (rout.rout_param.unit_hydrograph == NULL) { log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 8c2268c9f..17afbc127 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -37,6 +37,8 @@ void rout_init(void) { extern rout_struct rout; + extern domain_struct global_domain; + int *ivar = NULL; double *dvar = NULL; @@ -107,6 +109,22 @@ rout_init(void) rout.rout_param.source_y_ind[i] = (int) ivar[i]; } + // source_lat: Latitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "source_lat", + &i1start, &rout.rout_param.iSources, dvar); + for (i = 0; i < rout.rout_param.iSources; i++) { + rout.rout_param.source_lat[i] = (double) dvar[i]; + } + + // source_lat: Longitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "source_lon", + &i1start, &rout.rout_param.iSources, dvar); + for (i = 0; i < rout.rout_param.iSources; i++) { + rout.rout_param.source_lon[i] = (double) dvar[i]; + } + // Unit Hydrograph: get_nc_field_double(rout.param_filename, "unit_hydrograph", @@ -115,6 +133,28 @@ rout_init(void) rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; } + // TODO: MAPPING! + // TODO: Lat lon omgedraaid in netcdf?!?!??!?! + // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! + // Filling the VIC indices that corresponds to the routing file lat/lons + // Which source point of the routing corresponds to which gridcell index of VIC + size_t iSource; + for (iSource = 0; iSource < rout.rout_param.iSources; iSource++) { + for (i = 0; i < global_domain.ncells; i++) { + if (rout.rout_param.source_lat[iSource] == global_domain.locations[i].latitude && + rout.rout_param.source_lon[iSource] == global_domain.locations[i].longitude) { + rout.rout_param.source_VIC_index[iSource] = i; + } + } + } + + // TODO Weghalen + // Tijdelijk + printf("\nsource, index of VIC gridcell: \n "); + for (iSource = 0; iSource < rout.rout_param.iSources; iSource++) { + printf("%3i, %7i \n ",(int)(iSource),rout.rout_param.source_VIC_index[iSource]); + } + // cleanup free(ivar); free(dvar); diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index b55b84d71..26555df55 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -29,78 +29,87 @@ #include #include -void rout_run(void) -{ - log_info("In Routing Lohmann Model"); +void rout_run(void) { + //log_info("In Routing Lohmann Model"); + + extern rout_struct rout; + extern domain_struct global_domain; + extern out_data_struct **out_data; + size_t i, j, s; + + ///TESTS!!! + printf("\nmapping test!!!..."); + + for (j = 0; j < rout.rout_param.iSources; j++) { + printf("\nsource: %2zu, outlet_ind: %2zu, Lon_source: , %8.4f, Lat_source: %8.4f", j, rout.rout_param.source2outlet_ind[j], + rout.rout_param.source_lon[j], + rout.rout_param.source_lat[j]); + } + + - extern rout_struct rout; - extern domain_struct global_domain; - extern out_data_struct **out_data; - size_t i; // even worse stuff here for (i = 0; i < global_domain.ncells; i++) { - rout.rout_param.aggrunin[i]= out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; + rout.rout_param.aggrunin[i] = out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; } - //TODO: Check if nOutlets in ROUTING is the same (same lat lons and same length) as VIC - // completely useless double stuff here - - log_info("Tolkien here"); - size_t j; - size_t ni = rout.rout_param.iSubsetLength; - size_t nj = rout.rout_param.iOutlets; - -// printf("\nThe Ring...\n"); -// for (j=0;j Date: Mon, 14 Sep 2015 13:38:15 +0200 Subject: [PATCH 004/294] Small update (eg Makefile) --- vic/drivers/image/Makefile | 142 ++----------------------------------- 1 file changed, 7 insertions(+), 135 deletions(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 29b0e8bca..dcc9f3f80 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -68,13 +68,12 @@ else CC = mpicc-mpich-mp endif -<<<<<<< HEAD # set routing extension here (rout_stub means: no routing) -ROUT=rout_stub -#ROUT=rout_rvic +#ROUT=rout_stub +ROUT=rout_rvic include ${EXTPATH}/${ROUT}/rout.mk -======= + # Set the log level # To turn off warning statements, set LOG_LVL >= 30 # | Level | Numeric value | @@ -84,7 +83,6 @@ include ${EXTPATH}/${ROUT}/rout.mk # | INFO | < 20 | # | DEBUG | < 10 | LOG_LVL = 5 ->>>>>>> 04fa923e12e7b33e74586c174b473073e95d2ee8 # set includes INCLUDES = -I ${DRIVERPATH}/include -I ${VICPATH}/include -I ${SHAREDPATH}/include -I ${NETCDFPATH}/include -I ${MPIPATH}/include -I ${EXTPATH}/${ROUT}/include @@ -112,142 +110,19 @@ EXT = .exe # MOST USERS DO NOT NEED TO MODIFY BELOW THIS LINE # ----------------------------------------------------------------------- -<<<<<<< HEAD -HDRS = ${VICPATH}/include/vic_def.h \ - ${VICPATH}/include/vic_run.h \ - ${DRIVERPATH}/include/vic_driver_image.h \ - ${SHAREDPATH}/include/vic_driver_shared.h \ - ${VICPATH}/include/vic_physical_constants.h \ - ${VICPATH}/include/vic_log.h \ - ${INCL_ROUT} - -OBJS = \ - ${DRIVERPATH}/src/alloc_atmos.o \ - ${DRIVERPATH}/src/alloc_veg_hist.o \ - ${DRIVERPATH}/src/display_current_settings.o \ - ${DRIVERPATH}/src/get_global_domain.o \ - ${DRIVERPATH}/src/get_global_param.o \ - ${DRIVERPATH}/src/get_nc_dimension.o \ - ${DRIVERPATH}/src/get_nc_field.o \ - ${DRIVERPATH}/src/init_library.o \ - ${DRIVERPATH}/src/initialize_energy.o \ - ${DRIVERPATH}/src/initialize_model_state.o \ - ${DRIVERPATH}/src/output_list_utils.o \ - ${DRIVERPATH}/src/parse_output_info.o \ - ${DRIVERPATH}/src/print_library_image.o \ - ${DRIVERPATH}/src/put_nc_field.o \ - ${DRIVERPATH}/src/vic_alloc.o \ - ${DRIVERPATH}/src/vic_finalize.o \ - ${DRIVERPATH}/src/vic_force.o \ - ${DRIVERPATH}/src/vic_image.o \ - ${DRIVERPATH}/src/vic_image_run.o \ - ${DRIVERPATH}/src/vic_init.o \ - ${DRIVERPATH}/src/vic_init_output.o \ - ${DRIVERPATH}/src/vic_mpi_support.o \ - ${DRIVERPATH}/src/vic_nc_info.o \ - ${DRIVERPATH}/src/vic_restore.o \ - ${DRIVERPATH}/src/vic_start.o \ - ${DRIVERPATH}/src/vic_store.o \ - ${DRIVERPATH}/src/vic_write.o \ - ${SHAREDPATH}/src/calc_root_fraction.o \ - ${SHAREDPATH}/src/cmd_proc.o \ - ${SHAREDPATH}/src/compress_files.o \ - ${SHAREDPATH}/src/compute_treeline.o \ - ${SHAREDPATH}/src/free_all_vars.o \ - ${SHAREDPATH}/src/free_vegcon.o \ - ${SHAREDPATH}/src/get_dist.o \ - ${SHAREDPATH}/src/get_parameters.o \ - ${SHAREDPATH}/src/initialize_files.o \ - ${SHAREDPATH}/src/initialize_global.o \ - ${SHAREDPATH}/src/initialize_options.o \ - ${SHAREDPATH}/src/initialize_parameters.o \ - ${SHAREDPATH}/src/initialize_snow.o \ - ${SHAREDPATH}/src/initialize_soil.o \ - ${SHAREDPATH}/src/initialize_veg.o \ - ${SHAREDPATH}/src/make_all_vars.o \ - ${SHAREDPATH}/src/make_cell_data.o \ - ${SHAREDPATH}/src/make_dmy.o \ - ${SHAREDPATH}/src/make_energy_bal.o \ - ${SHAREDPATH}/src/make_snow_data.o \ - ${SHAREDPATH}/src/make_veg_var.o \ - ${SHAREDPATH}/src/open_file.o \ - ${SHAREDPATH}/src/print_library_shared.o \ - ${SHAREDPATH}/src/soil_moisture_from_water_table.o \ - ${SHAREDPATH}/src/vic_log.o \ - ${SHAREDPATH}/src/vic_time.o \ - ${VICPATH}/src/CalcAerodynamic.o \ - ${VICPATH}/src/CalcBlowingSnow.o \ - ${VICPATH}/src/IceEnergyBalance.o \ - ${VICPATH}/src/SnowPackEnergyBalance.o \ - ${VICPATH}/src/StabilityCorrection.o \ - ${VICPATH}/src/advected_sensible_heat.o \ - ${VICPATH}/src/arno_evap.o \ - ${VICPATH}/src/calc_Nscale_factors.o \ - ${VICPATH}/src/calc_atmos_energy_bal.o \ - ${VICPATH}/src/calc_rainonly.o \ - ${VICPATH}/src/calc_snow_coverage.o \ - ${VICPATH}/src/calc_surf_energy_bal.o \ - ${VICPATH}/src/calc_veg_params.o \ - ${VICPATH}/src/calc_water_energy_balance_errors.o \ - ${VICPATH}/src/canopy_assimilation.o \ - ${VICPATH}/src/canopy_evap.o \ - ${VICPATH}/src/compute_coszen.o \ - ${VICPATH}/src/compute_pot_evap.o \ - ${VICPATH}/src/compute_soil_resp.o \ - ${VICPATH}/src/compute_zwt.o \ - ${VICPATH}/src/correct_precip.o \ - ${VICPATH}/src/estimate_T1.o \ - ${VICPATH}/src/faparl.o \ - ${VICPATH}/src/frozen_soil.o \ - ${VICPATH}/src/func_atmos_energy_bal.o \ - ${VICPATH}/src/func_atmos_moist_bal.o \ - ${VICPATH}/src/func_canopy_energy_bal.o \ - ${VICPATH}/src/func_surf_energy_bal.o \ - ${VICPATH}/src/ice_melt.o \ - ${VICPATH}/src/initialize_lake.o \ - ${VICPATH}/src/lakes.eb.o \ - ${VICPATH}/src/latent_heat_from_snow.o \ - ${VICPATH}/src/massrelease.o \ - ${VICPATH}/src/modify_Ksat.o \ - ${VICPATH}/src/newt_raph_func_fast.o \ - ${VICPATH}/src/penman.o \ - ${VICPATH}/src/photosynth.o \ - ${VICPATH}/src/physics.o \ - ${VICPATH}/src/prepare_full_energy.o \ - ${VICPATH}/src/put_data.o \ - ${VICPATH}/src/root_brent.o \ - ${VICPATH}/src/runoff.o \ - ${VICPATH}/src/snow_intercept.o \ - ${VICPATH}/src/snow_melt.o \ - ${VICPATH}/src/snow_utility.o \ - ${VICPATH}/src/soil_carbon_balance.o \ - ${VICPATH}/src/soil_conduction.o \ - ${VICPATH}/src/soil_thermal_eqn.o \ - ${VICPATH}/src/solve_snow.o \ - ${VICPATH}/src/surface_fluxes.o \ - ${VICPATH}/src/svp.o \ - ${VICPATH}/src/vic_run.o \ - ${VICPATH}/src/water_energy_balance.o \ - ${VICPATH}/src/water_under_ice.o \ - ${VICPATH}/src/write_layer.o \ - ${VICPATH}/src/write_vegvar.o \ - ${VICPATH}/src/zero_output_list.o \ - ${OBJS_ROUT} - -SRCS = $(OBJS:%.o=%.c) -======= HDRS = \ $(wildcard ${VICPATH}/include/*.h) \ $(wildcard ${DRIVERPATH}/include/*.h) \ - $(wildcard ${SHAREDPATH}/include/*.h) + $(wildcard ${SHAREDPATH}/include/*.h) \ + $(wildcard ${EXTPATH}/${ROUT}/include/*.h) SRCS = \ $(wildcard ${VICPATH}/src/*.c) \ $(wildcard ${DRIVERPATH}/src/*.c) \ - $(wildcard ${SHAREDPATH}/src/*.c) + $(wildcard ${SHAREDPATH}/src/*.c) \ + $(wildcard ${EXTPATH}/${ROUT}/src/*.c) OBJS = $(SRCS:%.o=%.c) ->>>>>>> 04fa923e12e7b33e74586c174b473073e95d2ee8 all: make depend @@ -264,12 +139,9 @@ full: make model clean:: -<<<<<<< HEAD /bin/rm -f ${DRIVERPATH}/src/*.o ${SHAREDPATH}/src/*.o ${VICPATH}/src/*.o core ${EXTPATH}/${ROUT}/src/*.o log ${DRIVERPATH}/src/*~ ${SHAREDPATH}/src/*.~ ${VICPATH}/src/*~ ${EXTPATH}/${ROUT}/src/*~ vic_image -======= \rm -f core log \rm -rf ${COMPEXE}${EXT} ${COMPEXE}${EXT}.dSYM ->>>>>>> 04fa923e12e7b33e74586c174b473073e95d2ee8 model: $(OBJS) $(CC) -o ${COMPEXE}${EXT} $(OBJS) $(CFLAGS) $(LIBRARY) From c06ae0ae886ce0875d505a2f2673a547d7151d5f Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 15 Sep 2015 11:40:27 +0200 Subject: [PATCH 005/294] *Created: OUT_DISCHARGE variable for NetCDF *Made mapping: rout-outlet-index to VIC-index *Filled: OUT_DISCHARGE variable --- .gitignore | 6 +++ vic/drivers/classic/src/read_soilparam.c | 2 - vic/drivers/image/Makefile | 1 - vic/drivers/image/src/output_list_utils.c | 1 + vic/drivers/image/src/vic_nc_info.c | 1 + vic/extensions/rout_rvic/include/rout.h | 20 ++++++---- vic/extensions/rout_rvic/src/rout_alloc.c | 16 ++++++++ vic/extensions/rout_rvic/src/rout_init.c | 45 ++++++++++++++++++++--- vic/extensions/rout_rvic/src/rout_run.c | 18 ++++----- vic/vic_run/include/vic_def.h | 1 + 10 files changed, 86 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 994034abe..395ae0326 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,9 @@ TAGS # Python stuff .ipynb_checkpoints .eggs + +# Netbeans stuff +nbproject + +# Test folders +image_test diff --git a/vic/drivers/classic/src/read_soilparam.c b/vic/drivers/classic/src/read_soilparam.c index 2159c9a57..116575a60 100644 --- a/vic/drivers/classic/src/read_soilparam.c +++ b/vic/drivers/classic/src/read_soilparam.c @@ -98,7 +98,6 @@ read_soilparam(FILE *soilparam, log_err("Can't find values for CELL NUMBER in soil file"); } sscanf(token, "%d", &temp.gridcel); - token = strtok(NULL, delimiters); while (token != NULL && (length = strlen(token)) == 0) { token = strtok(NULL, delimiters); @@ -107,7 +106,6 @@ read_soilparam(FILE *soilparam, log_err("Can't find values for CELL LATITUDE in soil file"); } sscanf(token, "%lf", &temp.lat); - token = strtok(NULL, delimiters); while (token != NULL && (length = strlen(token)) == 0) { token = strtok(NULL, delimiters); diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index dcc9f3f80..03bf8c8e4 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -139,7 +139,6 @@ full: make model clean:: - /bin/rm -f ${DRIVERPATH}/src/*.o ${SHAREDPATH}/src/*.o ${VICPATH}/src/*.o core ${EXTPATH}/${ROUT}/src/*.o log ${DRIVERPATH}/src/*~ ${SHAREDPATH}/src/*.~ ${VICPATH}/src/*~ ${EXTPATH}/${ROUT}/src/*~ vic_image \rm -f core log \rm -rf ${COMPEXE}${EXT} ${COMPEXE}${EXT}.dSYM diff --git a/vic/drivers/image/src/output_list_utils.c b/vic/drivers/image/src/output_list_utils.c index 1e16be750..074e07d83 100644 --- a/vic/drivers/image/src/output_list_utils.c +++ b/vic/drivers/image/src/output_list_utils.c @@ -78,6 +78,7 @@ create_output_list() strcpy(out_data[OUT_DELSOILMOIST].varname, "OUT_DELSOILMOIST"); /* change in soil water content [mm] */ strcpy(out_data[OUT_DELSWE].varname, "OUT_DELSWE"); /* change in snow water equivalent [mm] */ strcpy(out_data[OUT_DELSURFSTOR].varname, "OUT_DELSURFSTOR"); /* change in surface liquid water storage [mm] */ + strcpy(out_data[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); /* river discharge [m3] (ALMA_OUTPUT: [m3/s]) */ strcpy(out_data[OUT_EVAP].varname, "OUT_EVAP"); /* total net evaporation [mm] (ALMA_OUTPUT: [mm/s]) */ strcpy(out_data[OUT_EVAP_BARE].varname, "OUT_EVAP_BARE"); /* net evaporation from bare soil [mm] (ALMA_OUTPUT: [mm/s]) */ strcpy(out_data[OUT_EVAP_CANOP].varname, "OUT_EVAP_CANOP"); /* net evaporation from canopy interception [mm] (ALMA_OUTPUT: [mm/s]) */ diff --git a/vic/drivers/image/src/vic_nc_info.c b/vic/drivers/image/src/vic_nc_info.c index b3bf01b14..88c12d64f 100644 --- a/vic/drivers/image/src/vic_nc_info.c +++ b/vic/drivers/image/src/vic_nc_info.c @@ -258,6 +258,7 @@ vic_nc_info(nc_file_struct *nc_hist_file, strncpy(nc_vars[i].nc_units, "m3", MAXSTRING); break; // rate in m3 per timestep, changed to m3/s for ALMA_OUTPUT + case OUT_DISCHARGE: case OUT_LAKE_BF_IN_V: case OUT_LAKE_BF_OUT_V: case OUT_LAKE_CHAN_IN_V: diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index a6a27f493..57b202d4a 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -32,18 +32,21 @@ * @brief Routing Structs *****************************************************************************/ typedef struct { - size_t iSubsetLength; /*scalar - number of timesteps*/ - size_t iSources; /*scalar - number of sources*/ - size_t iOutlets; /*scalar - length of subset*/ + size_t iSubsetLength; /*scalar - number of timesteps*/ + size_t iSources; /*scalar - number of sources*/ + size_t iOutlets; /*scalar - length of subset*/ size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ int *source_y_ind ; /*1d array - source y location*/ int *source_x_ind; /*1d array - source x location*/ - double *source_lat; /*1d array - Latitude coordinate of source grid cell*/ - double *source_lon; /*1d array - Longitude coordinate of source grid cell*/ - int *source_VIC_index; /*1d array - mapping of VIC index versus rout lat/lons*/ + double *source_lat; /*1d array - Latitude coordinate of source grid cell*/ + double *source_lon; /*1d array - Longitude coordinate of source grid cell*/ + double *outlet_lat; /*1d array - Latitude coordinate of outlet grid cell*/ + double *outlet_lon; /*1d array - Longitude coordinate of outlet grid cell*/ + int *source_VIC_index; /*1d array - mapping of routing-source index to VIC index*/ + int *outlet_VIC_index; /*1d array - mapping of routing-outlet index to VIC index*/ int *source_time_offset; /*1d array - source time offset*/ - double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ - double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ + double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ + double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ } rout_param_struct; /****************************************************************************** @@ -53,6 +56,7 @@ typedef struct { char param_filename[MAXSTRING]; rout_param_struct rout_param; double *ring; + double *discharge; } rout_struct; /****************************************************************************** diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 97ce93d27..946be6450 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -72,6 +72,18 @@ void rout_alloc(void) if (rout.rout_param.source_VIC_index == NULL) { log_err("Memory allocation error in rout.rout_param.source_VIC_index()."); } + rout.rout_param.outlet_lat = (double *) malloc (rout.rout_param.iOutlets * sizeof (double)); + if (rout.rout_param.outlet_lat == NULL) { + log_err("Memory allocation error in rout.rout_param.outlet_lat()."); + } + rout.rout_param.outlet_lon = (double *) malloc (rout.rout_param.iOutlets * sizeof (double)); + if (rout.rout_param.outlet_lon == NULL) { + log_err("Memory allocation error in rout.rout_param.outlet_lon()."); + } + rout.rout_param.outlet_VIC_index = (int *) malloc (rout.rout_param.iOutlets * sizeof (int)); + if (rout.rout_param.outlet_VIC_index == NULL) { + log_err("Memory allocation error in rout.rout_param.outlet_VIC_index()."); + } rout.rout_param.unit_hydrograph = (double *) malloc (rout.rout_param.iSources * rout.rout_param.iSubsetLength * sizeof (double)); if (rout.rout_param.unit_hydrograph == NULL) { log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); @@ -80,6 +92,10 @@ void rout_alloc(void) if (rout.rout_param.aggrunin == NULL) { log_err("Memory allocation error in rout.rout_param.aggrunin()."); } + rout.discharge = (double *)malloc (local_domain.ncells * sizeof (double)); + if (rout.discharge == NULL) { + log_err("Memory allocation error in rout.rout_param.discharge()."); + } // Allocate memory for the ring rout.ring = (double *)malloc (rout.rout_param.iSubsetLength * rout.rout_param.iOutlets * sizeof (double)); diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 17afbc127..1cfb68d4e 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -77,6 +77,11 @@ rout_init(void) } } + // discharge + for (j=0;j Date: Mon, 28 Sep 2015 14:41:34 +0200 Subject: [PATCH 006/294] uncrusified routing related files --- .gitignore | 2 + vic/drivers/image/src/vic_image.c | 6 +- vic/extensions/rout_rvic/include/rout.h | 77 +++++---- vic/extensions/rout_rvic/src/convolve.c | 158 ++++++++++--------- vic/extensions/rout_rvic/src/cshift.c | 70 +++++--- vic/extensions/rout_rvic/src/rout_alloc.c | 73 ++++++--- vic/extensions/rout_rvic/src/rout_finalize.c | 3 +- vic/extensions/rout_rvic/src/rout_init.c | 133 ++++++++-------- vic/extensions/rout_rvic/src/rout_run.c | 65 +++++--- vic/extensions/rout_rvic/src/rout_start.c | 21 +-- vic/extensions/rout_rvic/src/rout_write.c | 4 +- vic/extensions/rout_stub/src/rout.c | 20 ++- 12 files changed, 359 insertions(+), 273 deletions(-) diff --git a/.gitignore b/.gitignore index 395ae0326..bf8aaceb7 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ nbproject # Test folders image_test +uncrust.sh +*.exe diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index c9bc88cef..06e5fa345 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -100,10 +100,10 @@ main(int argc, // read global parameters vic_start(); - + // read global parameters for routing rout_start(); // Routing routine (extension) - + // allocate memory vic_alloc(); @@ -148,7 +148,7 @@ main(int argc, // clean up vic_finalize(); - // clean up routing + // clean up routing rout_finalize(); // Routing routine (extension) // finalize MPI diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 57b202d4a..00f4ebcfa 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -32,31 +32,31 @@ * @brief Routing Structs *****************************************************************************/ typedef struct { - size_t iSubsetLength; /*scalar - number of timesteps*/ - size_t iSources; /*scalar - number of sources*/ - size_t iOutlets; /*scalar - length of subset*/ - size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ - int *source_y_ind ; /*1d array - source y location*/ - int *source_x_ind; /*1d array - source x location*/ - double *source_lat; /*1d array - Latitude coordinate of source grid cell*/ - double *source_lon; /*1d array - Longitude coordinate of source grid cell*/ - double *outlet_lat; /*1d array - Latitude coordinate of outlet grid cell*/ - double *outlet_lon; /*1d array - Longitude coordinate of outlet grid cell*/ - int *source_VIC_index; /*1d array - mapping of routing-source index to VIC index*/ - int *outlet_VIC_index; /*1d array - mapping of routing-outlet index to VIC index*/ - int *source_time_offset; /*1d array - source time offset*/ - double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ - double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ + size_t iSubsetLength; /*scalar - number of timesteps*/ + size_t iSources; /*scalar - number of sources*/ + size_t iOutlets; /*scalar - length of subset*/ + size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ + int *source_y_ind; /*1d array - source y location*/ + int *source_x_ind; /*1d array - source x location*/ + double *source_lat; /*1d array - Latitude coordinate of source grid cell*/ + double *source_lon; /*1d array - Longitude coordinate of source grid cell*/ + double *outlet_lat; /*1d array - Latitude coordinate of outlet grid cell*/ + double *outlet_lon; /*1d array - Longitude coordinate of outlet grid cell*/ + int *source_VIC_index; /*1d array - mapping of routing-source index to VIC index*/ + int *outlet_VIC_index; /*1d array - mapping of routing-outlet index to VIC index*/ + int *source_time_offset; /*1d array - source time offset*/ + double *unit_hydrograph; /*2d array[times][sources] - unit hydrographs*/ + double *aggrunin; /*2d array[ysize][xsize] - vic runoff flux*/ } rout_param_struct; /****************************************************************************** * @brief main routing Struct *****************************************************************************/ typedef struct { - char param_filename[MAXSTRING]; - rout_param_struct rout_param; - double *ring; - double *discharge; + char param_filename[MAXSTRING]; + rout_param_struct rout_param; + double *ring; + double *discharge; } rout_struct; /****************************************************************************** @@ -73,27 +73,26 @@ void rout_finalize(void); // clean up routine for routing * @brief Convolution function adapted from the RVIC scheme *****************************************************************************/ void convolve_new(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ - // const size_t x_size, - const int* source2outlet_ind, /*1d array - source to outlet mapping*/ - // const int* source_y_ind, /*1d array - source y location*/ - // const int* source_x_ind, /*1d array - source x location*/ - const int* source_time_offset, /*1d array - source time offset*/ - const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - //const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double* ring); + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + // const size_t x_size, + const int *source2outlet_ind, /*1d array - source to outlet mapping*/ + // const int* source_y_ind, /*1d array - source y location*/ + // const int* source_x_ind, /*1d array - source x location*/ + const int *source_time_offset, /*1d array - source time offset*/ + const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + // const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double *ring); void convolve(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ - const size_t x_size, - const int* source2outlet_ind, /*1d array - source to outlet mapping*/ - const int* source_y_ind, /*1d array - source y location*/ - const int* source_x_ind, /*1d array - source x location*/ - const int* source_time_offset, /*1d array - source time offset*/ - const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double* ring); + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + const size_t x_size, const int*source2outlet_ind, /*1d array - source to outlet mapping*/ + const int*source_y_ind, /*1d array - source y location*/ + const int*source_x_ind, /*1d array - source x location*/ + const int*source_time_offset, /*1d array - source time offset*/ + const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + const double*aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double*ring); void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); void print_array(double *, int, int); diff --git a/vic/extensions/rout_rvic/src/convolve.c b/vic/extensions/rout_rvic/src/convolve.c index 6c5a6bd04..f5b0b597f 100644 --- a/vic/extensions/rout_rvic/src/convolve.c +++ b/vic/extensions/rout_rvic/src/convolve.c @@ -2,55 +2,54 @@ #include #include -//function call: - // convolve_new(rout.rout_param.iSources, /*scalar - number of sources*/ - // rout.rout_param.iOutlets, /*scalar - length of subset*/ - // rout.rout_param.iSubsetLength, /*scalar - length of subset*/ - // global_domain.n_nx, - // rout.rout_param.source2outlet_ind, /*1d array - source to outlet mapping*/ - // rout.rout_param.source_y_ind, /*1d array - source y location*/ - // rout.rout_param.source_x_ind, /*1d array - source x location*/ - // rout.rout_param.source_time_offset, /*1d array - source time offset*/ - // rout.rout_param.unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - // //rout.rout_param.aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - // rout.ring); /*2d array[times][outlets] - convolution ring*/ - - - -void convolve_new(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ -// const size_t x_size, - const int* source2outlet_ind, /*1d array - source to outlet mapping*/ -// const int* source_y_ind, /*1d array - source y location*/ -// const int* source_x_ind, /*1d array - source x location*/ - const int* source_time_offset, /*1d array - source time offset*/ - const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ -// const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double* ring) /*2d array[times][outlets] - convolution ring*/ +// function call: +// convolve_new(rout.rout_param.iSources, /*scalar - number of sources*/ +// rout.rout_param.iOutlets, /*scalar - length of subset*/ +// rout.rout_param.iSubsetLength, /*scalar - length of subset*/ +// global_domain.n_nx, +// rout.rout_param.source2outlet_ind, /*1d array - source to outlet mapping*/ +// rout.rout_param.source_y_ind, /*1d array - source y location*/ +// rout.rout_param.source_x_ind, /*1d array - source x location*/ +// rout.rout_param.source_time_offset, /*1d array - source time offset*/ +// rout.rout_param.unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ +// //rout.rout_param.aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ +// rout.ring); /*2d array[times][outlets] - convolution ring*/ + + +void +convolve_new(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ +// const size_t x_size, + const int *source2outlet_ind, /*1d array - source to outlet mapping*/ +// const int* source_y_ind, /*1d array - source y location*/ +// const int* source_x_ind, /*1d array - source x location*/ + const int *source_time_offset, /*1d array - source time offset*/ + const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ +// const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double *ring) /*2d array[times][outlets] - convolution ring*/ { log_info("Doing convolution test!"); - size_t s, i, j; /*counters*/ - //int y, x; - int offset, outlet; /*2d indicies*/ -// int xyind; - int rind, uhind; /*1d indicies*/ - extern out_data_struct **out_data; - extern rout_struct rout; + size_t s, i, j; /*counters*/ + // int y, x; + int offset, outlet; /*2d indicies*/ +// int xyind; + int rind, uhind; /*1d indicies*/ + extern out_data_struct **out_data; + extern rout_struct rout; /*Loop through all sources*/ for (s = 0; s < nsources; s++) { - outlet = source2outlet_ind[s]; -// y = source_y_ind[s]; - // x = source_x_ind[s]; +// y = source_y_ind[s]; +// x = source_x_ind[s]; offset = source_time_offset[s]; - //1d index location - //2d-->1d indexing goes like this: ind = y*x_size + x - // xyind = y*x_size + x; - - //printf("source: %4i: , outlet: %4i: ,x: %4i: ,y: %4i ,offset: %4i ,xyind: %4i\n",s,outlet,x,y,offset,xyind); + // 1d index location + // 2d-->1d indexing goes like this: ind = y*x_size + x + // xyind = y*x_size + x; + + // printf("source: %4i: , outlet: %4i: ,x: %4i: ,y: %4i ,offset: %4i ,xyind: %4i\n",s,outlet,x,y,offset,xyind); /* Do the convolution */ // i is the position in the unit hydrograph @@ -58,55 +57,62 @@ void convolve_new(const size_t nsources, /*scalar - number of sour for (i = 0; i < subset_length; i++) { j = i + offset; - //1d index locations + // 1d index locations rind = j * noutlets + outlet; uhind = i * nsources + s; - - // printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); -// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; - // printf(" %4i: ,%4i: ,%4i: ,%4i\n",i,rind,uhind,xyind); - // ring[i] += unit_hydrograph[uhind] * aggrunin[xyind]; // rind = noutlets + outlet + j; - - // uhind = s * subset_length + i; - // printf("new: %4i: , %4i: , %4i: ,%4i: ,%4i: ,%4i\n", s, outlet, i, rind, uhind, xyind); - -// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; -// ring[rind] += unit_hydrograph[uhind]; - //ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; - ring[rind] += (unit_hydrograph[uhind] * (out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0])); - } - } + + // printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); +// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; + // printf(" %4i: ,%4i: ,%4i: ,%4i\n",i,rind,uhind,xyind); + // ring[i] += unit_hydrograph[uhind] * aggrunin[xyind]; // rind = noutlets + outlet + j; + + // uhind = s * subset_length + i; + // printf("new: %4i: , %4i: , %4i: ,%4i: ,%4i: ,%4i\n", s, outlet, i, rind, uhind, xyind); + +// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; +// ring[rind] += unit_hydrograph[uhind]; + // ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; + ring[rind] += + (unit_hydrograph[uhind] * + (out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF]. + data[0] + + + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW]. + data[0 + ])); + } + } } -void convolve(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ - const size_t x_size, - const int* source2outlet_ind, /*1d array - source to outlet mapping*/ - const int* source_y_ind, /*1d array - source y location*/ - const int* source_x_ind, /*1d array - source x location*/ - const int* source_time_offset, /*1d array - source time offset*/ - const double* unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double* ring) /*2d array[times][outlets] - convolution ring*/ +void +convolve(const size_t nsources, /*scalar - number of sources*/ + const size_t noutlets, /*scalar - length of subset*/ + const size_t subset_length, /*scalar - length of subset*/ + const size_t x_size, + const int *source2outlet_ind, /*1d array - source to outlet mapping*/ + const int *source_y_ind, /*1d array - source y location*/ + const int *source_x_ind, /*1d array - source x location*/ + const int *source_time_offset, /*1d array - source time offset*/ + const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ + const double*aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ + double *ring) /*2d array[times][outlets] - convolution ring*/ { log_info("Doing convolution test!"); size_t s, i, j; /*counters*/ - int y, x, offset, outlet; /*2d indicies*/ - int xyind, rind, uhind; /*1d indicies*/ + int y, x, offset, outlet; /*2d indicies*/ + int xyind, rind, uhind; /*1d indicies*/ /*Loop through all sources*/ for (s = 0; s < nsources; s++) { - outlet = source2outlet_ind[s]; y = source_y_ind[s]; x = source_x_ind[s]; offset = source_time_offset[s]; - //1d index location - //2d-->1d indexing goes like this: ind = y*x_size + x - xyind = y*x_size + x; + // 1d index location + // 2d-->1d indexing goes like this: ind = y*x_size + x + xyind = y * x_size + x; /* Do the convolution */ // i is the position in the unit hydrograph @@ -114,10 +120,10 @@ void convolve(const size_t nsources, /*scalar - number of sources* for (i = 0; i < subset_length; i++) { j = i + offset; - //1d index locations + // 1d index locations rind = j * noutlets + outlet; uhind = i * nsources + s; - printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); + printf("%4i: ,%4i: ,%4i\n", rind, uhind, xyind); ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; } diff --git a/vic/extensions/rout_rvic/src/cshift.c b/vic/extensions/rout_rvic/src/cshift.c index a1afb799d..28d4f714e 100644 --- a/vic/extensions/rout_rvic/src/cshift.c +++ b/vic/extensions/rout_rvic/src/cshift.c @@ -1,8 +1,14 @@ #include #include -void cshift(double *data, int nx, int ny, int axis, int direction) { - int x, y; +void +cshift(double *data, + int nx, + int ny, + int axis, + int direction) +{ + int x, y; double b; if (axis == 0 && direction == 1) { @@ -46,11 +52,15 @@ void cshift(double *data, int nx, int ny, int axis, int direction) { } } -void print_array(double *data, int nx, int ny) { +void +print_array(double *data, + int nx, + int ny) +{ int x, y; for (y = 0; y != ny; y++) { for (x = 0; x != nx; x++) { - printf("%3i:%9.6f ",(int)(x * ny + y),data[x * ny + y]); + printf("%3i:%9.6f ", (int)(x * ny + y), data[x * ny + y]); } printf("\n"); } @@ -68,11 +78,16 @@ void print_array(double *data, int nx, int ny) { #define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) #define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT) -void Print2DArray(double *A, int nr, int nc) { +void +Print2DArray(double *A, + int nr, + int nc) +{ int r, c; for (r = 0; r < nr; r++) { - for (c = 0; c < nc; c++) + for (c = 0; c < nc; c++) { printf("%7.1f", *(A + r * nc + c)); + } printf("\n"); } @@ -81,14 +96,18 @@ void Print2DArray(double *A, int nr, int nc) { // Non-square matrix transpose of matrix of size r x c and base address data -void MatrixInplaceTranspose(double *data, int r, int c) { - int size = r * c - 1; +void +MatrixInplaceTranspose(double *data, + int r, + int c) +{ + int size = r * c - 1; double temp1, temp2; // holds element to be replaced, eventually becomes next element to move - int next; // location of 'temp1' to be moved - int cycleBegin; // holds start of cycle - int i; // iterator + int next; // location of 'temp1' to be moved + int cycleBegin; // holds start of cycle + int i; // iterator - char bitarray[BITNSLOTS(size)]; + char bitarray[BITNSLOTS(size)]; memset(bitarray, 0, BITNSLOTS(size)); BITSET(bitarray, 0); @@ -98,32 +117,39 @@ void MatrixInplaceTranspose(double *data, int r, int c) { while (i < size) { cycleBegin = i; temp1 = *(data + i); - do { + do + { next = (i * r) % size; - //swap + // swap temp2 = *(data + next); *(data + next) = temp1; temp1 = temp2; BITSET(bitarray, i); i = next; - } while (i != cycleBegin); + } + while (i != cycleBegin); // Get Next Move - for (i = 1; i < size && BITTEST(bitarray, i); i++); + for (i = 1; i < size && BITTEST(bitarray, i); i++) { + ; + } } } // Driver program to test above function -int test_matrix(void) { - int r = 5, c = 6; - int size = r*c; +int +test_matrix(void) +{ + int r = 5, c = 6; + int size = r * c; double *A; - int i; - A = (double *) malloc(size * sizeof (double)); + int i; + A = (double *) malloc(size * sizeof(double)); - for (i = 0; i < size; i++) + for (i = 0; i < size; i++) { A[i] = i + 11.1; + } Print2DArray(A, r, c); MatrixInplaceTranspose(A, r, c); diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 946be6450..ebcee7c54 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -32,73 +32,94 @@ /****************************************************************************** * @brief Allocate memory for Routing structures. *****************************************************************************/ -void rout_alloc(void) +void +rout_alloc(void) { - extern domain_struct local_domain; - extern rout_struct rout; - //char *nc_name="./input/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc"; - + extern domain_struct local_domain; + extern rout_struct rout; + // char *nc_name="./input/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc"; + // Get some dimensions - rout.rout_param.iSubsetLength = get_nc_dimension(rout.param_filename, "timesteps"); - rout.rout_param.iOutlets = get_nc_dimension(rout.param_filename, "outlets"); - rout.rout_param.iSources = get_nc_dimension(rout.param_filename, "sources"); + rout.rout_param.iSubsetLength = get_nc_dimension(rout.param_filename, + "timesteps"); + rout.rout_param.iOutlets = get_nc_dimension(rout.param_filename, "outlets"); + rout.rout_param.iSources = get_nc_dimension(rout.param_filename, "sources"); // Allocate memory in rout param_struct - rout.rout_param.source2outlet_ind = (size_t *) malloc (rout.rout_param.iSources * sizeof (size_t)); + rout.rout_param.source2outlet_ind = (size_t *) malloc( + rout.rout_param.iSources * sizeof(size_t)); if (rout.rout_param.source2outlet_ind == NULL) { - log_err("Memory allocation error in rout.rout_param.source2outlet_ind()."); + log_err( + "Memory allocation error in rout.rout_param.source2outlet_ind()."); } - rout.rout_param.source_time_offset = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + rout.rout_param.source_time_offset = (int *) malloc( + rout.rout_param.iSources * sizeof(int)); if (rout.rout_param.source_time_offset == NULL) { - log_err("Memory allocation error in rout.rout_param.source_time_offset()."); + log_err( + "Memory allocation error in rout.rout_param.source_time_offset()."); } - rout.rout_param.source_x_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + rout.rout_param.source_x_ind = (int *) malloc( + rout.rout_param.iSources * sizeof(int)); if (rout.rout_param.source_x_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_x_ind()."); } - rout.rout_param.source_y_ind = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + rout.rout_param.source_y_ind = (int *) malloc( + rout.rout_param.iSources * sizeof(int)); if (rout.rout_param.source_y_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_y_ind()."); } - rout.rout_param.source_lat = (double *) malloc (rout.rout_param.iSources * sizeof (double)); + rout.rout_param.source_lat = (double *) malloc( + rout.rout_param.iSources * sizeof(double)); if (rout.rout_param.source_lat == NULL) { log_err("Memory allocation error in rout.rout_param.source_lat()."); } - rout.rout_param.source_lon = (double *) malloc (rout.rout_param.iSources * sizeof (double)); + rout.rout_param.source_lon = (double *) malloc( + rout.rout_param.iSources * sizeof(double)); if (rout.rout_param.source_lon == NULL) { log_err("Memory allocation error in rout.rout_param.source_lon()."); } - rout.rout_param.source_VIC_index = (int *) malloc (rout.rout_param.iSources * sizeof (int)); + rout.rout_param.source_VIC_index = (int *) malloc( + rout.rout_param.iSources * sizeof(int)); if (rout.rout_param.source_VIC_index == NULL) { - log_err("Memory allocation error in rout.rout_param.source_VIC_index()."); + log_err( + "Memory allocation error in rout.rout_param.source_VIC_index()."); } - rout.rout_param.outlet_lat = (double *) malloc (rout.rout_param.iOutlets * sizeof (double)); + rout.rout_param.outlet_lat = (double *) malloc( + rout.rout_param.iOutlets * sizeof(double)); if (rout.rout_param.outlet_lat == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lat()."); } - rout.rout_param.outlet_lon = (double *) malloc (rout.rout_param.iOutlets * sizeof (double)); + rout.rout_param.outlet_lon = (double *) malloc( + rout.rout_param.iOutlets * sizeof(double)); if (rout.rout_param.outlet_lon == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lon()."); } - rout.rout_param.outlet_VIC_index = (int *) malloc (rout.rout_param.iOutlets * sizeof (int)); + rout.rout_param.outlet_VIC_index = (int *) malloc( + rout.rout_param.iOutlets * sizeof(int)); if (rout.rout_param.outlet_VIC_index == NULL) { - log_err("Memory allocation error in rout.rout_param.outlet_VIC_index()."); + log_err( + "Memory allocation error in rout.rout_param.outlet_VIC_index()."); } - rout.rout_param.unit_hydrograph = (double *) malloc (rout.rout_param.iSources * rout.rout_param.iSubsetLength * sizeof (double)); + rout.rout_param.unit_hydrograph = (double *) malloc( + rout.rout_param.iSources * rout.rout_param.iSubsetLength * + sizeof(double)); if (rout.rout_param.unit_hydrograph == NULL) { log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); } - rout.rout_param.aggrunin = (double *)malloc (local_domain.ncells * sizeof (double)); + rout.rout_param.aggrunin = + (double *)malloc(local_domain.ncells * sizeof(double)); if (rout.rout_param.aggrunin == NULL) { log_err("Memory allocation error in rout.rout_param.aggrunin()."); } - rout.discharge = (double *)malloc (local_domain.ncells * sizeof (double)); + rout.discharge = (double *)malloc(local_domain.ncells * sizeof(double)); if (rout.discharge == NULL) { log_err("Memory allocation error in rout.rout_param.discharge()."); } // Allocate memory for the ring - rout.ring = (double *)malloc (rout.rout_param.iSubsetLength * rout.rout_param.iOutlets * sizeof (double)); + rout.ring = (double *)malloc( + rout.rout_param.iSubsetLength * rout.rout_param.iOutlets * + sizeof(double)); if (rout.ring == NULL) { log_err("Memory allocation error in rout.ring()."); } diff --git a/vic/extensions/rout_rvic/src/rout_finalize.c b/vic/extensions/rout_rvic/src/rout_finalize.c index f84d33450..0a225ca39 100644 --- a/vic/extensions/rout_rvic/src/rout_finalize.c +++ b/vic/extensions/rout_rvic/src/rout_finalize.c @@ -24,6 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -void rout_finalize(void) +void +rout_finalize(void) { } diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 1cfb68d4e..197242c47 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -36,19 +36,19 @@ void rout_init(void) { - extern rout_struct rout; - extern domain_struct global_domain; - - int *ivar = NULL; - double *dvar = NULL; + extern rout_struct rout; + extern domain_struct global_domain; - size_t i, j; - size_t i1start; - size_t d3count[3]; - size_t d3start[3]; + int *ivar = NULL; + double *dvar = NULL; + + size_t i, j; + size_t i1start; + size_t d3count[3]; + size_t d3start[3]; i1start = 0; - + d3start[0] = 0; d3start[1] = 0; d3start[2] = 0; @@ -62,95 +62,98 @@ rout_init(void) if (ivar == NULL) { log_err("Memory allocation error in vic_init()."); } - + // allocate memory for variables to be read - dvar = (double *) malloc(rout.rout_param.iSubsetLength * rout.rout_param.iSources * - sizeof(double)); + dvar = (double *) malloc( + rout.rout_param.iSubsetLength * rout.rout_param.iSources * + sizeof(double)); if (dvar == NULL) { log_err("Memory allocation error in vic_init()."); } - + // The Ring - for (j=0;j #include -void rout_run(void) { - //log_info("In Routing Lohmann Model"); +void +rout_run(void) +{ + // log_info("In Routing Lohmann Model"); - extern rout_struct rout; + extern rout_struct rout; extern out_data_struct **out_data; - size_t i, j, s; + size_t i, j, s; - ///TESTS!!! + // /TESTS!!! printf("\nmapping test!!!..."); for (j = 0; j < rout.rout_param.iSources; j++) { - printf("\nsource: %2zu, outlet_ind: %2zu, Lon_source: , %8.4f, Lat_source: %8.4f", j, rout.rout_param.source2outlet_ind[j], - rout.rout_param.source_lon[j], - rout.rout_param.source_lat[j]); + printf( + "\nsource: %2zu, outlet_ind: %2zu, Lon_source: , %8.4f, Lat_source: %8.4f", + j, rout.rout_param.source2outlet_ind[j], + rout.rout_param.source_lon[j], + rout.rout_param.source_lat[j]); } -// // even worse stuff here -// for (i = 0; i < global_domain.ncells; i++) { -// rout.rout_param.aggrunin[i] = out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; -// } +// // even worse stuff here +// for (i = 0; i < global_domain.ncells; i++) { +// rout.rout_param.aggrunin[i] = out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; +// } printf("\nThe hydrograph, just printed...\n"); - print_array(rout.rout_param.unit_hydrograph, rout.rout_param.iSubsetLength, rout.rout_param.iSources); + print_array(rout.rout_param.unit_hydrograph, rout.rout_param.iSubsetLength, + rout.rout_param.iSources); // Filling the ring with dummy data for (j = 0; j < rout.rout_param.iOutlets; j++) { for (i = 0; i < rout.rout_param.iSubsetLength; i++) { - // rout.ring[i * rout.rout_param.iOutlets + j]=i * rout.rout_param.iOutlets + j; + // rout.ring[i * rout.rout_param.iOutlets + j]=i * rout.rout_param.iOutlets + j; } } @@ -68,13 +73,17 @@ void rout_run(void) { rout.ring[i] = 0.0; } - print_array(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.iSubsetLength, + rout.rout_param.iOutlets); // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets, 0, 1); + cshift(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets, + 0, + 1); printf("\nThe Ring, c-shifted...\n"); - print_array(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.iSubsetLength, + rout.rout_param.iOutlets); printf("\nDoing convolution test!\n"); int offset, outlet; /*2d indicies*/ @@ -82,7 +91,6 @@ void rout_run(void) { /*Loop through all sources*/ for (s = 0; s < rout.rout_param.iSources; s++) { - outlet = rout.rout_param.source2outlet_ind[s]; offset = rout.rout_param.source_time_offset[s]; @@ -92,24 +100,29 @@ void rout_run(void) { for (i = 0; i < rout.rout_param.iSubsetLength; i++) { j = i + offset; - //1d index locations + // 1d index locations rind = j * rout.rout_param.iOutlets + outlet; uhind = i * rout.rout_param.iSources + s; - // ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; - // ring[rind] += unit_hydrograph[uhind]; - //ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; + // ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; + // ring[rind] += unit_hydrograph[uhind]; + // ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; rout.ring[rind] += (rout.rout_param.unit_hydrograph[uhind] * - (out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + - out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0])); + (out_data[rout.rout_param.source_VIC_index[s]][ + OUT_RUNOFF].data[0] + + out_data[rout.rout_param.source_VIC_index[s]][ + OUT_BASEFLOW].data[0])); } } printf("\nThe Ring, after convolution...\n"); - print_array(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.iSubsetLength, + rout.rout_param.iOutlets); // Write to output struct... for (s = 0; s < rout.rout_param.iOutlets; s++) { - out_data[rout.rout_param.outlet_VIC_index[s]][OUT_DISCHARGE].aggdata[0] = rout.ring[s]; + out_data[rout.rout_param.outlet_VIC_index[s]][OUT_DISCHARGE].aggdata[0] + = + rout.ring[s]; } } diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 1da41025a..fa455de03 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -30,13 +30,14 @@ #include /****************************************************************************** - * @brief + * @brief *****************************************************************************/ -void rout_start(void) +void +rout_start(void) { - extern filenames_struct filenames; - extern filep_struct filep; - extern int mpi_rank; + extern filenames_struct filenames; + extern filep_struct filep; + extern int mpi_rank; if (mpi_rank == 0) { // read global settings @@ -45,11 +46,12 @@ void rout_start(void) } } -void get_global_param_rout(FILE *gp) +void +get_global_param_rout(FILE *gp) { extern rout_struct rout; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; /** Read through global control file to find parameters **/ rewind(gp); @@ -71,8 +73,7 @@ void get_global_param_rout(FILE *gp) if (strcasecmp("ROUT_PARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", rout.param_filename); } - } - fgets(cmdstr, MAXSTRING, gp); + fgets(cmdstr, MAXSTRING, gp); } } diff --git a/vic/extensions/rout_rvic/src/rout_write.c b/vic/extensions/rout_rvic/src/rout_write.c index 93e4c3d9c..193a58578 100644 --- a/vic/extensions/rout_rvic/src/rout_write.c +++ b/vic/extensions/rout_rvic/src/rout_write.c @@ -27,6 +27,8 @@ #include #include -void rout_write() { +void +rout_write() +{ log_info("In rout_write"); } diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 289fb6f22..539ab7f18 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -25,32 +25,38 @@ *****************************************************************************/ // read global parameters for routing -void rout_start(void) +void +rout_start(void) { -// log_info("In Routing Stub Model"); +// log_info("In Routing Stub Model"); } // allocate memory -void rout_alloc(void) +void +rout_alloc(void) { } // initialize model parameters from parameter files -void rout_init(void) +void +rout_init(void) { } // run routing over the domain -void rout_run(void) +void +rout_run(void) { } // write routine for routing -void rout_write(void) +void +rout_write(void) { } // clean up routine for routing -void rout_finalize(void) +void +rout_finalize(void) { } From 1dd197f0214fda9f516af49c4f3fff9d8316c442 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 28 Sep 2015 15:51:34 +0200 Subject: [PATCH 007/294] tiny updates --- vic/extensions/rout_rvic/include/rout.h | 2 ++ vic/extensions/rout_stub/include/rout.h | 2 ++ vic/extensions/rout_stub/src/rout.c | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 00f4ebcfa..5727a8adc 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -26,6 +26,8 @@ #ifndef ROUT_RVIC_H #define ROUT_RVIC_H +#define ROUT_EXT "rout_rvic" + #include /****************************************************************************** diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 448247d43..2ed0a7a75 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -26,6 +26,8 @@ #ifndef ROUT_STUB_H #define ROUT_STUB_H +#define ROUT_EXT "rout_stub" + /****************************************************************************** * @brief main routing Struct *****************************************************************************/ diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 539ab7f18..e005ef446 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -28,7 +28,6 @@ void rout_start(void) { -// log_info("In Routing Stub Model"); } // allocate memory From f3358e96bc582513b8e50d262c11fd92bd9d6327 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 29 Sep 2015 11:10:04 +0200 Subject: [PATCH 008/294] source index of VIC gridcell check outlet index of VIC gridcell check --- vic/drivers/image/src/get_global_domain.c | 6 ++---- vic/extensions/rout_rvic/src/rout_init.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/vic/drivers/image/src/get_global_domain.c b/vic/drivers/image/src/get_global_domain.c index 20ad2c33a..087302340 100644 --- a/vic/drivers/image/src/get_global_domain.c +++ b/vic/drivers/image/src/get_global_domain.c @@ -112,8 +112,7 @@ get_global_domain(char *nc_name, // get longitude - // TBD: read var id from file -// get_nc_field_double(nc_name, "xc", - get_nc_field_double(nc_name, "yc", //WF + get_nc_field_double(nc_name, "xc", d2start, d2count, var); for (i = 0; i < global_domain->ncells; i++) { // rescale to [-180., 180]. Note that the if statement is not strictly @@ -126,8 +125,7 @@ get_global_domain(char *nc_name, // get latitude // TBD: read var id from file -// get_nc_field_double(nc_name, "yc", - get_nc_field_double(nc_name, "xc", + get_nc_field_double(nc_name, "yc", d2start, d2count, var); for (i = 0; i < global_domain->ncells; i++) { global_domain->locations[i].latitude = (double) var[idx[i]]; diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 197242c47..23184be6b 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -157,7 +157,6 @@ rout_init(void) rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; } - // TODO: Lat lon omgedraaid in netcdf?!?!??!?! // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! // Mapping: Let the routing-source index numbers correspond to the VIC index numbers size_t iSource; @@ -172,11 +171,15 @@ rout_init(void) } } - // TODO Weghalen printf("\nsource, index of VIC gridcell: \n "); for (iSource = 0; iSource < rout.rout_param.iSources; iSource++) { printf("%3i, %7i \n ", (int)(iSource), rout.rout_param.source_VIC_index[iSource]); + if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || + (size_t)rout.rout_param.source_VIC_index[iSource] > + global_domain.ncells) { + log_err("invalid source, index of VIC gridcell"); + } } // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers @@ -192,11 +195,15 @@ rout_init(void) } } - // TODO Weghalen printf("\noutlet, index of VIC gridcell: \n "); for (iOutlet = 0; iOutlet < rout.rout_param.iOutlets; iOutlet++) { printf("%3i, %7i \n ", (int)(iOutlet), rout.rout_param.outlet_VIC_index[iOutlet]); + if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || + (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > + global_domain.ncells) { + log_err("invalid outlet, index of VIC gridcell"); + } } // cleanup From 1f56af78687ffd9bd5b04a36b532f003afdcace7 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 14 Jan 2016 11:50:46 -0800 Subject: [PATCH 009/294] compile time extension settings are now printed when vic_driver -o is called from the command line --- vic/drivers/image/include/vic_driver_image.h | 3 +++ .../image/src/display_current_settings.c | 19 +++++++++++++++++-- vic/extensions/rout_rvic/include/rout.h | 6 ++++-- vic/extensions/rout_stub/include/rout.h | 2 ++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/vic/drivers/image/include/vic_driver_image.h b/vic/drivers/image/include/vic_driver_image.h index 716596bbd..61b7ccff4 100644 --- a/vic/drivers/image/include/vic_driver_image.h +++ b/vic/drivers/image/include/vic_driver_image.h @@ -30,9 +30,12 @@ #include #include #include +// Extensions +#include #define VIC_DRIVER "Image" + #define MAXDIMS 10 /****************************************************************************** diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 842ae30fa..c1e2ff8c9 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -54,29 +54,44 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "COMPILE-TIME OPTIONS (set in .h files)\n"); - fprintf(LOG_DEST, "----------------------------------------\n\n"); + fprintf(LOG_DEST, "======================================\n\n"); fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); + fprintf(LOG_DEST, "--------------------\n"); fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); - fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); + fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); + + fprintf(LOG_DEST, "Minimum Physical Dimensions:\n"); + fprintf(LOG_DEST, "----------------------------\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_VEGCOVER\t\t%f\n", MIN_VEGCOVER); fprintf(LOG_DEST, "\n"); + + fprintf(LOG_DEST, "Timestep Constraints:\n"); + fprintf(LOG_DEST, "---------------------\n"); fprintf(LOG_DEST, "MIN_SUBDAILY_STEPS_PER_DAY %d\n", MIN_SUBDAILY_STEPS_PER_DAY); fprintf(LOG_DEST, "MAX_SUBDAILY_STEPS_PER_DAY %d\n", MAX_SUBDAILY_STEPS_PER_DAY); fprintf(LOG_DEST, "\n"); + fprintf(LOG_DEST, "Extensions:\n"); + fprintf(LOG_DEST, "-----------\n"); + + fprintf(LOG_DEST, "ROUTING\t\t\t%2s\n", EXT_ROUTING); + + fprintf(LOG_DEST, "\n"); + + if (mode == DISP_COMPILE_TIME) { return; } diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index cba97a5f8..e1c96f017 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -28,6 +28,8 @@ #include +#define EXT_ROUTING "RVIC" + /****************************************************************************** * @brief Routing Structs *****************************************************************************/ @@ -47,8 +49,8 @@ typedef struct { * @brief main routing Struct *****************************************************************************/ typedef struct { - char param_filename[MAXSTRING]; - rout_param_struct rout_param; + char param_filename[MAXSTRING]; + rout_param_struct rout_param; double *ring; } rout_struct; diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 448247d43..4b531818a 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -26,6 +26,8 @@ #ifndef ROUT_STUB_H #define ROUT_STUB_H +#define EXT_ROUTING "STUB" + /****************************************************************************** * @brief main routing Struct *****************************************************************************/ From 1580dfe6c748ea1a06435618d18f630f76364fb1 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 14 Mar 2016 11:52:44 +0100 Subject: [PATCH 010/294] minor thing --- vic/drivers/image/src/display_current_settings.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 3b838f1f6..7b1713267 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -52,32 +52,25 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "COMPILE-TIME OPTIONS (set in .h files)\n"); - fprintf(LOG_DEST, "======================================\n\n"); + fprintf(LOG_DEST, "----------------------------------------\n\n"); fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "--------------------\n"); fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); - fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); + fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); - - fprintf(LOG_DEST, "Minimum Physical Dimensions:\n"); - fprintf(LOG_DEST, "----------------------------\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); fprintf(LOG_DEST, "\n"); - - fprintf(LOG_DEST, "Timestep Constraints:\n"); - fprintf(LOG_DEST, "---------------------\n"); fprintf(LOG_DEST, "MIN_SUBDAILY_STEPS_PER_DAY %d\n", MIN_SUBDAILY_STEPS_PER_DAY); fprintf(LOG_DEST, "MAX_SUBDAILY_STEPS_PER_DAY %d\n", @@ -86,12 +79,9 @@ display_current_settings(int mode) fprintf(LOG_DEST, "Extensions:\n"); fprintf(LOG_DEST, "-----------\n"); - - fprintf(LOG_DEST, "ROUTING\t\t\t%2s\n", EXT_ROUTING); - + //fprintf(LOG_DEST, "ROUTING\t\t\t%2s\n", ROUT_EXT); fprintf(LOG_DEST, "\n"); - if (mode == DISP_COMPILE_TIME) { return; } From f78af31e6cc86703f378281269240edc2ef22ac8 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 29 Mar 2016 15:08:17 +0200 Subject: [PATCH 011/294] some renaming and restructuring --- vic/extensions/rout_rvic/include/rout.h | 8 +- vic/extensions/rout_rvic/src/cshift.c | 8 +- vic/extensions/rout_rvic/src/rout_alloc.c | 30 +++--- vic/extensions/rout_rvic/src/rout_init.c | 91 +++++++++-------- vic/extensions/rout_rvic/src/rout_run.c | 119 +++++++++++----------- 5 files changed, 130 insertions(+), 126 deletions(-) diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 59b6f1f1b..658b7a379 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -34,9 +34,9 @@ * @brief Routing Structs *****************************************************************************/ typedef struct { - size_t iSubsetLength; /*scalar - number of timesteps*/ - size_t iSources; /*scalar - number of sources*/ - size_t iOutlets; /*scalar - length of subset*/ + size_t nTimesteps; /*scalar - number of timesteps*/ + size_t nSources; /*scalar - number of sources*/ + size_t nOutlets; /*scalar - length of subset*/ size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ int *source_y_ind; /*1d array - source y location*/ int *source_x_ind; /*1d array - source x location*/ @@ -86,6 +86,6 @@ void convolve(const size_t nsources, /*scalar - number of sources* double*ring); void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); -void print_array(double *, int, int); +void print_array(double *, int, int, int); #endif diff --git a/vic/extensions/rout_rvic/src/cshift.c b/vic/extensions/rout_rvic/src/cshift.c index 28d4f714e..db6633cc0 100644 --- a/vic/extensions/rout_rvic/src/cshift.c +++ b/vic/extensions/rout_rvic/src/cshift.c @@ -55,12 +55,14 @@ cshift(double *data, void print_array(double *data, int nx, - int ny) + int ny, + int nlines) { int x, y; - for (y = 0; y != ny; y++) { + + for (y = 0; y != nlines; y++) { for (x = 0; x != nx; x++) { - printf("%3i:%9.6f ", (int)(x * ny + y), data[x * ny + y]); + printf("%3i:%9.6f, ", (int)(x * ny + y), data[x * ny + y]); } printf("\n"); } diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index d5ff33ab6..c87db2a21 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -40,68 +40,68 @@ rout_alloc(void) // char *nc_name="./input/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc"; // Get some dimensions - rout.rout_param.iSubsetLength = get_nc_dimension(rout.param_filename, + rout.rout_param.nTimesteps = get_nc_dimension(rout.param_filename, "timesteps"); - rout.rout_param.iOutlets = get_nc_dimension(rout.param_filename, "outlets"); - rout.rout_param.iSources = get_nc_dimension(rout.param_filename, "sources"); + rout.rout_param.nOutlets = get_nc_dimension(rout.param_filename, "outlets"); + rout.rout_param.nSources = get_nc_dimension(rout.param_filename, "sources"); // Allocate memory in rout param_struct rout.rout_param.source2outlet_ind = (size_t *) malloc( - rout.rout_param.iSources * sizeof(size_t)); + rout.rout_param.nSources * sizeof(size_t)); if (rout.rout_param.source2outlet_ind == NULL) { log_err( "Memory allocation error in rout.rout_param.source2outlet_ind()."); } rout.rout_param.source_time_offset = (int *) malloc( - rout.rout_param.iSources * sizeof(int)); + rout.rout_param.nSources * sizeof(int)); if (rout.rout_param.source_time_offset == NULL) { log_err( "Memory allocation error in rout.rout_param.source_time_offset()."); } rout.rout_param.source_x_ind = (int *) malloc( - rout.rout_param.iSources * sizeof(int)); + rout.rout_param.nSources * sizeof(int)); if (rout.rout_param.source_x_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_x_ind()."); } rout.rout_param.source_y_ind = (int *) malloc( - rout.rout_param.iSources * sizeof(int)); + rout.rout_param.nSources * sizeof(int)); if (rout.rout_param.source_y_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_y_ind()."); } rout.rout_param.source_lat = (double *) malloc( - rout.rout_param.iSources * sizeof(double)); + rout.rout_param.nSources * sizeof(double)); if (rout.rout_param.source_lat == NULL) { log_err("Memory allocation error in rout.rout_param.source_lat()."); } rout.rout_param.source_lon = (double *) malloc( - rout.rout_param.iSources * sizeof(double)); + rout.rout_param.nSources * sizeof(double)); if (rout.rout_param.source_lon == NULL) { log_err("Memory allocation error in rout.rout_param.source_lon()."); } rout.rout_param.source_VIC_index = (int *) malloc( - rout.rout_param.iSources * sizeof(int)); + rout.rout_param.nSources * sizeof(int)); if (rout.rout_param.source_VIC_index == NULL) { log_err( "Memory allocation error in rout.rout_param.source_VIC_index()."); } rout.rout_param.outlet_lat = (double *) malloc( - rout.rout_param.iOutlets * sizeof(double)); + rout.rout_param.nOutlets * sizeof(double)); if (rout.rout_param.outlet_lat == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lat()."); } rout.rout_param.outlet_lon = (double *) malloc( - rout.rout_param.iOutlets * sizeof(double)); + rout.rout_param.nOutlets * sizeof(double)); if (rout.rout_param.outlet_lon == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lon()."); } rout.rout_param.outlet_VIC_index = (int *) malloc( - rout.rout_param.iOutlets * sizeof(int)); + rout.rout_param.nOutlets * sizeof(int)); if (rout.rout_param.outlet_VIC_index == NULL) { log_err( "Memory allocation error in rout.rout_param.outlet_VIC_index()."); } rout.rout_param.unit_hydrograph = (double *) malloc( - rout.rout_param.iSources * rout.rout_param.iSubsetLength * + rout.rout_param.nSources * rout.rout_param.nTimesteps * sizeof(double)); if (rout.rout_param.unit_hydrograph == NULL) { log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); @@ -118,7 +118,7 @@ rout_alloc(void) // Allocate memory for the ring rout.ring = (double *)malloc( - rout.rout_param.iSubsetLength * rout.rout_param.iOutlets * + rout.rout_param.nTimesteps * rout.rout_param.nOutlets * sizeof(double)); if (rout.ring == NULL) { log_err("Memory allocation error in rout.ring()."); diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index c395de14a..6a87b1a96 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -37,7 +37,7 @@ void rout_init(void) { extern rout_struct rout; - extern domain_struct global_domain; + extern domain_struct local_domain; int *ivar = NULL; double *dvar = NULL; @@ -52,98 +52,98 @@ rout_init(void) d3start[0] = 0; d3start[1] = 0; d3start[2] = 0; - d3count[0] = rout.rout_param.iSubsetLength; - d3count[1] = rout.rout_param.iSources; + d3count[0] = rout.rout_param.nTimesteps; + d3count[1] = rout.rout_param.nSources; d3count[2] = 1; // tracers dimension // allocate memory for variables to be read - ivar = (int *) malloc(sizeof(int) * rout.rout_param.iSources); + ivar = (int *) malloc(sizeof(int) * rout.rout_param.nSources); if (ivar == NULL) { log_err("Memory allocation error in vic_init()."); } // allocate memory for variables to be read dvar = (double *) malloc( - rout.rout_param.iSubsetLength * rout.rout_param.iSources * + rout.rout_param.nTimesteps * rout.rout_param.nSources * sizeof(double)); if (dvar == NULL) { log_err("Memory allocation error in vic_init()."); } // The Ring - for (j = 0; j < rout.rout_param.iOutlets; j++) { - for (i = 0; i < rout.rout_param.iSubsetLength; i++) { - rout.ring[j * rout.rout_param.iSubsetLength + i] = 0.0; + for (j = 0; j < rout.rout_param.nOutlets; j++) { + for (i = 0; i < rout.rout_param.nTimesteps; i++) { + rout.ring[j * rout.rout_param.nTimesteps + i] = 0.0; } } // discharge - for (j = 0; j < global_domain.ncells_active; j++) { + for (j = 0; j < local_domain.ncells_active; j++) { rout.discharge[j] = 0.0; } // source2outlet_ind: source to outlet index mapping get_nc_field_int(rout.param_filename, "source2outlet_ind", - &i1start, &rout.rout_param.iSources, ivar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source2outlet_ind[i] = (int) ivar[i]; } // source_time_offset: Number of leading timesteps ommited get_nc_field_int(rout.param_filename, "source_time_offset", - &i1start, &rout.rout_param.iSources, ivar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source_time_offset[i] = (int) ivar[i]; } // source_x_ind: x grid coordinate of source grid cell get_nc_field_int(rout.param_filename, "source_x_ind", - &i1start, &rout.rout_param.iSources, ivar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source_x_ind[i] = (int) ivar[i]; } // source_y_ind: y grid coordinate of source grid cell get_nc_field_int(rout.param_filename, "source_y_ind", - &i1start, &rout.rout_param.iSources, ivar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source_y_ind[i] = (int) ivar[i]; } // source_lat: Latitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "source_lat", - &i1start, &rout.rout_param.iSources, dvar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, dvar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source_lat[i] = (double) dvar[i]; } // source_lon: Longitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "source_lon", - &i1start, &rout.rout_param.iSources, dvar); - for (i = 0; i < rout.rout_param.iSources; i++) { + &i1start, &rout.rout_param.nSources, dvar); + for (i = 0; i < rout.rout_param.nSources; i++) { rout.rout_param.source_lon[i] = (double) dvar[i]; } // outlet_lat: Latitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "outlet_lat", - &i1start, &rout.rout_param.iOutlets, dvar); - for (i = 0; i < rout.rout_param.iOutlets; i++) { + &i1start, &rout.rout_param.nOutlets, dvar); + for (i = 0; i < rout.rout_param.nOutlets; i++) { rout.rout_param.outlet_lat[i] = (double) dvar[i]; } // outlet_lon: Longitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "outlet_lon", - &i1start, &rout.rout_param.iOutlets, dvar); - for (i = 0; i < rout.rout_param.iOutlets; i++) { + &i1start, &rout.rout_param.nOutlets, dvar); + for (i = 0; i < rout.rout_param.nOutlets; i++) { rout.rout_param.outlet_lon[i] = (double) dvar[i]; } @@ -152,7 +152,7 @@ rout_init(void) "unit_hydrograph", d3start, d3count, dvar); for (i = 0; - i < (rout.rout_param.iSubsetLength * rout.rout_param.iSources); + i < (rout.rout_param.nTimesteps * rout.rout_param.nSources); i++) { rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; } @@ -160,48 +160,55 @@ rout_init(void) // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! // Mapping: Let the routing-source index numbers correspond to the VIC index numbers size_t iSource; - for (iSource = 0; iSource < rout.rout_param.iSources; iSource++) { - for (i = 0; i < global_domain.ncells_active; i++) { + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + for (i = 0; i < local_domain.ncells_active; i++) { if (rout.rout_param.source_lat[iSource] == - global_domain.locations[i].latitude && + local_domain.locations[i].latitude && rout.rout_param.source_lon[iSource] == - global_domain.locations[i].longitude) { + local_domain.locations[i].longitude) { + rout.rout_param.source_VIC_index[iSource] = i; } } } printf("\nsource, index of VIC gridcell: \n "); - for (iSource = 0; iSource < rout.rout_param.iSources; iSource++) { - printf("%3i, %7i \n ", (int)(iSource), - rout.rout_param.source_VIC_index[iSource]); + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { +// printf("iSource: iVIC: %3i, %7i, %5.2f, %5.2f %5.2f, %5.2f \n ", +// (int)(iSource), +// rout.rout_param.source_VIC_index[iSource], +// rout.rout_param.source_lon[iSource], +// local_domain.locations[rout.rout_param.source_VIC_index[iSource]].longitude, +// rout.rout_param.source_lat[iSource], +// local_domain.locations[rout.rout_param.source_VIC_index[iSource]].latitude +// ); if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || (size_t)rout.rout_param.source_VIC_index[iSource] > - global_domain.ncells_active) { + local_domain.ncells_active) { log_err("invalid source, index of VIC gridcell"); } } // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers size_t iOutlet; - for (iOutlet = 0; iOutlet < rout.rout_param.iOutlets; iOutlet++) { - for (i = 0; i < global_domain.ncells_active; i++) { + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + for (i = 0; i < local_domain.ncells_active; i++) { if (rout.rout_param.outlet_lat[iOutlet] == - global_domain.locations[i].latitude && + local_domain.locations[i].latitude && rout.rout_param.outlet_lon[iOutlet] == - global_domain.locations[i].longitude) { + local_domain.locations[i].longitude) { rout.rout_param.outlet_VIC_index[iOutlet] = i; } } } printf("\noutlet, index of VIC gridcell: \n "); - for (iOutlet = 0; iOutlet < rout.rout_param.iOutlets; iOutlet++) { - printf("%3i, %7i \n ", (int)(iOutlet), - rout.rout_param.outlet_VIC_index[iOutlet]); + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { +// printf("%3i, %7i \n ", (int)(iOutlet), +// rout.rout_param.outlet_VIC_index[iOutlet]); if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > - global_domain.ncells_active) { + local_domain.ncells_active) { log_err("invalid outlet, index of VIC gridcell"); } } diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 0e176b5fe..600a76736 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -36,93 +36,88 @@ rout_run(void) extern rout_struct rout; extern out_data_struct **out_data; - size_t i, j, s; - - // /TESTS!!! - printf("\nmapping test!!!..."); - - for (j = 0; j < rout.rout_param.iSources; j++) { - printf( - "\nsource: %2zu, outlet_ind: %2zu, Lon_source: , %8.4f, Lat_source: %8.4f", - j, rout.rout_param.source2outlet_ind[j], - rout.rout_param.source_lon[j], - rout.rout_param.source_lat[j]); - } - - -// // even worse stuff here + extern dmy_struct *dmy; + size_t iSource, iOutlet, iTimestep , jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ + + printf("\n######### Time: %i/%i/%i %i", dmy->year,dmy->month,dmy->day,dmy->dayseconds); + +// // even worse stuffy here // for (i = 0; i < global_domain.ncells; i++) { // rout.rout_param.aggrunin[i] = out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; // } printf("\nThe hydrograph, just printed...\n"); - print_array(rout.rout_param.unit_hydrograph, rout.rout_param.iSubsetLength, - rout.rout_param.iSources); - - // Filling the ring with dummy data - for (j = 0; j < rout.rout_param.iOutlets; j++) { - for (i = 0; i < rout.rout_param.iSubsetLength; i++) { - // rout.ring[i * rout.rout_param.iOutlets + j]=i * rout.rout_param.iOutlets + j; - } - } + print_array(rout.rout_param.unit_hydrograph, rout.rout_param.nTimesteps, + rout.rout_param.nSources, 5); + +// // Filling the ring with dummy data +// for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { +// for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { +// rout.ring[iOutlet]=iOutlet; +// //rout.ring[iTimestep * rout.rout_param.nOutlets + iOutlet] = rout.ring[iTimestep * rout.rout_param.nOutlets + iOutlet] + iTimestep * rout.rout_param.nOutlets + iOutlet; +// +// } +// } // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. printf("\nThe Ring (ZERO)...\n"); - for (i = 0; i < rout.rout_param.iOutlets; i++) { - rout.ring[i] = 0.0; + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + rout.ring[iOutlet] = 0.0; } - print_array(rout.ring, rout.rout_param.iSubsetLength, - rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.nTimesteps, + rout.rout_param.nOutlets, 5); // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.iSubsetLength, rout.rout_param.iOutlets, - 0, - 1); + cshift(rout.ring, rout.rout_param.nTimesteps, rout.rout_param.nOutlets, 0, 1); printf("\nThe Ring, c-shifted...\n"); - print_array(rout.ring, rout.rout_param.iSubsetLength, - rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.nTimesteps, + rout.rout_param.nOutlets, 5); - printf("\nDoing convolution test!\n"); - int offset, outlet; /*2d indicies*/ - int rind, uhind; /*1d indicies*/ + // Filling the ring with dummy data + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { + // rout.ring[j]=55; + } + //rout.ring[iOutlet]=iOutlet*0.5; + } /*Loop through all sources*/ - for (s = 0; s < rout.rout_param.iSources; s++) { - outlet = rout.rout_param.source2outlet_ind[s]; - offset = rout.rout_param.source_time_offset[s]; + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + iOutlet = rout.rout_param.source2outlet_ind[iSource]; + offset = rout.rout_param.source_time_offset[iSource]; /* Do the convolution */ - // i is the position in the unit hydrograph - // j is the position in the ring - for (i = 0; i < rout.rout_param.iSubsetLength; i++) { - j = i + offset; - - // 1d index locations - rind = j * rout.rout_param.iOutlets + outlet; - uhind = i * rout.rout_param.iSources + s; - - // ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; - // ring[rind] += unit_hydrograph[uhind]; - // ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; - rout.ring[rind] += (rout.rout_param.unit_hydrograph[uhind] * - (out_data[rout.rout_param.source_VIC_index[s]][ - OUT_RUNOFF].data[0] + - out_data[rout.rout_param.source_VIC_index[s]][ - OUT_BASEFLOW].data[0])); + // iTimestep is the position in the unit hydrograph + // jTimestep is the position in the ring + for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { + jTimestep = iTimestep + offset; + jTimestep = iTimestep; + + // index locations + iRing = ( jTimestep * rout.rout_param.nOutlets ) + iOutlet; + iUH = ( iTimestep * rout.rout_param.nSources ) + iSource; + + // printf("(iSource: %zu, year: %i, iTimestep: %zu, j: %zu, iRing: %zu, iUH: %zu\n", s, dmy[1].year, iTimestep, j, iRing, iUH); + rout.ring[iRing] += rout.rout_param.unit_hydrograph[iUH] * (1); +// rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * +// (out_data[rout.rout_param.source_VIC_index[(iSource]][ +// OUT_RUNOFF].data[0] + +// out_data[rout.rout_param.source_VIC_index[(iSource]][ +// OUT_BASEFLOW].data[0])); } } printf("\nThe Ring, after convolution...\n"); - print_array(rout.ring, rout.rout_param.iSubsetLength, - rout.rout_param.iOutlets); + print_array(rout.ring, rout.rout_param.nTimesteps, + rout.rout_param.nOutlets, 5); // Write to output struct... - for (s = 0; s < rout.rout_param.iOutlets; s++) { - out_data[rout.rout_param.outlet_VIC_index[s]][OUT_DISCHARGE].aggdata[0] - = - rout.ring[s]; + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE].aggdata[0] = rout.ring[iOutlet]; } } From ff7baa49303558442ba44fb2c4e3a719c994c85e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 29 Mar 2016 15:15:21 +0200 Subject: [PATCH 012/294] removed convolve.c --- vic/extensions/rout_rvic/include/rout.h | 10 -- vic/extensions/rout_rvic/src/convolve.c | 131 ------------------------ 2 files changed, 141 deletions(-) delete mode 100644 vic/extensions/rout_rvic/src/convolve.c diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 658b7a379..729faf635 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -74,16 +74,6 @@ void rout_finalize(void); // clean up routine for routing /****************************************************************************** * @brief Convolution function adapted from the RVIC scheme *****************************************************************************/ -void convolve(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ - const size_t x_size, const int*source2outlet_ind, /*1d array - source to outlet mapping*/ - const int*source_y_ind, /*1d array - source y location*/ - const int*source_x_ind, /*1d array - source x location*/ - const int*source_time_offset, /*1d array - source time offset*/ - const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - const double*aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double*ring); void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); void print_array(double *, int, int, int); diff --git a/vic/extensions/rout_rvic/src/convolve.c b/vic/extensions/rout_rvic/src/convolve.c deleted file mode 100644 index f5b0b597f..000000000 --- a/vic/extensions/rout_rvic/src/convolve.c +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include -#include - -// function call: -// convolve_new(rout.rout_param.iSources, /*scalar - number of sources*/ -// rout.rout_param.iOutlets, /*scalar - length of subset*/ -// rout.rout_param.iSubsetLength, /*scalar - length of subset*/ -// global_domain.n_nx, -// rout.rout_param.source2outlet_ind, /*1d array - source to outlet mapping*/ -// rout.rout_param.source_y_ind, /*1d array - source y location*/ -// rout.rout_param.source_x_ind, /*1d array - source x location*/ -// rout.rout_param.source_time_offset, /*1d array - source time offset*/ -// rout.rout_param.unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ -// //rout.rout_param.aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ -// rout.ring); /*2d array[times][outlets] - convolution ring*/ - - -void -convolve_new(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ -// const size_t x_size, - const int *source2outlet_ind, /*1d array - source to outlet mapping*/ -// const int* source_y_ind, /*1d array - source y location*/ -// const int* source_x_ind, /*1d array - source x location*/ - const int *source_time_offset, /*1d array - source time offset*/ - const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ -// const double* aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double *ring) /*2d array[times][outlets] - convolution ring*/ -{ - log_info("Doing convolution test!"); - size_t s, i, j; /*counters*/ - // int y, x; - int offset, outlet; /*2d indicies*/ -// int xyind; - int rind, uhind; /*1d indicies*/ - extern out_data_struct **out_data; - extern rout_struct rout; - - /*Loop through all sources*/ - for (s = 0; s < nsources; s++) { - outlet = source2outlet_ind[s]; -// y = source_y_ind[s]; -// x = source_x_ind[s]; - offset = source_time_offset[s]; - - // 1d index location - // 2d-->1d indexing goes like this: ind = y*x_size + x - // xyind = y*x_size + x; - - // printf("source: %4i: , outlet: %4i: ,x: %4i: ,y: %4i ,offset: %4i ,xyind: %4i\n",s,outlet,x,y,offset,xyind); - - /* Do the convolution */ - // i is the position in the unit hydrograph - // j is the position in the ring - for (i = 0; i < subset_length; i++) { - j = i + offset; - - // 1d index locations - rind = j * noutlets + outlet; - uhind = i * nsources + s; - - - // printf("%4i: ,%4i: ,%4i\n",rind,uhind,xyind); -// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; - // printf(" %4i: ,%4i: ,%4i: ,%4i\n",i,rind,uhind,xyind); - // ring[i] += unit_hydrograph[uhind] * aggrunin[xyind]; // rind = noutlets + outlet + j; - - // uhind = s * subset_length + i; - // printf("new: %4i: , %4i: , %4i: ,%4i: ,%4i: ,%4i\n", s, outlet, i, rind, uhind, xyind); - -// ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; -// ring[rind] += unit_hydrograph[uhind]; - // ring[rind] += out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF].data[0] + out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW].data[0]; - ring[rind] += - (unit_hydrograph[uhind] * - (out_data[rout.rout_param.source_VIC_index[s]][OUT_RUNOFF]. - data[0] - + - out_data[rout.rout_param.source_VIC_index[s]][OUT_BASEFLOW]. - data[0 - ])); - } - } -} - -void -convolve(const size_t nsources, /*scalar - number of sources*/ - const size_t noutlets, /*scalar - length of subset*/ - const size_t subset_length, /*scalar - length of subset*/ - const size_t x_size, - const int *source2outlet_ind, /*1d array - source to outlet mapping*/ - const int *source_y_ind, /*1d array - source y location*/ - const int *source_x_ind, /*1d array - source x location*/ - const int *source_time_offset, /*1d array - source time offset*/ - const double*unit_hydrograph, /*2d array[times][sources] - unit hydrographs*/ - const double*aggrunin, /*2d array[ysize][xsize] - vic runoff flux*/ - double *ring) /*2d array[times][outlets] - convolution ring*/ -{ - log_info("Doing convolution test!"); - size_t s, i, j; /*counters*/ - int y, x, offset, outlet; /*2d indicies*/ - int xyind, rind, uhind; /*1d indicies*/ - - /*Loop through all sources*/ - for (s = 0; s < nsources; s++) { - outlet = source2outlet_ind[s]; - y = source_y_ind[s]; - x = source_x_ind[s]; - offset = source_time_offset[s]; - - // 1d index location - // 2d-->1d indexing goes like this: ind = y*x_size + x - xyind = y * x_size + x; - - /* Do the convolution */ - // i is the position in the unit hydrograph - // j is the position in the ring - for (i = 0; i < subset_length; i++) { - j = i + offset; - - // 1d index locations - rind = j * noutlets + outlet; - uhind = i * nsources + s; - printf("%4i: ,%4i: ,%4i\n", rind, uhind, xyind); - - ring[rind] += unit_hydrograph[uhind] * aggrunin[xyind]; - } - } -} From f6e6d967f5021114d1346a945092e648bb31d1b6 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 1 Apr 2016 11:02:07 +0200 Subject: [PATCH 013/294] minor update --- vic/drivers/shared_all/include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/output_list_utils.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index a340deced..24fff5fdc 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -123,11 +123,11 @@ enum OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ // Water Balance Terms - fluxes OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_DISCHARGE, /** */ OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ OUT_DELSOILMOIST, /**< change in soil water content [mm] */ OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ OUT_DELSWE, /**< change in snow water equivalent [mm] */ + OUT_DISCHARGE, /**< river discharge [m3] (ALMA_OUTPUT: [m3/s]) */ OUT_EVAP, /**< total net evaporation [mm] (ALMA_OUTPUT: [mm/s]) */ OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] (ALMA_OUTPUT: [mm/s]) */ OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] (ALMA_OUTPUT: [mm/s]) */ diff --git a/vic/drivers/shared_all/src/output_list_utils.c b/vic/drivers/shared_all/src/output_list_utils.c index 1cce58328..2cf048f01 100644 --- a/vic/drivers/shared_all/src/output_list_utils.c +++ b/vic/drivers/shared_all/src/output_list_utils.c @@ -79,6 +79,7 @@ create_output_list() strcpy(out_data[OUT_EVAP_BARE].varname, "OUT_EVAP_BARE"); /* net evaporation from bare soil [mm] (ALMA_OUTPUT: [mm/s]) */ strcpy(out_data[OUT_EVAP_CANOP].varname, "OUT_EVAP_CANOP"); /* net evaporation from canopy interception [mm] (ALMA_OUTPUT: [mm/s]) */ strcpy(out_data[OUT_INFLOW].varname, "OUT_INFLOW"); /* moisture that reaches top of soil column [mm] (ALMA_OUTPUT: [mm/s]) */ + strcpy(out_data[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); /* river discharge [m3] (ALMA_OUTPUT: [m3/s]) */ strcpy(out_data[OUT_LAKE_BF_IN].varname, "OUT_LAKE_BF_IN"); /* incoming baseflow from lake catchment [mm] (ALMA_OUTPUT: [mm/s]) */ strcpy(out_data[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); /* incoming volumetric baseflow from lake catchment [m3] (ALMA_OUTPUT: [m3/s]) */ strcpy(out_data[OUT_LAKE_BF_OUT].varname, "OUT_LAKE_BF_OUT"); /* outgoing baseflow lake [mm] (ALMA_OUTPUT: [mm/s]) */ @@ -297,6 +298,7 @@ create_output_list() out_data[OUT_EVAP_BARE].aggtype = AGG_TYPE_SUM; out_data[OUT_EVAP_CANOP].aggtype = AGG_TYPE_SUM; out_data[OUT_INFLOW].aggtype = AGG_TYPE_SUM; + out_data[OUT_DISCHARGE].aggtype = AGG_TYPE_SUM; out_data[OUT_LAKE_BF_IN].aggtype = AGG_TYPE_SUM; out_data[OUT_LAKE_BF_IN_V].aggtype = AGG_TYPE_SUM; out_data[OUT_LAKE_BF_OUT].aggtype = AGG_TYPE_SUM; From 063b81deb9605d3d90a037263d943073694144bd Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 27 May 2016 13:29:03 +0200 Subject: [PATCH 014/294] cleaned up a bit --- .gitignore | 2 + vic/drivers/image/src/vic_force.c | 1 + .../shared_image/src/vic_init_output.c | 2 +- vic/extensions/rout_rvic/src/rout_run.c | 84 +++++-------------- 4 files changed, 27 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 9d7d27a0b..d77be0323 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ nbproject image_test uncrust.sh *.exe + +not4git diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index cb82f8013..f28513fd6 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -349,6 +349,7 @@ vic_force(void) // precipitation in mm/period atmos[i].prec[j] *= global_param.snow_dt; // pressure in Pa + // atmos[i].pressure[j] = atmos[i].pressure[j] *1000; // vapor pressure in Pa (we read specific humidity in kg/kg) atmos[i].vp[j] = q_to_vp(atmos[i].vp[j], atmos[i].pressure[j]); // vapor pressure deficit in Pa diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index 2a8561d0e..7dc727390 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -476,7 +476,7 @@ set_global_nc_attributes(int ncid, // username if (getlogin_r(userstr, MAXSTRING) != 0) { - log_err("Error getting username"); + // log_err("Error getting username"); } // hostname if (gethostname(hoststr, MAXSTRING) != 0) { diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 600a76736..6a119517e 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -32,59 +32,24 @@ void rout_run(void) { - // log_info("In Routing Lohmann Model"); + log_info("In Routing Lohmann Model"); extern rout_struct rout; extern out_data_struct **out_data; - extern dmy_struct *dmy; - size_t iSource, iOutlet, iTimestep , jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ - - printf("\n######### Time: %i/%i/%i %i", dmy->year,dmy->month,dmy->day,dmy->dayseconds); - -// // even worse stuffy here -// for (i = 0; i < global_domain.ncells; i++) { -// rout.rout_param.aggrunin[i] = out_data[i][OUT_RUNOFF].data[0] + out_data[i][OUT_BASEFLOW].data[0]; -// } - - printf("\nThe hydrograph, just printed...\n"); - print_array(rout.rout_param.unit_hydrograph, rout.rout_param.nTimesteps, - rout.rout_param.nSources, 5); - -// // Filling the ring with dummy data -// for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { -// for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { -// rout.ring[iOutlet]=iOutlet; -// //rout.ring[iTimestep * rout.rout_param.nOutlets + iOutlet] = rout.ring[iTimestep * rout.rout_param.nOutlets + iOutlet] + iTimestep * rout.rout_param.nOutlets + iOutlet; -// -// } -// } + extern dmy_struct *dmy; + size_t iSource, iOutlet, iTimestep, jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. - printf("\nThe Ring (ZERO)...\n"); for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { rout.ring[iOutlet] = 0.0; } - print_array(rout.ring, rout.rout_param.nTimesteps, - rout.rout_param.nOutlets, 5); - // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.nTimesteps, rout.rout_param.nOutlets, 0, 1); - - printf("\nThe Ring, c-shifted...\n"); - print_array(rout.ring, rout.rout_param.nTimesteps, - rout.rout_param.nOutlets, 5); - - // Filling the ring with dummy data - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { - // rout.ring[j]=55; - } - //rout.ring[iOutlet]=iOutlet*0.5; - } + cshift(rout.ring, rout.rout_param.nTimesteps, rout.rout_param.nOutlets, 0, + 1); /*Loop through all sources*/ for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { @@ -94,30 +59,27 @@ rout_run(void) /* Do the convolution */ // iTimestep is the position in the unit hydrograph // jTimestep is the position in the ring - for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { - jTimestep = iTimestep + offset; - jTimestep = iTimestep; - - // index locations - iRing = ( jTimestep * rout.rout_param.nOutlets ) + iOutlet; - iUH = ( iTimestep * rout.rout_param.nSources ) + iSource; + for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; + iTimestep++) { + jTimestep = iTimestep + offset; // need to be corrected (buffer overflow) - // printf("(iSource: %zu, year: %i, iTimestep: %zu, j: %zu, iRing: %zu, iUH: %zu\n", s, dmy[1].year, iTimestep, j, iRing, iUH); - rout.ring[iRing] += rout.rout_param.unit_hydrograph[iUH] * (1); -// rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * -// (out_data[rout.rout_param.source_VIC_index[(iSource]][ -// OUT_RUNOFF].data[0] + -// out_data[rout.rout_param.source_VIC_index[(iSource]][ -// OUT_BASEFLOW].data[0])); + // index locations + iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; + iUH = (iTimestep * rout.rout_param.nSources) + iSource; + + rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * + (out_data[rout.rout_param.source_VIC_index[ + iSource]][ + OUT_RUNOFF].data[0] + + out_data[rout.rout_param.source_VIC_index[ + iSource]][ + OUT_BASEFLOW].data[0])); } } - printf("\nThe Ring, after convolution...\n"); - print_array(rout.ring, rout.rout_param.nTimesteps, - rout.rout_param.nOutlets, 5); - // Write to output struct... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE].aggdata[0] = rout.ring[iOutlet]; + out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE]. + aggdata[0] = rout.ring[iOutlet]; } } From 0bb5cdcbf7d130e131e979334ac9a6b3ade542ff Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 3 Jun 2016 14:45:22 +0200 Subject: [PATCH 015/294] Applied some comments from github --- vic/drivers/image/src/vic_force.c | 1 - vic/extensions/rout_rvic/include/rout.h | 1 + vic/extensions/rout_rvic/src/rout_alloc.c | 73 ++++++++++++-------- vic/extensions/rout_rvic/src/rout_finalize.c | 18 +++++ vic/extensions/rout_rvic/src/rout_run.c | 5 +- vic/extensions/rout_rvic/src/rout_start.c | 1 + 6 files changed, 66 insertions(+), 33 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index f28513fd6..cb82f8013 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -349,7 +349,6 @@ vic_force(void) // precipitation in mm/period atmos[i].prec[j] *= global_param.snow_dt; // pressure in Pa - // atmos[i].pressure[j] = atmos[i].pressure[j] *1000; // vapor pressure in Pa (we read specific humidity in kg/kg) atmos[i].vp[j] = q_to_vp(atmos[i].vp[j], atmos[i].pressure[j]); // vapor pressure deficit in Pa diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 729faf635..388bb573c 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -34,6 +34,7 @@ * @brief Routing Structs *****************************************************************************/ typedef struct { + size_t full_time_length; /*scalar - total number of timesteps*/ size_t nTimesteps; /*scalar - number of timesteps*/ size_t nSources; /*scalar - number of sources*/ size_t nOutlets; /*scalar - length of subset*/ diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index c87db2a21..778fc850f 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -37,89 +37,102 @@ rout_alloc(void) { extern domain_struct local_domain; extern rout_struct rout; - // char *nc_name="./input/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc"; + int ivar; + size_t d1count[1]; + size_t d1start[1]; + + d1count[0] = 0; + d1start[0] = 1; + + // Get some values and dimensions + get_nc_field_int(rout.param_filename, + "full_time_length", + d1start, + d1count, + &ivar); + rout.rout_param.full_time_length = (int) ivar; - // Get some dimensions rout.rout_param.nTimesteps = get_nc_dimension(rout.param_filename, - "timesteps"); + "timesteps"); rout.rout_param.nOutlets = get_nc_dimension(rout.param_filename, "outlets"); rout.rout_param.nSources = get_nc_dimension(rout.param_filename, "sources"); // Allocate memory in rout param_struct - rout.rout_param.source2outlet_ind = (size_t *) malloc( - rout.rout_param.nSources * sizeof(size_t)); + rout.rout_param.source2outlet_ind = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source2outlet_ind)); if (rout.rout_param.source2outlet_ind == NULL) { log_err( "Memory allocation error in rout.rout_param.source2outlet_ind()."); } - rout.rout_param.source_time_offset = (int *) malloc( - rout.rout_param.nSources * sizeof(int)); + rout.rout_param.source_time_offset = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_time_offset)); if (rout.rout_param.source_time_offset == NULL) { log_err( "Memory allocation error in rout.rout_param.source_time_offset()."); } - rout.rout_param.source_x_ind = (int *) malloc( - rout.rout_param.nSources * sizeof(int)); + rout.rout_param.source_x_ind = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_x_ind)); if (rout.rout_param.source_x_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_x_ind()."); } - rout.rout_param.source_y_ind = (int *) malloc( - rout.rout_param.nSources * sizeof(int)); + rout.rout_param.source_y_ind = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_y_ind)); if (rout.rout_param.source_y_ind == NULL) { log_err("Memory allocation error in rout.rout_param.source_y_ind()."); } - rout.rout_param.source_lat = (double *) malloc( - rout.rout_param.nSources * sizeof(double)); + rout.rout_param.source_lat = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_lat)); if (rout.rout_param.source_lat == NULL) { log_err("Memory allocation error in rout.rout_param.source_lat()."); } - rout.rout_param.source_lon = (double *) malloc( - rout.rout_param.nSources * sizeof(double)); + rout.rout_param.source_lon = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_lon)); if (rout.rout_param.source_lon == NULL) { log_err("Memory allocation error in rout.rout_param.source_lon()."); } - rout.rout_param.source_VIC_index = (int *) malloc( - rout.rout_param.nSources * sizeof(int)); + rout.rout_param.source_VIC_index = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_VIC_index)); if (rout.rout_param.source_VIC_index == NULL) { log_err( "Memory allocation error in rout.rout_param.source_VIC_index()."); } - rout.rout_param.outlet_lat = (double *) malloc( - rout.rout_param.nOutlets * sizeof(double)); + rout.rout_param.outlet_lat = malloc( + rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lat)); if (rout.rout_param.outlet_lat == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lat()."); } - rout.rout_param.outlet_lon = (double *) malloc( - rout.rout_param.nOutlets * sizeof(double)); + rout.rout_param.outlet_lon = malloc( + rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lon)); if (rout.rout_param.outlet_lon == NULL) { log_err("Memory allocation error in rout.rout_param.outlet_lon()."); } - rout.rout_param.outlet_VIC_index = (int *) malloc( - rout.rout_param.nOutlets * sizeof(int)); + rout.rout_param.outlet_VIC_index = malloc( + rout.rout_param.nOutlets * sizeof(rout.rout_param.outlet_VIC_index)); if (rout.rout_param.outlet_VIC_index == NULL) { log_err( "Memory allocation error in rout.rout_param.outlet_VIC_index()."); } - rout.rout_param.unit_hydrograph = (double *) malloc( + rout.rout_param.unit_hydrograph = malloc( rout.rout_param.nSources * rout.rout_param.nTimesteps * - sizeof(double)); + sizeof(*rout.rout_param.unit_hydrograph)); if (rout.rout_param.unit_hydrograph == NULL) { log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); } rout.rout_param.aggrunin = - (double *)malloc(local_domain.ncells_active * sizeof(double)); + malloc(local_domain.ncells_active * sizeof(*rout.rout_param.aggrunin)); if (rout.rout_param.aggrunin == NULL) { log_err("Memory allocation error in rout.rout_param.aggrunin()."); } - rout.discharge = (double *)malloc(local_domain.ncells_active * sizeof(double)); + rout.discharge = + malloc(local_domain.ncells_active * sizeof(*rout.discharge)); if (rout.discharge == NULL) { log_err("Memory allocation error in rout.rout_param.discharge()."); } // Allocate memory for the ring - rout.ring = (double *)malloc( - rout.rout_param.nTimesteps * rout.rout_param.nOutlets * - sizeof(double)); + rout.ring = malloc( + rout.rout_param.full_time_length * rout.rout_param.nOutlets * + sizeof(*rout.ring)); if (rout.ring == NULL) { log_err("Memory allocation error in rout.ring()."); } diff --git a/vic/extensions/rout_rvic/src/rout_finalize.c b/vic/extensions/rout_rvic/src/rout_finalize.c index 0a225ca39..0f46a2e18 100644 --- a/vic/extensions/rout_rvic/src/rout_finalize.c +++ b/vic/extensions/rout_rvic/src/rout_finalize.c @@ -24,7 +24,25 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ +#include + void rout_finalize(void) { + extern rout_struct rout; + + free(rout.rout_param.source2outlet_ind); + free(rout.rout_param.source_time_offset); + free(rout.rout_param.source_x_ind); + free(rout.rout_param.source_y_ind); + free(rout.rout_param.source_lat); + free(rout.rout_param.source_lon); + free(rout.rout_param.source_VIC_index); + free(rout.rout_param.outlet_lat); + free(rout.rout_param.outlet_lon); + free(rout.rout_param.outlet_VIC_index); + free(rout.rout_param.unit_hydrograph); + free(rout.rout_param.aggrunin); + free(rout.discharge); + free(rout.ring); } diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 6a119517e..d3c33b9bd 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -48,7 +48,8 @@ rout_run(void) } // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.nTimesteps, rout.rout_param.nOutlets, 0, + cshift(rout.ring, rout.rout_param.full_time_length, + rout.rout_param.nOutlets, 0, 1); /*Loop through all sources*/ @@ -61,7 +62,7 @@ rout_run(void) // jTimestep is the position in the ring for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; iTimestep++) { - jTimestep = iTimestep + offset; // need to be corrected (buffer overflow) + jTimestep = iTimestep + offset; // index locations iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index fa455de03..1972df5e0 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -72,6 +72,7 @@ get_global_param_rout(FILE *gp) *************************************/ if (strcasecmp("ROUT_PARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", rout.param_filename); + break; } } fgets(cmdstr, MAXSTRING, gp); From ab8e4f092b1fc0d25cc90304edf1db51db934798 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 22 Jun 2016 10:36:27 +0200 Subject: [PATCH 016/294] merge --- .gitignore | 1 + ci/requirements.yml | 2 + .../Drivers/Classic/DefaultOutputs.md | 16 +- .../Drivers/Classic/FluxOutputFiles.md | 75 +- .../Drivers/Classic/FrozenSoilOutputFile.md | 2 +- .../Drivers/Classic/GlobalParam.md | 213 +- .../Drivers/Classic/LakeOutputFile.md | 24 +- .../Drivers/Classic/OutputFormatting.md | 134 +- docs/Documentation/Drivers/Classic/Outputs.md | 4 +- .../Drivers/Classic/SnowOutputFile.md | 27 - .../Drivers/Image/Ascii_to_NetCDF_params.md | 142 + .../Drivers/Image/GlobalParam.md | 12 +- .../Drivers/Image/ImageDriver.md | 5 +- docs/Documentation/Drivers/Image/Inputs.md | 2 + docs/Documentation/Drivers/Image/LakeParam.md | 3 + docs/Documentation/Drivers/Image/Params.md | 564 +++- docs/Documentation/HowToAddNewOutputVars.md | 82 +- docs/Documentation/OutputVarList.md | 324 +-- mkdocs.yml | 4 +- readme.md | 3 +- samples/global.param.sample.classic.txt | 67 +- samples/global.param.sample.image.txt | 77 +- .../global_param.classic.STEHE.feb.txt | 8 - .../global_param.classic.STEHE.save_state.txt | 8 - tests/examples/global_param.classic.STEHE.txt | 8 - .../global_param.classic.STEHE.wb_output.txt | 11 +- .../examples/global_param.image.STEHE.feb.txt | 6 +- tests/run_tests.py | 19 +- .../global.classic.STEHE.allhistvars.txt | 218 ++ .../global.classic.STEHE.multistream.txt | 111 + ...obal.classic.STEHE.restart.FROZEN_SOIL.txt | 11 +- tests/system/global.classic.STEHE.restart.txt | 9 +- tests/system/global.classic.STEHE.txt | 9 +- ...global.image.STEHE.restart.FROZEN_SOIL.txt | 5 +- tests/system/global.image.STEHE.restart.txt | 5 +- tests/system/global.image.STEHE.txt | 6 +- tests/system/system_tests.cfg | 13 +- tests/test_image_driver.py | 4 +- tests/test_restart.py | 21 +- tests/test_utils.py | 154 +- tests/unit/shared/test_initialize_global.py | 1 - tests/unit/shared/test_initialize_options.py | 2 +- tests/unit/shared/test_input_tools.py | 82 + tests/unit/shared/test_vic_time.py | 73 +- vic/drivers/cesm/include/vic_driver_cesm.h | 2 - vic/drivers/cesm/src/cesm_interface_c.c | 27 +- .../cesm/src/display_current_settings.c | 45 - vic/drivers/cesm/src/get_global_param.c | 283 +- vic/drivers/cesm/src/vic_cesm_start.c | 6 +- .../classic/include/vic_driver_classic.h | 28 +- vic/drivers/classic/src/close_files.c | 24 +- .../classic/src/display_current_settings.c | 39 +- vic/drivers/classic/src/free_out_data_files.c | 42 - vic/drivers/classic/src/get_global_param.c | 447 +-- .../classic/src/make_in_and_outfiles.c | 45 +- vic/drivers/classic/src/parse_output_info.c | 327 ++- vic/drivers/classic/src/read_snowband.c | 2 +- vic/drivers/classic/src/set_output_defaults.c | 303 --- vic/drivers/classic/src/vic_classic.c | 102 +- vic/drivers/classic/src/write_data.c | 264 +- vic/drivers/classic/src/write_forcing_file.c | 125 - vic/drivers/classic/src/write_header.c | 333 +-- vic/drivers/classic/src/write_output.c | 105 +- .../image/src/display_current_settings.c | 44 - vic/drivers/image/src/get_global_param.c | 340 +-- vic/drivers/image/src/vic_force.c | 8 +- vic/drivers/image/src/vic_image.c | 28 +- vic/drivers/image/src/vic_image_start.c | 2 +- .../python/src/display_current_settings.c | 38 - vic/drivers/python/src/globals.c | 1 + .../include/vic_driver_shared_all.h | 416 ++- vic/drivers/shared_all/include/vic_version.h | 5 +- vic/drivers/shared_all/src/agg_data.c | 99 + vic/drivers/shared_all/src/alarms.c | 122 + vic/drivers/shared_all/src/cmd_proc.c | 6 +- vic/drivers/shared_all/src/compress_files.c | 16 +- .../shared_all/src/generate_default_state.c | 4 +- vic/drivers/shared_all/src/history_metadata.c | 1504 +++++++++++ .../shared_all/src/initialize_global.c | 3 - .../shared_all/src/initialize_options.c | 8 +- vic/drivers/shared_all/src/input_tools.c | 392 +++ .../shared_all/src/output_list_utils.c | 439 --- .../shared_all/src/print_library_shared.c | 112 +- vic/drivers/shared_all/src/put_data.c | 772 +++--- .../shared_all/src/set_output_defaults.c | 294 ++ vic/drivers/shared_all/src/vic_history.c | 475 ++++ vic/drivers/shared_all/src/vic_time.c | 176 +- vic/drivers/shared_all/src/zero_output_list.c | 10 +- .../include/vic_driver_shared_image.h | 63 +- vic/drivers/shared_image/include/vic_mpi.h | 22 +- vic/drivers/shared_image/include/vic_nc_log.h | 70 + vic/drivers/shared_image/src/get_nc_field.c | 54 +- vic/drivers/shared_image/src/init_library.c | 2 +- .../shared_image/src/parse_output_info.c | 215 +- .../src/print_library_shared_image.c | 12 +- vic/drivers/shared_image/src/put_nc_attr.c | 2 +- vic/drivers/shared_image/src/put_nc_field.c | 181 -- vic/drivers/shared_image/src/state_metadata.c | 699 +++++ vic/drivers/shared_image/src/vic_alloc.c | 4 +- vic/drivers/shared_image/src/vic_finalize.c | 28 +- vic/drivers/shared_image/src/vic_image_run.c | 14 +- vic/drivers/shared_image/src/vic_init.c | 3 + .../shared_image/src/vic_init_output.c | 702 +++-- .../shared_image/src/vic_mpi_support.c | 769 +++--- vic/drivers/shared_image/src/vic_nc_info.c | 553 ++-- vic/drivers/shared_image/src/vic_restore.c | 190 +- vic/drivers/shared_image/src/vic_start.c | 24 +- vic/drivers/shared_image/src/vic_store.c | 2396 ++++++++--------- vic/drivers/shared_image/src/vic_write.c | 227 +- vic/extensions/rout_rvic/src/rout_run.c | 12 +- vic/vic_run/include/vic_def.h | 57 +- vic/vic_run/include/vic_log.h | 14 +- vic/vic_run/include/vic_run.h | 4 +- vic/vic_run/src/soil_conduction.c | 4 +- 114 files changed, 9948 insertions(+), 6803 deletions(-) delete mode 100644 docs/Documentation/Drivers/Classic/SnowOutputFile.md create mode 100644 docs/Documentation/Drivers/Image/Ascii_to_NetCDF_params.md create mode 100644 docs/Documentation/Drivers/Image/LakeParam.md create mode 100644 tests/system/global.classic.STEHE.allhistvars.txt create mode 100644 tests/system/global.classic.STEHE.multistream.txt create mode 100644 tests/unit/shared/test_input_tools.py delete mode 100644 vic/drivers/classic/src/free_out_data_files.c delete mode 100644 vic/drivers/classic/src/set_output_defaults.c delete mode 100644 vic/drivers/classic/src/write_forcing_file.c create mode 100644 vic/drivers/shared_all/src/agg_data.c create mode 100644 vic/drivers/shared_all/src/alarms.c create mode 100644 vic/drivers/shared_all/src/history_metadata.c create mode 100644 vic/drivers/shared_all/src/input_tools.c delete mode 100644 vic/drivers/shared_all/src/output_list_utils.c create mode 100644 vic/drivers/shared_all/src/set_output_defaults.c create mode 100644 vic/drivers/shared_all/src/vic_history.c create mode 100644 vic/drivers/shared_image/include/vic_nc_log.h delete mode 100644 vic/drivers/shared_image/src/put_nc_field.c create mode 100644 vic/drivers/shared_image/src/state_metadata.c diff --git a/.gitignore b/.gitignore index d77be0323..65b0554a6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ .cache build/ dist/ +vic_headers.py # Shared objects (inc. Windows DLLs) *.dll diff --git a/ci/requirements.yml b/ci/requirements.yml index f23e8a02b..6e97212fb 100644 --- a/ci/requirements.yml +++ b/ci/requirements.yml @@ -13,3 +13,5 @@ dependencies: - pip: - git+https://github.com/UW-Hydro/tonic.git - engarde + - pytest-faulthandler + - pytest-xdist diff --git a/docs/Documentation/Drivers/Classic/DefaultOutputs.md b/docs/Documentation/Drivers/Classic/DefaultOutputs.md index 99e9d895f..b46b2e95d 100644 --- a/docs/Documentation/Drivers/Classic/DefaultOutputs.md +++ b/docs/Documentation/Drivers/Classic/DefaultOutputs.md @@ -4,24 +4,30 @@ If the user does not give explicit output file instructions in the global parame ## Flux Files -The primary output file type for the VIC-NL model is the flux file, which contains information about moisture and energy fluxes for each time step. These output files are based on the model output files used for the PILPS-2C project. The number of variables in this file depends on the values of FULL_ENERGY and FROZEN_SOIL in the [global parameter file](GlobalParam.md); when either FULL_ENERGY or FROZEN_SOIL are true, the file will contain the same number of columns as found in the PILPS-2C files for comparison purposes. Flux files are always written, regardless of the mode of operation. Flux files begin with the prefix "fluxes_". +The primary output file type for the VIC model is the flux file, which contains information about moisture and energy fluxes for each time step. These output files are based on the model output files used for the PILPS-2C project. The number of variables in this file depends on the values of `FULL_ENERGY` and `FROZEN_SOIL` in the [global parameter file](GlobalParam.md). When either `FULL_ENERGY` or `FROZEN_SOIL` are true, flux files are always written, regardless of the mode of operation. Flux files begin with the prefix `fluxes_`. For more information on the Flux Output Files, [click here](FluxOutputFiles.md). ## Snow Files -The snow file contains information about the snowpack, averaged across all elevation bands and vegetation tiles. The set of variables in this file depends on the values of FULL_ENERGY and FROZEN_SOIL in the [global parameter file](GlobalParam.md). Snow files are always written, regardless of the mode of operation. Snow files begin with the prefix "snow_". +The snow file contains information about the snowpack, averaged across all elevation bands and vegetation tiles. The set of variables in this file depends on the values of `FULL_ENERGY` and `FROZEN_SOIL` in the [global parameter file](GlobalParam.md). Snow files are always written, regardless of the mode of operation. Snow files begin with the prefix `snow_`. For more information on the Snow Output File, [click here](SnowOutputFile.md). ## Frozen Soil Files -When the model is run with FROZEN_SOIL set to TRUE in the [global parameter file](GlobalParam.md), a third output file is produced which contains soil thermal output parameters. Frozen soil files begin with the prefix "fdepth_". +When the model is run with `FROZEN_SOIL` set to TRUE in the [global parameter file](GlobalParam.md), a third output file is produced which contains soil thermal output parameters. Frozen soil files begin with the prefix `fdepth_`. For more information on the Frozen Soil Output File, [click here](FrozenSoilOutputFile.md). +## Snow Band Files + +When the model is run with snow elevation bands, and default outputs are specified in the [global parameter file](GlobalParam.md), snow pack information for each elevation band will be output to files in the results directory with the prefix `snow_band_`. Energy fluxes are output only for the full energy balance model, so there are file descriptions for both full energy and water balance model output files. + +For more information on the Snow Band Output Files, [click here](SnowBandOutputFiles.md). + ## Lake Files -The lake file contains information about the lake fraction of the grid cell. Lake files are only written when LAKES is set equal to a valid lake parameter file, in the [global parameter file](GlobalParam.md). Lake files begin with the prefix "lake_". +The lake file contains information about the lake fraction of each grid cell. Lake files are only written when LAKES is set equal to a valid lake parameter file, in the [global parameter file](GlobalParam.md). Lake files begin with the prefix `lake_`. -For more information on the Lake Output File, [click here](LakeOutputFile.md). \ No newline at end of file +For more information on the Lake Output File, [click here](LakeOutputFile.md). diff --git a/docs/Documentation/Drivers/Classic/FluxOutputFiles.md b/docs/Documentation/Drivers/Classic/FluxOutputFiles.md index b914a5321..a5319c5aa 100644 --- a/docs/Documentation/Drivers/Classic/FluxOutputFiles.md +++ b/docs/Documentation/Drivers/Classic/FluxOutputFiles.md @@ -1,43 +1,42 @@ # Default Flux Output Files -The primary output file type for the VIC Classic Driver is the flux file, which contains information about moisture and energy fluxes for each time step. The number of variables in this file depends on the values of FULL_ENERGY and FROZEN_SOIL in the [global parameter file](GlobalParam.md); when either FULL_ENERGY or FROZEN_SOIL are true, the file will contain the same number of columns as found in the PILPS-2C files for comparison purposes. Flux files are always written, regardless of the mode of operation. Flux files begin with the prefix "fluxes_". +The primary output file type for the VIC Classic Driver is the flux file, which contains information about moisture and energy fluxes for each time step. The number of variables in this file depends on the values of `FULL_ENERGY` and `FROZEN_SOIL` in the [global parameter file](GlobalParam.md); when either `FULL_ENERGY` or `FROZEN_SOIL` are true, the file will contain the same number of columns as found in the PILPS-2C files for comparison purposes. Flux files are always written, regardless of the mode of operation. Flux files begin with the prefix `fluxes_`. -Each output file contains model output from one grid cell. The files use the naming convention "fluxes_xx.xx_yy.yy", where xx.xx is the latitude, and yy.yy is the longitude. The number of decimal places in the output filename is determined by GRID_DECIMAL in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). +Each output file contains model output from one grid cell. The files use the naming convention `fluxes_xx.xx_yy.yy`, where `xx.xx` is the latitude, and `yy.yy` is the longitude. The number of decimal places in the output filename is determined by `GRID_DECIMAL` in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). ## Flux File Format - -| Column | Variable Name | Units | Description | -|---------------------------------------------------------------------------------------------------------------------|-----------------|----------|-----------------------------------------------------------------------| -| 1 | year | year | Year of current record | -| 2 | month | month | Month of current record | -| 3 | day | day | Day of current record | -| 4 | hour | hour | Hour of current record (if time step is sub-daily) | -| 5 | OUT_PREC | mm | Precipitation for current record | -| 6 | OUT_EVAP | mm | Evaporation for current record | -| 7 | OUT_RUNOFF | mm | Runoff for current record | -| 8 | OUT_BASEFLOW | mm | Baseflow for current record | -| 9 | OUT_WDEW | mm | Canopy interception of liquid water | -| 10: Nlayer+9 | OUT_SOIL_LIQ | mm | Moisture content of each soil layer | -| OUT_RAD_TEMP is only output when FULL_ENERGY or FROZEN_SOIL is TRUE in the global parameter file | | | | -| Nlayer+10 | OUT_RAD_TEMP | K | Radiative temperature of the surface | -| Nlayer+11 | OUT_SWNET | W/m2 | Net shortwave radiation at the surface | -| Nlayer+12 | OUT_R_NET | W/m2 | Net radiation at the surface, includes long and shortwave radiation | -| OUT_LATENT is only output when FULL_ENERGY or FROZEN_SOIL is TRUE in the global parameter file | | | | -| Nlayer+13 | OUT_LATENT | W/m2 | Latent heat from the surface | -| Nlayer+14 | OUT_EVAP_CANOP | mm | Evaporation from canopy storage | -| Nlayer+15 | OUT_TRANSP_VEG | mm | Transpiration from the vegetation | -| Nlayer+16 | OUT_EVAP_BARE | mm | Evaporation from bare soil | -| Nlayer+17 | OUT_SUB_CANOP | mm | Sublimation from canopy interception | -| Nlayer+18 | OUT_SUB_SNOW | mm | Sublimation from ground snow pack | -| The following four variables are only output when FULL_ENERGY or FROZEN_SOIL is TRUE in the global parameter file | | | | -| Nlayer+19 | OUT_SENSIBLE | W/m2 | Sensible heat flux from the surface | -| Nlayer+20 | OUT_GRND_FLUX | W/m2 | Ground heat flux plus heat storage in the top soil layer | -| Nlayer+21 | OUT_DELTAH | W/m2 | Rate of change in heat storage | -| Nlayer+22 | OUT_FUSION | W/m2 | Net energy used to melt/freeze soil moisture | -| Nlayer+23 | OUT_AERO_RESIST | s/m | Aerodynamic resistance | -| Nlayer+24 | OUT_SURF_TEMP | C | Surface temperature | -| Nlayer+25 | OUT_ALBEDO | fraction | Albedo of surface cover | -| Nlayer+26 | OUT_REL_HUMID | fraction | Relative humidity | -| Nlayer+27 | OUT_IN_LONG | W/m2 | Incoming longwave at ground surface (under vegetation) | -| Nlayer+28 | OUT_AIR_TEMP | C | Air temperature | -| Nlayer+29 | OUT_WIND | m/s | Near surface wind speed | \ No newline at end of file +| Column | Variable Name | Units | Description | +|------------------------------------------------------------------------------------------------------------------- |----------------- |-------------------------- |--------------------------------------------------------------------- | +| 1 | year | year | Year of current record | +| 2 | month | month | Month of current record | +| 3 | day | day | Day of current record | +| 4 | hour | hour | Hour of current record (if time step is sub-daily) | +| 5 | OUT_PREC | mm | Precipitation for current record | +| 6 | OUT_EVAP | mm | Evaporation for current record | +| 7 | OUT_RUNOFF | mm | Runoff for current record | +| 8 | OUT_BASEFLOW | mm | Baseflow for current record | +| 9 | OUT_WDEW | mm | Canopy interception of liquid water | +| 10: Nlayer+9 | OUT_SOIL_LIQ | mm | Moisture content of each soil layer | +| OUT_RAD_TEMP is only output when `FULL_ENERGY` or `FROZEN_SOIL` is TRUE in the global parameter file | | | | +| Nlayer+10 | OUT_RAD_TEMP | K | Radiative temperature of the surface | +| Nlayer+11 | OUT_SWNET | W/m2 | Net shortwave radiation at the surface | +| Nlayer+12 | OUT_R_NET | W/m2 | Net radiation at the surface, includes long and shortwave radiation | +| OUT_LATENT is only output when `FULL_ENERGY` or `FROZEN_SOIL` is TRUE in the global parameter file | | | | +| Nlayer+13 | OUT_LATENT | W/m2 | Latent heat from the surface | +| Nlayer+14 | OUT_EVAP_CANOP | mm | Evaporation from canopy storage | +| Nlayer+15 | OUT_TRANSP_VEG | mm | Transpiration from the vegetation | +| Nlayer+16 | OUT_EVAP_BARE | mm | Evaporation from bare soil | +| Nlayer+17 | OUT_SUB_CANOP | mm | Sublimation from canopy interception | +| Nlayer+18 | OUT_SUB_SNOW | mm | Sublimation from ground snow pack | +| The following four variables are only output when `FULL_ENERGY` or `FROZEN_SOIL` is TRUE in the global parameter file | | | | +| Nlayer+19 | OUT_SENSIBLE | W/m2 | Sensible heat flux from the surface | +| Nlayer+20 | OUT_GRND_FLUX | W/m2 | Ground heat flux plus heat storage in the top soil layer | +| Nlayer+21 | OUT_DELTAH | W/m2 | Rate of change in heat storage | +| Nlayer+22 | OUT_FUSION | W/m2 | Net energy used to melt/freeze soil moisture | +| Nlayer+23 | OUT_AERO_RESIST | s/m | Aerodynamic resistance | +| Nlayer+24 | OUT_SURF_TEMP | C | Surface temperature | +| Nlayer+25 | OUT_ALBEDO | fraction | Albedo of surface cover | +| Nlayer+26 | OUT_REL_HUMID | fraction | Relative humidity | +| Nlayer+27 | OUT_IN_LONG | W/m2 | Incoming longwave at ground surface (under vegetation) | +| Nlayer+28 | OUT_AIR_TEMP | C | Air temperature | +| Nlayer+29 | OUT_WIND | m/s | Near surface wind speed | diff --git a/docs/Documentation/Drivers/Classic/FrozenSoilOutputFile.md b/docs/Documentation/Drivers/Classic/FrozenSoilOutputFile.md index 32ad17dd1..9fdeb6828 100644 --- a/docs/Documentation/Drivers/Classic/FrozenSoilOutputFile.md +++ b/docs/Documentation/Drivers/Classic/FrozenSoilOutputFile.md @@ -2,7 +2,7 @@ When the model is run with the frozen soil algorithms, a third output file is produced which contains soil thermal output parameters. Since the frozen soils algorithm only works in with the full energy balance, there is only one format for the output file. -Each output file contains model output from one grid cell. The files use the naming convention "fdepth_xx.xx_yy.yy", where xx.xx is the latitude, and yy.yy is the longitude. The number of decimal places in the output filename is determined by GRID_DECIMAL in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). +Each output file contains model output from one grid cell. The files use the naming convention `fdepth_xx.xx_yy.yy`, where `xx.xx` is the latitude, and `yy.yy` is the longitude. The number of decimal places in the output filename is determined by GRID_DECIMAL in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). * * * diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index 0a20b6b39..2350ddb80 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -9,7 +9,7 @@ The order of the options in the global parameter file is not important, but the # Define Simulation Parameters -The following options determine the type of simulation that wil3l be performed. +The following options determine the type of simulation that will be performed. ## Main Simulation Parameters @@ -131,9 +131,9 @@ This section describes how to define the forcing files needed by the VIC model. Unlike model parameters, for which 1 file contains data for all grid cells, the meteorological forcings are stored as a separate time series for each grid cell. The time step length of the input forcings must match the time step length at which VIC is running. Input files can be ASCII or Binary (signed or unsigned short ints) column formatted. Columns in the file must be in the same order as they are defined in the global control file. -VIC will allow forcing data to be stored in two different files per grid cell (e.g., precip and wind speed in one file, tmin and tmax in another file; or meteorological variables in one file, and vegetation timeseries in another file). Note that if you are using two forcing files per grid cell, the parameters for the first file must be defined before those for the second. **Bold** numbers indicate the order in which these values should be defined, after each forcing file (FORCING1 or FORCING2). Options that do not have a bold number apply to both forcing file types and should appear after the numbered options. +VIC will allow forcing data to be stored in two different files per grid cell (e.g., precip and wind speed in one file, tmin and tmax in another file; or meteorological variables in one file, and vegetation timeseries in another file). Note that if you are using two forcing files per grid cell, the parameters for the first file must be defined before those for the second. **Bold** numbers indicate the order in which these values should be defined, after each forcing file (`FORCING1` or `FORCING2`). Options that do not have a bold number apply to both forcing file types and should appear after the numbered options. -All FORCING filenames are actually the pathname, and prefix for gridded data types: ex. DATA/forcing_YY.YYY_XX.XXX. Latitude and longitude index suffix is added by VIC based on GRID_DECIMAL parameter defined above, and the latitude and longitude values defined in the [soil parameter file](SoilParam.md). +All FORCING filenames are actually the pathname, and prefix for gridded data types: ex. `DATA/forcing_YY.YYY_XX.XXX`. Latitude and longitude index suffix is added by VIC based on the `GRID_DECIMAL` parameter defined above, and the latitude and longitude values defined in the [soil parameter file](SoilParam.md). | Name | Type | Units | Description | |------------------ |--------- |-------------------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -149,7 +149,6 @@ All FORCING filenames are actually the pathname, and prefix for gridded data typ | (9) FORCEDAY | integer | day | Day meteorological forcing files start | | GRID_DECIMAL | integer | N/A | Number of decimals to use in gridded file name extensions | | WIND_H | float | m | Height of wind speed measurement over bare soil and snow cover. ***Wind measurement height over vegetation is now read from the vegetation library file for all types, the value in the global file only controls the wind height over bare soil and over the snow pack when a vegetation canopy is not defined.*** | -| ALMA_INPUT | string | TRUE or FALSE | This option tells VIC the units to expect for the input variables:
  • **FALSE** = Use standard VIC units: for moisture fluxes, use cumulative mm over the time step; for temperature, use degrees C;
  • **TRUE** = Use the units of the ALMA convention: for moisture fluxes, use the average rate in mm/s (or kg/m2s) over the time step; for temperature, use degrees K;

    Default = FALSE. | - If using one forcing file, use only FORCING1, if using two forcing files, define all parameters for FORCING1, and then define all forcing parameters for FORCING2\. All parameters need to be defined for both forcing files when a second file is used. @@ -157,22 +156,41 @@ _Examples._ a standard four column daily forcing data file will be defined as: ## ASCII File - FORCING1 FORCING_DATA/LDAS_ONE_DEGREE/data_ - N_TYPES 4 - FORCE_TYPE PREC - FORCE_TYPE WIND - FORCE_FORMAT ASCII - FORCE_STEPS_PER_DAY 24 + FORCING1 forcings/full_data_ + FORCE_FORMAT ASCII + FORCE_TYPE PREC + FORCE_TYPE AIR_TEMP + FORCE_TYPE SWDOWN + FORCE_TYPE LWDOWN + FORCE_TYPE SKIP # This column is air density, which is not needed by VIC + FORCE_TYPE PRESSURE + FORCE_TYPE VP + FORCE_TYPE WIND + FORCE_STEPS_PER_DAY 24 # Forcing time step length (hours) + FORCEYEAR 1949 # Year of first forcing record + FORCEMONTH 01 # Month of first forcing record + FORCEDAY 01 # Day of first forcing record + GRID_DECIMAL 4 # Number of digits after decimal point in forcing file names + WIND_H 10.0 # height of wind speed measurement (m) ## Binary File - FORCING1 FORCING_DATA/LDAS_ONE_DEGREE/data_ - N_TYPES 4 - FORCE_TYPE PREC UNSIGNED 40 - FORCE_TYPE WIND SIGNED 100 - FORCE_FORMAT BINARY - FORCE_ENDIAN LITTLE - FORCE_STEPS_PER_DAY 24 + FORCING1 forcings/full_data_ + FORCE_FORMAT BINARY + FORCE_ENDIAN LITTLE + FORCE_TYPE PREC UNSIGNED 40 + FORCE_TYPE AIR_TEMP SIGNED 100 + FORCE_TYPE SWDOWN UNSIGNED 100 + FORCE_TYPE LWDOWN UNSIGNED 100 + FORCE_TYPE PRESSURE UNSIGNED 100 + FORCE_TYPE VP UNSIGNED 100 + FORCE_TYPE WIND UNSIGNED 100 + FORCE_STEPS_PER_DAY 24 # Forcing time step length (hours) + FORCEYEAR 1949 # Year of first forcing record + FORCEMONTH 01 # Month of first forcing record + FORCEDAY 01 # Day of first forcing record + GRID_DECIMAL 4 # Number of digits after decimal point in forcing file names + WIND_H 10.0 # height of wind speed measurement (m) # Define Parameter Files @@ -184,7 +202,7 @@ The following options describe the input parameter files. | SOIL | string | path/filename | the Soil parameter file. | | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file:
  • **ARNO** = fields 5-8 of the soil parameter file are the standard VIC baseflow parameters
  • **NIJSSEN2001** = fields 5-8 of the soil parameter file are the baseflow parameters from Nijssen et al (2001)

    Default = ARNO. | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional column (July_Tavg) in the soil parameter file to contain the grid cell's average July temperature. If your soil parameter file contains this optional column, you MUST set JULY_TAVG_SUPPLIED to TRUE so that VIC can read the soil parameter file correctly.

    *NOTE*: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE.

    Default = FALSE. | -| ORGANIC_FRACT | string | TRUE or FALSE | (release 4.1.2 and later)
  • **TRUE** = the soil parameter file contains `3*Nlayer` extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer.
  • **FALSE** = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | +| ORGANIC_FRACT | string | TRUE or FALSE |
  • **TRUE** = the soil parameter file contains `3*Nlayer` extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer.
  • **FALSE** = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | | VEGLIB | string | path/filename | Vegetation library file name | | VEGPARAM | string | path/filename | Vegetation parameter file name | | ROOT_ZONES | integer | N/A | Number of defined root zones defined for root distribution. | @@ -212,50 +230,24 @@ The following options only take effect when the lake model is running. # Define Output Files -The following options describe the output files. Click [here](OutputFormatting.md) for more information. - -| Name | Type | Units | Description | -|---------------------- |--------- |--------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| LOG_DIR | string | path name | Name of directory where log files should be written (optional, default is stdout) | -| RESULT_DIR | string | path name | Name of directory where model results are written | -| OUT_STEP | integer | hours | Output time step length | -| SKIPYEAR | integer | years | Number of years to skip before starting to write output file. Used to reduce output by not including spin-up years. | -| COMPRESS | string | TRUE or FALSE | if TRUE compress input and output files when done (uses gzip) | -| OUT_FORMAT | string | BINARY OR ASCII | If BINARY write output files in binary (default is ASCII). | -| ALMA_OUTPUT | string | TRUE or FALSE | Options for output units:
  • **FALSE** = standard VIC units. Moisture fluxes are in cumulative mm over the time step; temperatures are in degrees C
  • **TRUE** = units follow the ALMA convention. Moisture fluxes are in average mm/s (kg/m2s) over the time step; temperatures are in degrees K

    Default = FALSE. [Click here for more information.](OutputFormatting.md) | -| MOISTFRACT | string | TRUE or FALSE | Options for output soil moisture units (default is FALSE):
  • **FALSE** = Standard VIC units. Soil moisture is in mm over the grid cell area
  • **TRUE** = Soil moisture is volume fraction | -| PRT_HEADER | string | TRUE or FALSE | Options for output file headers (default is FALSE):
  • **FALSE** = output files contain no headers
  • **TRUE** = headers are inserted into the beginning of each output file, listing the names of the variables in each field of the file (if ASCII) and/or the variable data types (if BINARY)

    [Click here for more information.](OutputFormatting.md) | -| PRT_SNOW_BAND | string | TRUE or FALSE | if TRUE then print snow variables for each snow band in a separate output file (`snow_band_*`).

    *NOTE*: this option is ignored if output file contents are specified. | -| OUTFILE\* |
    string
    |
    prefix
    | Information about this output file:
    Prefix of the output file (to which the lat and lon will be appended)
    This should be specified once for each output file. [Click here for more information.](OutputFormatting.md) | -| OUTVAR\* |
    string
    string
    string
    integer
    |
    name
    format
    type
    multiplier
    | Information about this output variable:
    Name (must match a name listed in vicNl_def.h)
    Output format (C fprintf-style format code)
    Data type (one of: OUT_TYPE_DEFAULT, OUT_TYPE_CHAR, OUT_TYPE_SINT, OUT_TYPE_USINT, OUT_TYPE_INT, OUT_TYPE_FLOAT,OUT_TYPE_DOUBLE)
    Multiplier - number to multiply the data with in order to recover the original values (only valid with OUT_FORMAT=BINARY)

    This should be specified once for each output variable. [Click here for more information.](OutputFormatting.md)| - -\* *Note: `OUTFILE`, and `OUTVAR` are optional; if omitted, traditional output files are produced. [Click here for details on using these instructions](OutputFormatting.md).* - -# Obsolete Options from Earlier Versions - -The following options are no longer supported. - -| Name | Type | Units | Description | -|------------- |-------- |----------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| TIME_STEP | integer | hour | Simulation time step length | -| SNOW_STEP | integer | hour | Snow model time step length | -| STARTHOUR | integer | hour | Hour model simulation starts | -| GRND_FLUX | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE, compute ground heat flux and energy balance; if FALSE, do not compute ground heat flux. Default: If FULL_ENERGY or FROZEN_SOIL are TRUE, GRND_FLUX is automatically set to TRUE; otherwise GRND_FLUX is automatically set to FALSE. | -| MIN_LIQ | string | TRUE or FALSE | Version 4.1.1 only. Options for handling minimum soil moisture in presence of ice (default is FALSE):
  • **FALSE** = Use residual moisture as lower bound on soil moisture in Brooks-Corey/Campbell and other relationships involving liquid water.
  • **TRUE** = Use (`residual moisture * unfrozen water fraction` as function of temperature) as lower bound on soil moisture in Brooks-Corey/Campbell and other relationships involving liquid water. | -| GLOBAL_LAI | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly LAI values for each vegetation type for each grid cell.

    *NOTE*: This option has been replaced by the two options LAI_SRC and VEGPARAM_LAI. | -| OUTPUT_FORCE | string | TRUE or FALSE | If TRUE, perform disaggregation of forcings, skip the simulation, and output the disaggregated forcings. | -| FORCEHOUR | integer | hour | Hour meteorological forcing files start | -| MEASURE_H | decimal | m | Height of humidity measurement | -| PRT_FLUX | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print energy fluxes debugging files . | -| PRT_BALANCE | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print water balance debugging files . | -| PRT_SOIL | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print soil parameter debugging files . | -| PRT_VEGE | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print vegetation parameter debugging files . | -| PRT_GLOBAL | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print global parameter debugging files . | -| PRT_ATMOS | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print forcing data debugging files . | -| PRT_SNOW | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print snow debugging files . | -| PRT_MOIST | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print soil moisture debugging files . | -| PRT_TEMP | string | TRUE or FALSE | Versions 4.1.1 and earlier. If TRUE print soil thermal debugging files . | -| DEBUG_DIR | string | char * pathname | Versions 4.1.1 and earlier. Debugging files output directory (default directory is the current directory, '.'). | +The following options describe the location of the log and model history files. Click [here](OutputFormatting.md) for more information. + +| Name | Type | Units | Description | +|---------------------- |--------- |--------------- |----------------------------------------------------------------------------------- | +| LOG_DIR | string | path name | Name of directory where log files should be written (optional, default is stdout) | +| RESULT_DIR | string | path name | Name of directory where model results are written | + +The following options describe the settings for each output stream: + +| Name | Type | Units | Description | +|------------ |--------- |--------------- |----------------------------------------------------------------------------------- | +| OUTFILE\* | string | prefix | Information about this output file:
    Prefix of the output file (to which the lat and lon will be appended3)
    This should be specified once for each output file. [Click here for more information.](OutputFormatting.md) | +| AGGFREQ | string
    [integer/string] | frequency
    count | Describes aggregation frequency for output stream. Valid options for frequency are: NEVER, NSTEPS, NSECONDS, NMINUTES, NHOURS, NDAYS, NMONTHS, NYEARS, DATE, END. Count may be an positive integer or a string with date format YYYY-MM-DD[-SSSSS] in the case of DATE.
    Default `frequency` is `NDAYS`. Default `count` is 1. | +| COMPRESS | string/integer | TRUE, FALSE, or lvl | if TRUE or > 0 compress input and output files when done (uses `gzip`), if an integer [1-9] is supplied, it is used to set the`gzip` compression level | +| OUT_FORMAT | string | BINARY OR ASCII | If BINARY write output files in binary (default is ASCII). | +| OUTVAR\* |
    string
    string
    string
    integer
    string
    |
    name
    format
    type
    multiplier
    aggtype
    | Information about this output variable:
    Name (must match a name listed in vic_driver_shared_all.h)
    Output format (C fprintf-style format code) (only valid with OUT_FORMAT=ASCII)
    Data type (one of: OUT_TYPE_DEFAULT, OUT_TYPE_CHAR, OUT_TYPE_SINT, OUT_TYPE_USINT, OUT_TYPE_INT, OUT_TYPE_FLOAT,OUT_TYPE_DOUBLE)
    Multiplier - number to multiply the data with in order to recover the original values (only valid with OUT_FORMAT=BINARY)
    Aggregation method - temporal aggregation method to use (one of: AGG_TYPE_DEFAULT, AGG_TYPE_AVG, AGG_TYPE_BEG, AGG_TYPE_END, AGG_TYPE_MAX, AGG_TYPE_MIN, AGG_TYPE_SUM)

    This should be specified once for each output variable. [Click here for more information.](OutputFormatting.md)| + + - *Note: `OUTFILE`, and `OUTVAR` are optional; if omitted, traditional output files are produced. [Click here for details on using these instructions](OutputFormatting.md).* ## Example Global Parameter File: ``` @@ -347,7 +339,7 @@ FROZEN_SOIL FALSE # TRUE = calculate frozen soils. Default = FALSE. #VP_INTERP TRUE # This controls sub-daily humidity estimates; TRUE = interpolate daily VP estimates linearly between sunrise of one day to the next; FALSE = hold VP constant for entire day #LW_TYPE LW_PRATA # This controls the algorithm used to estimate clear-sky longwave radiation: # # LW_TVA = Tennessee Valley Authority algorithm (1972) (this was traditional VIC algorithm) -# # other options listed in vic_driver_shared.h +# # other options listed in vic_driver_shared_all.h # # default = LW_PRATA #LW_CLOUD LW_CLOUD_DEARDORFF # This controls the algorithm used to estimate the influence of clouds on total longwave: # # LW_CLOUD_BRAS = method from Bras textbook (this was the traditional VIC algorithm) @@ -394,21 +386,22 @@ FROZEN_SOIL FALSE # TRUE = calculate frozen soils. Default = FALSE. # or (ASCII): # FORCE_TYPE PREC ####################################################################### -FORCING1 (put the forcing path/prefix here) # Forcing file path and prefix, ending in "_" -FORCE_FORMAT BINARY # BINARY or ASCII -FORCE_ENDIAN LITTLE # LITTLE (PC/Linux) or BIG (SUN) -N_TYPES 4 # Number of variables (columns) -FORCE_TYPE PREC UNSIGNED 40 -FORCE_TYPE TMAX SIGNED 100 -FORCE_TYPE TMIN SIGNED 100 -FORCE_TYPE WIND SIGNED 100 -FORCE_STEPS_PER_DAY 24 # Forcing time step length (hours) -FORCEYEAR 2000 # Year of first forcing record -FORCEMONTH 01 # Month of first forcing record -FORCEDAY 01 # Day of first forcing record -GRID_DECIMAL 4 # Number of digits after decimal point in forcing file names -WIND_H 10.0 # height of wind speed measurement (m) -ALMA_INPUT FALSE # TRUE = ALMA-compliant input variable units; FALSE = standard VIC units +FORCING1 forcings/full_data_ +FORCE_FORMAT ASCII +FORCE_TYPE PREC +FORCE_TYPE AIR_TEMP +FORCE_TYPE SWDOWN +FORCE_TYPE LWDOWN +FORCE_TYPE SKIP # This column is air density, which is not needed by VIC +FORCE_TYPE PRESSURE +FORCE_TYPE VP +FORCE_TYPE WIND +FORCE_STEPS_PER_DAY 24 # Forcing time step length (hours) +FORCEYEAR 1949 # Year of first forcing record +FORCEMONTH 01 # Month of first forcing record +FORCEDAY 01 # Day of first forcing record +GRID_DECIMAL 4 # Number of digits after decimal point in forcing file names +WIND_H 10.0 # height of wind speed measurement (m) ####################################################################### # Land Surface Files and Parameters @@ -441,56 +434,59 @@ SNOW_BAND 1 # Number of snow bands; if number of snow bands > 1, you must in ####################################################################### # Output Files and Parameters ####################################################################### +LOG_DIR (put the log directory path here) # Log directory path RESULT_DIR (put the result directory path here) # Results directory path -OUTPUT_STEPS_PER_DAY 0 # Output interval (hours); if 0, OUT_STEP = MODEL_STEPS_PER_DAY -SKIPYEAR 0 # Number of years of output to omit from the output files -COMPRESS FALSE # TRUE = compress input and output files when done -OUT_FORMAT BINARY # BINARY or ASCII -ALMA_OUTPUT FALSE # TRUE = ALMA-format output files; FALSE = standard VIC units -MOISTFRACT FALSE # TRUE = output soil moisture as volumetric fraction; FALSE = standard VIC units -PRT_SNOW_BAND FALSE # TRUE = write a "snowband" output file, containing band-specific values of snow variables. ####################################################################### # # Output File Contents # -# As of VIC 4.0.6 and 4.1.0, you can specify your output file names and -# contents # in the global param file (see the README.txt file for more -# information). +# You can specify your output file names and contents in the global param file +# (see the VIC documentation for more information). # # If you do not specify file names and contents in the global param # file, VIC will produce the same set of output files that it has # produced in earlier versions, namely "fluxes" and "snow" files, plus # "fdepth" files if FROZEN_SOIL is TRUE and "snowband" files if -# PRT_SNOW_BAND is TRUE. These files will have the same contents and +# snowbands are specified. These files will have the same contents and # format as in earlier versions. # -# The OPTIMIZE and LDAS_OUTPUT options have been removed. These -# output configurations can be selected with the proper set of -# instructions in the global param file. (see the output.*.template -# files included in this distribution for more information.) -# -# If you do specify the file names and contents in the global param file, -# PRT_SNOW_BAND will have no effect. -# # Format: # # OUTFILE -# OUTVAR [ ] -# OUTVAR [ ] -# OUTVAR [ ] +# AGGFREQ +# COMPRESS +# OUT_FORMAT +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # OUTFILE -# OUTVAR [ ] -# OUTVAR [ ] -# OUTVAR [ ] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # # where # = name of the output file, NOT including latitude # and longitude +# = Describes aggregation frequency for output stream. Valid +# options for frequency are: +# NEVER = never write to history file +# NSTEPS = write to history every steps +# NSECONDS = write to history every seconds +# NMINUTES = write to history every minutes +# NHOURS = write to history every hours +# NDAYS = write to history every days +# NMONTHS = write to history every months +# NYEARS = write to history every years +# DATE = write to history on the date: +# END = write to history at the end of the simulation +# = integer or date string (YYYY-MM-DD) describing the number +# of intervals to pass before writing to the history file. +# = gzip compression option. TRUE, FALSE, or integer between 1-9. # = name of the variable (this must be one of the -# output variable names listed in vic_driver_shared.h.) +# output variable names listed in vic_driver_shared_all.h.) # = (for ascii output files) fprintf format string, # e.g. # %.4f = floating point with 4 decimal places @@ -513,6 +509,15 @@ PRT_SNOW_BAND FALSE # TRUE = write a "snowband" output file, containing band # = (for binary output files) factor to multiply # the data by before writing, to increase precision. # * = use the default multiplier for this variable +# = Aggregation method to use for temporal aggregation. Valid +# options for aggtype are: +# AGG_TYPE_DEFAULT = default aggregation type for variable +# AGG_TYPE_AVG = average over aggregation window +# AGG_TYPE_BEG = beginning of aggregation window +# AGG_TYPE_END = end of aggregation window +# AGG_TYPE_MAX = maximum in aggregation window +# AGG_TYPE_MIN = minimum in aggregation window +# AGG_TYPE_SUM = sum over aggregation window # ####################################################################### ``` diff --git a/docs/Documentation/Drivers/Classic/LakeOutputFile.md b/docs/Documentation/Drivers/Classic/LakeOutputFile.md index 7dbaee968..74af578f9 100644 --- a/docs/Documentation/Drivers/Classic/LakeOutputFile.md +++ b/docs/Documentation/Drivers/Classic/LakeOutputFile.md @@ -1,16 +1,16 @@ # Lake Output File -The lake file contains information about the lake fraction of the grid cell. Lake files are only written when LAKES is set equal to a valid lake parameter file, in the [global parameter file](GlobalParam.md). Lake files begin with the prefix "lake_". +The lake file contains information about the lake fraction of the grid cell. Lake files are only written when LAKES is set equal to a valid lake parameter file, in the [global parameter file](GlobalParam.md). Lake files begin with the prefix `lake_`. -Each output file contains model output from one grid cell. The files use the naming convention "fluxes_xx.xx_yy.yy", where xx.xx is the latitude, and yy.yy is the longitude. The number of decimal places in the output filename is determined by GRID_DECIMAL in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). +Each output file contains model output from one grid cell. The files use the naming convention `fluxes_xx.xx_yy.yy`, where `xx.xx` is the latitude, and `yy.yy` is the longitude. The number of decimal places in the output filename is determined by the `GRID_DECIMAL` in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). -| Column | Variable Name | Units | Description | -|--------|---------------------|----------|-----------------------------------------------------------| -| 1 | OUT_LAKE_ICE_TEMP | C | Temperature of lake ice | -| 2 | OUT_LAKE_ICE_HEIGHT | cm | Thickness of lake ice | -| 3 | OUT_LAKE_ICE_FRACT | fraction | Fractional coverage of lake ice | -| 4 | OUT_LAKE_DEPTH | m | Lake depth (distance between surface and deepest point) | -| 5 | OUT_LAKE_SURF_AREA | m2 | Lake surface area | -| 6 | OUT_LAKE_VOLUME | m3 | Lake volume | -| 7 | OUT_LAKE_SURF_TEMP | C | Lake surface temperature | -| 8 | OUT_EVAP_LAKE | mm | Net evaporation from lake surface | \ No newline at end of file +| Column | Variable Name | Units | Description | +|-------- |--------------------- |-------------- |--------------------------------------------------------- | +| 1 | OUT_LAKE_ICE_TEMP | C | Temperature of lake ice | +| 2 | OUT_LAKE_ICE_HEIGHT | cm | Thickness of lake ice | +| 3 | OUT_LAKE_ICE_FRACT | fraction | Fractional coverage of lake ice | +| 4 | OUT_LAKE_DEPTH | m | Lake depth (distance between surface and deepest point) | +| 5 | OUT_LAKE_SURF_AREA | m2 | Lake surface area | +| 6 | OUT_LAKE_VOLUME | m3 | Lake volume | +| 7 | OUT_LAKE_SURF_TEMP | C | Lake surface temperature | +| 8 | OUT_EVAP_LAKE | mm | Net evaporation from lake surface | diff --git a/docs/Documentation/Drivers/Classic/OutputFormatting.md b/docs/Documentation/Drivers/Classic/OutputFormatting.md index 12fc43201..50b55b7f7 100644 --- a/docs/Documentation/Drivers/Classic/OutputFormatting.md +++ b/docs/Documentation/Drivers/Classic/OutputFormatting.md @@ -7,9 +7,7 @@ VIC allows the user to specify exactly which output files to create and which va **Main points:** 1. Output file names and contents can be specified in the [global parameter file](GlobalParam.md) (see below). -2. If you do not specify file names and contents in the [global parameter file](GlobalParam.md), VIC will produce the same set of output files that it has produced in earlier versions, namely "fluxes" and "snow" files, plus "fdepth" files if FROZEN_SOIL is TRUE and "snowband" files if PRT_SNOW_BAND is TRUE. These files will have the same contents and format as in earlier versions. -3. The OPTIMIZE and LDAS_OUTPUT options have been removed. These output configurations can be selected with the proper set of instructions in the [global parameter file](GlobalParam.md). (see the `output.*.template` files included in this distribution for more information.) -4. If you do specify the file names and contents in the [global parameter file](GlobalParam.md), PRT_SNOW_BAND will have no effect. +2. If you do not specify file names and contents in the [global parameter file](GlobalParam.md), VIC will produce the same set of output files that it has produced in earlier versions, namely `fluxes_` and `snow_` files, plus `fdepth_` files if `FROZEN_SOIL` is TRUE. These files will have the same contents and format as in earlier versions. **To specify file names and contents in the [global parameter file](GlobalParam.md):** @@ -20,63 +18,88 @@ VIC allows the user to specify exactly which output files to create and which va ``` # Output File Contents OUTFILE _prefix_ -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] +OUTVAR _varname_ [_format_ _type_ _multiplier_] +OUTVAR _varname_ [_format_ _type_ _multiplier_] +OUTVAR _varname_ [_format_ _type_ _multiplier_] OUTFILE _prefix_ -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] -OUTVAR _varname_ [_format_ _type_ _multiplier_ [_aggtype_]] +OUTVAR _varname_ [_format_ [_type_ [_multiplier_ [_aggtype_]]]] +OUTVAR _varname_ [_format_ [_type_ [_multiplier_ [_aggtype_]]]] +OUTVAR _varname_ [_format_ [_type_ [_multiplier_ [_aggtype_]]]] ``` where -         _prefix_ = name of the output file, NOT including latitude and longitude - -         _varname_ = name of the variable (this must be one of the output variable names listed in `vic_driver_shared.h`.) - -         _format_, _type_, and _multiplier_ are optional. For a given variable, -you can specify either NONE of these, or ALL of these. If these -are omitted, the default values will be used. - -         _format_ = (for ascii output files) `fprintf` format string, e.g.
    -                  `%.4f` = floating point with 4 decimal places
    -                  `%.7e` = scientific notation w/ 7 decimal places
    -                  `*` = use the default format for this variable
    - -         _type_ = (for `BINARY` output files) data type code. Must be one of:
    -                  `OUT_TYPE_DOUBLE` = double-precision floating point
    -                  `OUT_TYPE_FLOAT` = single-precision floating point
    -                  `OUT_TYPE_INT` = integer
    -                  `OUT_TYPE_USINT` = unsigned short integer
    -                  `OUT_TYPE_SINT` = short integer
    -                  `OUT_TYPE_CHAR` = char
    -                  `*` = use the default type
    - -         _multiplier_ = (for `BINARY` output files) factor to multiply the data by before writing, to increase precision compared to not using the multiplier.
    -                  `*` = use the default multiplier for this variable - -          _aggtype_ = Aggregation method to use for temporal aggregation. Valid options for aggtype are:
    -                  `AGG_TYPE_DEFAULT` = default aggregation type for variable
    -                  `AGG_TYPE_AVG` = average over aggregation window
    -                  `AGG_TYPE_BEG` = beginning of aggregation window
    -                  `AGG_TYPE_END` = end of aggregation window
    -                  `AGG_TYPE_MAX` = maximum in aggregation window
    -                  `AGG_TYPE_MIN` = minimum in aggregation window
    -                  `AGG_TYPE_SUM` = sum over aggregation window
    +``` + _prefix_ = name of the output file, NOT including latitude + and longitude + _freq_ = Describes aggregation frequency for output stream. Valid + options for frequency are: + NEVER = never write to history file + NSTEPS = write to history every _value_ steps + NSECONDS = write to history every _value_ seconds + NMINUTES = write to history every _value_ minutes + NHOURS = write to history every _value_ hours + NDAYS = write to history every _value_ days + NMONTHS = write to history every _value_ months + NYEARS = write to history every _value_ years + DATE = write to history on the date: _value_ + END = write to history at the end of the simulation + _value_ = integer describing the number of _freq_ intervals to pass + before writing to the history file. + _compress_ = gzip compression option. TRUE, FALSE, or integer between 1-9. + _varname_ = name of the variable (this must be one of the + output variable names listed in vic_driver_shared_all.h.) + _format_ = (for ascii output files) fprintf format string, + e.g. + %.4f = floating point with 4 decimal places + %.7e = scientific notation w/ 7 decimal places + * = use the default format for this variable + + _format_, _type_, and _multiplier_ are optional. For a given + variable, you can specify either NONE of these, or ALL of + these. If these are omitted, the default values will be used. + + _type_ = (for binary output files) data type code. + Must be one of: + OUT_TYPE_DOUBLE = double-precision floating point + OUT_TYPE_FLOAT = single-precision floating point + OUT_TYPE_INT = integer + OUT_TYPE_USINT = unsigned short integer + OUT_TYPE_SINT = short integer + OUT_TYPE_CHAR = char + * = use the default type + _multiplier_ = (for binary output files) factor to multiply + the data by before writing, to increase precision. + * = use the default multiplier for this variable + _aggtype_ = Aggregation method to use for temporal aggregation. Valid + options for aggtype are: + AGG_TYPE_DEFAULT = default aggregation type for variable + AGG_TYPE_AVG = average over aggregation window + AGG_TYPE_BEG = beginning of aggregation window + AGG_TYPE_END = end of aggregation window + AGG_TYPE_MAX = maximum in aggregation window + AGG_TYPE_MIN = minimum in aggregation window + AGG_TYPE_SUM = sum over aggregation window +``` -Here's an example. To specify 2 output files, named "wbal" and "ebal", and containing water balance and energy balance terms, respectively, you could do something like this: +Here's an example. To specify 2 output files, named `wbal` and `ebal`, and containing water balance and energy balance terms, respectively, you could do something like this: ``` OUTFILE wbal -OUTVAR OUT_PREC -OUTVAR OUT_EVAP -OUTVAR OUT_RUNOFF -OUTVAR OUT_BASEFLOW -OUTVAR OUT_SWE -OUTVAR OUT_SOIL_MOIST +AGGFREQ NDAYS 1 +COMPRESS FALSE +OUT_FORMAT ASCII +OUTVAR OUT_PREC %.7g * * AGG_TYPE_AVG +OUTVAR OUT_EVAP %.7g * * AGG_TYPE_AVG +OUTVAR OUT_RUNOFF %.7g * * AGG_TYPE_AVG +OUTVAR OUT_BASEFLOW %.7g * * AGG_TYPE_AVG +OUTVAR OUT_SWE %.7g * * AGG_TYPE_END +OUTVAR OUT_SOIL_MOIST %.7g * * AGG_TYPE_AVG OUTFILE ebal +AGGFREQ NHOURS 3 +COMPRESS TRUE +OUT_FORMAT BINARY OUTVAR OUT_NET_SHORT OUTVAR OUT_NET_LONG OUTVAR OUT_LATENT @@ -86,11 +109,11 @@ OUTVAR OUT_SNOW_FLUX OUTVAR OUT_ALBEDO ``` -Since no format, type, or multiplier were specified for any variables, VIC will use the default format, type, and multiplier for the variables. +In the second file, none of the _format_, _type, _multiplier_, or _aggtype_ parameters were specified for any variables, VIC will use the default _format_, _type, _multiplier_, or _aggtype_ for the variables. -If you wanted scientific notation with 10 significant digits for ALBEDO, you could do the following: +For example, to specify scientific notation with 10 significant digits, you could do the following: -```OUTVAR OUT_ALBEDO %.9e * *``` +```OUTVAR OUT_ALBEDO %.9e``` Note that even if you only want to specify the format, you must supply a value in the type and multiplier columns as well. This can be `*` to indicate the default value. Similarly, if you only want to specify the type (e.g. as a double), you would need to do something like: @@ -112,7 +135,7 @@ Since variables like SOIL_MOIST have 1 value per soil layer, these variables wil **Snow band output:** -To specify writing the values of variables in each snow band, append "BAND" to the variable name (this only works for some variables - see the list in vic_driver_shared.h). If you specify these variables, the value of the variable in each band will be written, one band per column. For example, for a cell having 2 snow bands: +To specify writing the values of variables in each snow band, append "BAND" to the variable name (this only works for some variables - see the list in `vic_driver_shared_all.h`). If you specify these variables, the value of the variable in each band will be written, one band per column. For example, for a cell having 2 snow bands: ``` OUTVAR OUT_SWE_BAND @@ -125,7 +148,7 @@ will result in an output file containing: ## Specifying Output Time Step -VIC can now aggregate the output variables to a user-defined output interval, via the OUT_STEP setting in the [global parameter file](GlobalParam.md). Currently, the largest output interval allowed is 24 hours, so this option is only useful for simulations running at sub-daily time steps. +VIC can now aggregate the output variables to a user-defined output interval, via the `OUTFREQ` setting in the [global parameter file](GlobalParam.md). When `OUTFREQ` is set, it describes aggregation frequency for an output stream. Valid options for frequency are: NEVER, NSTEPS, NSECONDS, NMINUTES, NHOURS, NDAYS, NMONTHS, NYEARS, DATE, END. Count may be a positive integer or a string with date format YYYY-MM-DD[-SSSSS] in the case of DATE. Default `frequency` is `NDAYS`. Default `count` is 1. ## Optional Output File Headers @@ -136,14 +159,12 @@ For ascii files, the output header has the following format: ``` # SIMULATION: (OUTFILE prefix) # MODEL_VERSION: (Version String) -# ALMA_UNITS: (True or False) VARNAME VARNAME VARNAME ... ``` where - SIMULATION: OUTFILE prefix from global parameter file - MODEL_VERSION: VIC Version String -- ALMA_OUTPUT = Indicates units of the variables; TRUE or FALSE For binary files, the output header has the following format: @@ -162,7 +183,6 @@ For binary files, the output header has the following format: // startmonth (int)*1 Month of first record // startday (int)*1 Day of first record // starthour (int)*1 Hour of first record -// ALMA_OUTPUT (char)*1 0 = standard VIC units; 1 = ALMA units // Nvars (char)*1 Number of variables in the file, // including date fields // diff --git a/docs/Documentation/Drivers/Classic/Outputs.md b/docs/Documentation/Drivers/Classic/Outputs.md index 051b7d14c..b55744ae3 100644 --- a/docs/Documentation/Drivers/Classic/Outputs.md +++ b/docs/Documentation/Drivers/Classic/Outputs.md @@ -2,11 +2,11 @@ ## Model Results -The contents of the results files can be controlled by the user, by options/instructions in the global parameter file. If no output file instructions are given in the [global parameter file](GlobalParam.md), [VIC will create the same 2 or 3 output files as in earlier versions, by default.](DefaultOutputs.md) +The contents of the results files can be controlled by the user, by options/instructions in the global parameter file. If no output file instructions are given in the [global parameter file](GlobalParam.md), VIC will create the same 2 or 3 output files [by default](DefaultOutputs.md). [How to Control the Contents of VIC Output Files](OutputFormatting.md) -[List of possible output variables](../../OutputVarList.md) (given in the file `vicNl_def.h`) +[List of possible output variables](../../OutputVarList.md) (given in the file `vic_driver_shared_all.h`) [Default Output Files](DefaultOutputs.md) diff --git a/docs/Documentation/Drivers/Classic/SnowOutputFile.md b/docs/Documentation/Drivers/Classic/SnowOutputFile.md deleted file mode 100644 index 1e128cdb4..000000000 --- a/docs/Documentation/Drivers/Classic/SnowOutputFile.md +++ /dev/null @@ -1,27 +0,0 @@ -# Snow Output File - -The snow file contains information about the snowpack, averaged across all elevation bands and vegetation tiles. The set of variables in this file depends on the values of FULL_ENERGY and FROZEN_SOIL in the global parameter file. Snow files are always written, regardless of the mode of operation. Snow files begin with the prefix "snow_". - -Each output file contains model output from one grid cell. The files use the naming convention "fluxes_xx.xx_yy.yy", where xx.xx is the latitude, and yy.yy is the longitude. The number of decimal places in the output filename is determined by GRID_DECIMAL in the [global parameter file](GlobalParam.md), while the latitude and longitude values come from the [soil parameter file](SoilParam.md). - -| Column | Variable Name | Units | Description | -|----------------------------------------------------------------------------------------------------------------|--------------------|----------|----------------------------------------------------------| -| 1 | OUT_SWE | mm | Snow water equivalent in snow pack | -| 2 | OUT_SNOW_DEPTH | cm | Depth of snow pack | -| 3 | OUT_SNOW_CANOPY | mm | Snow interception storage in canopy | -| 4 | OUT_SNOW_COVER | fraction | Fractional area of snow cover | -| The following variables are only output when FULL_ENERGY or FROZEN_SOIL is TRUE in the global parameter file | | | | -| 5 | OUT_ADVECTION | W/m2 | Advected energy | -| 6 | OUT_DELTACC | W/m2 | Rate of change in cold content in snow pack | -| 7 | OUT_SNOW_FLUX | W/m2 | Energy flux though snow pack | -| 8 | OUT_RFRZ_ENERGY | W/m2 | Net energy used to refreeze liquid water in snowpack | -| 9 | OUT_MELT_ENERGY | W/m2 | Energy of fusion (melting) in snowpack | -| 10 | OUT_ADV_SENS | W/m2 | Net sensible heat flux advected to snow pack | -| 11 | OUT_LATENT_SUB | W/m2 | Net upward latent heat flux due to sublimation | -| 12 | OUT_SNOW_SURF_TEMP | C | Snow surface temperature | -| 13 | OUT_SNOW_PACK_TEMP | C | Snow pack temperature | -| 14 | OUT_SNOW_MELT | mm | Snow melt | -| The following variables are only output when BLOWING is TRUE in the global parameter file | | | | -| 15 | OUT_SUB_BLOWING | mm | Net sublimation of blowing snow | -| 16 | OUT_SUB_SURFACE | mm | Net sublimation from snow pack surface | -| 17 | OUT_SUB_SNOW | mm | Total sublimation from snow pack (surface and blowing) | \ No newline at end of file diff --git a/docs/Documentation/Drivers/Image/Ascii_to_NetCDF_params.md b/docs/Documentation/Drivers/Image/Ascii_to_NetCDF_params.md new file mode 100644 index 000000000..fa3265a8c --- /dev/null +++ b/docs/Documentation/Drivers/Image/Ascii_to_NetCDF_params.md @@ -0,0 +1,142 @@ +# VIC Model Parameters + +We are developing a few scripts to aid users in moving from VIC 4 to VIC 5. These scripts are currently distributed via the [`tonic`](https://github.com/UW-Hydro/tonic) [Python](https://www.python.org/) package. + +To convert ASCII parameters to NetCDF parameters for usage in the VIC 5.0 Image Driver, we have instructions for installing Tonic and its dependencies and then reading in and converting ASCII parameters to NetCDF. + +### Option 1: Installing Tonic Using Anaconda + +The easiest way to install Tonic and its dependencies is to use the [Anaconda Python distribution](https://store.continuum.io/cshop/anaconda/). The instructions below assume the user is using the `bash` shell. `tonic` supports the use of Python 2.7 or 3.4+. + +To install Anaconda, follow these two simple steps (check to make sure the installer version is the most current) + +1. download and run the Anaconda installer: [http://continuum.io/downloads](http://continuum.io/downloads) + +2. setup a virtual environment for Tonic +```shell +conda create -n tonic python=3.4 netcdf4 pandas numpy scipy matplotlib xray basemap +source activate tonic +``` + +*Note: you'll need to do the `source activate tonic` to activate the tonic virtual environment in any new shells.* + +Now, download the Tonic source code: + +```shell +git clone git@github.com:UW-Hydro/tonic.git +cd tonic +``` + +From the Tonic source code repository, Tonic can be installed using Python's `distutils`: + +```shell +python setup.py install +``` + +This installs a top level script, `vic_utils`, into your `$CONDA_ROOT/envs/vic_test/bin` directory and the `tonic` package into your conda environment (e.g. `$CONDA_ROOT/lib/.../site-packages/tonic`). Note that for most `conda` installations, `$CONDA_ROOT` represents the directory where the root `conda` installation is (e.g. `~/anaconda`). + +If you don't want to use the Anaconda installation I've shown above, you can build the package in your local python installation using: +```shell +python setup.py develop +``` + +Below are two methods for installing `tonic` if you do not use `anaconda`. This may or may not require write permissions. Because this is not our preferred method for installing `tonic`, the user should read the [Python documentation](https://docs.python.org/3.5/install/) for further instructions on how to install Python packages. + +### Option 2a: Using a local Python Install (With Write Permissions) + +If you have write permissions to the location of your Python distribution, you can just run + +```shell +python setup.py install +``` + +from the top level Tonic directory. This will install `tonic` into your `$PYTHONPATH`. + +### Option 2b: Using a local Python Install (Without Write Permissions) + +If you do not have write permissions, you can install Tonic in your local `$PYTHONPATH` by following these steps: + +Create a `lib/python` directory in your `$HOME` directory: + +```shell +mkdir -p $HOME/lib/python/ +``` + +Add this library path to your `$PYTHONPATH` in your `.bashrc`: + +```shell +export PYTHONPATH=$HOME/lib/python:$PYTHONPATH +``` + +Run `setup.py`: + +```shell +python setup.py install --home=$HOME +``` + +### Testing your install + +From the following command line: + +```shell +vic_utils -h +python -c 'import tonic' +``` + +If you don't get any errors, you should be ready to use `tonic`. + +## Using Tonic to convert VIC 4 parameters to netCDF format for VIC 5 + +### Option 1: Using the `vic_utils` command-line utility + +Tonic includes a command-line utility for converting VIC style parameters to gridded netCDF. Usage of the utility can be found by running: + +```shell +vic_utils grid_params --help +``` + +### Option 2: Using the `tonic` api + +This option allows the user to specify the format of the individual VIC parameter files. This can be quite useful if the format does not match the assumptions used by the command-line utility. + +Example usage: + +```Python +from tonic.models.vic.grid_params import soil, snow, veg, veg_class, Cols, Desc + +n_veg_classes = 4 +root_zones = 3 + +# Read the soil parameters +soil_dict = soil('~/workdir/Stehekin_soil.txt', c=Cols(nlayers=3)) + +# Read the snow parameters +snow_dict = snow('~/workdir/Stehekin_snowbands.txt', + soil_dict, c=Cols(snow_bands=5)) + +# Read the veg parameter file +veg_dict = veg('~/workdir/Stehekin_vegparam.txt', + soil_dict, + lai_index=False, + veg_classes=n_veg_classes) + +# Read the veg library file +veg_lib = veg_class('~/workdir/Stehekin_veglib.txt', + skiprows=1) + +# Determine the grid shape +target_grid, target_attrs = calc_grid(soil_dict['lats'], soil_dict['lons']) + +# Grid all the parameters +grid_dict = grid_params(soil_dict, target_grid, version=version + veg_dict=veg_dict, veglib_dict=veg_lib, snow_dict=snow_dict) + +# Write a netCDF file with all the parameters +write_netcdf('~/workdir/example.params.vic5.nc', target_attrs, + target_grid=target_grid, + soil_grid=grid_dict['soil_dict'], + snow_grid=grid_dict['snow_dict'], + veglib_dict=veg_lib, + veg_grid=grid_dict['veg_dict'], + version='5.0.dev') +``` diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index 283a3eb6b..9cdda9701 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -1,2 +1,10 @@ -!!! Warning - Docs not written yet. +# VIC Run-Time Options - Global Parameter File + +NOTE: this page is under development, and further details will be added shortly. + +The global parameter file serves two main purposes: + +1. Tells VIC the names, locations, and formats of input and output files +2. Defines global parameters of the simulation (known as _run-time_ options) + +The order of the options in the global parameter file is not important, but the complete option name must be followed by the required option type information. diff --git a/docs/Documentation/Drivers/Image/ImageDriver.md b/docs/Documentation/Drivers/Image/ImageDriver.md index b3e29f093..2adec431d 100644 --- a/docs/Documentation/Drivers/Image/ImageDriver.md +++ b/docs/Documentation/Drivers/Image/ImageDriver.md @@ -7,5 +7,6 @@ The Image Driver represents the modern implementation of the VIC model. It uses ## Modeling the Land Surface using VIC 1. [VIC Input Files](Inputs.md) -1. [Running VIC](RunVIC.md) -1. [VIC Output Files](Outputs.md) +2. [Converting ASCII Parameter Files to NetCDF](Ascii_to_NetCDF_params.md) +3. [Running VIC](RunVIC.md) +4. [VIC Output Files](Outputs.md) diff --git a/docs/Documentation/Drivers/Image/Inputs.md b/docs/Documentation/Drivers/Image/Inputs.md index 5302ed2cf..dff766816 100644 --- a/docs/Documentation/Drivers/Image/Inputs.md +++ b/docs/Documentation/Drivers/Image/Inputs.md @@ -9,5 +9,7 @@ To run VIC, several sets of input data are necessary: * [Parameters File](Params.md): Spatially distributed parameters describing the land surface. And a few more are optional: + * [Constants File](../../Constants.md): Model parameters that are constant in time and space. * [Initial State File](StateFile.md): Moisture storages (soil moisture, snow pack, etc), energy storages (soil temperatures, etc) and other information describing the current state of the system. A state file saved from a previous VIC simulation may be used as the initial state for another run. +* [Lake/Wetland Parameter File](LakeParam.md): File containing lake model parameters. By default, VIC does not simulate lakes or other impoundment of surface water. diff --git a/docs/Documentation/Drivers/Image/LakeParam.md b/docs/Documentation/Drivers/Image/LakeParam.md new file mode 100644 index 000000000..4c31b7a9a --- /dev/null +++ b/docs/Documentation/Drivers/Image/LakeParam.md @@ -0,0 +1,3 @@ +# VIC Lake/Wetland Parameter File + +This feature is under development. diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index 80769d341..2d20f713e 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -1,145 +1,443 @@ # VIC Model Parameters -!!! Warning - Docs not written yet. +The Image Driver uses the [NetCDF](http://www.unidata.ucar.edu/software/netcdf/) file format for its input model parameters. It is possible to convert the VIC ASCII style parameters to this format. We have put together an example ([Tutorial](Ascii_to_NetCDF_params.md) and [Ipython Notebook](../../../../samples/notebooks/example_reformat_vic4_parameters_to_vic5image.ipynb)) that provide examples of how to do this conversion. Our example uses the `tonic` [Python](https://www.python.org/) Package. -# Converting from VIC 4 to VIC 5 - -We are developing a few scripts to aid users in moving from VIC 4 to VIC 5. These scripts are currently distributed via the [`tonic`](https://github.com/UW-Hydro/tonic) [Python](https://www.python.org/) package. - -### Option 1: Installing Tonic Using Anaconda - -The easiest way to install Tonic and its dependencies is to use the [Anaconda Python distribution](https://store.continuum.io/cshop/anaconda/). The instructions below assume the user is using the `bash` shell. `tonic` supports the use of Python 2.7 or 3.4+. - -To install Anaconda, follow these two simple steps (check to make sure the installer version is the most current) - -1. download and run the Anaconda installer: [http://continuum.io/downloads](http://continuum.io/downloads) - -2. setup a virtual environment for Tonic -```shell -conda create -n tonic python=3.4 netcdf4 pandas numpy scipy matplotlib xray basemap -source activate tonic -``` - -*Note: you'll need to do the `source activate tonic` to activate the tonic virtual environment in any new shells.* - -Now, download the Tonic source code: - -```shell -git clone git@github.com:UW-Hydro/tonic.git -cd tonic -``` - -From the Tonic source code repository, Tonic can be installed using Python's `distutils`: - -```shell -python setup.py install -``` - -This installs a top level script, `vic_utils`, into your `$CONDA_ROOT/envs/vic_test/bin` directory and the `tonic` package into your conda environment (e.g. `$CONDA_ROOT/lib/.../site-packages/tonic`). Note that for most `conda` installations, `$CONDA_ROOT` represents the directory where the root `conda` installation is (e.g. `~/anaconda`). - -If you don't want to use the Anaconda installation I've shown above, you can build the package in your local python installation using: -```shell -python setup.py develop -``` - -Below are two methods for installing `tonic` if you do not use `anaconda`. This may or may not require write permissions. Because this is not our preferred method for installing `tonic`, the user should read the [Python documentation](https://docs.python.org/3.5/install/) for further instructions on how to install Python packages. - -### Option 2a: Using a local Python Install (With Write Permissions) - -If you have write permissions to the location of your Python distribution, you can just run - -```shell -python setup.py install -``` - -from the top level Tonic directory. This will install `tonic` into your `$PYTHONPATH`. - -### Option 2b: Using a local Python Install (Without Write Permissions) - -If you do not have write permissions, you can install Tonic in your local `$PYTHONPATH` by following these steps: - -Create a `lib/python` directory in your `$HOME` directory: +Regardless of the method used to generate the Image Driver parameters, you should end up with a NetCDF file that looks like this: ```shell -mkdir -p $HOME/lib/python/ +ncdump -h example.params.vic5.nc +netcdf Stehekin_test_params_20160327 { +dimensions: + lon = 5 ; + lat = 4 ; + nlayer = 3 ; + snow_band = 5 ; + veg_class = 12 ; + root_zone = 3 ; + month = 12 ; +variables: + double lat(lat) ; + lat:units = "degrees_north" ; + lat:long_name = "latitude of grid cell center" ; + double lon(lon) ; + lon:units = "degrees_east" ; + lon:long_name = "longitude of grid cell center" ; + int mask(lat, lon) ; + mask:long_name = "area of grid cell" ; + mask:comment = "0 value indicates cell is not active" ; + mask:note = "unitless" ; + mask:standard_name = "area" ; + mask:units = "m2" ; + mask:axis = "Y" ; + int layer(nlayer) ; + layer:long_name = "soil layer" ; + int run_cell(lat, lon) ; + run_cell:_FillValue = -2147483647 ; + run_cell:units = "N/A" ; + run_cell:description = "1 = Run Grid Cell, 0 = Do Not Run" ; + run_cell:long_name = "run_cell" ; + int gridcell(lat, lon) ; + gridcell:_FillValue = -2147483647 ; + gridcell:units = "N/A" ; + gridcell:description = "Grid cell number" ; + gridcell:long_name = "gridcell" ; + double lats(lat, lon) ; + lats:_FillValue = 9.96920996838687e+36 ; + lats:units = "degrees" ; + lats:description = "Latitude of grid cell" ; + lats:long_name = "lats" ; + double lons(lat, lon) ; + lons:_FillValue = 9.96920996838687e+36 ; + lons:units = "degrees" ; + lons:description = "Longitude of grid cell" ; + lons:long_name = "lons" ; + double infilt(lat, lon) ; + infilt:_FillValue = 9.96920996838687e+36 ; + infilt:units = "mm/day" ; + infilt:description = "Variable infiltration curve parameter (binfilt)" ; + infilt:long_name = "infilt" ; + double Ds(lat, lon) ; + Ds:_FillValue = 9.96920996838687e+36 ; + Ds:units = "fraction" ; + Ds:description = "Fraction of Dsmax where non-linear baseflow begins" ; + Ds:long_name = "Ds" ; + double Dsmax(lat, lon) ; + Dsmax:_FillValue = 9.96920996838687e+36 ; + Dsmax:units = "mm/day" ; + Dsmax:description = "Maximum velocity of baseflow" ; + Dsmax:long_name = "Dsmax" ; + double Ws(lat, lon) ; + Ws:_FillValue = 9.96920996838687e+36 ; + Ws:units = "fraction" ; + Ws:description = "Fraction of maximum soil moisture where non-linear baseflow occurs" ; + Ws:long_name = "Ws" ; + double c(lat, lon) ; + c:_FillValue = 9.96920996838687e+36 ; + c:units = "N/A" ; + c:description = "Exponent used in baseflow curve, normally set to 2" ; + c:long_name = "c" ; + double expt(nlayer, lat, lon) ; + expt:_FillValue = 9.96920996838687e+36 ; + expt:units = "N/A" ; + expt:description = "Exponent n (=3+2/lambda) in Campbells eqn for hydraulic conductivity, HBH 5.6 (where lambda = soil pore size distribution parameter). Values should be > 3.0." ; + expt:long_name = "expt" ; + double Ksat(nlayer, lat, lon) ; + Ksat:_FillValue = 9.96920996838687e+36 ; + Ksat:units = "mm/day" ; + Ksat:description = "Saturated hydrologic conductivity" ; + Ksat:long_name = "Ksat" ; + double phi_s(nlayer, lat, lon) ; + phi_s:_FillValue = 9.96920996838687e+36 ; + phi_s:units = "mm/mm" ; + phi_s:description = "Soil moisture diffusion parameter" ; + phi_s:long_name = "phi_s" ; + double init_moist(nlayer, lat, lon) ; + init_moist:_FillValue = 9.96920996838687e+36 ; + init_moist:units = "mm" ; + init_moist:description = "Initial layer moisture content" ; + init_moist:long_name = "init_moist" ; + double elev(lat, lon) ; + elev:_FillValue = 9.96920996838687e+36 ; + elev:units = "m" ; + elev:description = "Average elevation of grid cell" ; + elev:long_name = "elev" ; + double depth(nlayer, lat, lon) ; + depth:_FillValue = 9.96920996838687e+36 ; + depth:units = "m" ; + depth:description = "Thickness of each soil moisture layer" ; + depth:long_name = "depth" ; + double avg_T(lat, lon) ; + avg_T:_FillValue = 9.96920996838687e+36 ; + avg_T:units = "C" ; + avg_T:description = "Average soil temperature, used as the bottom boundary for soil heat flux solutions" ; + avg_T:long_name = "avg_T" ; + double dp(lat, lon) ; + dp:_FillValue = 9.96920996838687e+36 ; + dp:units = "m" ; + dp:description = "Soil thermal damping depth (depth at which soil temperature remains constant through the year, ~4 m)" ; + dp:long_name = "dp" ; + double bubble(nlayer, lat, lon) ; + bubble:_FillValue = 9.96920996838687e+36 ; + bubble:units = "cm" ; + bubble:description = "Bubbling pressure of soil. Values should be > 0.0" ; + bubble:long_name = "bubble" ; + double quartz(nlayer, lat, lon) ; + quartz:_FillValue = 9.96920996838687e+36 ; + quartz:units = "fraction" ; + quartz:description = "Quartz content of soil" ; + quartz:long_name = "quartz" ; + double bulk_density(nlayer, lat, lon) ; + bulk_density:_FillValue = 9.96920996838687e+36 ; + bulk_density:units = "kg/m3" ; + bulk_density:description = "Bulk density of soil layer" ; + bulk_density:long_name = "bulk_density" ; + double soil_density(nlayer, lat, lon) ; + soil_density:_FillValue = 9.96920996838687e+36 ; + soil_density:units = "kg/m3" ; + soil_density:description = "Soil particle density, normally 2685 kg/m3" ; + soil_density:long_name = "soil_density" ; + double off_gmt(lat, lon) ; + off_gmt:_FillValue = 9.96920996838687e+36 ; + off_gmt:units = "hours" ; + off_gmt:description = "Time zone offset from GMT. This parameter determines how VIC interprets sub-daily time steps relative to the model start date and time." ; + off_gmt:long_name = "off_gmt" ; + double Wcr_FRACT(nlayer, lat, lon) ; + Wcr_FRACT:_FillValue = 9.96920996838687e+36 ; + Wcr_FRACT:units = "fraction" ; + Wcr_FRACT:description = "Fractional soil moisture content at the critical point (~70%% of field capacity) (fraction of maximum moisture)" ; + Wcr_FRACT:long_name = "Wcr_FRACT" ; + double Wpwp_FRACT(nlayer, lat, lon) ; + Wpwp_FRACT:_FillValue = 9.96920996838687e+36 ; + Wpwp_FRACT:units = "fraction" ; + Wpwp_FRACT:description = "Fractional soil moisture content at the wilting point (fraction of maximum moisture)" ; + Wpwp_FRACT:long_name = "Wpwp_FRACT" ; + double rough(lat, lon) ; + rough:_FillValue = 9.96920996838687e+36 ; + rough:units = "m" ; + rough:description = "Surface roughness of bare soil" ; + rough:long_name = "rough" ; + double snow_rough(lat, lon) ; + snow_rough:_FillValue = 9.96920996838687e+36 ; + snow_rough:units = "m" ; + snow_rough:description = "Surface roughness of snowpack" ; + snow_rough:long_name = "snow_rough" ; + double annual_prec(lat, lon) ; + annual_prec:_FillValue = 9.96920996838687e+36 ; + annual_prec:units = "mm" ; + annual_prec:description = "Average annual precipitation." ; + annual_prec:long_name = "annual_prec" ; + double resid_moist(nlayer, lat, lon) ; + resid_moist:_FillValue = 9.96920996838687e+36 ; + resid_moist:units = "fraction" ; + resid_moist:description = "Soil moisture layer residual moisture." ; + resid_moist:long_name = "resid_moist" ; + int fs_active(lat, lon) ; + fs_active:_FillValue = -2147483647 ; + fs_active:units = "binary" ; + fs_active:description = "If set to 1, then frozen soil algorithm is activated for the grid cell. A 0 indicates that frozen soils are not computed even if soil temperatures fall below 0C." ; + fs_active:long_name = "fs_active" ; + int snow_band(snow_band) ; + snow_band:long_name = "snow band" ; + double cellnum(lat, lon) ; + cellnum:_FillValue = 9.96920996838687e+36 ; + cellnum:units = "N/A" ; + cellnum:description = "Grid cell number (should match numbers assigned in soil parameter file)" ; + double AreaFract(snow_band, lat, lon) ; + AreaFract:_FillValue = 9.96920996838687e+36 ; + AreaFract:units = "fraction" ; + AreaFract:description = "Fraction of grid cell covered by each elevation band. Sum of the fractions must equal 1." ; + double elevation(snow_band, lat, lon) ; + elevation:_FillValue = 9.96920996838687e+36 ; + elevation:units = "m" ; + elevation:description = "Mean (or median) elevation of elevation band. This is used to compute the change in air temperature from the grid cell mean elevation." ; + double Pfactor(snow_band, lat, lon) ; + Pfactor:_FillValue = 9.96920996838687e+36 ; + Pfactor:units = "fraction" ; + Pfactor:description = "Fraction of cell precipitation thatfalls on each elevation band. Total must equal 1. To ignore effects of elevation on precipitation, set these fractions equal to the area fractions." ; + int veg_class(veg_class) ; + veg_class:long_name = "Vegetation Class" ; + string veg_descr(veg_class) ; + veg_descr:long_name = "Vegetation Class Description" ; + int root_zone(root_zone) ; + root_zone:long_name = "root zone" ; + int month(month) ; + month:long_name = "month of year" ; + int Nveg(lat, lon) ; + Nveg:_FillValue = -2147483647 ; + Nveg:long_name = "Nveg" ; + Nveg:units = "N/A" ; + Nveg:description = "Number of vegetation tiles in the grid cell" ; + double Cv(veg_class, lat, lon) ; + Cv:_FillValue = 9.96920996838687e+36 ; + Cv:long_name = "Cv" ; + Cv:units = "fraction" ; + Cv:description = "Fraction of grid cell covered by vegetation tile" ; + double root_depth(veg_class, root_zone, lat, lon) ; + root_depth:_FillValue = 9.96920996838687e+36 ; + root_depth:long_name = "root_depth" ; + root_depth:units = "m" ; + root_depth:description = "Root zone thickness (sum of depths is total depth of root penetration)" ; + double root_fract(veg_class, root_zone, lat, lon) ; + root_fract:_FillValue = 9.96920996838687e+36 ; + root_fract:long_name = "root_fract" ; + root_fract:units = "fraction" ; + root_fract:description = "Fraction of root in the current root zone" ; + double LAI(veg_class, month, lat, lon) ; + LAI:_FillValue = 9.96920996838687e+36 ; + LAI:long_name = "LAI" ; + LAI:units = "m2/m2" ; + LAI:description = "Leaf Area Index, one per month" ; + int overstory(veg_class, lat, lon) ; + overstory:_FillValue = -2147483647 ; + overstory:long_name = "overstory" ; + overstory:units = "N/A" ; + overstory:description = "Flag to indicate whether or not the current vegetation type has an overstory (1 for overstory present [e.g. trees], 0 for overstory not present [e.g. grass])" ; + double rarc(veg_class, lat, lon) ; + rarc:_FillValue = 9.96920996838687e+36 ; + rarc:long_name = "rarc" ; + rarc:units = "s/m" ; + rarc:description = "Architectural resistance of vegetation type (~2 s/m)" ; + double rmin(veg_class, lat, lon) ; + rmin:_FillValue = 9.96920996838687e+36 ; + rmin:long_name = "rmin" ; + rmin:units = "s/m" ; + rmin:description = "Minimum stomatal resistance of vegetation type (~100 s/m)" ; + double wind_h(veg_class, lat, lon) ; + wind_h:_FillValue = 9.96920996838687e+36 ; + wind_h:long_name = "wind_h" ; + wind_h:units = "m" ; + wind_h:description = "Height at which wind speed is measured." ; + double RGL(veg_class, lat, lon) ; + RGL:_FillValue = 9.96920996838687e+36 ; + RGL:long_name = "RGL" ; + RGL:units = "W/m^2." ; + RGL:description = "Minimum incoming shortwave radiation at which there will be transpiration. For trees this is about 30 W/m^2, for crops about 100 W/m^2." ; + double rad_atten(veg_class, lat, lon) ; + rad_atten:_FillValue = 9.96920996838687e+36 ; + rad_atten:long_name = "rad_atten" ; + rad_atten:units = "fraction" ; + rad_atten:description = "Radiation attenuation factor. Normally set to 0.5, though may need to be adjusted for high latitudes." ; + double wind_atten(veg_class, lat, lon) ; + wind_atten:_FillValue = 9.96920996838687e+36 ; + wind_atten:long_name = "wind_atten" ; + wind_atten:units = "fraction" ; + wind_atten:description = "Wind speed attenuation through the overstory. The default value has been 0.5." ; + double trunk_ratio(veg_class, lat, lon) ; + trunk_ratio:_FillValue = 9.96920996838687e+36 ; + trunk_ratio:long_name = "trunk_ratio" ; + trunk_ratio:units = "fraction" ; + trunk_ratio:description = "Ratio of total tree height that is trunk (no branches). The default value has been 0.2." ; + double albedo(veg_class, month, lat, lon) ; + albedo:_FillValue = 9.96920996838687e+36 ; + albedo:long_name = "albedo" ; + albedo:units = "fraction" ; + albedo:description = "Shortwave albedo for vegetation type" ; + double veg_rough(veg_class, month, lat, lon) ; + veg_rough:_FillValue = 9.96920996838687e+36 ; + veg_rough:long_name = "veg_rough" ; + veg_rough:units = "m" ; + veg_rough:description = "Vegetation roughness length (typically 0.123 * vegetation height)" ; + double displacement(veg_class, month, lat, lon) ; + displacement:_FillValue = 9.96920996838687e+36 ; + displacement:long_name = "displacement" ; + displacement:units = "m" ; + displacement:description = "Vegetation displacement height (typically 0.67 * vegetation height)" ; + // global attributes: + :description = "VIC parameter file" ; + :history = "Created: Mon Mar 28 09:32:46 2016\n/Users/jhamman/anaconda/lib/python3.4/site-packages/ipykernel/__main__.py -f /Users/jhamman/Library/Jupyter/runtime/kernel-b8627880-fe9e-4d1a-b2d7-fa3fb6a23e22.json\n" ; + :source = "/Users/jhamman/anaconda/lib/python3.4/site-packages/ipykernel/__main__.py" ; + :username = "jhamman" ; + :host = "Joes-iMac.local" ; + } ``` -Add this library path to your `$PYTHONPATH` in your `.bashrc`: - -```shell -export PYTHONPATH=$HOME/lib/python:$PYTHONPATH -``` +# Soil Parameters + +The Soil Parameters serve three main purposes: + +* Define the cell ID number of each grid cell. This ID number is essentially a database key that links a grid cell to its parameters in the various parameter files. +* Define the grid cell soil parameters +* Define initial soil moisture conditions, to be used in the absence of an initial state file. + +The soil parameters are supplied to VIC in a NetCDF file, with a separate variable for each soil parameter. + +Below is a list of soil parameters. + +| Variable Name | Dimension | Units | Type | Number of Values | Description | +|--------------------------|--------------------|----------|--------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| run_cell | [lat, lon] | N/A | int | 1 | 1 = Run Grid Cell, 0 = Do Not Run | +| gridcel | [lat, lon] | N/A | int | 1 | Grid cell number | +| lat | [lat, lon] | degrees | double | 1 | Latitude of grid cell | +| lon | [lat, lon] | degrees | double | 1 | Longitude of grid cell | +| infilt | [lat, lon] | N/A | double | 1 | Variable infiltration curve parameter (binfilt) | +| Ds | [lat, lon] | fraction | double | 1 | Fraction of Dsmax where non-linear baseflow begins | +| Dsmax | [lat, lon] | mm/day | double | 1 | Maximum velocity of baseflow | +| Ws | [lat, lon] | fraction | double | 1 | Fraction of maximum soil moisture where non-linear baseflow occurs | +| c | c | N/A | double | 1 | Exponent used in baseflow curve, normally set to 2 | +| expt | [nlayer, lat, lon] | N/A | double | Nlayer | Exponent n (=3+2/lambda) in Campbell's eqn for hydraulic conductivity, HBH 5.6 (where lambda = soil pore size distribution parameter). Values should be > 3.0. | +| Ksat | [nlayer, lat, lon] | mm/day | double | Nlayer | Saturated hydrologic conductivity | +| phi_s | [nlayer, lat, lon] | mm/mm | double | Nlayer | Soil moisture diffusion parameter | +| init_moist | [nlayer, lat, lon] | mm | double | Nlayer | Initial layer moisture content | +| elev | [lat, lon] | m | double | 1 | Average elevation of grid cell | +| depth | [nlayer, lat, lon] | m | double | Nlayer | Thickness of each soil moisture layer | +| avg_T | [lat, lon] | C | double | 1 | Average soil temperature, used as the bottom boundary for soil heat flux solutions | +| dp | [lat, lon] | m | double | 1 | Soil thermal damping depth (depth at which soil temperature remains constant through the year, ~4 m) | +| bubble | [nlayer, lat, lon] | cm | double | 1 | Bubbling pressure of soil. Values should be >0. | +| quartz | [nlayer, lat, lon] | N/A | double | Nlayer | Quartz content of soil | +| bulk_density | [nlayer, lat, lon] | kg/m3 | double | Nlayer | Bulk density of soil layer | +| soil_density | [nlayer, lat, lon] | kg/m3 | double | Nlayer | Soil particle density, normally 2685 kg/m3 | +| organic (optional) | [nlayer, lat, lon] | fraction | double | Nlayer | Fraction of soil layer that is organic. If ORGANIC_FRACT is TRUE in the global parameter file, this variable must be included in the soil parameter file. If ORGANIC_FRACT is FALSE then this variable must not appear in the soil parameter file. (release 4.1.2 and later) | +| bulk_dens_org (optional) | [nlayer, lat, lon] | kg/m3 | double | Nlayer | Bulk density of organic portion of soil. If ORGANIC_FRACT is TRUE in the global parameter file, this variable must be included in the soil parameter file. If ORGANIC_FRACT is FALSE then this variable must not appear in the soil parameter file. (release 4.1.2 and later) | +| soil_dens_org (optional) | [nlayer, lat, lon] | kg/m3 | double | Nlayer | Soil particle density of organic portion of soil, normally 1300 kg/m3. If ORGANIC_FRACT is TRUE in the global parameter file, this variable must be included in the soil parameter file. If ORGANIC_FRACT is FALSE then this variable must not appear in the soil parameter file. (release 4.1.2 and later) | +| off_gmt | [lat, lon] | hours | double | 1 | Time zone offset from GMT. This parameter determines how VIC interprets sub-daily time steps relative to the model start date and time. We have adopted the following convention for off_gmt:An off_gmt value of 0 indicates that the model start date/time is relative to Greenwich Mean Time (GMT).An off_gmt value of (grid_cell_longitude*24/360) indicates that the model start date/time is relative to local time.When outputting sub-daily results, VIC's output files are referenced to the model start date/time; therefore they are controlled by off_gmt (off_gmt=0 means VIC results are referenced to GMT; off_gmt=(grid_cell_longitude*24/360) means VIC results are referenced to local time). Daily supplied forcings are assumed to start/end at midnight in local time; the forcing start date/time is thus in local time. When VIC disaggregates daily forcings into sub-daily forcings, off_gmt will be used to determine the time lag between the start of the forcing's diurnal cycle and the start of the VIC simulation.Sub-daily supplied forcings are assumed to occur relative to the time zone indicated by off_gmt. Therefore, if VIC outputs these sub-daily forcings, they will occur at the exact same time of day as in the input files. Therefore, if mixing daily and sub-daily forcing inputs, it is important that any sub-daily forcing inputs be shifted as necessary to be in the time zone indicated by off_gmt. | +| Wcr_fract | [nlayer, lat, lon] | fraction | double | Nlayer | Fractional soil moisture content at the critical point (~70% of field capacity) (fraction of maximum moisture) | +| Wpwp_FRACT | [nlayer, lat, lon] | fraction | double | Nlayer | Fractional soil moisture content at the wilting point (fraction of maximum moisture) | +| rough | [lat, lon] | m | double | 1 | Surface roughness of bare soil | +| snow_rough | [lat, lon] | m | double | 1 | Surface roughness of snowpack | +| annual_prec | [lat, lon] | mm | double | 1 | Average annual precipitation | +| resid_moist | [nlayer, lat, lon] | fraction | double | Nlayer | Soil moisture layer residual moisture | +| fs_active | [lat, lon] | 1 or 0 | int | 1 | If set to 1, then frozen soil algorithm is activated for the grid cell. A 0 indicates that frozen soils are not computed even if soil temperatures fall below 0C. | +| frost_slope | [lat, lon] | C | double | 1 | Slope of uniform distribution of soil temperature (if SPATIAL_FROST == TRUE in the global parameter file). | +| max_snow_distrib_slope | [lat, lon] | m | double | 1 | Maximum slope of the snow depth distribution. This is only used if SPATIAL_SNOW == TRUE in the global parameter file. This parameter should be set to twice the spatial average snow depth at which coverage == 1.0. In other words, if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2depth_thresh. NOTE*: Partial snow coverage is only computed when the snow pack has started melting and thespatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting anddepth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. | +| July_Tavg | [lat, lon] | C | double | 1 | Average July air temperature, used for treeline computations (required if COMPUTE_TREELINE == TRUE in the global parameter file). | + +Note: if BASEFLOW is set to NIJSSEN2001 in the [global parameter file](GlobalParam.md), VIC will interpret the baseflow parameters Ds, Dsmax, Ws, and c to be the alternative baseflow parameters D1, D2, D3, and D4. + +# Vegetation Parameter File + +Vegetation parameters needed for the different VIC model set-ups are listed below. The number of vegetation tiles and fraction of grid cell covered are defined for each grid cell. + +| Variable Name | Units | Description | +|--------------- |------- |--------------------------------------------- | +| gridcel | N/A | Grid cell number | +| Nveg | N/A | Number of vegetation tiles in the grid cell | + +Repeats for each vegetation tile in the grid cell: + +| Variable Name | Units | Description | +|--------------- |---------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| veg_class | N/A | Vegetation class identification number (reference index to [vegetation library](../Classic/VegLib.md))

    *NOTE 1*: it is common practice to define only one tile for each vegetation class in the grid cell. But this is not strictly necessary. It is OK to define multiple tiles having the same vegetation class.

    *NOTE 2*: As of VIC 4.1.1, if you are simulating lakes, you MUST designate one of the tiles from each grid cell as the tile that contains the lake(s). This designation happens in the [lake parameter file](../Classic/LakeParam.md). You can either choose an existing tile to host the lakes, or insert a new tile (just make sure that the sum of the tile areas in the grid cell = 1.0). This extra lake/wetland tile may have the same vegetation class as one of the other existing tiles (see NOTE 1). | +| Cv | fraction | Fraction of grid cell covered by vegetation tile | + +For each vegetation tile, repeats for each defined root zone: + +| Variable Name | Units | Description | +|--------------- |---------- |------------------------------------------------------------------------ | +| root_depth | m | Root zone thickness (sum of depths is total depth of root penetration) | +| root_fract | fraction | Fraction of root in the current root zone. | + +OPTIONAL - If BLOWING_SNOW is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: + +| Variable Name | Units | Description | +|--------------- |------- |------------------------------------------------------------------------------------- | +| sigma_slope | N/A | Standard deviation of terrain slopes within vegetation tile | +| lag_one | N/A | Lag-one autocorrelation of terrain slope within vegetation tile | +| fetch | m | Average fetch (distance the wind blows without obstructions) within vegetation tile | + +OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each vegetation tile, the file will also contain the following parameters: + +| Variable Name | Units | Description | +|--------------- |---------- |-------------------------------- | +| LAI | fraction | Leaf Area Index, one per month | + +OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: + +| Variable Name | Units | Description | +|--------------- |---------- |-------------------------------------------------- | +| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | + +OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there following parameters will also be included in the NetCDF parameter file: + +| Variable Name | Units | Description | +|---------------|----------|-----------------------| +| ALBEDO | fraction | Albedo, one per month | + + +# Vegetation Library Parameters + +Vegetation parameters are given for different vegetation types. Below are a list of vegetation parameters: + +| Variable Name | Units | Number of Values | Description | +|----------------------------------------------------------------- |--------------------- |------------------ |---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| veg_class | N/A | 1 | Vegetation class identification number (reference index for library table) | +| overstory | N/A | 1 | Flag to indicate whether or not the current vegetation type has an overstory (TRUE for overstory present [*e.g. trees*], FALSE for overstory not present [*e.g. grass*]) | +| rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | +| rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | +| LAI | fraction | 12 | Leaf-area index of vegetation type | +| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| albedo | fraction | 12 | Shortwave albedo for vegetation type | +| rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | +| displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | +| wind_h | m | 1 | Height at which wind speed is measured. **If using snow interception routines please read the [documentation on wind_h](Definitions/#wind_h)**. | +| RGL | W/m2 | 1 | Minimum incoming shortwave radiation at which there will be transpiration. For trees this is about 30 W/m2, for crops about 100 W/m2. | +| rad_atten | fract | 1 | Radiation attenuation factor. Normally set to 0.5, though may need to be adjusted for high latitudes. | +| wind_atten | fract | 1 | Wind speed attenuation through the overstory. The default value has been 0.5. | +| trunk_ratio | fract | 1 | Ratio of total tree height that is trunk (no branches). The default value has been 0.2. | +| Ctype (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | 0 or 1 (0 = C3, 1 = C4) | 1 | Photosynthetic pathway (NOTE: the previous input values of "C3" and "C4" are still accepted but are deprecated. | +| MaxCarboxRate (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | mol CO2/m2s | 1 | Maximum carboxlyation rate at 25 deg C | +| MaxETransport (C3) or CO2Specificity (C4) (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | mol CO2/m2s | 1 | Maximum electron transport rate at 25 deg C (C3) or CO2 specificity at 25 deg C (C4) | +| LightUseEff (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | mol CO2/mol photons | 1 | Light-use efficiency | +| NscaleFlag (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | 0 or 1 | 1 | 1 = nitrogen-scaling factors are applicable to this veg class | +| Wnpp_inhib (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | fract | 1 | Fraction of maximum moisture storage in top soil layer above which photosynthesis begins to be inhibited by wet conditions | +| NPPfactor_sat (Only present if VEGLIB_PHOTO=TRUE in [global parameter file](GlobalParam.md) | fract | 1 | Ratio of NPP under saturated conditions (moisture fraction = 1.0) to NPP at moisture fraction = Wnpp_inhib | +| comment | N/A | 1 | Comment block for vegetation type. Model skips end of line so spaces are valid entries. | + + +# Elevation Bands (Optional) + +By default, VIC assumes each grid cell is flat. This assumption can lead to inaccuracies in snow pack estimates in mountainous grid cells. For this reason, the option exists to have VIC break each grid cell up into a number of _elevation bands_ (also called _snow bands_) and simulate them separately. Each band's mean elevation is used to lapse the grid cell average temperature, pressure, and precipitation to a more accurate local estimate. -Run `setup.py`: +The NetCDF Parameter file contains information needed to define the properties of each elevation band used by the snow model. Snow elevation bands are used to improve the model's performance in areas with pronounced topography, especially mountainous regions, where the effects of elevation on snow pack accumulation and ablation might be lost in a large grid cell. -```shell -python setup.py install --home=$HOME -``` +The number of snow elevation bands (_option.SNOW_BAND_) to be used with the model is defined in the [global parameter file](GlobalParam.md). The elevation band information is only read if the number of snow elevation bands is greater than 1. -### Testing your install +It is not necessary that all grid cells have the same number of elevation bands. _SNOW_BAND_ is simply the maximum number of elevation bands specified anywhere in the domain given by the domain file. For relatively flat grid cells, some of the elevation bands will have _AreaFract_ values of 0\. For these zero-area bands, a value of 0 may be supplied for _elevation_ and _Pfactor_. -From the following command line: +Below is a list of elevation band properties: -```shell -vic_utils -h -python -c 'import tonic' -``` - -If you don't get any errors, you should be ready to use `tonic`. - -## Using Tonic to convert VIC 4 parameters to netCDF format for VIC 5 - -### Option 1: Using the `vic_utils` command-line utility - -Tonic includes a command-line utility for converting VIC style parameters to gridded netCDF. Usage of the utility can be found by running: - -```shell -vic_utils grid_params --help -``` - -### Option 2: Using the `tonic` api - -This option allows the user to specify the format of the individual VIC parameter files. This can be quite useful if the format does not match the assumptions used by the command-line utility. - -Example usage: - -```Python -from tonic.models.vic.grid_params import soil, snow, veg, veg_class, Cols, Desc - -n_veg_classes = 4 -root_zones = 3 - -# Read the soil parameters -soil_dict = soil('~/workdir/Stehekin_VIC.4.1.2_soil.txt', c=Cols(nlayers=3)) - -# Read the snow parameters -soil_dict = snow('~/workdir/Stehekin_VIC.4.1.2_snow.txt', - soil_dict, c=Cols(snow_bands=5)) - -# Read the veg parameter file -veg_dict = veg('~/workdir/Stehekin_VIC.4.1.2_vegparam.txt', - soil_dict, - lai_index=False, - veg_classes=n_veg_classes) - -# Read the veg library file -veg_lib = veg_class('~/workdir/Stehekin_VIC.4.1.2_veglib.txt', - skiprows=1) - -# Determine the grid shape -target_grid, target_attrs = calc_grid(soil_dict['lats'], soil_dict['lons']) - -# Grid all the parameters -grid_dict = grid_params(soil_dict, target_grid, version=version - veg_dict=veg_dict, veglib_dict=veg_lib, snow_dict=snow_dict) - -# Write a netCDF file with all the parameters -write_netcdf('~/workdir/example.params.vic5.nc', target_attrs, - target_grid=target_grid, - soil_grid=grid_dict['soil_dict'], - snow_grid=grid_dict['snow_dict'], - veglib_dict=veg_lib, - veg_grid=grid_dict['veg_dict'], - version='5.0.dev') -``` +| Variable Name | Dimension | Units | Type | Number of Values | Description | +|---------------|-----------------------|----------|--------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| cellnum | [lat, lon] | N/A | double | 1 | Grid cell number (should match numbers assigned in soil parameter file) | +| AreaFract | [snow_band, lat, lon] | fraction | double | SNOW_BAND | Fraction of grid cell covered by each elevation band. Sum of the fractions must equal 1. | +| elevation | [snow_band, lat, lon] | m | double | SNOW_BAND | Mean (or median) elevation of elevation band. This is used to compute the change in air temperature from the grid cell mean elevation. | +| Pfactor | [snow_band, lat, lon] | fraction | double | SNOW_BAND | Fraction of cell precipitation that falls on each elevation band. Total must equal 1. To ignore effects of elevation on precipitation, set these fractions equal to the area fractions. | diff --git a/docs/Documentation/HowToAddNewOutputVars.md b/docs/Documentation/HowToAddNewOutputVars.md index ee497a082..e17ab87ef 100644 --- a/docs/Documentation/HowToAddNewOutputVars.md +++ b/docs/Documentation/HowToAddNewOutputVars.md @@ -1,14 +1,14 @@ # How to Add New Output Variables -VIC allows users to select which output variables to write to their output files. Variables that can be selected are listed [here](OutputVarList.md) as well as in the VIC source code file `vic_def.h` (listed as `OUT_*`). However, not all variables that VIC simulates are available for output. And of course if you are changing VIC's physics, any new variables you add are also not available for output (yet). +VIC allows users to select which output variables to write to their output files. Variables that can be selected are listed [here](OutputVarList.md) as well as in the VIC source code file `vic_driver_shared_all.h` (listed as `OUT_*`). However, not all variables that VIC simulates are available for output. And of course if you are changing VIC's physics, any new variables you add are also not available for output (yet). You can enable VIC to output new variables by making a few changes to the code, as follows: -## 1\. Make sure VIC sends the variable to put_data() +## 1. Make sure VIC sends the variable to `put_data()` -If VIC doesn't already compute the variable you need, or computes it but doesn't store it in one of the structures that is accessible to put_data(), you'll have to modify VIC to do this. The structures that put_data() has access to are: dmy, atmos_data, soil_con, cell_data, veg_con, veg_var, energy, snow_data, and all_vars. +If VIC doesn't already compute the variable you need, or computes it but doesn't store it in one of the structures that is accessible to `put_data()`, you'll have to modify VIC to do this. The structures that `put_data()` has access to are: `atmos_data`, `soil_con`, `cell_data`, `veg_con`, `veg_var`, `energy`, `snow_data`, and `lake_var`. -## 2\. Define the variable's name in `vic_def.h`. +## 2. Define the variable's name in `vic_driver_shared_all.h`. The list of output variables is a C `enum`. To add a new variable, begin by appending the new variable to the ***next to*** last position in the `enum`. See the example of adding `OUT_NEW_VAR_NAME` below: @@ -37,29 +37,33 @@ Similarly, for input meteorological variables, we have: *****************************************************************************/ enum { - AIR_TEMP, /**< air temperature per time step [C] (ALMA_INPUT: [K]) */ + AIR_TEMP, /**< air temperature per time step [C] (ALMA_INPUT: [K]) */ ... - WIND_N, /**< meridional component of wind speed [m/s] */ - NEW_FORCE_VAR, /**< Description of new forcing variable [units] */ - SKIP, /**< place holder for unused data columns */ + WIND, /**< meridional component of wind speed [m/s] */ + NEW_FORCE_VAR, /**< Description of new forcing variable [units] */ + SKIP, /**< place holder for unused data columns */ // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! // used as a loop counter and must be >= the largest value in this enum - N_FORCING_TYPES /**< Number of forcing types */ + N_FORCING_TYPES /**< Number of forcing types*/ }; ``` -## 3\. For output variables, populate the variable's metadata in output_list_utils.c. +## 3. For output variables, populate the variable's metadata in `vic_metadata.c`. -In the function create_output_list(), there is a series of calls to strcpy, one per variable: +In the function `set_output_met_data_info()`, there is a series of calls to `strcpy` setting metadata for each output variable: ```C -strcpy(out_data[OUT_NEW_VAR_NAME].varname,"OUT_NEW_VAR_NAME"); - ^ ^ - array index variable name + /* new variable metadata [kg m-2] */ + strcpy(out_metadata[OUT_NEW_VAR_NAME].varname, "OUT_NEW_VAR_NAME"); + strcpy(out_metadata[OUT_NEW_VAR_NAME].long_name, "a_descriptive_long_name"); + strcpy(out_metadata[OUT_NEW_VAR_NAME].standard_name, "new_out_var_std_name"); + strcpy(out_metadata[OUT_NEW_VAR_NAME].units, "kg m-2"); + strcpy(out_metadata[OUT_NEW_VAR_NAME].description, "new var description"); ``` -You must add an entry for your variable. The safest thing to do is to copy an existing entry and modify it. Make sure that the array index and variable name both match the name you entered in `vic_def.h` EXACTLY. -Next, if your variable consists of multiple values per grid cell (for example, per-layer soil moisture OUT_SOIL_MOIST has options.Nlayer values, while OUT_RUNOFF has only 1 value) you must define the number of elements for the variable. There is a series of lines defining the number of elements, as: +You must add an entry for your variable. The safest thing to do is to copy an existing entry and modify it. Make sure that the array index and variable name both match the name you entered in `vic_driver_shared_all.h` EXACTLY. + +Next, if your variable consists of multiple values per grid cell (for example, per-layer soil moisture `OUT_SOIL_MOIST` has `options.Nlayer` values, while `OUT_RUNOFF` has only 1 value) you must define the number of elements for the variable. There is a series of lines defining the number of elements, as: ```C out_data[OUT_NEW_VAR_NAME].nelem = options.Nlayer; @@ -67,15 +71,19 @@ out_data[OUT_NEW_VAR_NAME].nelem = options.Nlayer; To add an entry, copy an existing entry and modify it. -Next, define your variable's aggregation method. This refers to the method used to aggregate up from smaller time steps to larger time steps, e.g. from hourly to daily. By default, variables are aggregated via averaging the original values over the output time step; if this is acceptable for your variable, then you do not need to specify anything here. Otherwise, you need to specify a method, e.g.: +Next, define your variable's default aggregation method. This refers to the method used to aggregate up from smaller time steps to larger time steps, e.g. from hourly to daily. By default, variables are aggregated via averaging the original values over the output time step; if this is acceptable for your variable, then you do not need to specify anything here. Otherwise, you need to specify a method. This is done by adding your variable to the appropriate case/switch block in `get_default_outvar_aggtype()`, for example: ```C -out_data[OUT_NEW_VAR_NAME].aggtype = AGG_TYPE_END; + switch (varid) { + ... + // AGG_TYPE_END + ... + case OUT_NEW_VAR_NAME: ``` Once again, to add an entry, copy an existing entry and modify it. Possible aggregation methods are: -``` +```Shell AGG_TYPE_AVG : Aggregated value = average of the values over the interval (default; used for energy balance terms) AGG_TYPE_END : Aggregated value = final value over the interval (used for @@ -87,42 +95,44 @@ AGG_TYPE_MIN : Aggregated value = minimum of the values over the interval AGG_TYPE_MAX : Aggregated value = maximum of the values over the interval ``` -## 4\. For output variables, add logic to put_data.c to set the variable in the out_data[] array +## 4. For output variables, add logic to `put_data.c` to set the variable in the `out_data` array -Assuming that at this point, your variable is computed somewhere in VIC and stored in one of the data structures that put_data() has access to, you now need to assign this to the appropriate part of the out_data structure. In put_data(), there is a loop over elevation bands and veg tiles. The contribution of each band/tile combination is added to the running total (weighted by the band/tile's area fraction) in the out_data structure. For example, for single-element variables: +Assuming that at this point, your variable is computed somewhere in VIC and stored in one of the data structures that `put_data()` has access to, you now need to assign this to the appropriate part of the out_data structure. In `put_data()`, there is a loop over elevation bands and veg tiles. The contribution of each band/tile combination is added to the running total (weighted by the band/tile's area fraction) in the out_data structure. For example, for single-element variables: ```C /** record canopy interception **/ -if ( veg < veg_con[0].vegetat_type_num ) - out_data[OUT_WDEW].data[0] += veg_var[veg][band].Wdew - * Cv * mu * AreaFract[band] * TreeAdjustFactor[band]; +if ( veg < veg_con[0].vegetat_type_num ) { + out_data[OUT_WDEW][0] += veg_var[veg][band].Wdew + * Cv * mu * AreaFract[band] * TreeAdjustFactor[band]; +} + ``` For multiple-element variables, you must loop over the variable's index, e.g.: ```C -for(index = 0; index < MAX_FRONTS; index++) { - if(energy[veg][band].fdepth[index] != MISSING) - out_data[OUT_FDEPTH].data[index] += energy[veg][band].fdepth[index] - * Cv * 100\. * AreaFract[band] * TreeAdjustFactor[band]; - if(energy[veg][band].tdepth[index] != MISSING) - out_data[OUT_TDEPTH].data[index] += energy[veg][band].tdepth[index] - * Cv * 100\. * AreaFract[band] * TreeAdjustFactor[band]; +for (index = 0; index < MAX_FRONTS; index++) { + if (energy.fdepth[index] != MISSING) { + out_data[OUT_FDEPTH][index] += energy.fdepth[index] * AreaFactor * CM_PER_M; + } + if (energy.tdepth[index] != MISSING) { + out_data[OUT_TDEPTH][index] += energy.tdepth[index] * AreaFactor * CM_PER_M; + } } ``` -## 5\. Add the relevant information to the global parameter file. +## 5. Add the relevant information to the global parameter file. Input variables should be specified in the "Forcing Files" section. Output variables should be specified in the "Output Files" section, unless using the default output file format. -Note: if you simply want to add an output variable to the default output files, you can either modify the default output file format in set_output_defaults.c so that it includes your variable (and not add any information to your global parameter file), or you can paste the contents of the appropriate `output.*.template` file into your global parameter file, and then add your variable to that description. See the documentation on the flexible output configuration for more details on specifying output file contents in the global parameter file. +Note: if you simply want to add an output variable to the default output files, you can either modify the default output file format in the driver specific `set_output_defaults.c` so that it includes your variable (and not add any information to your global parameter file). -## 6\. If you have added new state variables to VIC, you must add them to state files +## 6. If you have added new state variables to VIC, you must add them to state files State variables are any type of storage term that must be "remembered" from one step to the next to preserve the model's internal state. Examples include snow water equivalent, soil moisture, soil temperature, etc. If these are not stored in the state file and read from the state file upon restart, the restarted simulation will not be identical to the same point in time of a continuous simulation, i.e. the missing states (e.g., snow water equivalent) will be reset to 0. -To do this, you must add writing of the new variable to write_model_state() and add reading of the new variable to read_initial_model_state(). +To do this, you must add writing of the new variable to `write_model_state()` and add reading of the new variable to `read_initial_model_state()`. -In addition, you must provide default initial values for the new variable in the case of no initial state file. These initial values should be assigned either in initialize_model_state() or one of the functions it calls, e.g. initialize_soil(), initialize_snow(), etc. +In addition, you must provide default initial values for the new variable in the case of no initial state file. These initial values should be assigned either in `initialize_model_state()` or one of the functions it calls, e.g. `initialize_soil()`, `initialize_snow()`, etc. diff --git a/docs/Documentation/OutputVarList.md b/docs/Documentation/OutputVarList.md index 8c7c7a5ba..9778d8868 100644 --- a/docs/Documentation/OutputVarList.md +++ b/docs/Documentation/OutputVarList.md @@ -3,176 +3,180 @@ Using options within the *global parameter file*, any combination of the variables listed below may be output by VIC. ## Water Balance Terms (state variables) -| Variable | Description | Units | -|--------------------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |---------------------------------------------------------------------------------------------- | -| OUT_ASAT | Saturated Area Fraction (of exposed land, i.e. non-lake; the total fraction of the grid cell that is completely full of water would be OUT_ASAT plus OUT_LAKE_AREA_FRAC) | fraction | -| OUT_LAKE_AREA_FRACT | (release 4.1.2 and later)Lake surface area as fraction of grid cell area | fraction | -| OUT_LAKE_DEPTH | Lake depth (distance between surface and deepest point) | m | -| OUT_LAKE_ICE | Moisture stored as lake ice | mm over lake ice area | -| OUT_LAKE_ICE_FRACT | Fractional coverage of lake ice | fraction | -| OUT_LAKE_ICE_HEIGHT | Thickness of lake ice | cm | -| OUT_LAKE_MOIST | Liquid water and ice stored in lake | mm over grid cell | -| OUT_LAKE_SURF_AREA | Lake surface area | m2 | -| OUT_LAKE_SWE | (release 4.1.2 and later) Liquid water equivalent of snow on top of lake ice | m over lake ice area | -| OUT_LAKE_SWE_V | (release 4.1.2 and later) Volumetric liquid water equivalent of snow on top of lake ice | m3 | -| OUT_LAKE_VOLUME | Lake volume | m3 | -| OUT_ROOTMOIST | Total soil moisture in layers that contain roots. | mm | -| OUT_SMFROZFRAC | Fraction of soil moisture (by mass) that is ice, for each soil layer | fraction | -| OUT_SMLIQFRAC | Fraction of soil moisture (by mass) that is liquid, for each soil layer | fraction | -| OUT_SNOW_CANOPY | Snow interception storage in canopy | mm | -| OUT_SNOW_COVER | Fractional area of snow cover | fraction | -| OUT_SNOW_DEPTH | Depth of snow pack | cm | -| OUT_SOIL_ICE | Soil ice content for each soil layer | mm | -| OUT_SOIL_LIQ | Soil liquid content for each soil layer | mm | -| OUT_SOIL_MOIST | Total soil moisture content for each soil layer | mm | -| OUT_SOIL_WET | Vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) | mm/mm | -| OUT_SURFSTOR | Storage of liquid water and ice (not snow) on surface (ponding) | mm | -| OUT_SURF_FROST_FRAC | Fraction of soil surface that is frozen | fraction | -| OUT_SWE | Snow water equivalent in snow pack (including vegetation-intercepted snow) | mm | -| OUT_WDEW | Total moisture interception storage in canopy | mm | -| OUT_ZWT | Water table position, using lowest unsaturated soil layer | cm (positive upwards, i.e. negative values indicate below soil surface; 0 = at soil surface) | -| OUT_ZWT_LUMPED | Water table position, lumping all layers' moistures together | cm (positive upwards, i.e. negative values indicate below soil surface; 0 = at soil surface) | +| Variable | Description | Units | +|--------------------- |-------------------------------------------------------------------------------------------- |---------------------- | +| OUT_ASAT | Saturated Area Fraction (of exposed land, i.e. non-lake; the total fraction of the grid cell that is completely full of water would be OUT_ASAT plus OUT_LAKE_AREA_FRAC) | fraction | +| OUT_LAKE_AREA_FRACT | Lake surface area as fraction of grid cell area | fraction | +| OUT_LAKE_DEPTH | Lake depth (distance between surface and deepest point) | m | +| OUT_LAKE_ICE | Moisture stored as lake ice | mm over lake ice area | +| OUT_LAKE_ICE_FRACT | Fractional coverage of lake ice | fraction | +| OUT_LAKE_ICE_HEIGHT | Thickness of lake ice | cm | +| OUT_LAKE_MOIST | Liquid water and ice stored in lake | mm over grid cell | +| OUT_LAKE_SURF_AREA | Lake surface area | m2 | +| OUT_LAKE_SWE | Liquid water equivalent of snow on top of lake ice | m over lake ice area | +| OUT_LAKE_SWE_V | Volumetric liquid water equivalent of snow on top of lake ice | m3 | +| OUT_LAKE_VOLUME | Lake volume | m3 | +| OUT_ROOTMOIST | Total soil moisture in layers that contain roots. | mm | +| OUT_SMFROZFRAC | Fraction of soil moisture (by mass) that is ice, for each soil layer | fraction | +| OUT_SMLIQFRAC | Fraction of soil moisture (by mass) that is liquid, for each soil layer | fraction | +| OUT_SNOW_CANOPY | Snow interception storage in canopy | mm | +| OUT_SNOW_COVER | Fractional area of snow cover | fraction | +| OUT_SNOW_DEPTH | Depth of snow pack | cm | +| OUT_SOIL_ICE | Soil ice content for each soil layer | mm | +| OUT_SOIL_LIQ | Soil liquid content for each soil layer | mm | +| OUT_SOIL_ICE_FRAC | Fractional soil ice content for each soil layer | fraction | +| OUT_SOIL_LIQ_FRAC | Fractional soil liquid content for each soil layer | fraction | +| OUT_SOIL_MOIST | Total soil moisture content for each soil layer | mm | +| OUT_SOIL_WET | Vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) | mm/mm | +| OUT_SURFSTOR | Storage of liquid water and ice (not snow) on surface (ponding) | mm | +| OUT_SURF_FROST_FRAC | Fraction of soil surface that is frozen | fraction | +| OUT_SWE | Snow water equivalent in snow pack (including vegetation-intercepted snow) | mm | +| OUT_WDEW | Total moisture interception storage in canopy | mm | +| OUT_ZWT | Water table position, using lowest unsaturated soil layer | cm (positive upwards, i.e. negative values indicate below soil surface; 0 = at soil surface) | +| OUT_ZWT_LUMPED | Water table position, lumping all layers' moistures together | cm (positive upwards, i.e. negative values indicate below soil surface; 0 = at soil surface) | ## Water Balance Terms (fluxes) -| Variable | Description | Units | -|------------------------ |------------------------------------------------------------------------------------------- |------------------------ | -| OUT_BASEFLOW | Baseflow out of the bottom layer | mm (ALMA_OUTPUT: mm/s) | -| OUT_DELINTERCEPT | Change in canopy interception storage | mm | -| OUT_DELSOILMOIST | Change in soil water content | mm | -| OUT_DELSURFSTOR | Change in surface liquid water storage | mm | -| OUT_DELSWE | Change in snow water equivalent | mm | -| OUT_EVAP | Total net evaporation | mm (ALMA_OUTPUT: mm/s) | -| OUT_EVAP_BARE | Net evaporation from bare soil | mm (ALMA_OUTPUT: mm/s) | -| OUT_EVAP_CANOP | Net evaporation from canopy interception | mm (ALMA_OUTPUT: mm/s) | -| OUT_INFLOW | Moisture that reaches top of soil column | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_BF_IN | (release 4.1.2 and later) Incoming baseflow from lake catchment | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_BF_IN_V | (release 4.1.2 and later) Incoming volumetric baseflow from lake catchment | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_BF_OUT | (release 4.1.2 and later) Outgoing baseflow from lake to channel network | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_BF_OUT_V | (release 4.1.2 and later) Outgoing volumetric baseflow from lake to channel network | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_CHANNEL_IN | (release 4.1.2 and later) Channel inflow from upstream | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_CHANNEL_IN_V | (release 4.1.2 and later) Volumetric channel inflow from upstream | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_CHANNEL_OUT | (release 4.1.2 and later) Channel outflow from lake to channel network | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_CHANNEL_OUT_V | (release 4.1.2 and later) Volumetric channel outflow from lake to channel network | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_DSTOR | (release 4.1.2 and later) Change in lake moisture storage (liquid plus ice cover) | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_DSTOR_V | (release 4.1.2 and later) Volumetric change in lake moisture storage (liquid plus ice cover) | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_DSWE | (release 4.1.2 and later) Change in swe on top of lake ice | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_DSWE_V | (release 4.1.2 and later) Volumetric change in swe on top of lake ice | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_EVAP | (release 4.1.2 and later) Net evaporation from lake surface | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_EVAP_V | (release 4.1.2 and later) Net volumetric evaporation from lake surface | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_PREC_V | (release 4.1.2 and later) Volumetric precipitation over lake surface | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_RCHRG | (release 4.1.2 and later) Recharge from lake to surrounding wetland | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_RCHRG_V | (release 4.1.2 and later) Volumetric recharge from lake to surrounding wetland | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_RO_IN | (release 4.1.2 and later) Incoming runoff from lake catchment | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_RO_IN_V | (release 4.1.2 and later) Incoming volumetric runoff from lake catchment | m3 (ALMA_OUTPUT: m3/s) | -| OUT_LAKE_VAPFLX | (release 4.1.2 and later) Outgoing sublimation from snow on top of lake ice | mm (ALMA_OUTPUT: mm/s) | -| OUT_LAKE_VAPFLX_V | (release 4.1.2 and later) Outgoing volumetric sublimation from snow on top of lake ice | m3 (ALMA_OUTPUT: m3/s) | -| OUT_PET | Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. | mm (ALMA_OUTPUT: mm/s) | -| OUT_PREC | Incoming precipitation | mm (ALMA_OUTPUT: mm/s) | -| OUT_RAINF | Rainfall | mm (ALMA_OUTPUT: mm/s) | -| OUT_REFREEZE | Refreezing of water in the snow | mm (ALMA_OUTPUT: mm/s) | -| OUT_RUNOFF | Surface runoff | mm (ALMA_OUTPUT: mm/s) | -| OUT_SNOW_MELT | Snow melt | mm (ALMA_OUTPUT: mm/s) | -| OUT_SNOWF | Snowfall | mm (ALMA_OUTPUT: mm/s) | -| OUT_SUB_BLOWING | Net sublimation of blowing snow | mm (ALMA_OUTPUT: mm/s) | -| OUT_SUB_CANOP | Net sublimation from snow stored in canopy | mm (ALMA_OUTPUT: mm/s) | -| OUT_SUB_SNOW | Total net sublimation from snow pack (surface and blowing) | mm (ALMA_OUTPUT: mm/s) | -| OUT_SUB_SURFACE | Net sublimation from snow pack surface | mm (ALMA_OUTPUT: mm/s) | -| OUT_TRANSP_VEG | Net transpiration from vegetation | mm (ALMA_OUTPUT: mm/s) | -| OUT_WATER_ERROR | Water budget error | mm | +| Variable | Description | Units | +|------------------------ |------------------------------------------------------------------------------------------- |------------- | +| OUT_BASEFLOW | Baseflow out of the bottom layer | mm | +| OUT_DELINTERCEPT | Change in canopy interception storage | mm | +| OUT_DELSOILMOIST | Change in soil water content | mm | +| OUT_DELSURFSTOR | Change in surface liquid water storage | mm | +| OUT_DELSWE | Change in snow water equivalent | mm | +| OUT_EVAP | Total net evaporation | mm | +| OUT_EVAP_BARE | Net evaporation from bare soil | mm | +| OUT_EVAP_CANOP | Net evaporation from canopy interception | mm | +| OUT_INFLOW | Moisture that reaches top of soil column | mm | +| OUT_LAKE_BF_IN | Incoming baseflow from lake catchment | mm | +| OUT_LAKE_BF_IN_V | Incoming volumetric baseflow from lake catchment | m3 | +| OUT_LAKE_BF_OUT | Outgoing baseflow from lake to channel network | mm | +| OUT_LAKE_BF_OUT_V | Outgoing volumetric baseflow from lake to channel network | m3 | +| OUT_LAKE_CHANNEL_IN | Channel inflow from upstream | mm | +| OUT_LAKE_CHANNEL_IN_V | Volumetric channel inflow from upstream | m3 | +| OUT_LAKE_CHANNEL_OUT | Channel outflow from lake to channel network | mm | +| OUT_LAKE_CHANNEL_OUT_V | Volumetric channel outflow from lake to channel network | m3 | +| OUT_LAKE_DSTOR | Change in lake moisture storage (liquid plus ice cover) | mm | +| OUT_LAKE_DSTOR_V | Volumetric change in lake moisture storage (liquid plus ice cover) | m3 | +| OUT_LAKE_DSWE | Change in swe on top of lake ice | mm | +| OUT_LAKE_DSWE_V | Volumetric change in swe on top of lake ice | m3 | +| OUT_LAKE_EVAP | Net evaporation from lake surface | mm | +| OUT_LAKE_EVAP_V | Net volumetric evaporation from lake surface | m3 | +| OUT_LAKE_PREC_V | Volumetric precipitation over lake surface | m3 | +| OUT_LAKE_RCHRG | Recharge from lake to surrounding wetland | mm | +| OUT_LAKE_RCHRG_V | Volumetric recharge from lake to surrounding wetland | m3 | +| OUT_LAKE_RO_IN | Incoming runoff from lake catchment | mm | +| OUT_LAKE_RO_IN_V | Incoming volumetric runoff from lake catchment | m3 | +| OUT_LAKE_VAPFLX | Outgoing sublimation from snow on top of lake ice | mm | +| OUT_LAKE_VAPFLX_V | Outgoing volumetric sublimation from snow on top of lake ice | m3 | +| OUT_PET | Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. | mm | +| OUT_PREC | Incoming precipitation | mm | +| OUT_RAINF | Rainfall | mm | +| OUT_REFREEZE | Refreezing of water in the snow | mm | +| OUT_RUNOFF | Surface runoff | mm | +| OUT_SNOW_MELT | Snow melt | mm | +| OUT_SNOWF | Snowfall | mm | +| OUT_SUB_BLOWING | Net sublimation of blowing snow | mm | +| OUT_SUB_CANOP | Net sublimation from snow stored in canopy | mm | +| OUT_SUB_SNOW | Total net sublimation from snow pack (surface and blowing) | mm | +| OUT_SUB_SURFACE | Net sublimation from snow pack surface | mm | +| OUT_TRANSP_VEG | Net transpiration from vegetation | mm | +| OUT_WATER_ERROR | Water budget error | mm | ## Energy Balance Terms (state variables) -| Variable | Description | Units | -|-------------------- |------------------------------------------------------------ |--------------------- | -| OUT_ALBEDO | Average surface albedo | fraction | -| OUT_BARESOILT | Bare soil surface temperature | C (ALMA_OUTPUT: K) | -| OUT_FDEPTH | Depth of freezing fronts for each freezing front | cm (ALMA_OUTPUT: m) | -| OUT_LAKE_ICE_TEMP | Temperature of lake ice | K | -| OUT_LAKE_SURF_TEMP | Lake surface temperature | K | -| OUT_RAD_TEMP | Average radiative surface temperature | K | -| OUT_SALBEDO | Snow pack albedo | fraction | -| OUT_SNOW_PACK_TEMP | Snow pack temperature | C (ALMA_OUTPUT: K) | -| OUT_SNOW_SURF_TEMP | Snow surface temperature | C (ALMA_OUTPUT: K) | -| OUT_SNOWT_FBFLAG | Snow surface temperature fallback flag | 0 or 1 | -| OUT_SOIL_TEMP | Soil temperature for each soil layer | C (ALMA_OUTPUT: K) | -| OUT_SOIL_TNODE | Soil temperature for each soil thermal node | C (ALMA_OUTPUT: K) | -| OUT_SOIL_TNODE_WL | Soil temperature for each soil thermal node in the wetland | C (ALMA_OUTPUT: K) | -| OUT_SOILT_FBFLAG | Soil temperature flag for each soil thermal node | 0 or 1 | -| OUT_SURF_TEMP | Average surface temperature | C (ALMA_OUTPUT: K) | -| OUT_SURFT_FBFLAG | Surface temperature fallback flag | 0 or 1 | -| OUT_TCAN_FBFLAG | Tcanopy fallback flag | 0 or 1 | -| OUT_TDEPTH | Depth of thawing fronts for each thawing front | cm (ALMA_OUTPUT: m) | -| OUT_TFOL_FBFLAG | Tfoliage fallback flag | 0 or 1 | -| OUT_VEGT | Average vegetation canopy temperature | C (ALMA_OUTPUT: K) | +| Variable | Description | Units | +|-------------------- |------------------------------------------------------------ |--------- | +| OUT_ALBEDO | Average surface albedo | fraction | +| OUT_BARESOILT | Bare soil surface temperature | C | +| OUT_FDEPTH | Depth of freezing fronts for each freezing front | cm | +| OUT_LAKE_ICE_TEMP | Temperature of lake ice | K | +| OUT_LAKE_SURF_TEMP | Lake surface temperature | K | +| OUT_RAD_TEMP | Average radiative surface temperature | K | +| OUT_SALBEDO | Snow pack albedo | fraction | +| OUT_SNOW_PACK_TEMP | Snow pack temperature | C | +| OUT_SNOW_SURF_TEMP | Snow surface temperature | C | +| OUT_SNOWT_FBFLAG | Snow surface temperature fallback flag | 0 or 1 | +| OUT_SOIL_TEMP | Soil temperature for each soil layer | C | +| OUT_SOIL_TNODE | Soil temperature for each soil thermal node | C | +| OUT_SOIL_TNODE_WL | Soil temperature for each soil thermal node in the wetland | C | +| OUT_SOILT_FBFLAG | Soil temperature flag for each soil thermal node | 0 or 1 | +| OUT_SURF_TEMP | Average surface temperature | C | +| OUT_SURFT_FBFLAG | Surface temperature fallback flag | 0 or 1 | +| OUT_TCAN_FBFLAG | Tcanopy fallback flag | 0 or 1 | +| OUT_TDEPTH | Depth of thawing fronts for each thawing front | cm | +| OUT_TFOL_FBFLAG | Tfoliage fallback flag | 0 or 1 | +| OUT_VEGT | Average vegetation canopy temperature | C | ## Energy Balance Terms (fluxes) -| Variable | Description | Units | -|------------------ |------------------------------------------------------ |-------------------------- | -| OUT_ADV_SENS | Net sensible flux advected to snow pack | W/m2 | -| OUT_ADVECTION | Advected energy | W/m2 | -| OUT_DELTACC | Rate of change in cold content in snow pack | W/m2 (ALMA_OUTPUT: J/m2) | -| OUT_DELTAH | Rate of change in heat storage | W/m2 (ALMA_OUTPUT: J/m2) | -| OUT_ENERGY_ERROR | Energy budget error | W/m2 | -| OUT_FUSION | Net energy used to melt/freeze soil moisture | W/m2 | -| OUT_GRND_FLUX | Net heat flux into ground | W/m2 | -| OUT_IN_LONG | Incoming longwave at ground surface (under veg) | W/m2 | -| OUT_LATENT | Net upward latent heat flux | W/m2 | -| OUT_LATENT_SUB | Net upward latent heat flux from sublimation | W/m2 | -| OUT_MELT_ENERGY | Energy of fusion (melting) in snowpack | W/m2 | -| OUT_LWNET | Net downward longwave flux | W/m2 | -| OUT_SWNET | Net downward shortwave flux | W/m2 | -| OUT_R_NET | Net downward radiation flux | W/m2 | -| OUT_RFRZ_ENERGY | Net energy used to refreeze liquid water in snowpack | W/m2 | -| OUT_SENSIBLE | Net upward sensible heat flux | W/m2 | -| OUT_SNOW_FLUX | Energy flux through snow pack | W/m2 | +| Variable | Description | Units | +|------------------ |------------------------------------------------------ |---------------- | +| OUT_ADV_SENS | Net sensible flux advected to snow pack | W/m2 | +| OUT_ADVECTION | Advected energy | W/m2 | +| OUT_DELTACC | Rate of change in cold content in snow pack | W/m2 | +| OUT_DELTAH | Rate of change in heat storage | W/m2 | +| OUT_ENERGY_ERROR | Energy budget error | W/m2 | +| OUT_FUSION | Net energy used to melt/freeze soil moisture | W/m2 | +| OUT_GRND_FLUX | Net heat flux into ground | W/m2 | +| OUT_IN_LONG | Incoming longwave at ground surface (under veg) | W/m2 | +| OUT_LATENT | Net upward latent heat flux | W/m2 | +| OUT_LATENT_SUB | Net upward latent heat flux from sublimation | W/m2 | +| OUT_MELT_ENERGY | Energy of fusion (melting) in snowpack | W/m2 | +| OUT_LWNET | Net downward longwave flux | W/m2 | +| OUT_SWNET | Net downward shortwave flux | W/m2 | +| OUT_R_NET | Net downward radiation flux | W/m2 | +| OUT_RFRZ_ENERGY | Net energy used to refreeze liquid water in snowpack | W/m2 | +| OUT_SENSIBLE | Net upward sensible heat flux | W/m2 | +| OUT_SNOW_FLUX | Energy flux through snow pack | W/m2 | ## Miscellaneous Terms -| OUT_AERO_COND | Scene aerodynamic conductance (tiles with overstory contribute overstory conductance; others contribute surface conductance) | m/s | -|------------------ |---------------------------------------------------------------------------------------------------------------------------------- |----------------------- | -| OUT_AERO_COND1 | Surface aerodynamic conductance | m/s | -| OUT_AERO_COND2 | Overstory aerodynamic conductance | m/s | -| OUT_AERO_RESIST | Scenecanopy aerodynamic resistance (tiles with overstory contribute over story resistance; others contribute surface resistance) | s/m | -| OUT_AERO_RESIST1 | Surface aerodynamic resistance | s/m | -| OUT_AERO_RESIST2 | Overstory aerodynamic resistance | s/m | -| OUT_AIR_TEMP | Air temperature | C (ALMA_OUTPUT: K) | -| OUT_DENSITY | Near-surface atmospheric density | kg/m3 | -| OUT_FCANOPY | Vegetation canopy cover fraction | fraction | -| OUT_FDIR | fraction of incoming shortwave that is direct | fraction | -| OUT_LAI | Leaf Area Index | fraction | -| OUT_LWDOWN | Incoming longwave | W/m2 | -| OUT_PRESSURE | Near surface atmospheric pressure | kPa (ALMA_OUTPUT: Pa) | -| OUT_QAIR | Specific humidity | kg/kg | -| OUT_REL_HUMID | Relative humidity | fraction | -| OUT_SWDOWN | Incoming shortwave | W/m2 | -| OUT_SURF_COND | Surface conductance | m/s | -| OUT_TSKC | (release 4.1.2 and later) Cloud fraction | fraction | -| OUT_VP | Near surface vapor pressure | kPa (ALMA_OUTPUT: Pa) | -| OUT_VPD | Near surface vapor pressure deficit | kPa (ALMA_OUTPUT: Pa) | -| OUT_WIND | Near surface wind speed | m/s | +| OUT_AERO_COND | Scene aerodynamic conductance (tiles with overstory contribute overstory conductance; others contribute surface conductance) | m/s | +|------------------ |---------------------------------------------------------------------------------------------------------------------------------- |----------------- | +| OUT_AERO_COND | "scene" aerodynamic conductance (tiles with overstory contribute overstory conductance; others contribute surface conductance) | m/s | +| OUT_AERO_COND1 | Surface aerodynamic conductance | m/s | +| OUT_AERO_COND2 | Overstory aerodynamic conductance | m/s | +| OUT_AERO_RESIST | Scenecanopy aerodynamic resistance (tiles with overstory contribute over story resistance; others contribute surface resistance) | s/m | +| OUT_AERO_RESIST1 | Surface aerodynamic resistance | s/m | +| OUT_AERO_RESIST2 | Overstory aerodynamic resistance | s/m | +| OUT_AIR_TEMP | Air temperature | C | +| OUT_CATM | atmospheric CO2 concentrtaion | ppm | +| OUT_DENSITY | Near-surface atmospheric density | kg/m3 | +| OUT_FCANOPY | Vegetation canopy cover fraction | fraction | +| OUT_FDIR | fraction of incoming shortwave that is direct | fraction | +| OUT_LAI | Leaf Area Index | fraction | +| OUT_LWDOWN | Incoming longwave | W/m2 | +| OUT_PAR | Incoming photosynthetically active radiation | W/m2 | +| OUT_PRESSURE | Near surface atmospheric pressure | kPa | +| OUT_QAIR | Specific humidity | kg/kg | +| OUT_REL_HUMID | Relative humidity | fraction | +| OUT_SWDOWN | Incoming shortwave | W/m2 | +| OUT_SURF_COND | Surface conductance | m/s | +| OUT_VP | Near surface vapor pressure | kPa | +| OUT_VPD | Near surface vapor pressure deficit | kPa | +| OUT_WIND | Near surface wind speed | m/s | ## Band-specific quantities -| Variable | Description | Units | -|---------------------- |------------------------------------------------------ |-------------------- | -| OUT_ADV_SENS_BAND | Net sensible heat flux advected to snow pack | W/m2 | -| OUT_ADVECTION_BAND | Advected energy | W/m2 | -| OUT_ALBEDO_BAND | Average surface albedo | fraction | -| OUT_DELTACC_BAND | Change in cold content in snow pack | W/m2 | -| OUT_GRND_FLUX_BAND | Net heat flux into ground | W/m2 | -| OUT_IN_LONG_BAND | Incoming longwave at ground surface (under veg) | W/m2 | -| OUT_LATENT_BAND | Net upward latent heat flux | W/m2 | -| OUT_LATENT_SUB_BAND | Net upward latent heat flux due to sublimation | W/m2 | -| OUT_MELT_ENERGY_BAND | Energy of fusion (melting) in snowpack | W/m2 | -| OUT_LWNET_BAND | Net downward longwave flux | W/m2 | -| OUT_SWNET_BAND | Net downward shortwave flux | W/m2 | -| OUT_RFRZ_ENERGY_BAND | Net energy used to refreeze liquid water in snowpack | W/m2 | -| OUT_SENSIBLE_BAND | Net upward sensible heat flux | W/m2 | -| OUT_SNOW_CANOPY_BAND | Snow interception storage in canopy | mm | -| OUT_SNOW_COVER_BAND | Fractional area of snow cover | fraction | -| OUT_SNOW_DEPTH_BAND | Depth of snow pack | cm | -| OUT_SNOW_FLUX_BAND | Energy flux through snow pack | W/m2 | -| OUT_SNOW_MELT_BAND | Snow melt | mm | -| OUT_SNOW_PACKT_BAND | Snow pack temperature | C (ALMA_OUTPUT: K) | -| OUT_SNOW_SURFT_BAND | Snow surface temperature | C (ALMA_OUTPUT: K) | -| OUT_SWE_BAND | Snow water equivalent in snow pack | mm | +| Variable | Description | Units | +|---------------------- |------------------------------------------------------ |---------------- | +| OUT_ADV_SENS_BAND | Net sensible heat flux advected to snow pack | W/m2 | +| OUT_ADVECTION_BAND | Advected energy | W/m2 | +| OUT_ALBEDO_BAND | Average surface albedo | fraction | +| OUT_DELTACC_BAND | Change in cold content in snow pack | W/m2 | +| OUT_GRND_FLUX_BAND | Net heat flux into ground | W/m2 | +| OUT_IN_LONG_BAND | Incoming longwave at ground surface (under veg) | W/m2 | +| OUT_LATENT_BAND | Net upward latent heat flux | W/m2 | +| OUT_LATENT_SUB_BAND | Net upward latent heat flux due to sublimation | W/m2 | +| OUT_MELT_ENERGY_BAND | Energy of fusion (melting) in snowpack | W/m2 | +| OUT_LWNET_BAND | Net downward longwave flux | W/m2 | +| OUT_SWNET_BAND | Net downward shortwave flux | W/m2 | +| OUT_RFRZ_ENERGY_BAND | Net energy used to refreeze liquid water in snowpack | W/m2 | +| OUT_SENSIBLE_BAND | Net upward sensible heat flux | W/m2 | +| OUT_SNOW_CANOPY_BAND | Snow interception storage in canopy | mm | +| OUT_SNOW_COVER_BAND | Fractional area of snow cover | fraction | +| OUT_SNOW_DEPTH_BAND | Depth of snow pack | cm | +| OUT_SNOW_FLUX_BAND | Energy flux through snow pack | W/m2 | +| OUT_SNOW_MELT_BAND | Snow melt | mm | +| OUT_SNOW_PACKT_BAND | Snow pack temperature | C | +| OUT_SNOW_SURFT_BAND | Snow surface temperature | C | +| OUT_SWE_BAND | Snow water equivalent in snow pack | mm | ## Carbon Cycle Terms | Variable | Description | Units | diff --git a/mkdocs.yml b/mkdocs.yml index 6334276c0..76c01bb44 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,7 +53,7 @@ pages: - 'Outputs': 'Documentation/Drivers/Classic/Outputs.md' - 'RunVIC': 'Documentation/Drivers/Classic/RunVIC.md' - 'Snow Band': 'Documentation/Drivers/Classic/SnowBand.md' - - 'SnowOutputFile': 'Documentation/Drivers/Classic/SnowOutputFile.md' + - 'SnowBandOutputFiles': 'Documentation/Drivers/Classic/SnowBandOutputFiles.md' - 'Soil Param': 'Documentation/Drivers/Classic/SoilParam.md' - 'State File': 'Documentation/Drivers/Classic/StateFile.md' - 'Veg Lib': 'Documentation/Drivers/Classic/VegLib.md' @@ -65,7 +65,9 @@ pages: - 'Outputs': 'Documentation/Drivers/Image/Outputs.md' - 'Params': 'Documentation/Drivers/Image/Params.md' - 'RunVIC': 'Documentation/Drivers/Image/RunVIC.md' + - 'Lake Param': 'Documentation/Drivers/Image/LakeParam.md' - 'StateFile': 'Documentation/Drivers/Image/StateFile.md' + - 'Ascii_to_NetCDF_params.md': 'Documentation/Drivers/Image/Ascii_to_NetCDF_params.md' - 'SoilParam': 'Documentation/Drivers/Image/SoilParam.md' - 'OutputFormatting': 'Documentation/Drivers/Image/OutputFormatting.md' - 'DefaultOutputs': 'Documentation/Drivers/Image/DefaultOutputs.md' diff --git a/readme.md b/readme.md index 45326ebb0..5f1b88b98 100644 --- a/readme.md +++ b/readme.md @@ -7,7 +7,8 @@ | VIC Users Listserve | [![VIC Users Listserve](https://img.shields.io/badge/VIC%20Users%20Listserve-Active-blue.svg)](https://mailman.u.washington.edu/mailman/listinfo/vic_users) | | Developers Gitter Room | [![Join the chat at https://gitter.im/UW-Hydro/VIC](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/UW-Hydro/VIC?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | | License | [![GitHub license](https://img.shields.io/badge/license-GPLv2-blue.svg)](https://raw.githubusercontent.com/UW-Hydro/VIC/master/LICENSE.txt) | -| Current Release DOI | [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.35302.svg)](http://dx.doi.org/10.5281/zenodo.35302) | +| Current Release DOI | +[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.56057.svg)](http://dx.doi.org/10.5281/zenodo.56057) | ---------- diff --git a/samples/global.param.sample.classic.txt b/samples/global.param.sample.classic.txt index b6877b235..62f67a9e0 100644 --- a/samples/global.param.sample.classic.txt +++ b/samples/global.param.sample.classic.txt @@ -165,57 +165,59 @@ SNOW_BAND 1 # Number of snow bands; if number of snow bands > 1, you must insert ####################################################################### # Output Files and Parameters ####################################################################### -RESULT_DIR (put the result directory path here) # Results directory path -OUTPUT_STEPS_PER_DAY 0 # Output interval (hours); if 0, OUTPUT_STEPS_PER_DAY = MODEL_STEPS_PER_DAY -SKIPYEAR 0 # Number of years of output to omit from the output files -COMPRESS FALSE # TRUE = compress input and output files when done -OUT_FORMAT ASCII # BINARY OR ASCII -ALMA_OUTPUT FALSE # TRUE = ALMA-format output files; FALSE = standard VIC units -MOISTFRACT FALSE # TRUE = output soil moisture as volumetric fraction; FALSE = standard VIC units -PRT_HEADER FALSE # TRUE = insert a header at the beginning of each output file; FALSE = no header -PRT_SNOW_BAND FALSE # TRUE = write a "snowband" output file, containing band-specific values of snow variables; NOTE: this is ignored if any OUTFILEs are specified below. +LOG_DIR (put the log directory path here) # Log directory path +RESULT_DIR (put the result directory path here) # Results directory path ####################################################################### # # Output File Contents # -# As of VIC 4.0.6 and 4.1.0, you can specify your output file names and -# contents # in the global param file (see the README.txt file for more -# information). +# You can specify your output file names and contents in the global param file +# (see the VIC documentation for more information). # # If you do not specify file names and contents in the global param # file, VIC will produce the same set of output files that it has # produced in earlier versions, namely "fluxes" and "snow" files, plus # "fdepth" files if FROZEN_SOIL is TRUE and "snowband" files if -# PRT_SNOW_BAND is TRUE. These files will have the same contents and +# snowbands are specified. These files will have the same contents and # format as in earlier versions. # -# The OPTIMIZE and LDAS_OUTPUT options have been removed. These -# output configurations can be selected with the proper set of -# instructions in the global param file. (see the output.*.template -# files included in this distribution for more information.) -# -# If you do specify the file names and contents in the global param file, -# PRT_SNOW_BAND will have no effect. -# # Format: # # OUTFILE -# OUTVAR [ ] -# OUTVAR [ ] -# OUTVAR [ ] +# AGGFREQ +# COMPRESS +# OUT_FORMAT +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # OUTFILE -# OUTVAR [ ] -# OUTVAR [ ] -# OUTVAR [ ] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # # where # = name of the output file, NOT including latitude # and longitude +# = Describes aggregation frequency for output stream. Valid +# options for frequency are: +# NEVER = never write to history file +# NSTEPS = write to history every steps +# NSECONDS = write to history every seconds +# NMINUTES = write to history every minutes +# NHOURS = write to history every hours +# NDAYS = write to history every days +# NMONTHS = write to history every months +# NYEARS = write to history every years +# DATE = write to history on the date: +# END = write to history at the end of the simulation +# = integer describing the number of intervals to pass +# before writing to the history file. +# = gzip compression option. TRUE, FALSE, or integer between 1-9. # = name of the variable (this must be one of the -# output variable names listed in vic_driver_shared.h.) +# output variable names listed in vic_driver_shared_all.h.) # = (for ascii output files) fprintf format string, # e.g. # %.4f = floating point with 4 decimal places @@ -238,5 +240,14 @@ PRT_SNOW_BAND FALSE # TRUE = write a "snowband" output file, containing band # = (for binary output files) factor to multiply # the data by before writing, to increase precision. # * = use the default multiplier for this variable +# = Aggregation method to use for temporal aggregation. Valid +# options for aggtype are: +# AGG_TYPE_DEFAULT = default aggregation type for variable +# AGG_TYPE_AVG = average over aggregation window +# AGG_TYPE_BEG = beginning of aggregation window +# AGG_TYPE_END = end of aggregation window +# AGG_TYPE_MAX = maximum in aggregation window +# AGG_TYPE_MIN = minimum in aggregation window +# AGG_TYPE_SUM = sum over aggregation window # ####################################################################### diff --git a/samples/global.param.sample.image.txt b/samples/global.param.sample.image.txt index f84df267a..0c0402e53 100644 --- a/samples/global.param.sample.image.txt +++ b/samples/global.param.sample.image.txt @@ -160,47 +160,84 @@ SNOW_BAND 1 # Number of snow bands; if number of snow bands > 1, you must insert ####################################################################### # Output Files and Parameters ####################################################################### -RESULT_DIR (put the result directory path here) # Results directory path -OUTPUT_STEPS_PER_DAY 0 # Output interval (hours); if 0, OUTPUT_STEPS_PER_DAY = MODEL_STEPS_PER_DAY -#OUT_FORMAT NETCDF4_CLASSIC # Output file format, valid options: NETCDF3_CLASSIC, NETCDF3_64BIT_OFFSET, NETCDF4_CLASSIC, NETCDF4 -SKIPYEAR 0 # Number of years of output to omit from the output files -ALMA_OUTPUT FALSE # TRUE = ALMA-format output files; FALSE = standard VIC units -MOISTFRACT FALSE # TRUE = output soil moisture as volumetric fraction; FALSE = standard VIC units -PRT_SNOW_BAND FALSE # TRUE = write a "snowband" output file, containing band-specific values of snow variables; NOTE: this is ignored if any OUTFILEs are specified below. +LOG_DIR (put the log directory path here) # Log directory path +RESULT_DIR (put the result directory path here) # Results directory path ####################################################################### # # Output File Contents # -# Specify output file names and contents in the global param file (see the -# VIC documentation file for more information). +# You can specify your output file names and contents in the global param file +# (see the VIC documentation for more information). # # If you do not specify file names and contents in the global param # file, VIC will produce the same set of output files that it has # produced in earlier versions, namely "fluxes" and "snow" files, plus # "fdepth" files if FROZEN_SOIL is TRUE and "snowband" files if -# PRT_SNOW_BAND is TRUE. These files will have the same contents and +# snowbands are specified. These files will have the same contents and # format as in earlier versions. # -# If you do specify the file names and contents in the global param file, -# PRT_SNOW_BAND will have no effect. -# # Format: # # OUTFILE -# OUTVAR -# OUTVAR -# OUTVAR +# AGGFREQ +# COMPRESS +# OUT_FORMAT +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # OUTFILE -# OUTVAR -# OUTVAR -# OUTVAR +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] +# OUTVAR [ [ [ [ ]]]] # # # where # = name of the output file, NOT including latitude # and longitude +# = Describes aggregation frequency for output stream. Valid +# options for frequency are: +# NEVER = never write to history file +# NSTEPS = write to history every steps +# NSECONDS = write to history every seconds +# NMINUTES = write to history every minutes +# NHOURS = write to history every hours +# NDAYS = write to history every days +# NMONTHS = write to history every months +# NYEARS = write to history every years +# DATE = write to history on the date: +# END = write to history at the end of the simulation +# = integer describing the number of intervals to pass +# before writing to the history file. +# = gzip compression option. TRUE, FALSE, or integer between 1-9. # = name of the variable (this must be one of the -# output variable names listed in vic_driver_shared.h.) +# output variable names listed in vic_driver_shared_all.h.) + +# , and are optional. For a given +# variable, you can specify either NONE of these, or ALL of +# these. If these are omitted, the default values will be used. +# +# = (for binary output files) data type code. +# Must be one of: +# OUT_TYPE_DOUBLE = double-precision floating point +# OUT_TYPE_FLOAT = single-precision floating point +# OUT_TYPE_INT = integer +# OUT_TYPE_USINT = unsigned short integer +# OUT_TYPE_SINT = short integer +# OUT_TYPE_CHAR = char +# * = use the default type +# = (for binary output files) factor to multiply +# the data by before writing, to increase precision. +# * = use the default multiplier for this variable +# = Aggregation method to use for temporal aggregation. Valid +# options for aggtype are: +# AGG_TYPE_DEFAULT = default aggregation type for variable +# AGG_TYPE_AVG = average over aggregation window +# AGG_TYPE_BEG = beginning of aggregation window +# AGG_TYPE_END = end of aggregation window +# AGG_TYPE_MAX = maximum in aggregation window +# AGG_TYPE_MIN = minimum in aggregation window +# AGG_TYPE_SUM = sum over aggregation window +# ####################################################################### diff --git a/tests/examples/global_param.classic.STEHE.feb.txt b/tests/examples/global_param.classic.STEHE.feb.txt index cee79879f..35641cb9b 100644 --- a/tests/examples/global_param.classic.STEHE.feb.txt +++ b/tests/examples/global_param.classic.STEHE.feb.txt @@ -39,11 +39,3 @@ VEGPARAM_LAI TRUE LAI_SRC FROM_VEGLIB SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE diff --git a/tests/examples/global_param.classic.STEHE.save_state.txt b/tests/examples/global_param.classic.STEHE.save_state.txt index 0c548292e..5a74aacae 100644 --- a/tests/examples/global_param.classic.STEHE.save_state.txt +++ b/tests/examples/global_param.classic.STEHE.save_state.txt @@ -44,11 +44,3 @@ VEGPARAM_LAI TRUE LAI_SRC FROM_VEGLIB SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE diff --git a/tests/examples/global_param.classic.STEHE.txt b/tests/examples/global_param.classic.STEHE.txt index 03ff87c9c..72cb4c409 100644 --- a/tests/examples/global_param.classic.STEHE.txt +++ b/tests/examples/global_param.classic.STEHE.txt @@ -39,11 +39,3 @@ VEGPARAM_LAI TRUE LAI_SRC FROM_VEGLIB SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE diff --git a/tests/examples/global_param.classic.STEHE.wb_output.txt b/tests/examples/global_param.classic.STEHE.wb_output.txt index aa22d79e3..5c0c7da8d 100644 --- a/tests/examples/global_param.classic.STEHE.wb_output.txt +++ b/tests/examples/global_param.classic.STEHE.wb_output.txt @@ -39,16 +39,11 @@ VEGPARAM_LAI TRUE LAI_SRC FROM_VEGLIB SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE OUTFILE wb +COMPRESS FALSE +OUT_FORMAT ASCII +AGGFREQ NDAYS 1 OUTVAR OUT_PREC OUTVAR OUT_EVAP OUTVAR OUT_RUNOFF diff --git a/tests/examples/global_param.image.STEHE.feb.txt b/tests/examples/global_param.image.STEHE.feb.txt index 7bc3b23fa..e9c55f04d 100644 --- a/tests/examples/global_param.image.STEHE.feb.txt +++ b/tests/examples/global_param.image.STEHE.feb.txt @@ -41,10 +41,12 @@ ROOT_ZONES 3 VEGLIB $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc SNOW_BAND 1 $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -RESULT_DIR $result_dir/Stehekin.history.nc -OUTPUT_STEPS_PER_DAY 24 +RESULT_DIR $result_dir OUTFILE fluxes +COMPRESS FALSE +OUT_FORMAT NETCDF4 +AGGFREQ NDAYS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/run_tests.py b/tests/run_tests.py index c0167f304..340954af6 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -12,7 +12,7 @@ import pytest -from tonic.models.vic.vic import VIC, default_vic_valgrind_error_code +from tonic.models.vic.vic import VIC from tonic.io import read_config, read_configobj from tonic.testing import VICTestError from test_utils import (setup_test_dirs, print_test_dict, @@ -20,7 +20,8 @@ check_returncode, process_error, test_classic_driver_all_complete, test_classic_driver_no_output_file_nans, - find_global_param_value) + find_global_param_value, + check_multistream) from test_image_driver import test_image_driver_no_output_file_nans from test_restart import (prepare_restart_run_periods, setup_subdirs_and_fill_in_global_param_restart_test, @@ -244,7 +245,7 @@ def run_unit_tests(test_dir): print('Running Unit Tests') print('-'.ljust(OUTPUT_WIDTH, '-')) - retcode = pytest.main(['-x', os.path.join(test_dir, 'unit')]) + retcode = pytest.main(['-x', os.path.join(test_dir, 'unit'), '--boxed']) return {'unittests': TestResults('unittests', test_complete=True, passed=retcode == 0, @@ -405,13 +406,13 @@ def run_system(config_file, vic_exe, test_data_dir, out_dir, driver): returncode = vic_exe.run(test_global_file, logdir=dirs['logs']) # Check return code - check_returncode(returncode, + check_returncode(vic_exe, test_dict.pop('expected_retval', 0)) else: returncode = vic_exe.run(test_global_file, logdir=dirs['logs'], **run_kwargs) # Check return code - check_returncode(returncode, + check_returncode(vic_exe, test_dict.pop('expected_retval', 0)) test_complete = True @@ -450,6 +451,10 @@ def run_system(config_file, vic_exe, test_data_dir, out_dir, driver): check_exact_restart_states(dirs['state'], driver, run_periods, statesec) + if 'multistream' in test_dict['check']: + fnames = glob.glob(os.path.join(dirs['results'], '*')) + check_multistream(fnames, driver) + # if we got this far, the test passed. test_passed = True @@ -564,7 +569,7 @@ def run_science(config_file, vic_exe, test_data_dir, out_dir, driver): test_complete = True # Check return code - check_returncode(returncode) + check_returncode(vic_exe) # check output files (different tests depending on driver) if test_dict['check']: @@ -701,7 +706,7 @@ def run_examples(config_file, vic_exe, test_data_dir, out_dir, driver): test_complete = True # Check return code - check_returncode(returncode) + check_returncode(vic_exe) # check output files (different tests depending on driver) if test_dict['check']: diff --git a/tests/system/global.classic.STEHE.allhistvars.txt b/tests/system/global.classic.STEHE.allhistvars.txt new file mode 100644 index 000000000..77aa0f6c6 --- /dev/null +++ b/tests/system/global.classic.STEHE.allhistvars.txt @@ -0,0 +1,218 @@ +NLAYER 3 +NODES 3 +MODEL_STEPS_PER_DAY 24 +SNOW_STEPS_PER_DAY 24 +RUNOFF_STEPS_PER_DAY 24 +STARTYEAR 1949 +STARTMONTH 01 +STARTDAY 01 +ENDYEAR 1949 +ENDMONTH 01 +ENDDAY 10 +FULL_ENERGY FALSE +FROZEN_SOIL FALSE + +#INIT_STATE +STATENAME $state_dir/states +STATEYEAR 1949 +STATEMONTH 1 +STATEDAY 10 +STATESEC 82800 +STATE_FORMAT ASCII + +FORCING1 $test_data_dir/classic/Stehekin/forcings/full_data_ +FORCE_FORMAT ASCII +FORCE_TYPE PREC +FORCE_TYPE AIR_TEMP +FORCE_TYPE SWDOWN +FORCE_TYPE LWDOWN +FORCE_TYPE SKIP # This column is air density, which is not needed by VIC +FORCE_TYPE PRESSURE +FORCE_TYPE VP +FORCE_TYPE WIND +FORCE_STEPS_PER_DAY 24 +FORCEYEAR 1949 +FORCEMONTH 01 +FORCEDAY 01 +GRID_DECIMAL 4 +WIND_H 10.0 + +SOIL $test_data_dir/classic/Stehekin/parameters/Stehekin_soil.txt +BASEFLOW ARNO +JULY_TAVG_SUPPLIED FALSE +ORGANIC_FRACT FALSE +VEGLIB $test_data_dir/classic/Stehekin/parameters/Stehekin_veglib.txt +VEGPARAM $test_data_dir/classic/Stehekin/parameters/Stehekin_vegparam.txt +ROOT_ZONES 3 +VEGPARAM_LAI TRUE +LAI_SRC FROM_VEGPARAM +SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt + +RESULT_DIR $result_dir + +# Instantaneous output +OUTFILE allvars +AGGFREQ NSTEPS 1 +OUTVAR OUT_ASAT +OUTVAR OUT_LAKE_AREA_FRAC +OUTVAR OUT_LAKE_DEPTH +OUTVAR OUT_LAKE_ICE +OUTVAR OUT_LAKE_ICE_FRACT +OUTVAR OUT_LAKE_ICE_HEIGHT +OUTVAR OUT_LAKE_MOIST +OUTVAR OUT_LAKE_SURF_AREA +OUTVAR OUT_LAKE_SWE +OUTVAR OUT_LAKE_SWE_V +OUTVAR OUT_LAKE_VOLUME +OUTVAR OUT_ROOTMOIST +OUTVAR OUT_SMFROZFRAC +OUTVAR OUT_SMLIQFRAC +OUTVAR OUT_SNOW_CANOPY +OUTVAR OUT_SNOW_COVER +OUTVAR OUT_SNOW_DEPTH +OUTVAR OUT_SOIL_ICE +OUTVAR OUT_SOIL_LIQ +OUTVAR OUT_SOIL_ICE_FRAC +OUTVAR OUT_SOIL_LIQ_FRAC +OUTVAR OUT_SOIL_MOIST +OUTVAR OUT_SOIL_WET +OUTVAR OUT_SURFSTOR +OUTVAR OUT_SURF_FROST_FRAC +OUTVAR OUT_SWE +OUTVAR OUT_WDEW +OUTVAR OUT_ZWT +OUTVAR OUT_ZWT_LUMPED +OUTVAR OUT_BASEFLOW +OUTVAR OUT_DELINTERCEPT +OUTVAR OUT_DELSOILMOIST +OUTVAR OUT_DELSWE +OUTVAR OUT_DELSURFSTOR +OUTVAR OUT_EVAP +OUTVAR OUT_EVAP_BARE +OUTVAR OUT_EVAP_CANOP +OUTVAR OUT_INFLOW +OUTVAR OUT_LAKE_BF_IN +OUTVAR OUT_LAKE_BF_IN_V +OUTVAR OUT_LAKE_BF_OUT +OUTVAR OUT_LAKE_BF_OUT_V +OUTVAR OUT_LAKE_CHAN_IN +OUTVAR OUT_LAKE_CHAN_IN_V +OUTVAR OUT_LAKE_CHAN_OUT +OUTVAR OUT_LAKE_CHAN_OUT_V +OUTVAR OUT_LAKE_DSTOR +OUTVAR OUT_LAKE_DSTOR_V +OUTVAR OUT_LAKE_DSWE +OUTVAR OUT_LAKE_DSWE_V +OUTVAR OUT_LAKE_EVAP +OUTVAR OUT_LAKE_EVAP_V +OUTVAR OUT_LAKE_PREC_V +OUTVAR OUT_LAKE_RCHRG +OUTVAR OUT_LAKE_RCHRG_V +OUTVAR OUT_LAKE_RO_IN +OUTVAR OUT_LAKE_RO_IN_V +OUTVAR OUT_LAKE_VAPFLX +OUTVAR OUT_LAKE_VAPFLX_V +OUTVAR OUT_PET +OUTVAR OUT_PREC +OUTVAR OUT_RAINF +OUTVAR OUT_REFREEZE +OUTVAR OUT_RUNOFF +OUTVAR OUT_SNOW_MELT +OUTVAR OUT_SNOWF +OUTVAR OUT_SUB_BLOWING +OUTVAR OUT_SUB_CANOP +OUTVAR OUT_SUB_SNOW +OUTVAR OUT_SUB_SURFACE +OUTVAR OUT_TRANSP_VEG +OUTVAR OUT_ALBEDO +OUTVAR OUT_BARESOILT +OUTVAR OUT_FDEPTH +OUTVAR OUT_LAKE_ICE_TEMP +OUTVAR OUT_LAKE_SURF_TEMP +OUTVAR OUT_RAD_TEMP +OUTVAR OUT_SALBEDO +OUTVAR OUT_SNOW_PACK_TEMP +OUTVAR OUT_SNOW_SURF_TEMP +OUTVAR OUT_SNOWT_FBFLAG +OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_SOIL_TNODE +OUTVAR OUT_SOIL_TNODE_WL +OUTVAR OUT_SOILT_FBFLAG +OUTVAR OUT_SURF_TEMP +OUTVAR OUT_SURFT_FBFLAG +OUTVAR OUT_TCAN_FBFLAG +OUTVAR OUT_TDEPTH +OUTVAR OUT_TFOL_FBFLAG +OUTVAR OUT_VEGT +OUTVAR OUT_ADV_SENS +OUTVAR OUT_ADVECTION +OUTVAR OUT_DELTACC +OUTVAR OUT_DELTAH +OUTVAR OUT_ENERGY_ERROR +OUTVAR OUT_WATER_ERROR +OUTVAR OUT_FUSION +OUTVAR OUT_GRND_FLUX +OUTVAR OUT_IN_LONG +OUTVAR OUT_LATENT +OUTVAR OUT_LATENT_SUB +OUTVAR OUT_MELT_ENERGY +OUTVAR OUT_LWNET +OUTVAR OUT_SWNET +OUTVAR OUT_R_NET +OUTVAR OUT_RFRZ_ENERGY +OUTVAR OUT_SENSIBLE +OUTVAR OUT_SNOW_FLUX +OUTVAR OUT_AERO_COND +OUTVAR OUT_AERO_COND1 +OUTVAR OUT_AERO_COND2 +OUTVAR OUT_AERO_RESIST +OUTVAR OUT_AERO_RESIST1 +OUTVAR OUT_AERO_RESIST2 +OUTVAR OUT_AIR_TEMP +OUTVAR OUT_CATM +OUTVAR OUT_DENSITY +OUTVAR OUT_FCANOPY +OUTVAR OUT_FDIR +OUTVAR OUT_LAI +OUTVAR OUT_LWDOWN +OUTVAR OUT_PAR +OUTVAR OUT_PRESSURE +OUTVAR OUT_QAIR +OUTVAR OUT_REL_HUMID +OUTVAR OUT_SWDOWN +OUTVAR OUT_SURF_COND +OUTVAR OUT_VP +OUTVAR OUT_VPD +OUTVAR OUT_WIND +OUTVAR OUT_APAR +OUTVAR OUT_GPP +OUTVAR OUT_RAUT +OUTVAR OUT_NPP +OUTVAR OUT_LITTERFALL +OUTVAR OUT_RHET +OUTVAR OUT_NEE +OUTVAR OUT_CLITTER +OUTVAR OUT_CINTER +OUTVAR OUT_CSLOW +OUTVAR OUT_ADV_SENS_BAND +OUTVAR OUT_ADV_SENS +OUTVAR OUT_ADVECTION_BAND +OUTVAR OUT_ALBEDO_BAND +OUTVAR OUT_DELTACC_BAND +OUTVAR OUT_GRND_FLUX_BAND +OUTVAR OUT_IN_LONG_BAND +OUTVAR OUT_LATENT_BAND +OUTVAR OUT_LATENT_SUB_BAND +OUTVAR OUT_MELT_ENERGY_BAND +OUTVAR OUT_LWNET_BAND +OUTVAR OUT_SWNET_BAND +OUTVAR OUT_RFRZ_ENERGY_BAND +OUTVAR OUT_SENSIBLE_BAND +OUTVAR OUT_SNOW_CANOPY_BAND +OUTVAR OUT_SNOW_COVER_BAND +OUTVAR OUT_SNOW_DEPTH_BAND +OUTVAR OUT_SNOW_FLUX_BAND +OUTVAR OUT_SNOW_MELT_BAND +OUTVAR OUT_SNOW_PACKT_BAND +OUTVAR OUT_SNOW_SURFT_BAND +OUTVAR OUT_SWE_BAND diff --git a/tests/system/global.classic.STEHE.multistream.txt b/tests/system/global.classic.STEHE.multistream.txt new file mode 100644 index 000000000..ddcd61c8d --- /dev/null +++ b/tests/system/global.classic.STEHE.multistream.txt @@ -0,0 +1,111 @@ +NLAYER 3 +NODES 3 +MODEL_STEPS_PER_DAY 24 +SNOW_STEPS_PER_DAY 24 +RUNOFF_STEPS_PER_DAY 24 +STARTYEAR 1949 +STARTMONTH 01 +STARTDAY 01 +ENDYEAR 1949 +ENDMONTH 01 +ENDDAY 10 +FULL_ENERGY FALSE +FROZEN_SOIL FALSE + +#INIT_STATE +STATENAME $state_dir/states +STATEYEAR 1949 +STATEMONTH 1 +STATEDAY 10 +STATESEC 82800 +STATE_FORMAT ASCII + +FORCING1 $test_data_dir/classic/Stehekin/forcings/full_data_ +FORCE_FORMAT ASCII +FORCE_TYPE PREC +FORCE_TYPE AIR_TEMP +FORCE_TYPE SWDOWN +FORCE_TYPE LWDOWN +FORCE_TYPE SKIP # This column is air density, which is not needed by VIC +FORCE_TYPE PRESSURE +FORCE_TYPE VP +FORCE_TYPE WIND +FORCE_STEPS_PER_DAY 24 +FORCEYEAR 1949 +FORCEMONTH 01 +FORCEDAY 01 +GRID_DECIMAL 4 +WIND_H 10.0 + +SOIL $test_data_dir/classic/Stehekin/parameters/Stehekin_soil.txt +BASEFLOW ARNO +JULY_TAVG_SUPPLIED FALSE +ORGANIC_FRACT FALSE +VEGLIB $test_data_dir/classic/Stehekin/parameters/Stehekin_veglib.txt +VEGPARAM $test_data_dir/classic/Stehekin/parameters/Stehekin_vegparam.txt +ROOT_ZONES 3 +VEGPARAM_LAI TRUE +LAI_SRC FROM_VEGPARAM +SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt + +RESULT_DIR $result_dir + +# Instantaneous output +OUTFILE STREAM_NSTEPS_1 +AGGFREQ NSTEPS 1 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_BEG +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_PRESSURE * * * AGG_TYPE_BEG +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_BEG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_BEG + +# Output every 7200 seconds +OUTFILE STREAM_NSECONDS_7200 +AGGFREQ NSECONDS 7200 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_MAX +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_MIN +OUTVAR OUT_PRESSURE * * * AGG_TYPE_SUM +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_AVG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_END + +# Output every 180 minutes (3 hours) +OUTFILE STREAM_NMINUTES_180 +AGGFREQ NMINUTES 180 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_MAX +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_MIN +OUTVAR OUT_PRESSURE * * * AGG_TYPE_SUM +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_AVG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_END + +# Output every 4 hours +OUTFILE STREAM_NHOURS_4 +AGGFREQ NHOURS 4 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_MAX +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_MIN +OUTVAR OUT_PRESSURE * * * AGG_TYPE_SUM +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_AVG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_END + +# Output every 1 day +OUTFILE STREAM_NDAYS_1 +AGGFREQ NDAYS 1 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_MAX +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_MIN +OUTVAR OUT_PRESSURE * * * AGG_TYPE_SUM +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_AVG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_END + +# Output every 2 days +OUTFILE STREAM_NDAYS_2 +AGGFREQ NDAYS 2 +OUTVAR OUT_ALBEDO * * * AGG_TYPE_MAX +OUTVAR OUT_SOIL_TEMP * * * AGG_TYPE_MIN +OUTVAR OUT_PRESSURE * * * AGG_TYPE_SUM +OUTVAR OUT_AIR_TEMP * * * AGG_TYPE_BEG +OUTVAR OUT_SWDOWN * * * AGG_TYPE_AVG +OUTVAR OUT_LWDOWN * * * AGG_TYPE_END diff --git a/tests/system/global.classic.STEHE.restart.FROZEN_SOIL.txt b/tests/system/global.classic.STEHE.restart.FROZEN_SOIL.txt index fed0eba04..61bba6191 100644 --- a/tests/system/global.classic.STEHE.restart.FROZEN_SOIL.txt +++ b/tests/system/global.classic.STEHE.restart.FROZEN_SOIL.txt @@ -49,17 +49,10 @@ VEGPARAM_LAI TRUE LAI_SRC FROM_VEGPARAM SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt -RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE +RESULT_DIR $result_dir OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/global.classic.STEHE.restart.txt b/tests/system/global.classic.STEHE.restart.txt index f2d2447bc..ab1b31ae8 100644 --- a/tests/system/global.classic.STEHE.restart.txt +++ b/tests/system/global.classic.STEHE.restart.txt @@ -50,16 +50,9 @@ LAI_SRC FROM_VEGPARAM SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/global.classic.STEHE.txt b/tests/system/global.classic.STEHE.txt index c4c2ba8fa..6be855e96 100644 --- a/tests/system/global.classic.STEHE.txt +++ b/tests/system/global.classic.STEHE.txt @@ -49,16 +49,9 @@ LAI_SRC FROM_VEGPARAM SNOW_BAND 5 $test_data_dir/classic/Stehekin/parameters/Stehekin_snowbands.txt RESULT_DIR $result_dir -OUTPUT_STEPS_PER_DAY 0 -SKIPYEAR 0 -COMPRESS FALSE -OUT_FORMAT ASCII -ALMA_OUTPUT FALSE -MOISTFRACT FALSE -PRT_HEADER TRUE -PRT_SNOW_BAND FALSE OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt index fd6139018..57849869b 100644 --- a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt +++ b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt @@ -45,14 +45,13 @@ ORGANIC_FRACT FALSE VEGLIB $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc VEGPARAM $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc ROOT_ZONES 3 -VEGPARAM_LAI TRUE LAI_SRC FROM_VEGPARAM SNOW_BAND 1 $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -RESULT_DIR $result_dir/Stehekin.history.nc -OUTPUT_STEPS_PER_DAY 24 +RESULT_DIR $result_dir OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/global.image.STEHE.restart.txt b/tests/system/global.image.STEHE.restart.txt index 680b08485..761f5ca98 100644 --- a/tests/system/global.image.STEHE.restart.txt +++ b/tests/system/global.image.STEHE.restart.txt @@ -45,14 +45,13 @@ ORGANIC_FRACT FALSE VEGLIB $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc VEGPARAM $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc ROOT_ZONES 3 -VEGPARAM_LAI TRUE LAI_SRC FROM_VEGPARAM SNOW_BAND 1 $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -RESULT_DIR $result_dir/Stehekin.history.nc -OUTPUT_STEPS_PER_DAY 24 +RESULT_DIR $result_dir OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/global.image.STEHE.txt b/tests/system/global.image.STEHE.txt index 7bc3b23fa..8ef5326cf 100644 --- a/tests/system/global.image.STEHE.txt +++ b/tests/system/global.image.STEHE.txt @@ -29,7 +29,7 @@ FORCE_TYPE AIR_TEMP tas FORCE_TYPE PREC prcp FORCE_TYPE PRESSURE pres FORCE_TYPE SWDOWN dswrf -FORCE_TYPE LWDOWN dlwrf +FORCE_TYPE LWDOWN dlwrf FORCE_TYPE VP shum FORCE_TYPE WIND wind WIND_H 10.0 @@ -41,10 +41,10 @@ ROOT_ZONES 3 VEGLIB $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc SNOW_BAND 1 $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -RESULT_DIR $result_dir/Stehekin.history.nc -OUTPUT_STEPS_PER_DAY 24 +RESULT_DIR $result_dir/ OUTFILE fluxes +AGGFREQ NHOURS 1 OUTVAR OUT_PREC OUTVAR OUT_RAINF OUTVAR OUT_SNOWF diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 96b375783..dd88c4955 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -198,5 +198,16 @@ FULL_ENERGY=TRUE FROZEN_SOIL=TRUE NODES=10 +[System-streams_classic_compare_to_instantaneous] +test_description = Test that the stream averaging is working expected. +driver = classic +global_parameter_file = global.classic.STEHE.multistream.txt +expected_retval = 0 +check = multistream - +[System-streams_classic_all_output_vars] +test_description = Test that all output variables can be successfully written to a stream +driver = classic +global_parameter_file = global.classic.STEHE.allhistvars.txt +expected_retval = 0 +check = nonans diff --git a/tests/test_image_driver.py b/tests/test_image_driver.py index c9f183498..3be2ddc2f 100644 --- a/tests/test_image_driver.py +++ b/tests/test_image_driver.py @@ -11,8 +11,8 @@ def test_image_driver_no_output_file_nans(fnames, domain_file): Test that all VIC image driver output files have the same nan structure as the domain file ''' + ds_domain = xr.open_dataset(domain_file) for fname in fnames: - ds_domain = xr.open_dataset(domain_file) ds_output = xr.open_dataset(fname) assert_nan_equal(ds_domain, ds_output) @@ -34,7 +34,7 @@ def assert_nan_equal(ds_domain, ds_output): npt.assert_allclose(ds_output[var], ds_domain[var], equal_nan=True) # check that nans are occurring in the same place in the arrays - # --- check all variables in the dataset ---# + # check all variables in the dataset for da in ds_output.data_vars: # get dimensions to reduce DataArray on dim_diff = set(ds_domain['mask'].dims).symmetric_difference( diff --git a/tests/test_restart.py b/tests/test_restart.py index b25243f69..7501ce825 100644 --- a/tests/test_restart.py +++ b/tests/test_restart.py @@ -7,6 +7,7 @@ import glob import xarray as xr from test_utils import read_vic_ascii +from tonic.testing import VICTestError def prepare_restart_run_periods(restart_dict, state_basedir, statesec): @@ -226,7 +227,7 @@ def check_exact_restart_fluxes(result_basedir, driver, run_periods): # --- a dict of flux at each grid cell, keyed by flux basename ---# dict_df_full_run = {} for fname in glob.glob(os.path.join(result_dir, '*')): - df = read_vic_ascii(fname, header=True) + df = read_vic_ascii(fname) dict_df_full_run[os.path.basename(fname)] = df elif driver == 'image': if len(glob.glob(os.path.join(result_dir, '*.nc'))) > 1: @@ -253,16 +254,15 @@ def check_exact_restart_fluxes(result_basedir, driver, run_periods): for flux_basename in dict_df_full_run.keys(): # Read in flux data fname = os.path.join(result_dir, flux_basename) - df = read_vic_ascii(fname, header=True) + df = read_vic_ascii(fname) # Extract the same period from the full run df_full_run_split_period =\ - dict_df_full_run[flux_basename].truncate( - before=start_date, - after=end_date) + dict_df_full_run[flux_basename].truncate(df.index[0], df.index[-1]) # Compare split run fluxes with full run np.testing.assert_almost_equal(df.values, df_full_run_split_period.values, - decimal=6) + decimal=6, + err_msg='fluxes are not a close match') elif driver == 'image': # Read in flux data if len(glob.glob(os.path.join(result_dir, '*.nc'))) > 1: @@ -277,7 +277,8 @@ def check_exact_restart_fluxes(result_basedir, driver, run_periods): # Compare split run fluxes with full run for var in ds_full_run.data_vars: np.testing.assert_array_equal( - ds[var].values, ds_full_run_split_period[var].values) + ds[var].values, ds_full_run_split_period[var].values, + err_msg='Fluxes are not an exact match') def check_exact_restart_states(state_basedir, driver, run_periods, statesec, @@ -346,7 +347,8 @@ def check_exact_restart_states(state_basedir, driver, run_periods, statesec, # Compare split run states with full run # --- If ASCII state file, check if almost the same ---# if state_format == 'ASCII': - np.testing.assert_almost_equal(states, states_full_run, decimal=3) + np.testing.assert_almost_equal(states, states_full_run, decimal=3, + err_msg='States are not a close match') # --- If BINARY state file, check if exactly the same ---# elif state_format == 'BINARY': if states != states_full_run: @@ -365,7 +367,8 @@ def check_exact_restart_states(state_basedir, driver, run_periods, statesec, # Compare split run states with full run for var in ds_states.data_vars: np.testing.assert_array_equal(ds_states[var].values, - ds_states_full_run[var].values) + ds_states_full_run[var].values, + err_msg='states are not an exact match') def read_ascii_state(state_fname): diff --git a/tests/test_utils.py b/tests/test_utils.py index 486b914cc..e802eb0e8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -3,7 +3,10 @@ import os from collections import OrderedDict -import string + +import traceback + +import numpy as np import pandas as pd from tonic.models.vic.vic import (VICRuntimeError, @@ -42,11 +45,18 @@ def print_test_dict(d): print('{0: <48} | {1: <6} | {2}'.format('Test Name', 'Passed', 'Comment')) print('-'.ljust(OUTPUT_WIDTH, '-')) for k, v in d.items(): - print('{0: <48} | {1: <6} | {2}'.format(v.name, str(bool(v.passed)), + print('{0: <48} | {1: <6} | {2}'.format(clip_string(v.name, 48), + str(bool(v.passed)), v.comment)) print('-'.ljust(OUTPUT_WIDTH, '-')) +def clip_string(string, length=50): + if len(string) > length: + string = string[:length - 3] + '...' + return string + + def print_tail(string, n=20, indent='\t--->'): '''print tail of multiline string''' lines = string.decode().splitlines() @@ -101,38 +111,39 @@ def pop_run_kwargs(config): return run_kwargs -def check_returncode(returncode, expected=0): +def check_returncode(exe, expected=0): '''check return code given by VIC, raise error if appropriate''' - if returncode == expected: + if exe.returncode == expected: return None - elif returncode == default_vic_valgrind_error_code: - raise VICValgrindError('Valgrind raised an error') + elif exe.returncode == default_vic_valgrind_error_code: + raise VICValgrindError( + 'Valgrind raised an error when running: "{}"'.format(exe.argstring)) else: - raise VICReturnCodeError('VIC return code ({0}) does not match ' - 'expected ({1})'.format(returncode, expected)) + raise VICReturnCodeError( + 'VIC return code ({0}) did not match expected ({1}) when running ' + '"{2}"'.format(exe.returncode, expected, exe.argstring)) def process_error(error, vic_exe): '''Helper function to process possible error raised during testing''' + tail = None if isinstance(error, VICRuntimeError): test_comment = 'Test failed during simulation' - error_message = error tail = vic_exe.stderr elif isinstance(error, VICTestError): test_comment = 'Test failed during testing of output files' - error_message = error - tail = None elif isinstance(error, VICValgrindError): test_comment = 'Test failed due to memory error detected by valgrind' - error_message = error tail = vic_exe.stderr elif isinstance(error, VICReturnCodeError): test_comment = 'Test failed due to incorrect return code' - error_message = error tail = vic_exe.stderr + elif isinstance(error, AssertionError): + test_comment = 'AssertionError raised during testing' else: raise error - + error_message = error + traceback.print_stack() print('\t{0}'.format(test_comment)) print('\t{0}'.format(error_message)) if tail is not None: @@ -150,7 +161,7 @@ def test_classic_driver_all_complete(fnames): start = None end = None for fname in fnames: - df = read_vic_ascii(fname, header=True) + df = read_vic_ascii(fname) # check that each dataframe includes all timestamps if (start is not None) and (end is not None): @@ -163,14 +174,13 @@ def test_classic_driver_all_complete(fnames): def test_classic_driver_no_output_file_nans(fnames): '''Test that all VIC classic driver output files in fnames have no nans''' for fname in fnames: - df = read_vic_ascii(fname, header=True) + df = read_vic_ascii(fname) check_for_nans(df) -# TODO: Update tonic version of this function, need to check that subdaily -# works -def read_vic_ascii(filepath, header=True, parse_dates=True, - datetime_index=None, names=None, **kwargs): +# TODO: Update tonic version of this function, need to check that subdaily works +def read_vic_ascii(filepath, parse_dates=True, datetime_index=None, sep='\t', + comment='#', **kwargs): '''Generic reader function for VIC ASCII output with a standard header filepath: path to VIC output file header (True or False): Standard VIC header is present @@ -180,32 +190,22 @@ def read_vic_ascii(filepath, header=True, parse_dates=True, **kwargs: passed to Pandas.read_table returns Pandas.DataFrame ''' - kwargs['header'] = None - - if header: - kwargs['skiprows'] = 4 - # get names - if names is None: - with open(filepath) as f: - # skip lines 0 through 3 - for _ in range(3): - next(f) + df = pd.read_table(filepath, sep=sep, comment=comment, **kwargs) + # Strip extra whitespace around variable names + df.rename(columns=lambda x: x.strip(), inplace=True) - # process header - names = next(f) - names = names.strip('#').replace('OUT_', '').split() - - kwargs['names'] = names + if parse_dates and datetime_index: + raise ValueError('cannot specify both parse_dates and datetime_index') if parse_dates: time_cols = ['YEAR', 'MONTH', 'DAY'] - if 'SECONDS' in names: - time_cols.append('SECONDS') - kwargs['parse_dates'] = {'datetime': time_cols} - kwargs['index_col'] = 0 - - df = pd.read_table(filepath, **kwargs) + df.index = pd.to_datetime(df[time_cols]) + if 'SEC' in df: + df.index += pd.Series([pd.Timedelta(s, unit='s') for s in df['SEC']], + index=df.index) + time_cols.append('SEC') + df.drop(time_cols, axis=1) if datetime_index is not None: df.index = datetime_index @@ -236,5 +236,73 @@ def find_global_param_value(gp, param_name): if key == param_name: return line_list[1] -if __name__ == '__main__': - main() + +def check_multistream(fnames, driver): + ''' + + ''' + + if driver.lower() != 'classic': + raise ValueError('only classic driver is supported in this test') + + how_dict = {'OUT_ALBEDO': 'max', + 'OUT_SOIL_TEMP_1': 'min', + 'OUT_PRESSURE': 'sum', + 'OUT_AIR_TEMP': 'first', + 'OUT_SWDOWN': 'mean', + 'OUT_LWDOWN': 'last'} + + streams = {} # Dictionary to store parsed stream names + gridcells = [] # list of gridcells (lat_lon) + + for path in fnames: + # split up the path name to get info about the stream + resultdir, fname = os.path.split(path) + pieces = os.path.splitext(fname)[0].split('_') + gridcells.append('_'.join(pieces[-2:])) + stream = '_'.join(pieces[:-2]) # stream name + freq_n = pieces[-3] # stream frequency n + + # set the stream frequency for pandas resample + if 'NSTEPS' in stream: + inst_stream = stream + else: + if 'NDAYS' in stream: + streams[stream] = '{}D'.format(freq_n) + elif 'NHOURS' in stream: + streams[stream] = '{}H'.format(freq_n) + elif 'NMINUTES' in stream: + streams[stream] = '{}min'.format(freq_n) + elif 'NSECONDS' in stream: + streams[stream] = '{}S'.format(freq_n) + else: + ValueError('stream %s not supported in this test' % stream) + + # unique gridcells + gridcells = list(set(gridcells)) + + # Loop over all grid cells in result dir + for gridcell in gridcells: + fname = os.path.join(resultdir, '{}_{}.txt'.format(inst_stream, gridcell)) + instant_df = read_vic_ascii(fname) + + # Loop over all streams + for stream, freq in streams.items(): + fname = os.path.join(resultdir, '{}_{}.txt'.format(stream, gridcell)) + agg_df = read_vic_ascii(fname) + + # Setup the resample of the instantaneous data + rs = instant_df.resample(freq) + + # Loop over the variables in the stream + for key, how in how_dict.items(): + # Get the aggregated values (from VIC) + actual = agg_df[key].values + # Calculated the expected values based on the resampling from pandas + expected = rs[key].aggregate(how).values + + # Compare the actual and expected (with tolerance) + np.testing.assert_almost_equal( + actual, expected, decimal=4, + err_msg='Variable=%s, freq=%s, how=%s: ' + 'failed comparison' % (key, freq, how)) diff --git a/tests/unit/shared/test_initialize_global.py b/tests/unit/shared/test_initialize_global.py index 9bd80f7e6..6657ee35d 100644 --- a/tests/unit/shared/test_initialize_global.py +++ b/tests/unit/shared/test_initialize_global.py @@ -4,4 +4,3 @@ def test_initialize_global(): assert vic_lib.initialize_global() is None assert vic_lib.global_param.dt == -99999 - assert vic_lib.global_param.out_dt == 86400 diff --git a/tests/unit/shared/test_initialize_options.py b/tests/unit/shared/test_initialize_options.py index 9aebd2b94..6c454fc66 100644 --- a/tests/unit/shared/test_initialize_options.py +++ b/tests/unit/shared/test_initialize_options.py @@ -9,4 +9,4 @@ def test_initialize_options(): def test_initialize_options_bools(): assert vic_lib.initialize_options() is None assert not vic_lib.options.BLOWING - assert not vic_lib.options.PRT_SNOW_BAND + assert vic_lib.options.TFALLBACK diff --git a/tests/unit/shared/test_input_tools.py b/tests/unit/shared/test_input_tools.py new file mode 100644 index 000000000..2db57b442 --- /dev/null +++ b/tests/unit/shared/test_input_tools.py @@ -0,0 +1,82 @@ +from vic import lib as vic_lib + + +def test_str_to_bool(): + for s, expected in [('TRUE', True), ('FALSE', False), + ('true', True), ('false', False), + ('TrUe', True), ('FaLsE', False)]: + assert vic_lib.str_to_bool(s.encode()) == expected + + +def test_str_to_agg_type(): + assert vic_lib.str_to_agg_type(''.encode()) == vic_lib.AGG_TYPE_DEFAULT + assert vic_lib.str_to_agg_type('*'.encode()) == vic_lib.AGG_TYPE_DEFAULT + for s in ['AGG_TYPE_AVG', 'AGG_TYPE_BEG', 'AGG_TYPE_END', + 'AGG_TYPE_MAX', 'AGG_TYPE_MIN', 'AGG_TYPE_SUM']: + expected = getattr(vic_lib, s) + assert vic_lib.str_to_agg_type(s.encode()) == expected + assert vic_lib.str_to_agg_type(s.lower().encode()) == expected + + +def test_str_to_out_type(): + assert vic_lib.str_to_out_type(''.encode()) == vic_lib.OUT_TYPE_DEFAULT + assert vic_lib.str_to_out_type('*'.encode()) == vic_lib.OUT_TYPE_DEFAULT + for s in ['OUT_TYPE_USINT', 'OUT_TYPE_SINT', 'OUT_TYPE_FLOAT', + 'OUT_TYPE_DOUBLE']: + expected = getattr(vic_lib, s) + assert vic_lib.str_to_out_type(s.encode()) == expected + assert vic_lib.str_to_out_type(s.lower().encode()) == expected + + +def test_str_to_out_mult(): + assert vic_lib.str_to_out_mult(''.encode()) == 0 + assert vic_lib.str_to_out_mult('*'.encode()) == 0 + for mult in range(0, 10000, 100): + assert vic_lib.str_to_out_mult(str(mult).encode()) == float(mult) + + +def test_str_to_freq_flag(): + for s in ['NEVER', 'NSTEPS', 'NSECONDS', 'NMINUTES', 'NHOURS', 'NDAYS', + 'NMONTHS', 'NYEARS', 'DATE', 'END']: + expected = getattr(vic_lib, 'FREQ_{}'.format(s)) + assert vic_lib.str_to_freq_flag(s.encode()) == expected + assert vic_lib.str_to_freq_flag(s.lower().encode()) == expected + + +def test_str_to_ascii_format(): + # TODO: figure out the best way to pass a mutable string to ffi + pass + + +def test_str_to_calendar(): + for s in ['STANDARD', 'GREGORIAN', 'PROLEPTIC_GREGORIAN', 'NOLEAP', + '365_DAY', '360_DAY', 'JULIAN', 'ALL_LEAP', '366_DAY']: + expected = getattr(vic_lib, 'CALENDAR_{}'.format(s)) + assert vic_lib.str_to_calendar(s.encode()) == expected + assert vic_lib.str_to_calendar(s.lower().encode()) == expected + # NOLEAP calendar has an alternate spelling + # s = 'CALENDAR_NO_LEAP' + # assert vic_lib.str_to_calendar(s.encode()) == vic_lib.CALENDAR_NOLEAP + # assert vic_lib.str_to_calendar(s.lower().encode()) == vic_lib.CALENDAR_NOLEAP + + +def test_str_to_timeunits(): + for s in ['SECONDS', 'MINUTES', 'HOURS', 'DAYS']: + expected = getattr(vic_lib, 'TIME_UNITS_{}'.format(s)) + assert vic_lib.str_to_timeunits(s.encode()) == expected + assert vic_lib.str_to_timeunits(s.lower().encode()) == expected + + +def test_str_from_time_units(): + # TODO: figure out the best way to pass a mutable string to ffi + pass + + +def test_str_from_calendar(): + # TODO: figure out the best way to pass a mutable string to ffi + pass + + +def test_cell_method_from_agg_type(): + # TODO: figure out the best way to pass a mutable string to ffi + pass diff --git a/tests/unit/shared/test_vic_time.py b/tests/unit/shared/test_vic_time.py index e93b9f9ab..caba01dfe 100644 --- a/tests/unit/shared/test_vic_time.py +++ b/tests/unit/shared/test_vic_time.py @@ -32,6 +32,18 @@ 'minutes': vic_lib.TIME_UNITS_MINUTES, 'seconds': vic_lib.TIME_UNITS_SECONDS} + +freqs = {'never': vic_lib.FREQ_NEVER, + 'steps': vic_lib.FREQ_NSTEPS, + 'seconds': vic_lib.FREQ_NSECONDS, + 'minutes': vic_lib.FREQ_NMINUTES, + 'hours': vic_lib.FREQ_NHOURS, + 'days': vic_lib.FREQ_NDAYS, + 'months': vic_lib.FREQ_NMONTHS, + 'years': vic_lib.FREQ_NYEARS, + 'date': vic_lib.FREQ_DATE, + 'end': vic_lib.FREQ_END} + vic_default_units = 'days since 0001-01-01' @@ -286,11 +298,9 @@ def test_dt_seconds_to_time_units(): def test_calendar_from_chars(): for cal, expected in calendars.items(): - actual = vic_lib.calendar_from_chars(ffi.new('char[]', cal.lower().encode())) - assert actual == expected - - actual = vic_lib.calendar_from_chars(ffi.new('char[]', cal.upper().encode())) - assert actual == expected + assert vic_lib.str_to_calendar(cal.encode()) == expected + assert vic_lib.str_to_calendar(cal.upper().encode()) == expected + assert vic_lib.str_to_calendar(cal.lower().encode()) == expected def timeunits_from_chars(): @@ -311,3 +321,56 @@ def test_parse_nc_time_units(): assert actual_dmy[0].month == 1 assert actual_dmy[0].day == 1 assert actual_dmy[0].dayseconds == 0 + + +def test_timedelta(): + + dmy = ffi.new('dmy_struct *') + dmy[0].year = 2015 + dmy[0].month = 1 + dmy[0].day = 1 + dmy[0].dayseconds = 0 + dmy[0].day_in_year = 1 + + # First check the easy (sub)daily time deltas + for n in range(1, 61, 5): + for freq in ['seconds', 'minutes', 'hours', 'days']: + print(freq, freqs[freq], n) + expected = pd.Timedelta(**{freq: n}).total_seconds() / 86400. + actual = vic_lib.time_delta(dmy, freqs[freq], n) # [days] + np.testing.assert_allclose(actual, expected) + + # Now, spot check a few of the harder ones + vic_lib.global_param.calendar = calendars['standard'] + actual = vic_lib.time_delta(dmy, freqs['months'], 1) + assert actual == 31 + + vic_lib.global_param.calendar = calendars['noleap'] + actual = vic_lib.time_delta(dmy, freqs['years'], 1) + assert actual == 365 + + vic_lib.global_param.calendar = calendars['all_leap'] + actual = vic_lib.time_delta(dmy, freqs['years'], 1) + assert actual == 366 + + +def test_dmy_equal(): + dmy1 = datetime_to_dmy(datetime.datetime(2015, 12, 12, 8)) + dmy2 = datetime_to_dmy(datetime.datetime(2015, 12, 12, 8)) + assert vic_lib.dmy_equal(dmy1, dmy2) + + dmy2 = datetime_to_dmy(datetime.datetime(2014, 12, 12, 8)) + assert not vic_lib.dmy_equal(dmy1, dmy2) + + +def test_strpdmy(): + dmy = ffi.new("dmy_struct *") + + dates = pd.date_range('2015-12-18', '2016-12-22', freq='1D') + date_format = '%Y-%m-%d' + for date in dates: + date_str = date.strftime(date_format) + vic_lib.strpdmy(date_str.encode(), date_format.encode(), dmy) + expected = date.to_datetime() + actual = dmy_to_datetime(dmy) + assert abs(expected - actual) < datetime.timedelta(seconds=1) diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index 1a9c89584..f39097064 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -165,8 +165,6 @@ void initialize_l2x_data(void); void initialize_vic_cesm_mpi(MPI_Fint *MPI_COMM_VIC_F); void initialize_x2l_data(void); void make_dummy_forcings(x2l_data_struct *x2l); -FILE *open_file(char *string, char *type); -int parse_output_info(FILE *gp, out_data_struct **out_data); void print_case_metadata(case_metadata *cmeta); void print_l2x_data(l2x_data_struct *l2x); void print_vic_clock(vic_clock *vclock); diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 1cc6a2752..d3bd5de6b 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -46,25 +46,27 @@ MPI_Datatype mpi_domain_struct_type; MPI_Datatype mpi_global_struct_type; MPI_Datatype mpi_filenames_struct_type; MPI_Datatype mpi_location_struct_type; -MPI_Datatype mpi_nc_file_struct_type; +MPI_Datatype mpi_alarm_struct_type; MPI_Datatype mpi_option_struct_type; MPI_Datatype mpi_param_struct_type; int *mpi_map_local_array_sizes = NULL; int *mpi_map_global_array_offsets = NULL; int mpi_rank; int mpi_size; -nc_file_struct nc_hist_file; -nc_var_struct nc_vars[N_OUTVAR_TYPES]; option_struct options; parameters_struct param; -out_data_struct **out_data; -save_data_struct *save_data; param_set_struct param_set; soil_con_struct *soil_con = NULL; veg_con_map_struct *veg_con_map = NULL; veg_con_struct **veg_con = NULL; veg_hist_struct **veg_hist = NULL; veg_lib_struct **veg_lib = NULL; +metadata_struct state_metadata[N_STATE_VARS]; +metadata_struct out_metadata[N_OUTVAR_TYPES]; +save_data_struct *save_data; // [ncells] +double ***out_data = NULL; // [ncells, nvars, nelem] +stream_struct *output_streams = NULL; // [nstreams] +nc_file_struct *nc_hist_files = NULL; // [nstreams] /****************************************************************************** * @brief Initialization function for CESM driver @@ -89,9 +91,9 @@ vic_cesm_init(vic_clock *vclock, vic_populate_model_state(trim(cmeta->starttype)); // initialize output structures - vic_init_output(); + vic_init_output(&dmy_current); - return 0; + return EXIT_SUCCESS; } /****************************************************************************** @@ -112,14 +114,11 @@ vic_cesm_run(vic_clock *vclock) // return fields to coupler vic_cesm_put_data(); - // if output: - if (check_write_flag(current)) { - vic_write(&dmy_current); - } + // Write history files + vic_write_output(&dmy_current); // if save: if (vclock->state_flag) { - log_warn("Skipping state file write"); vic_store(&dmy_current); } @@ -130,7 +129,7 @@ vic_cesm_run(vic_clock *vclock) advance_time(); assert_time_insync(vclock, &dmy_current); - return 0; + return EXIT_SUCCESS; } /****************************************************************************** @@ -142,5 +141,5 @@ vic_cesm_final() // clean up vic_cesm_finalize(); - return 0; + return EXIT_SUCCESS; } diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 4468ac873..27c1c540b 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -411,50 +411,5 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Output Data:\n"); fprintf(LOG_DEST, "Result dir:\t\t%s\n", filenames.result_dir); - fprintf(LOG_DEST, "OUT_STEP\t\t%f\n", global_param.out_dt); - if (options.ALMA_OUTPUT) { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tFALSE\n"); - } - - if (options.OUT_FORMAT == NETCDF3_CLASSIC) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF3_CLASSIC\n"); - } - else if (options.OUT_FORMAT == NETCDF3_64BIT_OFFSET) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF3_64BIT_OFFSET\n"); - } - else if (options.OUT_FORMAT == NETCDF4_CLASSIC) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF4_CLASSIC\n"); - } - else if (options.OUT_FORMAT == NETCDF4) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF4\n"); - } - if (options.COMPRESS) { - fprintf(LOG_DEST, "COMPRESS\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "COMPRESS\t\tFALSE\n"); - } - if (options.MOISTFRACT) { - fprintf(LOG_DEST, "MOISTFRACT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "MOISTFRACT\t\tFALSE\n"); - } - if (options.PRT_HEADER) { - fprintf(LOG_DEST, "PRT_HEADER\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_HEADER\t\tFALSE\n"); - } - if (options.PRT_SNOW_BAND) { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tFALSE\n"); - } - fprintf(LOG_DEST, "SKIPYEAR\t\t%d\n", global_param.skipyear); fprintf(LOG_DEST, "\n"); } diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 83ee4f007..b833144ac 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -70,161 +70,87 @@ get_global_param(FILE *gp) } else if (strcasecmp("OUT_TIME_UNITS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("SECONDS", flgstr) == 0) { - global_param.time_units = TIME_UNITS_SECONDS; - } - else if (strcasecmp("MINUTES", flgstr) == 0) { - global_param.time_units = TIME_UNITS_MINUTES; - } - else if (strcasecmp("HOURS", flgstr) == 0) { - global_param.time_units = TIME_UNITS_HOURS; - } - else if (strcasecmp("DAYS", flgstr) == 0) { - global_param.time_units = TIME_UNITS_DAYS; - } - else { - log_err("Unknown time units specified: %s", flgstr); - } + global_param.time_units = str_to_timeunits(flgstr); } else if (strcasecmp("FROZEN_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.FROZEN_SOIL = true; + options.FROZEN_SOIL = str_to_bool(flgstr); + // TODO: move these steps to a option validation + if (options.FROZEN_SOIL) { options.QUICK_FLUX = false; } else { - options.FROZEN_SOIL = false; options.IMPLICIT = false; options.EXP_TRANS = false; } } else if (strcasecmp("QUICK_FLUX", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_FLUX = true; - } - else { - options.QUICK_FLUX = false; - } + options.QUICK_FLUX = str_to_bool(flgstr); } else if (strcasecmp("QUICK_SOLVE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_SOLVE = true; - } - else { - options.QUICK_SOLVE = false; - } + options.QUICK_SOLVE = str_to_bool(flgstr); } else if ((strcasecmp("NOFLUX", optstr) == 0) || (strcasecmp("NO_FLUX", optstr) == 0)) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { - options.NOFLUX = true; - } - else { - options.NOFLUX = false; + options.NOFLUX = str_to_bool(flgstr); } } else if (strcasecmp("IMPLICIT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.IMPLICIT = true; - } - else { - options.IMPLICIT = false; - } + options.IMPLICIT = str_to_bool(flgstr); } else if (strcasecmp("EXP_TRANS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.EXP_TRANS = true; - } - else { - options.EXP_TRANS = false; - } + options.EXP_TRANS = str_to_bool(flgstr); } else if (strcasecmp("SNOW_DENSITY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("DENS_SNTHRM", flgstr) == 0) { options.SNOW_DENSITY = DENS_SNTHRM; } - else { + else if (strcasecmp("DENS_BRAS", flgstr) == 0) { options.SNOW_DENSITY = DENS_BRAS; } + else { + log_err("Unknown SNOW_DENSITY option: %s", flgstr); + } } else if (strcasecmp("BLOWING", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING = true; - } - else { - options.BLOWING = false; - } + options.BLOWING = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_VAR_THRESHOLD", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_VAR_THRESHOLD = true; - } - else { - options.BLOWING_VAR_THRESHOLD = false; - } + options.BLOWING_VAR_THRESHOLD = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_CALC_PROB", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_CALC_PROB = true; - } - else { - options.BLOWING_CALC_PROB = false; - } + options.BLOWING_CALC_PROB = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SIMPLE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SIMPLE = true; - } - else { - options.BLOWING_SIMPLE = false; - } + options.BLOWING_SIMPLE = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_FETCH", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_FETCH = true; - } - else { - options.BLOWING_FETCH = false; - } + options.BLOWING_FETCH = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SPATIAL_WIND", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SPATIAL_WIND = true; - } - else { - options.BLOWING_SPATIAL_WIND = false; - } + options.BLOWING_SPATIAL_WIND = str_to_bool(flgstr); } else if (strcasecmp("CORRPREC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CORRPREC = true; - } - else { - options.CORRPREC = false; - } + options.CORRPREC = str_to_bool(flgstr); } else if (strcasecmp("CLOSE_ENERGY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CLOSE_ENERGY = true; - } - else { - options.CLOSE_ENERGY = false; - } + options.CLOSE_ENERGY = str_to_bool(flgstr); } else if (strcasecmp("COMPUTE_TREELINE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -250,6 +176,9 @@ get_global_param(FILE *gp) else if (strcasecmp("AR_410", flgstr) == 0) { options.AERO_RESIST_CANSNOW = AR_410; } + else { + log_err("Unknown AERO_RESIST_CANSNOW option: %s", flgstr); + } } else if (strcasecmp("GRND_FLUX_TYPE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -259,6 +188,9 @@ get_global_param(FILE *gp) else if (strcasecmp("GF_410", flgstr) == 0) { options.GRND_FLUX_TYPE = GF_410; } + else { + log_err("Unknown GRND_FLUX_TYPE option: %s", flgstr); + } } else if (strcasecmp("SPATIAL_FROST", optstr) == 0) { sscanf(cmdstr, "%*s %s %s", flgstr, flgstr2); @@ -272,51 +204,34 @@ get_global_param(FILE *gp) } else if (strcasecmp("SPATIAL_SNOW", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SPATIAL_SNOW = true; - } - else { - options.SPATIAL_SNOW = false; - } + options.SPATIAL_SNOW = str_to_bool(flgstr); } else if (strcasecmp("TFALLBACK", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.TFALLBACK = true; - } - else { - options.TFALLBACK = false; - } + options.TFALLBACK = str_to_bool(flgstr); } else if (strcasecmp("SHARE_LAYER_MOIST", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SHARE_LAYER_MOIST = true; - } - else { - options.SHARE_LAYER_MOIST = false; - } + options.SHARE_LAYER_MOIST = str_to_bool(flgstr); } else if (strcasecmp("CANOPY_LAYERS", optstr) == 0) { sscanf(cmdstr, "%*s %zu", &options.Ncanopy); } else if (strcasecmp("CARBON", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CARBON = true; - } - else { - options.CARBON = false; - } + options.CARBON = str_to_bool(flgstr); } else if (strcasecmp("RC_MODE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("RC_PHOTO", flgstr) == 0) { options.RC_MODE = RC_PHOTO; } - else { + else if (strcasecmp("RC_JARVIS", flgstr) == 0) { options.RC_MODE = RC_JARVIS; } + else { + log_err("Unknown RC_MODE option: %s", flgstr); + } } /************************************* @@ -390,39 +305,27 @@ get_global_param(FILE *gp) if (strcasecmp("NIJSSEN2001", flgstr) == 0) { options.BASEFLOW = NIJSSEN2001; } - else { + else if (strcasecmp("ARNO", flgstr) == 0) { options.BASEFLOW = ARNO; } + else { + log_err("Unknown BASEFLOW option: %s", flgstr); + } } else if (strcasecmp("JULY_TAVG_SUPPLIED", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.JULY_TAVG_SUPPLIED = false; - } - else { - options.JULY_TAVG_SUPPLIED = true; - } + options.JULY_TAVG_SUPPLIED = str_to_bool(flgstr); } else if (strcasecmp("ORGANIC_FRACT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.ORGANIC_FRACT = false; - } - else { - options.ORGANIC_FRACT = true; - } + options.ORGANIC_FRACT = str_to_bool(flgstr); } else if (strcasecmp("VEGLIB", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veglib); } else if (strcasecmp("VEGLIB_PHOTO", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGLIB_PHOTO = true; - } - else { - options.VEGLIB_PHOTO = false; - } + options.VEGLIB_PHOTO = str_to_bool(flgstr); } else if (strcasecmp("VEGPARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veg); @@ -490,12 +393,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("LAKE_PROFILE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.LAKE_PROFILE = false; - } - else { - options.LAKE_PROFILE = true; - } + options.LAKE_PROFILE = str_to_bool(flgstr); } /************************************* @@ -504,49 +402,6 @@ get_global_param(FILE *gp) else if (strcasecmp("RESULT_DIR", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.result_dir); } - else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { - sscanf(cmdstr, "%*s %zu", &global_param.output_steps_per_day); - } - else if (strcasecmp("SKIPYEAR", optstr) == 0) { - sscanf(cmdstr, "%*s %hu", &global_param.skipyear); - } - else if (strcasecmp("OUT_FORMAT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("NETCDF3_CLASSIC", flgstr) == 0) { - options.OUT_FORMAT = NETCDF3_CLASSIC; - } - else if (strcasecmp("NETCDF3_64BIT_OFFSET", flgstr) == 0) { - options.OUT_FORMAT = NETCDF3_64BIT_OFFSET; - } - else if (strcasecmp("NETCDF4_CLASSIC", flgstr) == 0) { - options.OUT_FORMAT = NETCDF4_CLASSIC; - } - else if (strcasecmp("NETCDF4", flgstr) == 0) { - options.OUT_FORMAT = NETCDF4; - } - else { - log_err("OUT_FORMAT must be either NETCDF3_CLASSIC, " - "NETCDF3_64BIT_OFFSET, NETCDF4_CLASSIC, or NETCDF4."); - } - } - else if (strcasecmp("ALMA_OUTPUT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.ALMA_OUTPUT = true; - } - else { - options.ALMA_OUTPUT = false; - } - } - else if (strcasecmp("MOISTFRACT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.MOISTFRACT = true; - } - else { - options.MOISTFRACT = false; - } - } /************************************* Define output file contents @@ -557,6 +412,18 @@ get_global_param(FILE *gp) else if (strcasecmp("OUTVAR", optstr) == 0) { ; // do nothing } + else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("SKIPYEAR", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("COMPRESS", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("OUT_FORMAT", optstr) == 0) { + ; // do nothing + } // vegetation history not yet implemented in image mode // TBD: feature in VIC 4.2 that has been ported to classic // mode, but that does not exist in image mode (yet) @@ -564,39 +431,7 @@ get_global_param(FILE *gp) strcasecmp("LAI_IN", optstr) == 0 || strcasecmp("FCANOPY", optstr) == 0) { log_err("Time-varying vegetation parameters not implemented " - "in image mode"); - } - - /************************************* - Fail when depreciated options are used. - *************************************/ - else if (strcasecmp("TIME_STEP", optstr) == 0) { - log_err("TIME_STEP has been replaced with MODEL_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("SNOW_STEP", optstr) == 0) { - log_err("SNOW_STEP has been replaced with SNOW_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("OUT_STEP", optstr) == 0) { - log_err("OUT_STEP has been replaced with OUTPUT_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("FORCE_DT", optstr) == 0) { - log_err("FORCE_DT has been replaced with FORCE_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - - /************************************* - Fail when classic driver specific options are used - *************************************/ - else if (strcasecmp("ATMOS_STEPS_PER_DAY", optstr) == 0) { - log_err("ATMOS_STEPS_PER_DAY is not a valid option for this " - "driver. Update your global parameter file accordingly."); - } - else if (strcasecmp("OUTPUT_FORCE", optstr) == 0) { - log_err("OUTPUT_FORCE is not a valid option for this driver. " - "Update your global parameter file accordingly."); + "in CESM driver"); } /*********************************** @@ -679,9 +514,6 @@ validate_global_param(global_param_struct *gp) if (gp->model_steps_per_day != gp->atmos_steps_per_day) { log_err("atmos_steps_per_day must match model_steps_per_day"); } - if (gp->model_steps_per_day != gp->output_steps_per_day) { - log_err("output_steps_per_day must match model_steps_per_day"); - } } /****************************************************************************** @@ -797,7 +629,4 @@ validate_options(option_struct *options) if (options->STATE_FORMAT == UNSET_FILE_FORMAT) { options->STATE_FORMAT = NETCDF3_CLASSIC; } - if (options->OUT_FORMAT == UNSET_FILE_FORMAT) { - options->OUT_FORMAT = NETCDF3_CLASSIC; - } } diff --git a/vic/drivers/cesm/src/vic_cesm_start.c b/vic/drivers/cesm/src/vic_cesm_start.c index 1db9095ea..3097fde1a 100644 --- a/vic/drivers/cesm/src/vic_cesm_start.c +++ b/vic/drivers/cesm/src/vic_cesm_start.c @@ -44,7 +44,7 @@ vic_cesm_start(vic_clock *vclock, initialize_global_structures(); // Driver specific settings - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { strcpy(filenames.global, GLOBALPARAM); // read global settings filep.globalparam = open_file(filenames.global, "r"); @@ -56,14 +56,12 @@ vic_cesm_start(vic_clock *vclock, global_param.snow_dt = (double) vclock->timestep; global_param.runoff_dt = (double) vclock->timestep; global_param.atmos_dt = (double) vclock->timestep; - global_param.out_dt = (double) vclock->timestep; global_param.model_steps_per_day = (int) ((double) SEC_PER_DAY / global_param.dt); global_param.snow_steps_per_day = global_param.model_steps_per_day; global_param.runoff_steps_per_day = global_param.model_steps_per_day; global_param.atmos_steps_per_day = global_param.model_steps_per_day; - global_param.output_steps_per_day = global_param.model_steps_per_day; // Start date/time global_param.startyear = vclock->current_year; @@ -73,7 +71,7 @@ vic_cesm_start(vic_clock *vclock, global_param.nrecs = 1; // Calendar - global_param.calendar = calendar_from_chars(trim(vclock->calendar)); + global_param.calendar = str_to_calendar(trim(vclock->calendar)); // set NR and NF NF = global_param.snow_steps_per_day / global_param.model_steps_per_day; if (NF == 1) { diff --git a/vic/drivers/classic/include/vic_driver_classic.h b/vic/drivers/classic/include/vic_driver_classic.h index 48b4f7cb5..5a21d311d 100644 --- a/vic/drivers/classic/include/vic_driver_classic.h +++ b/vic/drivers/classic/include/vic_driver_classic.h @@ -42,25 +42,22 @@ 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); +void close_files(filep_struct *filep, stream_struct **streams); void compute_cell_area(soil_con_struct *); -size_t count_outfile_nvars(FILE *gp); -out_data_struct *create_output_list(); void free_atmos(int nrecs, atmos_data_struct **atmos); -void free_out_data_files(out_data_file_struct **); void free_veg_hist(int nrecs, int nveg, veg_hist_struct ***veg_hist); void free_veglib(veg_lib_struct **); double get_dist(double lat1, double long1, double lat2, double long2); 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); -void make_in_and_outfiles(filep_struct *, filenames_struct *, soil_con_struct *, - out_data_file_struct *); +void make_in_and_outfiles(filep_struct *filep, filenames_struct *filenames, + soil_con_struct *soil, stream_struct **streams, + dmy_struct *dmy); FILE *open_state_file(global_param_struct *, filenames_struct, size_t, size_t); void print_atmos_data(atmos_data_struct *atmos, size_t nr); -void parse_output_info(FILE *, out_data_file_struct **, out_data_struct *); +void parse_output_info(FILE *gp, stream_struct **output_streams, + dmy_struct *dmy_current); void read_atmos_data(FILE *, global_param_struct, int, int, double **, double ***); double **read_forcing_data(FILE **, global_param_struct, double ****); @@ -71,21 +68,14 @@ void read_snowband(FILE *, soil_con_struct *); soil_con_struct read_soilparam(FILE *, char *, char *); veg_lib_struct *read_veglib(FILE *, size_t *); 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 *, - out_data_struct *, dmy_struct *); -void write_header(out_data_file_struct *, out_data_struct *, dmy_struct *, - global_param_struct); +void write_data(stream_struct *streams, dmy_struct *dmy); +void write_header(stream_struct **streams, dmy_struct *dmy); void write_model_state(all_vars_struct *, int, int, filep_struct *, soil_con_struct *); -void write_output(out_data_struct *out_data, - out_data_file_struct *out_data_files, dmy_struct *dmy, - int rec); +void write_output(stream_struct **streams, dmy_struct *dmy); #endif diff --git a/vic/drivers/classic/src/close_files.c b/vic/drivers/classic/src/close_files.c index 635c6067d..da75f2db5 100644 --- a/vic/drivers/classic/src/close_files.c +++ b/vic/drivers/classic/src/close_files.c @@ -30,35 +30,31 @@ * @brief This routine closes all forcing data files, and output files. *****************************************************************************/ void -close_files(filep_struct *filep, - out_data_file_struct *out_data_files, - filenames_struct *fnames) +close_files(filep_struct *filep, + stream_struct **streams) { extern option_struct options; - size_t filenum; + + size_t streamnum; /********************** Close All Input Files **********************/ fclose(filep->forcing[0]); - if (options.COMPRESS) { - compress_files(fnames->forcing[0]); - } + if (filep->forcing[1] != NULL) { fclose(filep->forcing[1]); - if (options.COMPRESS) { - compress_files(fnames->forcing[1]); - } } /******************* Close Output Files *******************/ - for (filenum = 0; filenum < options.Noutfiles; filenum++) { - fclose(out_data_files[filenum].fh); - if (options.COMPRESS) { - compress_files(out_data_files[filenum].filename); + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + fclose((*streams)[streamnum].fh); + if ((*streams)[streamnum].compress) { + compress_files((*streams)[streamnum].filename, + (*streams)[streamnum].compress); } } } diff --git a/vic/drivers/classic/src/display_current_settings.c b/vic/drivers/classic/src/display_current_settings.c index 825f49a72..ccd3a9e91 100644 --- a/vic/drivers/classic/src/display_current_settings.c +++ b/vic/drivers/classic/src/display_current_settings.c @@ -432,43 +432,6 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Output Data:\n"); fprintf(LOG_DEST, "Result dir:\t\t%s\n", filenames.result_dir); - fprintf(LOG_DEST, "OUT_STEP\t\t%f\n", global_param.out_dt); - if (options.ALMA_OUTPUT) { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tFALSE\n"); - } - if (options.OUT_FORMAT == ASCII) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tASCII\n"); - } - else if (options.OUT_FORMAT == BINARY) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tBINARY\n"); - } - if (options.COMPRESS) { - fprintf(LOG_DEST, "COMPRESS\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "COMPRESS\t\tFALSE\n"); - } - if (options.MOISTFRACT) { - fprintf(LOG_DEST, "MOISTFRACT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "MOISTFRACT\t\tFALSE\n"); - } - if (options.PRT_HEADER) { - fprintf(LOG_DEST, "PRT_HEADER\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_HEADER\t\tFALSE\n"); - } - if (options.PRT_SNOW_BAND) { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tFALSE\n"); - } - fprintf(LOG_DEST, "SKIPYEAR\t\t%d\n", global_param.skipyear); + fprintf(LOG_DEST, "Noutstreams:\t\t%zu\n", options.Noutstreams); fprintf(LOG_DEST, "\n"); } diff --git a/vic/drivers/classic/src/free_out_data_files.c b/vic/drivers/classic/src/free_out_data_files.c deleted file mode 100644 index ca417fd57..000000000 --- a/vic/drivers/classic/src/free_out_data_files.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * This routine frees the list of output files. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief This routine frees the memory in the out_data_files array. - *****************************************************************************/ -void -free_out_data_files(out_data_file_struct **out_data_files) -{ - extern option_struct options; - size_t filenum; - - for (filenum = 0; filenum < options.Noutfiles; filenum++) { - free((char*) (*out_data_files)[filenum].varid); - } - free((char*) (*out_data_files)); -} diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 54a23575c..587adbc04 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -114,169 +114,97 @@ get_global_param(FILE *gp) } else if (strcasecmp("CALENDAR", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - global_param.calendar = calendar_from_chars(flgstr); + global_param.calendar = str_to_calendar(flgstr); } else if (strcasecmp("OUT_TIME_UNITS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - global_param.time_units = timeunits_from_chars(flgstr); + global_param.time_units = str_to_timeunits(flgstr); } else if (strcasecmp("FULL_ENERGY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.FULL_ENERGY = true; - } - else { - options.FULL_ENERGY = false; - } + options.FULL_ENERGY = str_to_bool(flgstr); } else if (strcasecmp("FROZEN_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.FROZEN_SOIL = true; + options.FROZEN_SOIL = str_to_bool(flgstr); + // TODO: move these steps to a option validation + if (options.FROZEN_SOIL) { options.QUICK_FLUX = false; } else { - options.FROZEN_SOIL = false; options.IMPLICIT = false; options.EXP_TRANS = false; } } else if (strcasecmp("QUICK_FLUX", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_FLUX = true; - } - else { - options.QUICK_FLUX = false; - } + options.QUICK_FLUX = str_to_bool(flgstr); } else if (strcasecmp("QUICK_SOLVE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_SOLVE = true; - } - else { - options.QUICK_SOLVE = false; - } + options.QUICK_SOLVE = str_to_bool(flgstr); } else if ((strcasecmp("NOFLUX", optstr) == 0) || (strcasecmp("NO_FLUX", optstr) == 0)) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.NOFLUX = true; - } - else { - options.NOFLUX = false; - } + options.NOFLUX = str_to_bool(flgstr); } else if (strcasecmp("IMPLICIT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.IMPLICIT = true; - } - else { - options.IMPLICIT = false; - } + options.IMPLICIT = str_to_bool(flgstr); } else if (strcasecmp("EXP_TRANS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.EXP_TRANS = true; - } - else { - options.EXP_TRANS = false; - } + options.EXP_TRANS = str_to_bool(flgstr); } else if (strcasecmp("SNOW_DENSITY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("DENS_SNTHRM", flgstr) == 0) { options.SNOW_DENSITY = DENS_SNTHRM; } - else { + else if (strcasecmp("DENS_BRAS", flgstr) == 0) { options.SNOW_DENSITY = DENS_BRAS; } + else { + log_err("Unknown SNOW_DENSITY option: %s", flgstr); + } } else if (strcasecmp("BLOWING", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING = true; - } - else { - options.BLOWING = false; - } + options.BLOWING = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_VAR_THRESHOLD", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_VAR_THRESHOLD = true; - } - else { - options.BLOWING_VAR_THRESHOLD = false; - } + options.BLOWING_VAR_THRESHOLD = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_CALC_PROB", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_CALC_PROB = true; - } - else { - options.BLOWING_CALC_PROB = false; - } + options.BLOWING_CALC_PROB = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SIMPLE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SIMPLE = true; - } - else { - options.BLOWING_SIMPLE = false; - } + options.BLOWING_SIMPLE = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_FETCH", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_FETCH = true; - } - else { - options.BLOWING_FETCH = false; - } + options.BLOWING_FETCH = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SPATIAL_WIND", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SPATIAL_WIND = true; - } - else { - options.BLOWING_SPATIAL_WIND = false; - } + options.BLOWING_SPATIAL_WIND = str_to_bool(flgstr); } else if (strcasecmp("CORRPREC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CORRPREC = true; - } - else { - options.CORRPREC = false; - } + options.CORRPREC = str_to_bool(flgstr); } else if (strcasecmp("CLOSE_ENERGY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CLOSE_ENERGY = true; - } - else { - options.CLOSE_ENERGY = false; - } + options.CLOSE_ENERGY = str_to_bool(flgstr); } else if (strcasecmp("CONTINUEONERROR", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CONTINUEONERROR = true; - } - else { - options.CONTINUEONERROR = false; - } + options.CONTINUEONERROR = str_to_bool(flgstr); } else if (strcasecmp("COMPUTE_TREELINE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -290,12 +218,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("EQUAL_AREA", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.EQUAL_AREA = true; - } - else { - options.EQUAL_AREA = false; - } + options.EQUAL_AREA = str_to_bool(flgstr); } else if (strcasecmp("RESOLUTION", optstr) == 0) { sscanf(cmdstr, "%*s %lf", &global_param.resolution); @@ -314,6 +237,9 @@ get_global_param(FILE *gp) else if (strcasecmp("AR_410", flgstr) == 0) { options.AERO_RESIST_CANSNOW = AR_410; } + else { + log_err("Unknown AERO_RESIST_CANSNOW option: %s", flgstr); + } } else if (strcasecmp("GRND_FLUX_TYPE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -323,64 +249,47 @@ get_global_param(FILE *gp) else if (strcasecmp("GF_410", flgstr) == 0) { options.GRND_FLUX_TYPE = GF_410; } + else { + log_err("Unknown GRND_FLUX_TYPE option: %s", flgstr); + } } else if (strcasecmp("SPATIAL_FROST", optstr) == 0) { sscanf(cmdstr, "%*s %s %s", flgstr, flgstr2); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SPATIAL_FROST = true; + options.SPATIAL_FROST = str_to_bool(flgstr); + if (options.SPATIAL_FROST) { options.Nfrost = atoi(flgstr2); } - else { - options.SPATIAL_FROST = false; - } } else if (strcasecmp("SPATIAL_SNOW", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SPATIAL_SNOW = true; - } - else { - options.SPATIAL_SNOW = false; - } + options.SPATIAL_SNOW = str_to_bool(flgstr); } else if (strcasecmp("TFALLBACK", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.TFALLBACK = true; - } - else { - options.TFALLBACK = false; - } + options.TFALLBACK = str_to_bool(flgstr); } else if (strcasecmp("SHARE_LAYER_MOIST", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SHARE_LAYER_MOIST = true; - } - else { - options.SHARE_LAYER_MOIST = false; - } + options.SHARE_LAYER_MOIST = str_to_bool(flgstr); } else if (strcasecmp("CANOPY_LAYERS", optstr) == 0) { sscanf(cmdstr, "%*s %zu", &options.Ncanopy); } else if (strcasecmp("CARBON", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CARBON = true; - } - else { - options.CARBON = false; - } + options.CARBON = str_to_bool(flgstr); } else if (strcasecmp("RC_MODE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("RC_PHOTO", flgstr) == 0) { options.RC_MODE = RC_PHOTO; } - else { + else if (strcasecmp("RC_JARVIS", flgstr) == 0) { options.RC_MODE = RC_JARVIS; } + else { + log_err("Unknown RC_MODE option: %s", flgstr); + } } /************************************* @@ -520,41 +429,6 @@ get_global_param(FILE *gp) else if (strcasecmp("SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.soil); } - else if (strcasecmp("ARC_SOIL", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - log_err("\"ARC_SOIL\" is no longer a supported option. " - "Please convert your soil parameter file and " - "remove this option from your global file"); - } - } - else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - log_err( - "Please change \"ARNO_PARAMS TRUE\" to \"BASEFLOW " - "NIJSSEN2001\" in your global parameter file."); - } - else { - log_err( - "Please change \"ARNO_PARAMS FALSE\" to \"BASEFLOW " - "ARNO\" in your global parameter file."); - } - } - else if (strcasecmp("NIJSSEN2001_BASEFLOW", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - log_err( - "Please change \"NIJSSEN2001_BASEFLOW TRUE\" to " - "\"BASEFLOW NIJSSEN2001\" in your global parameter " - "file."); - } - else { - log_err( - "Please change \"NIJSSEN2001_BASEFLOW FALSE\" to " - "\"BASEFLOW ARNO\" in your global parameter file."); - } - } else if (strcasecmp("BASEFLOW", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("NIJSSEN2001", flgstr) == 0) { @@ -566,59 +440,29 @@ get_global_param(FILE *gp) } else if (strcasecmp("JULY_TAVG_SUPPLIED", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.JULY_TAVG_SUPPLIED = true; - } - else { - options.JULY_TAVG_SUPPLIED = false; - } + options.JULY_TAVG_SUPPLIED = str_to_bool(flgstr); } else if (strcasecmp("ORGANIC_FRACT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.ORGANIC_FRACT = false; - } - else { - options.ORGANIC_FRACT = true; - } + options.ORGANIC_FRACT = str_to_bool(flgstr); } else if (strcasecmp("VEGLIB", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veglib); } else if (strcasecmp("VEGLIB_PHOTO", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGLIB_PHOTO = true; - } - else { - options.VEGLIB_PHOTO = false; - } + options.VEGLIB_PHOTO = str_to_bool(flgstr); } else if (strcasecmp("VEGLIB_FCAN", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGLIB_FCAN = true; - } - else { - options.VEGLIB_FCAN = false; - } - } - else if (strcasecmp("VEGLIB_VEGCOVER", optstr) == 0) { - log_err("The option VEGLIB_VEGCOVER has been replaced by " - "VEGLIB_FCAN. Please edit your global parameter " - "file and re-run."); + options.VEGLIB_FCAN = str_to_bool(flgstr); } else if (strcasecmp("VEGPARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veg); } else if (strcasecmp("VEGPARAM_LAI", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGPARAM_LAI = true; - } - else { - options.VEGPARAM_LAI = false; - } + options.VEGPARAM_LAI = str_to_bool(flgstr); } else if (strcasecmp("LAI_SRC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -638,12 +482,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("VEGPARAM_FCAN", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGPARAM_FCAN = true; - } - else { - options.VEGPARAM_FCAN = false; - } + options.VEGPARAM_FCAN = str_to_bool(flgstr); } else if (strcasecmp("FCAN_SRC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -666,12 +505,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("VEGPARAM_ALB", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGPARAM_ALB = true; - } - else { - options.VEGPARAM_ALB = false; - } + options.VEGPARAM_ALB = str_to_bool(flgstr); } else if (strcasecmp("ALB_SRC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -689,16 +523,6 @@ get_global_param(FILE *gp) "control file."); } } - else if (strcasecmp("VEGPARAM_VEGCOVER", optstr) == 0) { - log_err("The option VEGPARAM_VEGCOVER has been replaced by " - "VEGPARAM_FCAN. Please edit your global parameter " - "file and re-run."); - } - else if (strcasecmp("VEGCOVER_SRC", optstr) == 0) { - log_err("The option VEGCOVER_SRC has been replaced by " - "FCAN_SRC. Please edit your global parameter " - "file and re-run."); - } else if (strcasecmp("ROOT_ZONES", optstr) == 0) { sscanf(cmdstr, "%*s %zu", &options.ROOT_ZONES); } @@ -718,12 +542,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("LAKE_PROFILE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.LAKE_PROFILE = false; - } - else { - options.LAKE_PROFILE = true; - } + options.LAKE_PROFILE = str_to_bool(flgstr); } /************************************* @@ -732,83 +551,79 @@ get_global_param(FILE *gp) else if (strcasecmp("RESULT_DIR", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.result_dir); } - else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { - sscanf(cmdstr, "%*s %zu", &global_param.output_steps_per_day); + + /************************************* + Define output file contents + *************************************/ + else if (strcasecmp("OUTFILE", optstr) == 0) { + ; // do nothing } - else if (strcasecmp("SKIPYEAR", optstr) == 0) { - sscanf(cmdstr, "%*s %hu", &global_param.skipyear); + else if (strcasecmp("OUTVAR", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("AGGFREQ", optstr) == 0) { + ; // do nothing } else if (strcasecmp("COMPRESS", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.COMPRESS = true; - } - else { - options.COMPRESS = false; - } + ; // do nothing } else if (strcasecmp("OUT_FORMAT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("BINARY", flgstr) == 0) { - options.OUT_FORMAT = BINARY; - } - else if (strcasecmp("ASCII", flgstr) == 0) { - options.OUT_FORMAT = ASCII; - } - else { - log_err("OUT_FORMAT must be either ASCII or BINARY."); - } + ; // do nothing } - else if (strcasecmp("ALMA_OUTPUT", optstr) == 0) { + + /************************************* + Fail when deprecated options are used. + *************************************/ + else if (strcasecmp("ARC_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { - options.ALMA_OUTPUT = true; - } - else { - options.ALMA_OUTPUT = false; + log_err("\"ARC_SOIL\" is no longer a supported option. " + "Please convert your soil parameter file and " + "remove this option from your global file"); } } - else if (strcasecmp("MOISTFRACT", optstr) == 0) { + else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { - options.MOISTFRACT = true; + log_err( + "Please change \"ARNO_PARAMS TRUE\" to \"BASEFLOW " + "NIJSSEN2001\" in your global parameter file."); } else { - options.MOISTFRACT = false; + log_err( + "Please change \"ARNO_PARAMS FALSE\" to \"BASEFLOW " + "ARNO\" in your global parameter file."); } } - else if (strcasecmp("PRT_HEADER", optstr) == 0) { + else if (strcasecmp("NIJSSEN2001_BASEFLOW", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { - options.PRT_HEADER = true; + log_err( + "Please change \"NIJSSEN2001_BASEFLOW TRUE\" to " + "\"BASEFLOW NIJSSEN2001\" in your global parameter " + "file."); } else { - options.PRT_HEADER = false; + log_err( + "Please change \"NIJSSEN2001_BASEFLOW FALSE\" to " + "\"BASEFLOW ARNO\" in your global parameter file."); } } - else if (strcasecmp("PRT_SNOW_BAND", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.PRT_SNOW_BAND = true; - } - else { - options.PRT_SNOW_BAND = false; - } + else if (strcasecmp("VEGLIB_VEGCOVER", optstr) == 0) { + log_err("The option VEGLIB_VEGCOVER has been replaced by " + "VEGLIB_FCAN. Please edit your global parameter " + "file and re-run."); } - - /************************************* - Define output file contents - *************************************/ - else if (strcasecmp("OUTFILE", optstr) == 0) { - ; // do nothing + else if (strcasecmp("VEGPARAM_VEGCOVER", optstr) == 0) { + log_err("The option VEGPARAM_VEGCOVER has been replaced by " + "VEGPARAM_FCAN. Please edit your global parameter " + "file and re-run."); } - else if (strcasecmp("OUTVAR", optstr) == 0) { - ; // do nothing + else if (strcasecmp("VEGCOVER_SRC", optstr) == 0) { + log_err("The option VEGCOVER_SRC has been replaced by " + "FCAN_SRC. Please edit your global parameter " + "file and re-run."); } - - /************************************* - Fail when deprecated options are used. - *************************************/ else if (strcasecmp("TIME_STEP", optstr) == 0) { log_err("TIME_STEP has been replaced with MODEL_STEPS_PER_DAY, " "update your global parameter file accordingly"); @@ -833,6 +648,29 @@ get_global_param(FILE *gp) log_err("BINARY_STATE_FILE has been replaced with STATE_FORMAT, " "update your global parameter file accordingly"); } + else if (strcasecmp("ALMA_OUTPUT", optstr) == 0) { + log_err("ALMA_OUTPUT has been deprecated, update your global " + "parameter file accordingly"); + } + else if (strcasecmp("MOISTFRACT", optstr) == 0) { + log_err("MOISTFRACT has been deprecated and has been replaced " + "with two new output variables OUT_SOIL_ICE_FRAC and " + "OUT_SOIL_LIQ_FRAC, update your global parameter file " + "accordingly"); + } + else if (strcasecmp("PRT_HEADER", optstr) == 0) { + log_err("PRT_HEADER has been deprecated. All output files " + "include a header including pertinent metadata."); + } + else if (strcasecmp("PRT_SNOW_BAND", optstr) == 0) { + log_err("PRT_SNOW_BAND has been deprecated. To output band " + "specific variables, directly specify them in the " + "global parameter file"); + } + else if (strcasecmp("SKIPYEAR", optstr) == 0) { + log_err("SKIPYEAR has been deprecated. To avoid writing output" + "to history files, set AGGFREQ == FREQ_NEVER"); + } /*********************************** Unrecognized Global Parameter Flag @@ -1015,48 +853,6 @@ get_global_param(FILE *gp) (double) global_param.atmos_steps_per_day; } - // Validate the output step - if (global_param.output_steps_per_day == 0) { - global_param.output_steps_per_day = global_param.model_steps_per_day; - } - if (global_param.output_steps_per_day > - global_param.model_steps_per_day) { - log_err("Invalid value for OUTPUT_STEPS_PER_DAY (%zu). " - "OUTPUT_STEPS_PER_DAY must be <= MODEL_STEPS_PER_DAY (%zu)", - global_param.output_steps_per_day, - global_param.model_steps_per_day); - } - else if (global_param.model_steps_per_day % - global_param.output_steps_per_day != 0) { - log_err("Invalid value for OUTPUT_STEPS_PER_DAY (%zu). " - "MODEL_STEPS_PER_DAY (%zu) must be a multiple of " - "OUTPUT_STEPS_PER_DAY.", - global_param.output_steps_per_day, - global_param.model_steps_per_day); - } - else if (global_param.output_steps_per_day != 1 && - global_param.output_steps_per_day < MIN_SUBDAILY_STEPS_PER_DAY) { - log_err("The specified number of output steps per day (%zu) > 1 and < " - "the minimum number of subdaily steps per day (%d). Make " - "sure that the global file defines OUTPUT_STEPS_PER_DAY of at " - "least (%d).", global_param.model_steps_per_day, - MIN_SUBDAILY_STEPS_PER_DAY, - MIN_SUBDAILY_STEPS_PER_DAY); - } - else if (global_param.output_steps_per_day > - MAX_SUBDAILY_STEPS_PER_DAY) { - log_err("The specified number of model steps per day (%zu) > the " - "the maximum number of subdaily steps per day (%d). Make " - "sure that the global file defines MODEL_STEPS_PER_DAY of at " - "most (%d).", global_param.model_steps_per_day, - MAX_SUBDAILY_STEPS_PER_DAY, - MAX_SUBDAILY_STEPS_PER_DAY); - } - else { - global_param.out_dt = SEC_PER_DAY / - (double) global_param.output_steps_per_day; - } - // set NR and NF NF = global_param.snow_steps_per_day / global_param.model_steps_per_day; if (NF == 1) { @@ -1443,9 +1239,6 @@ get_global_param(FILE *gp) if (options.SAVE_STATE && options.STATE_FORMAT == UNSET_FILE_FORMAT) { options.STATE_FORMAT = ASCII; } - if (options.OUT_FORMAT == UNSET_FILE_FORMAT) { - options.OUT_FORMAT = ASCII; - } // Validate soil parameter/simulation mode combinations if (options.QUICK_FLUX) { diff --git a/vic/drivers/classic/src/make_in_and_outfiles.c b/vic/drivers/classic/src/make_in_and_outfiles.c index 0160f4fe4..a30d89e85 100644 --- a/vic/drivers/classic/src/make_in_and_outfiles.c +++ b/vic/drivers/classic/src/make_in_and_outfiles.c @@ -31,10 +31,11 @@ * @brief Build files names for input and output of grided data files. *****************************************************************************/ void -make_in_and_outfiles(filep_struct *filep, - filenames_struct *filenames, - soil_con_struct *soil, - out_data_file_struct *out_data_files) +make_in_and_outfiles(filep_struct *filep, + filenames_struct *filenames, + soil_con_struct *soil, + stream_struct **streams, + dmy_struct *dmy) { extern option_struct options; extern param_set_struct param_set; @@ -80,27 +81,29 @@ make_in_and_outfiles(filep_struct *filep, Output Files ********************************/ - for (filenum = 0; filenum < options.Noutfiles; filenum++) { - strcpy(out_data_files[filenum].filename, filenames->result_dir); - strcat(out_data_files[filenum].filename, "/"); - strcat(out_data_files[filenum].filename, - out_data_files[filenum].prefix); - strcat(out_data_files[filenum].filename, "_"); - strcat(out_data_files[filenum].filename, latchar); - strcat(out_data_files[filenum].filename, "_"); - strcat(out_data_files[filenum].filename, lngchar); - if (options.OUT_FORMAT == BINARY) { - strcat(out_data_files[filenum].filename, ".bin"); - out_data_files[filenum].fh = open_file( - out_data_files[filenum].filename, "wb"); + for (filenum = 0; filenum < options.Noutstreams; filenum++) { + strcpy((*streams)[filenum].filename, filenames->result_dir); + strcat((*streams)[filenum].filename, "/"); + strcat((*streams)[filenum].filename, + (*streams)[filenum].prefix); + strcat((*streams)[filenum].filename, "_"); + strcat((*streams)[filenum].filename, latchar); + strcat((*streams)[filenum].filename, "_"); + strcat((*streams)[filenum].filename, lngchar); + if ((*streams)[filenum].file_format == BINARY) { + strcat((*streams)[filenum].filename, ".bin"); + (*streams)[filenum].fh = open_file( + (*streams)[filenum].filename, "wb"); } - else if (options.OUT_FORMAT == ASCII) { - strcat(out_data_files[filenum].filename, ".txt"); - out_data_files[filenum].fh = open_file( - out_data_files[filenum].filename, "w"); + else if ((*streams)[filenum].file_format == ASCII) { + strcat((*streams)[filenum].filename, ".txt"); + (*streams)[filenum].fh = open_file( + (*streams)[filenum].filename, "w"); } else { log_err("Unrecognized OUT_FORMAT option"); } } + /** Write output file headers **/ + write_header(streams, dmy); } diff --git a/vic/drivers/classic/src/parse_output_info.c b/vic/drivers/classic/src/parse_output_info.c index 345475905..b50566bfd 100644 --- a/vic/drivers/classic/src/parse_output_info.c +++ b/vic/drivers/classic/src/parse_output_info.c @@ -31,122 +31,186 @@ * @brief Get output info from global parameter file. *****************************************************************************/ void -parse_output_info(FILE *gp, - out_data_file_struct **out_data_files, - out_data_struct *out_data) +parse_output_info(FILE *gp, + stream_struct **streams, + dmy_struct *dmy_current) { - extern option_struct options; - - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - short int outfilenum; - char varname[MAXSTRING]; - int outvarnum; - char format[MAXSTRING]; - char typestr[MAXSTRING]; - int type; - char multstr[MAXSTRING]; - double mult; - size_t noutfiles; - - strcpy(format, "*"); + extern option_struct options; + extern global_param_struct global_param; + + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + char flgstr[MAXSTRING]; + short int streamnum; + char varname[MAXSTRING]; + int outvarnum; + char freq_type_str[MAXSTRING]; + char freq_value_str[MAXSTRING]; + char format[MAXSTRING]; + char typestr[MAXSTRING]; + int type; + char multstr[MAXSTRING]; + char aggstr[MAXSTRING]; + double mult; + unsigned short int freq; + int freq_n; + dmy_struct freq_dmy; + unsigned short int agg_type; + int found; + size_t nstream_vars[MAX_OUTPUT_STREAMS]; + bool default_outputs = false; /** Read through global control file to find output info **/ - fgets(cmdstr, MAXSTRING, gp); - - outfilenum = -1; - outvarnum = 0; - // Count the number of output files listed in the global param file - noutfiles = count_n_outfiles(gp); + count_nstreams_nvars(gp, &(options.Noutstreams), nstream_vars); - // only parse the output info if there are output files to parse - if (noutfiles > 0) { - options.Noutfiles = noutfiles; + // If there weren't any output streams specified, get the defaults + if (options.Noutstreams == 0) { + default_outputs = true; + get_default_nstreams_nvars(&(options.Noutstreams), nstream_vars); + } - *out_data_files = calloc(options.Noutfiles, sizeof(*(*out_data_files))); - if (*out_data_files == NULL) { - log_err("Memory allocation error in parse_output_info()."); - } - init_output_list(out_data, false, "%.4g", OUT_TYPE_FLOAT, 1); + // Allocate streams + *streams = calloc(options.Noutstreams, sizeof(*(*streams))); + if (*streams == NULL) { + log_err("Memory allocation error in parse_output_info()."); + } - // PRT_SNOW_BAND is ignored if options.Noutfiles > 0 - options.PRT_SNOW_BAND = false; + // Setup streams + for (streamnum = 0; + streamnum < (short int) options.Noutstreams; + streamnum++) { + setup_stream(&(*streams)[streamnum], nstream_vars[streamnum], 1); + } + // only parse the output info if there are output files to parse + if (!default_outputs) { + // initialize counters + streamnum = -1; + outvarnum = 0; + + // rewind the global parameter file to the begining and parse only the + // output file info. + rewind(gp); + fgets(cmdstr, MAXSTRING, gp); while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); if (strcasecmp("OUTFILE", optstr) == 0) { - outfilenum++; - if (outfilenum >= (short int)options.Noutfiles) { + streamnum++; + if (streamnum >= (short int) options.Noutstreams) { log_err("Found too many output files, was expecting " - "%zu but found %hu", options.Noutfiles, - outfilenum); + "%zu but found %hu", options.Noutstreams, + streamnum); + } + if (sscanf(cmdstr, "%*s %s", + (*streams)[streamnum].prefix) != 1) { + log_err("Invalid specification for OUTFILE"); } - sscanf(cmdstr, "%*s %s", - (*out_data_files)[outfilenum].prefix); - // determine how many variable will be in this file before - // allocating (GH: 209) - (*out_data_files)[outfilenum].nvars = - count_outfile_nvars(gp); + // set default file format + (*streams)[streamnum].file_format = ASCII; - (*out_data_files)[outfilenum].varid = - calloc((*out_data_files)[outfilenum].nvars, - sizeof(*((*out_data_files)[outfilenum].varid))); - if ((*out_data_files)[outfilenum].varid == NULL) { - log_err( - "Memory allocation error in parse_output_info()."); - } outvarnum = 0; } - else if (strcasecmp("OUTVAR", optstr) == 0) { - if (outfilenum < 0) { + else if (strcasecmp("AGGFREQ", optstr) == 0) { + if (streamnum < 0) { log_err("Error in global param file: \"OUTFILE\" must be " - "specified before you can specify \"OUTVAR\"."); + "specified before you can specify \"AGGFREQ\"."); } - strcpy(format, ""); - strcpy(typestr, ""); - strcpy(multstr, ""); - sscanf(cmdstr, "%*s %s %s %s %s", varname, format, typestr, - multstr); - if (strcasecmp("", format) == 0) { - strcpy(format, "*"); - type = OUT_TYPE_DEFAULT; - mult = 0; // 0 means default multiplier + found = sscanf(cmdstr, "%*s %s %s", freq_type_str, + freq_value_str); + + if (!found) { + log_err("No arguments found after OUTFREQ"); } - else { - if (strcasecmp("OUT_TYPE_USINT", typestr) == 0) { - type = OUT_TYPE_USINT; - } - else if (strcasecmp("OUT_TYPE_SINT", typestr) == 0) { - type = OUT_TYPE_SINT; - } - else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { - type = OUT_TYPE_FLOAT; + // parse the frequency string to an enum value + freq = str_to_freq_flag(freq_type_str); + + if (freq == FREQ_DATE) { + // Make sure we have a datestring + if (found != 2) { + log_err( + "AGGFREQ was set to DATE but no date string was found"); } - else if (strcasecmp("OUT_TYPE_DOUBLE", typestr) == 0) { - type = OUT_TYPE_DOUBLE; - } - else { - type = OUT_TYPE_DEFAULT; - } - if (strcmp("*", multstr) == 0) { - mult = 0; // 0 means use default multiplier + // parse date from freq_value_str + strpdmy(freq_value_str, "%Y-%m-%d", &freq_dmy); + // set the alarm + set_alarm(dmy_current, freq, &freq_dmy, + (&(*streams)[streamnum].agg_alarm)); + } + else { + if (found != 2) { + // Default frequency is 1 + freq_n = 1; } else { - mult = (double) atof(multstr); + // get the frequency value as an integer + freq_n = atoi(freq_value_str); } + // set the alarm + set_alarm(dmy_current, freq, &freq_n, + (&(*streams)[streamnum].agg_alarm)); } - if (set_output_var((*out_data_files), true, outfilenum, - out_data, varname, outvarnum, format, - type, - mult) != 0) { - log_err("Invalid output variable specification."); + } + else if (strcasecmp("COMPRESS", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"COMPRESS\"."); + } + sscanf(cmdstr, "%*s %s", flgstr); + if (strcasecmp("TRUE", flgstr) == 0) { + (*streams)[streamnum].compress = COMPRESSION_LVL_UNSET; + } + else if (strcasecmp("FALSE", flgstr) == 0) { + (*streams)[streamnum].compress = 0; + } + else { + (*streams)[streamnum].compress = atoi(flgstr); + } + } + else if (strcasecmp("OUT_FORMAT", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"OUT_FORMAT\"."); } + sscanf(cmdstr, "%*s %s", flgstr); + if (strcasecmp("ASCII", flgstr) == 0) { + (*streams)[streamnum].file_format = ASCII; + } + else if (strcasecmp("BINARY", flgstr) == 0) { + (*streams)[streamnum].file_format = BINARY; + } + else { + log_err("Classic driver file format must be ASCII or " + "BINARY [stream=%hu]", streamnum); + } + } + else if (strcasecmp("OUTVAR", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"OUTVAR\"."); + } + // parse outvar options strcpy(format, ""); + strcpy(typestr, ""); + strcpy(multstr, ""); + found = sscanf(cmdstr, "%*s %s %s %s %s %s", varname, + format, typestr, multstr, aggstr); + if (!found) { + log_err("OUTVAR specified but no variable was listed"); + } + // interpret string options, set defaults if necessary + str_to_ascii_format(format); + agg_type = str_to_agg_type(aggstr); + type = str_to_out_type(typestr); + mult = str_to_out_mult(multstr); + + // Add OUTVAR to stream + set_output_var(&(*streams)[streamnum], varname, outvarnum, + format, type, mult, agg_type); outvarnum++; } } @@ -155,93 +219,14 @@ parse_output_info(FILE *gp, } // Otherwise, set output files and their contents to default configuration else { - *out_data_files = set_output_defaults(out_data); + set_output_defaults(streams, dmy_current, ASCII); } fclose(gp); -} -/****************************************************************************** - * @brief This routine determines the counts the number of output variables - in each output file specified in the global parameter file. - *****************************************************************************/ -size_t -count_outfile_nvars(FILE *gp) -{ - size_t nvars; - unsigned long start_position; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - // Figure out where we are in the input file - fflush(gp); - start_position = ftell(gp); - - // read the first line - fgets(cmdstr, MAXSTRING, gp); - - // initalize nvars - nvars = 0; - - // Loop through the lines - while (!feof(gp)) { - if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { - // line is not blank or a comment - sscanf(cmdstr, "%s", optstr); - - // if the line starts with OUTFILE - if (strcasecmp("OUTVAR", optstr) == 0) { - nvars++; - } - // else we're done with this file so break out of loop - else { - break; - } - } - fgets(cmdstr, MAXSTRING, gp); - } - - // put the position in the file back to where we started - fseek(gp, start_position, SEEK_SET); - - return nvars; -} - -/****************************************************************************** - * @brief This routine determines the counts the number of output files - specified in the global parameter file. - *****************************************************************************/ -size_t -count_n_outfiles(FILE *gp) -{ - size_t n_outfiles; - unsigned long start_position; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - // Figure out where we are in the input file - fflush(gp); - start_position = ftell(gp); - - // read the first line - fgets(cmdstr, MAXSTRING, gp); - - // initalize n_outfiles - n_outfiles = 0; - - // Loop through the lines - while (!feof(gp)) { - if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { - // line is not blank or a comment - sscanf(cmdstr, "%s", optstr); - - // if the line starts with OUTFILE - if (strcasecmp("OUTFILE", optstr) == 0) { - n_outfiles++; - } - } - fgets(cmdstr, MAXSTRING, gp); + for (streamnum = 0; + streamnum < (short int) options.Noutstreams; + streamnum++) { + // Allocate memory for the stream aggdata arrays + alloc_aggdata(&(*streams)[streamnum]); } - - // put the position in the file back to where we started - fseek(gp, start_position, SEEK_SET); - - return n_outfiles; } diff --git a/vic/drivers/classic/src/read_snowband.c b/vic/drivers/classic/src/read_snowband.c index ce4166f38..3fa146f5c 100644 --- a/vic/drivers/classic/src/read_snowband.c +++ b/vic/drivers/classic/src/read_snowband.c @@ -97,7 +97,7 @@ read_snowband(FILE *snowband, avg_elev += soil_con->BandElev[band] * soil_con->AreaFract[band]; } if (fabs(avg_elev - soil_con->elevation) > 1.0) { - log_warn("average band elevation %f not equal to grid_cell" + log_warn("average band elevation %f not equal to grid_cell " "average elevation %f; setting grid cell elevation to " "average band elevation.", avg_elev, soil_con->elevation); diff --git a/vic/drivers/classic/src/set_output_defaults.c b/vic/drivers/classic/src/set_output_defaults.c deleted file mode 100644 index 11db6cdbd..000000000 --- a/vic/drivers/classic/src/set_output_defaults.c +++ /dev/null @@ -1,303 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Set the out_data_files and out_data structures to default values. These can - * be overridden by the user in the global control file. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Set the out_data_files and out_data structures to default values. - These can be overridden by the user in the global control file. - *****************************************************************************/ -out_data_file_struct * -set_output_defaults(out_data_struct *out_data) -{ - extern option_struct options; - out_data_file_struct *out_data_files; - unsigned int filenum; - unsigned int varnum; - - // Output files - options.Noutfiles = 2; - if (options.FROZEN_SOIL) { - options.Noutfiles++; - } - if (options.PRT_SNOW_BAND) { - options.Noutfiles++; - } - if (options.LAKES) { - options.Noutfiles++; - } - out_data_files = calloc(options.Noutfiles, sizeof(*out_data_files)); - filenum = 0; - strcpy(out_data_files[filenum].prefix, "fluxes"); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - out_data_files[filenum].nvars = 26; - } - else { - out_data_files[filenum].nvars = 20; - } - filenum++; - strcpy(out_data_files[filenum].prefix, "snow"); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - out_data_files[filenum].nvars = 14; - } - else { - out_data_files[filenum].nvars = 4; - } - if (options.BLOWING) { - out_data_files[filenum].nvars += 3; - } - if (options.FROZEN_SOIL) { - filenum++; - strcpy(out_data_files[filenum].prefix, "fdepth"); - out_data_files[filenum].nvars = 4; - } - if (options.PRT_SNOW_BAND) { - filenum++; - strcpy(out_data_files[filenum].prefix, "snowband"); - if (options.FULL_ENERGY) { - out_data_files[filenum].nvars = 13; - } - else { - out_data_files[filenum].nvars = 9; - } - } - if (options.LAKES) { - filenum++; - strcpy(out_data_files[filenum].prefix, "lake"); - out_data_files[filenum].nvars = 8; - } - for (filenum = 0; filenum < options.Noutfiles; filenum++) { - out_data_files[filenum].varid = calloc( - out_data_files[filenum].nvars, - sizeof(*(out_data_files[filenum].varid))); - } - - // Variables in first file - filenum = 0; - varnum = 0; - set_output_var(out_data_files, true, filenum, out_data, "OUT_PREC", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_EVAP", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_RUNOFF", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_BASEFLOW", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_WDEW", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_SOIL_LIQ", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_RAD_TEMP", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - } - set_output_var(out_data_files, true, filenum, out_data, "OUT_SWNET", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_R_NET", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LATENT", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - } - set_output_var(out_data_files, true, filenum, out_data, - "OUT_EVAP_CANOP", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_TRANSP_VEG", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_EVAP_BARE", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_SUB_CANOP", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_SUB_SNOW", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SENSIBLE", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_GRND_FLUX", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_DELTAH", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_FUSION", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - } - set_output_var(out_data_files, true, filenum, out_data, - "OUT_AERO_RESIST", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_SURF_TEMP", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_ALBEDO", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_REL_HUMID", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_IN_LONG", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_AIR_TEMP", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, "OUT_WIND", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - - // Variables in second file - filenum++; - varnum = 0; - set_output_var(out_data_files, true, filenum, out_data, "OUT_SWE", - varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_DEPTH", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_CANOPY", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_COVER", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - if (options.FULL_ENERGY || options.FROZEN_SOIL) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_ADVECTION", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_DELTACC", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_FLUX", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_RFRZ_ENERGY", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_MELT_ENERGY", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_ADV_SENS", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LATENT_SUB", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_SURF_TEMP", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_PACK_TEMP", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_MELT", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - } - if (options.BLOWING) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SUB_BLOWING", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SUB_SURFACE", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SUB_SNOW", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - } - - // Variables in other files - if (options.FROZEN_SOIL) { - filenum++; - varnum = 0; - set_output_var(out_data_files, true, filenum, out_data, - "OUT_FDEPTH", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_TDEPTH", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SOIL_MOIST", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SURF_FROST_FRAC", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - } - if (options.PRT_SNOW_BAND) { - filenum++; - varnum = 0; - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SWE_BAND", varnum++, "%.4f", OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_DEPTH_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_CANOPY_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - if (options.FULL_ENERGY) { - set_output_var(out_data_files, true, filenum, out_data, - "OUT_ADVECTION_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_DELTACC_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SNOW_FLUX_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_RFRZ_ENERGY_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - } - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SWNET_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LWNET_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_ALBEDO_BAND", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LATENT_BAND", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_SENSIBLE_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_GRND_FLUX_BAND", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - } - if (options.LAKES) { - filenum++; - varnum = 0; - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_ICE_TEMP", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_ICE_HEIGHT", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_ICE_FRACT", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_DEPTH", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_SURF_AREA", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_VOLUME", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_SURF_TEMP", varnum++, "%.4f", - OUT_TYPE_FLOAT, 1); - set_output_var(out_data_files, true, filenum, out_data, - "OUT_LAKE_EVAP", varnum++, "%.4f", OUT_TYPE_FLOAT, - 1); - } - - return out_data_files; -} diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 4f8958ea9..65e46705c 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -41,6 +41,7 @@ param_set_struct param_set; parameters_struct param; filenames_struct filenames; filep_struct filep; +metadata_struct out_metadata[N_OUTVAR_TYPES]; /****************************************************************************** * @brief Classic driver of the VIC model @@ -55,28 +56,27 @@ main(int argc, char *argv[]) { /** Variable Declarations **/ - extern FILE *LOG_DEST; - - char MODEL_DONE; - char RUN_MODEL; - char write_flag; - char dmy_str[MAXSTRING]; - size_t rec; - size_t Nveg_type; - int cellnum; - int startrec; - int ErrorFlag; - size_t filenum; - dmy_struct *dmy; - atmos_data_struct *atmos; - veg_hist_struct **veg_hist; - veg_con_struct *veg_con; - soil_con_struct soil_con; - all_vars_struct all_vars; - lake_con_struct lake_con; - out_data_file_struct *out_data_files; - out_data_struct *out_data; - save_data_struct save_data; + extern FILE *LOG_DEST; + + char MODEL_DONE; + char RUN_MODEL; + char dmy_str[MAXSTRING]; + size_t rec; + size_t Nveg_type; + int cellnum; + int startrec; + int ErrorFlag; + size_t streamnum; + dmy_struct *dmy; + atmos_data_struct *atmos; + veg_hist_struct **veg_hist; + veg_con_struct *veg_con; + soil_con_struct soil_con; + all_vars_struct all_vars; + lake_con_struct lake_con; + stream_struct *streams = NULL; + double ***out_data; // [1, nvars, nelem] + save_data_struct save_data; // Initialize Log Destination initialize_log(); @@ -109,17 +109,17 @@ main(int argc, // Check that model parameters are valid validate_parameters(); + /** Make Date Data Structure **/ + initialize_time(); + dmy = make_dmy(&global_param); + /** Set up output data structures **/ - out_data = create_output_list(); + set_output_met_data_info(); + // out_data is shape [ngridcells (1), N_OUTVAR_TYPES] + alloc_out_data(1, &out_data); filep.globalparam = open_file(filenames.global, "r"); - parse_output_info(filep.globalparam, &out_data_files, out_data); - for (filenum = 0; filenum < options.Noutfiles; filenum++) { - if (out_data_files[filenum].nvars == 0) { - log_err("No output variables were set in OUTFILE %zu. " - "Must set at least one output variable (OUTVAR) " - "for each OUTFILE.", filenum + 1); - } - } + parse_output_info(filep.globalparam, &streams, &(dmy[0])); + validate_streams(&streams); /** Check and Open Files **/ check_files(&filep, &filenames); @@ -130,10 +130,6 @@ main(int argc, /** Initialize Parameters **/ cellnum = -1; - /** Make Date Data Structure **/ - initialize_time(); - dmy = make_dmy(&global_param); - /** allocate memory for the atmos_data_struct **/ alloc_atmos(global_param.nrecs, &atmos); @@ -176,12 +172,8 @@ main(int argc, } /** Build Gridded Filenames, and Open **/ - make_in_and_outfiles(&filep, &filenames, &soil_con, out_data_files); - - if (options.PRT_HEADER) { - /** Write output file headers **/ - write_header(out_data_files, out_data, dmy, global_param); - } + make_in_and_outfiles(&filep, &filenames, &soil_con, + &streams, dmy); /** Read Elevation Band Data if Used **/ read_snowband(filep.snowband, &soil_con); @@ -209,15 +201,10 @@ main(int argc, /** Update Error Handling Structure **/ Error.filep = filep; - Error.out_data_files = out_data_files; /** Initialize the storage terms in the water and energy balances **/ - - /** Sending a negative record number (-global_param.nrecs) to - put_data() will accomplish this **/ - put_data(&all_vars, &atmos[0], &soil_con, veg_con, veg_lib, - &lake_con, - out_data, &save_data, -global_param.nrecs); + initialize_save_data(&all_vars, &atmos[0], &soil_con, veg_con, + veg_lib, &lake_con, out_data[0], &save_data); /****************************************** Run Model in Grid Cell for all Time Steps @@ -247,14 +234,17 @@ main(int argc, Calculate cell average values for current time step **************************************************/ put_data(&all_vars, &atmos[rec], &soil_con, veg_con, veg_lib, - &lake_con, out_data, &save_data, rec); + &lake_con, out_data[0], &save_data); - write_flag = check_write_flag(rec); + for (streamnum = 0; + streamnum < options.Noutstreams; + streamnum++) { + agg_stream_data(&(streams[streamnum]), &(dmy[rec]), + out_data); + } // Write cell average values for current time step - if (write_flag) { - write_output(out_data, out_data_files, &dmy[rec], rec); - } + write_output(&streams, &dmy[rec]); /************************************ Save model state at assigned date @@ -288,7 +278,7 @@ main(int argc, } } /* End Rec Loop */ - close_files(&filep, out_data_files, &filenames); + close_files(&filep, &streams); free_veg_hist(global_param.nrecs, veg_con[0].vegetat_type_num, &veg_hist); @@ -305,8 +295,8 @@ main(int argc, /** cleanup **/ free_atmos(global_param.nrecs, &atmos); free_dmy(&dmy); - free_out_data_files(&out_data_files); - free_out_data(&out_data); + free_streams(&streams); + free_out_data(1, out_data); // 1 is for the number of gridcells, 1 in classic driver fclose(filep.soilparam); free_veglib(&veg_lib); fclose(filep.vegparam); diff --git a/vic/drivers/classic/src/write_data.c b/vic/drivers/classic/src/write_data.c index 9ff79393f..738e185bb 100644 --- a/vic/drivers/classic/src/write_data.c +++ b/vic/drivers/classic/src/write_data.c @@ -30,25 +30,25 @@ * @brief write all variables to output files. *****************************************************************************/ void -write_data(out_data_file_struct *out_data_files, - out_data_struct *out_data, - dmy_struct *dmy, - double dt) +write_data(stream_struct *stream, + dmy_struct *dmy) { - extern option_struct options; - size_t n; - size_t file_idx; - size_t var_idx; - size_t elem_idx; - size_t ptr_idx; - char *tmp_cptr; - short int *tmp_siptr; - unsigned short int *tmp_usiptr; - int *tmp_iptr; - float *tmp_fptr; - double *tmp_dptr; + extern option_struct options; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; - if (options.OUT_FORMAT == BINARY) { + size_t n; + size_t var_idx; + size_t elem_idx; + size_t ptr_idx; + unsigned int varid; + char *tmp_cptr; + short int *tmp_siptr; + unsigned short int *tmp_usiptr; + int *tmp_iptr; + float *tmp_fptr; + double *tmp_dptr; + + if (stream->file_format == BINARY) { n = N_OUTVAR_TYPES * options.Nlayer * options.SNOW_BAND; // Initialize pointers tmp_cptr = calloc(n, sizeof(*tmp_cptr)); @@ -64,115 +64,82 @@ write_data(out_data_file_struct *out_data_files, tmp_iptr[2] = dmy->day; tmp_iptr[3] = dmy->dayseconds; - // Loop over output files - for (file_idx = 0; file_idx < options.Noutfiles; file_idx++) { - // Write the date - if (dt < SEC_PER_DAY) { - // Write year, month, day, and sec - fwrite(tmp_iptr, sizeof(int), 4, - out_data_files[file_idx].fh); - } - else { - // Only write year, month, and day - fwrite(tmp_iptr, sizeof(int), 3, - out_data_files[file_idx].fh); - } + // Write the date + if (stream->agg_alarm.is_subdaily) { + // Write year, month, day, and sec + fwrite(tmp_iptr, sizeof(int), 4, + stream->fh); + } + else { + // Only write year, month, and day + fwrite(tmp_iptr, sizeof(int), 3, + stream->fh); + } - // Loop over this output file's data variables - for (var_idx = 0; - var_idx < out_data_files[file_idx].nvars; - var_idx++) { - // Loop over this variable's elements - ptr_idx = 0; - if (out_data[out_data_files[file_idx].varid[var_idx]].type == - OUT_TYPE_CHAR) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_cptr[ptr_idx++] = - (char)out_data[out_data_files[file_idx].varid[ - var_idx]]. - aggdata[elem_idx]; - } - fwrite(tmp_cptr, sizeof(char), ptr_idx, - out_data_files[file_idx].fh); + // Loop over this output file's data variables + for (var_idx = 0; var_idx < stream->nvars; var_idx++) { + varid = stream->varid[var_idx]; + // Loop over this variable's elements + ptr_idx = 0; + if (stream->type[var_idx] == OUT_TYPE_CHAR) { + for (elem_idx = 0; + elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_cptr[ptr_idx++] = + (char) stream->aggdata[0][var_idx][elem_idx][0]; } - else if (out_data[out_data_files[file_idx].varid[var_idx]].type - == - OUT_TYPE_SINT) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_siptr[ptr_idx++] = - (short int)out_data[out_data_files[file_idx].varid[ - var_idx]].aggdata[elem_idx]; - } - fwrite(tmp_siptr, sizeof(short int), ptr_idx, - out_data_files[file_idx].fh); + fwrite(tmp_cptr, sizeof(char), ptr_idx, + stream->fh); + } + else if (stream->type[var_idx] == OUT_TYPE_SINT) { + for (elem_idx = 0; elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_siptr[ptr_idx++] = + (short int) stream->aggdata[0][var_idx][elem_idx][0]; } - else if (out_data[out_data_files[file_idx].varid[var_idx]].type - == - OUT_TYPE_USINT) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_usiptr[ptr_idx++] = - (unsigned short int)out_data[out_data_files[file_idx - ]. - varid[var_idx]].aggdata - [elem_idx]; - } - fwrite(tmp_usiptr, sizeof(unsigned short int), ptr_idx, - out_data_files[file_idx].fh); + fwrite(tmp_siptr, sizeof(short int), ptr_idx, + stream->fh); + } + else if (stream->type[var_idx] == OUT_TYPE_USINT) { + for (elem_idx = 0; + elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_usiptr[ptr_idx++] = + (unsigned short int) stream->aggdata[var_idx][elem_idx][ + 0]; } - else if (out_data[out_data_files[file_idx].varid[var_idx]].type - == - OUT_TYPE_INT) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_iptr[ptr_idx++] = - (int)out_data[out_data_files[file_idx].varid[var_idx - ]]. - aggdata[elem_idx]; - } - fwrite(tmp_iptr, sizeof(int), ptr_idx, - out_data_files[file_idx].fh); + fwrite(tmp_usiptr, sizeof(unsigned short int), ptr_idx, + stream->fh); + } + else if (stream->type[var_idx] == OUT_TYPE_INT) { + for (elem_idx = 0; + elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_iptr[ptr_idx++] = + (int) stream->aggdata[0][var_idx][elem_idx][0]; } - else if (out_data[out_data_files[file_idx].varid[var_idx]].type - == - OUT_TYPE_FLOAT) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_fptr[ptr_idx++] = - (float)out_data[out_data_files[file_idx].varid[ - var_idx]] - .aggdata[elem_idx]; - } - fwrite(tmp_fptr, sizeof(float), ptr_idx, - out_data_files[file_idx].fh); + fwrite(tmp_iptr, sizeof(int), ptr_idx, + stream->fh); + } + else if (stream->type[var_idx] == OUT_TYPE_FLOAT) { + for (elem_idx = 0; + elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_fptr[ptr_idx++] = + (float) stream->aggdata[0][var_idx][elem_idx][0]; } - else if (out_data[out_data_files[file_idx].varid[var_idx]].type - == - OUT_TYPE_DOUBLE) { - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - tmp_dptr[ptr_idx++] = - (double)out_data[out_data_files[file_idx].varid[ - var_idx] - ].aggdata[elem_idx]; - } - fwrite(tmp_dptr, sizeof(double), ptr_idx, - out_data_files[file_idx].fh); + fwrite(tmp_fptr, sizeof(float), ptr_idx, + stream->fh); + } + else if (stream->type[var_idx] == OUT_TYPE_DOUBLE) { + for (elem_idx = 0; + elem_idx < out_metadata[varid].nelem; + elem_idx++) { + tmp_dptr[ptr_idx++] = + (double) stream->aggdata[0][var_idx][elem_idx][0]; } + fwrite(tmp_dptr, sizeof(double), ptr_idx, + stream->fh); } } @@ -184,43 +151,36 @@ write_data(out_data_file_struct *out_data_files, free((char *) tmp_fptr); free((char *) tmp_dptr); } - else if (options.OUT_FORMAT == ASCII) { - // Loop over output files - for (file_idx = 0; file_idx < options.Noutfiles; file_idx++) { - // Write the date - if (dt < SEC_PER_DAY) { - // Write year, month, day, and sec - fprintf(out_data_files[file_idx].fh, - "%04u\t%02hu\t%02hu\t%05u\t", - dmy->year, dmy->month, dmy->day, dmy->dayseconds); - } - else { - // Only write year, month, and day - fprintf(out_data_files[file_idx].fh, - "%04u\t%02hu\t%02hu\t", - dmy->year, dmy->month, dmy->day); - } + else if (stream->file_format == ASCII) { + // Write the date + if (stream->agg_alarm.is_subdaily) { + // Write year, month, day, and sec + fprintf(stream->fh, + "%04u\t%02hu\t%02hu\t%05u\t", + dmy->year, dmy->month, dmy->day, dmy->dayseconds); + } + else { + // Only write year, month, and day + fprintf(stream->fh, + "%04u\t%02hu\t%02hu\t", + dmy->year, dmy->month, dmy->day); + } - // Loop over this output file's data variables - for (var_idx = 0; - var_idx < out_data_files[file_idx].nvars; - var_idx++) { - // Loop over this variable's elements - for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; - elem_idx++) { - if (!(var_idx == 0 && elem_idx == 0)) { - fprintf(out_data_files[file_idx].fh, "\t "); - } - fprintf(out_data_files[file_idx].fh, - out_data[out_data_files[file_idx].varid[var_idx]].format, - out_data[out_data_files[file_idx].varid[var_idx]].aggdata[ - elem_idx]); + // Loop over this output file's data variables + for (var_idx = 0; var_idx < stream->nvars; var_idx++) { + varid = stream->varid[var_idx]; + // Loop over this variable's elements + for (elem_idx = 0; elem_idx < out_metadata[varid].nelem; + elem_idx++) { + if (!(var_idx == 0 && elem_idx == 0)) { + fprintf(stream->fh, "\t "); } + fprintf(stream->fh, + stream->format[var_idx], + stream->aggdata[0][var_idx][elem_idx][0]); } - fprintf(out_data_files[file_idx].fh, "\n"); } + fprintf(stream->fh, "\n"); } else { log_err("Unrecognized OUT_FORMAT option"); diff --git a/vic/drivers/classic/src/write_forcing_file.c b/vic/drivers/classic/src/write_forcing_file.c deleted file mode 100644 index aea3592fe..000000000 --- a/vic/drivers/classic/src/write_forcing_file.c +++ /dev/null @@ -1,125 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * This routine writes the complete forcing data files for use in future - * simulations. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Write forcing data files for use in future simulations. - *****************************************************************************/ -void -write_forcing_file(atmos_data_struct *atmos, - int nrecs, - out_data_file_struct *out_data_files, - out_data_struct *out_data, - dmy_struct *dmy) -{ - extern global_param_struct global_param; - extern option_struct options; - extern parameters_struct param; - - int rec, v; - unsigned i; - size_t j; - double dt_sec; - - dt_sec = global_param.dt; - - for (rec = 0; rec < nrecs; rec++) { - for (j = 0; j < NF; j++) { - out_data[OUT_AIR_TEMP].data[0] = atmos[rec].air_temp[j]; - out_data[OUT_DENSITY].data[0] = atmos[rec].density[j]; - out_data[OUT_LWDOWN].data[0] = atmos[rec].longwave[j]; - out_data[OUT_PREC].data[0] = atmos[rec].prec[j]; - out_data[OUT_PRESSURE].data[0] = atmos[rec].pressure[j] / - PA_PER_KPA; - out_data[OUT_QAIR].data[0] = CONST_EPS * atmos[rec].vp[j] / - atmos[rec].pressure[j]; - out_data[OUT_REL_HUMID].data[0] = FRACT_TO_PERCENT * - atmos[rec].vp[j] / - (atmos[rec].vp[j] + - atmos[rec].vpd[j]); - out_data[OUT_SWDOWN].data[0] = atmos[rec].shortwave[j]; - out_data[OUT_VP].data[0] = atmos[rec].vp[j] / PA_PER_KPA; - out_data[OUT_VPD].data[0] = atmos[rec].vpd[j] / PA_PER_KPA; - out_data[OUT_WIND].data[0] = atmos[rec].wind[j]; - if (out_data[OUT_AIR_TEMP].data[0] >= param.SNOW_MAX_SNOW_TEMP) { - out_data[OUT_RAINF].data[0] = out_data[OUT_PREC].data[0]; - out_data[OUT_SNOWF].data[0] = 0; - } - else if (out_data[OUT_AIR_TEMP].data[0] <= - param.SNOW_MIN_RAIN_TEMP) { - out_data[OUT_RAINF].data[0] = 0; - out_data[OUT_SNOWF].data[0] = out_data[OUT_PREC].data[0]; - } - else { - out_data[OUT_RAINF].data[0] = - ((out_data[OUT_AIR_TEMP].data[0] - - param.SNOW_MIN_RAIN_TEMP) / - (param.SNOW_MAX_SNOW_TEMP - - param.SNOW_MIN_RAIN_TEMP)) * out_data[OUT_PREC].data[0]; - out_data[OUT_SNOWF].data[0] = out_data[OUT_PREC].data[0] - - out_data[OUT_RAINF].data[0]; - } - if (options.CARBON) { - out_data[OUT_CATM].data[0] = atmos[rec].Catm[j] / - PPM_to_MIXRATIO; - out_data[OUT_FDIR].data[0] = atmos[rec].fdir[j]; - out_data[OUT_PAR].data[0] = atmos[rec].par[j]; - } - else { - out_data[OUT_CATM].data[0] = MISSING; - out_data[OUT_FDIR].data[0] = MISSING; - out_data[OUT_PAR].data[0] = MISSING; - } - - for (v = 0; v < N_OUTVAR_TYPES; v++) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] = out_data[v].data[i]; - } - } - - if (options.ALMA_OUTPUT) { - out_data[OUT_PREC].aggdata[0] /= dt_sec; - out_data[OUT_RAINF].aggdata[0] /= dt_sec; - out_data[OUT_SNOWF].aggdata[0] /= dt_sec; - out_data[OUT_AIR_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_PRESSURE].aggdata[0] *= PA_PER_KPA; - out_data[OUT_VP].aggdata[0] *= PA_PER_KPA; - out_data[OUT_VPD].aggdata[0] *= PA_PER_KPA; - } - - if (options.OUT_FORMAT == BINARY) { - for (v = 0; v < N_OUTVAR_TYPES; v++) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] *= out_data[v].mult; - } - } - } - write_data(out_data_files, out_data, &dmy[rec], global_param.dt); - } - } -} diff --git a/vic/drivers/classic/src/write_header.c b/vic/drivers/classic/src/write_header.c index 162e75adf..751e1acd9 100644 --- a/vic/drivers/classic/src/write_header.c +++ b/vic/drivers/classic/src/write_header.c @@ -30,69 +30,62 @@ * @brief Write a header for all output files. *****************************************************************************/ void -write_header(out_data_file_struct *out_data_files, - out_data_struct *out_data, - dmy_struct *dmy, - global_param_struct global) +write_header(stream_struct **streams, + dmy_struct *dmy) { - extern option_struct options; - size_t file_idx; - size_t var_idx; - unsigned elem_idx; - size_t i; - unsigned short int Identifier; - unsigned short int Nbytes; - unsigned short int Nbytes1; - unsigned short int Nbytes2; - char tmp_ALMA_OUTPUT; - size_t Nvars; - char tmp_len; - char *tmp_str; - char tmp_type; - float tmp_mult; - - if (options.ALMA_OUTPUT) { - tmp_ALMA_OUTPUT = 1; - } - else { - tmp_ALMA_OUTPUT = 0; - } + extern option_struct options; + extern global_param_struct global_param; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t stream_idx; + size_t var_idx; + unsigned elem_idx; + size_t i; + unsigned int varid; + unsigned short int Identifier; + unsigned short int Nbytes; + unsigned short int Nbytes1; + unsigned short int Nbytes2; + size_t nvars; + char tmp_len; + char *tmp_str; + char tmp_type; + float tmp_mult; + + + // Loop over output files + for (stream_idx = 0; stream_idx < options.Noutstreams; stream_idx++) { + if ((*streams)[stream_idx].file_format == BINARY) { + tmp_str = calloc(BINHEADERSIZE, sizeof(*tmp_str)); + + // Binary header format: + // + // Data Stored As Comment + // + // Identifier (unsigned short)*4 0xFFFF, repeated 4 times + // Nbytes (unsigned short)*1 Number of bytes in the header, + // INCLUDING THE IDENTIFIER + // + // Part 1: Global Attributes + // Nbytes1 (unsigned short)*1 Number of bytes in part 1 + // nrecs (int)*1 Number of records in the file + // startyear (int)*1 Year of first record + // startmonth (int)*1 Month of first record + // startday (int)*1 Day of first record + // startsec (int)*1 Second of first record + // nvars (char)*1 Number of variables in the file, including date fields + // + // Part 2: Variables + // Nbytes2 (unsigned short)*1 Number of bytes in part 2 + // For each variable, the following fields: { len varname type mult } + // len (char)*1 Number of characters in varname + // varname (char)*len Variable name + // type (char)*1 Code identifying variable type + // mult (float)*1 Multiplier for variable + + // Identifier + Identifier = 0xFFFF; - if (options.OUT_FORMAT == BINARY) { - tmp_str = calloc(BINHEADERSIZE, sizeof(*tmp_str)); - - // Binary header format: - // - // Data Stored As Comment - // - // Identifier (unsigned short)*4 0xFFFF, repeated 4 times - // Nbytes (unsigned short)*1 Number of bytes in the header, - // INCLUDING THE IDENTIFIER - // - // Part 1: Global Attributes - // Nbytes1 (unsigned short)*1 Number of bytes in part 1 - // nrecs (int)*1 Number of records in the file - // dt (int)*1 Output time step length in seconds - // startyear (int)*1 Year of first record - // startmonth (int)*1 Month of first record - // startday (int)*1 Day of first record - // startsec (int)*1 Second of first record - // ALMA_OUTPUT (char)*1 0 = standard VIC units; 1 = ALMA units - // Nvars (char)*1 Number of variables in the file, including date fields - // - // Part 2: Variables - // Nbytes2 (unsigned short)*1 Number of bytes in part 2 - // For each variable, the following fields: { len varname type mult } - // len (char)*1 Number of characters in varname - // varname (char)*len Variable name - // type (char)*1 Code identifying variable type - // mult (float)*1 Multiplier for variable - - // Identifier - Identifier = 0xFFFF; - - // Loop over output files - for (file_idx = 0; file_idx < options.Noutfiles; file_idx++) { // ***** Compute the number of bytes in part 1 ***** // 1 instance of Nbytes1 @@ -101,17 +94,11 @@ write_header(out_data_file_struct *out_data_files, // nrecs Nbytes1 += sizeof(size_t); - // dt - Nbytes1 += sizeof(double); - // start date (year, month, day, sec) Nbytes1 += sizeof(int) + 2 * sizeof(unsigned short int) + sizeof(unsigned int); - // ALMA_OUTPUT - Nbytes1 += sizeof(bool); - - // Nvars + // nvars Nbytes1 += sizeof(size_t); // ***** Compute the number of bytes in part 2 ***** @@ -126,30 +113,26 @@ write_header(out_data_file_struct *out_data_files, sizeof(float); // month Nbytes2 += sizeof(char) + 3 * sizeof(char) + sizeof(char) + sizeof(float); // day - if (global.out_dt < SEC_PER_DAY) { + if ((*streams)[stream_idx].agg_alarm.is_subdaily) { Nbytes2 += sizeof(char) + 4 * sizeof(char) + sizeof(char) + sizeof(float); // sec } // Loop over this output file's data variables - for (var_idx = 0; - var_idx < out_data_files[file_idx].nvars; + for (var_idx = 0; var_idx < (*streams)[stream_idx].nvars; var_idx++) { + varid = (*streams)[stream_idx].varid[var_idx]; // Loop over this variable's elements for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; + elem_idx < out_metadata[varid].nelem; elem_idx++) { - if (out_data[out_data_files[file_idx].varid[var_idx]].nelem - > - 1) { - sprintf(tmp_str, "%s_%d", - out_data[out_data_files[file_idx].varid[var_idx]].varname, + if (out_metadata[varid].nelem > 1) { + sprintf(tmp_str, "%s_%d", out_metadata[varid].varname, elem_idx); } else { strcpy(tmp_str, - out_data[out_data_files[file_idx].varid[var_idx]].varname); + out_metadata[varid].varname); } Nbytes2 += sizeof(char) + strlen(tmp_str) * sizeof(char) + sizeof(char) + sizeof(float); @@ -167,51 +150,44 @@ write_header(out_data_file_struct *out_data_files, // 4 instances of Identifier for (i = 0; i < 4; i++) { fwrite(&Identifier, sizeof(unsigned short), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); } // Nbytes fwrite(&Nbytes, sizeof(unsigned short), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); // Nbytes1 fwrite(&Nbytes1, sizeof(unsigned short), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); // nrecs - fwrite(&(global.nrecs), sizeof(size_t), 1, - out_data_files[file_idx].fh); - - // dt - fwrite(&(global.out_dt), sizeof(double), 1, - out_data_files[file_idx].fh); + fwrite(&(global_param.nrecs), sizeof(size_t), 1, + (*streams)[stream_idx].fh); // start date (year, month, day, sec) - fwrite(&(dmy->year), sizeof(int), 1, out_data_files[file_idx].fh); + fwrite(&(dmy->year), sizeof(int), 1, + (*streams)[stream_idx].fh); fwrite(&(dmy->month), sizeof(unsigned short int), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(&(dmy->day), sizeof(unsigned short int), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(&(dmy->dayseconds), sizeof(unsigned int), 1, - out_data_files[file_idx].fh); - - // ALMA_OUTPUT - fwrite(&tmp_ALMA_OUTPUT, sizeof(bool), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); - // Nvars - Nvars = out_data_files[file_idx].nvars; - if (global.out_dt < SEC_PER_DAY) { - Nvars += 4; + // nvars + nvars = (*streams)[stream_idx].nvars; + if ((*streams)[stream_idx].agg_alarm.is_subdaily) { + nvars += 4; } else { - Nvars += 3; + nvars += 3; } - fwrite(&Nvars, sizeof(size_t), 1, out_data_files[file_idx].fh); + fwrite(&nvars, sizeof(size_t), 1, (*streams)[stream_idx].fh); // Nbytes2 fwrite(&Nbytes2, sizeof(unsigned short), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); // Date fields tmp_type = OUT_TYPE_INT; @@ -220,155 +196,140 @@ write_header(out_data_file_struct *out_data_files, // year strcpy(tmp_str, "YEAR"); tmp_len = strlen(tmp_str); - fwrite(&tmp_len, sizeof(char), 1, out_data_files[file_idx].fh); + fwrite(&tmp_len, sizeof(char), 1, (*streams)[stream_idx].fh); fwrite(tmp_str, sizeof(char), tmp_len, - out_data_files[file_idx].fh); - fwrite(&tmp_type, sizeof(char), 1, out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); + fwrite(&tmp_type, sizeof(char), 1, + (*streams)[stream_idx].fh); fwrite(&tmp_mult, sizeof(float), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); // month strcpy(tmp_str, "MONTH"); tmp_len = strlen(tmp_str); - fwrite(&tmp_len, sizeof(char), 1, out_data_files[file_idx].fh); + fwrite(&tmp_len, sizeof(char), 1, (*streams)[stream_idx].fh); fwrite(tmp_str, sizeof(char), tmp_len, - out_data_files[file_idx].fh); - fwrite(&tmp_type, sizeof(char), 1, out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); + fwrite(&tmp_type, sizeof(char), 1, + (*streams)[stream_idx].fh); fwrite(&tmp_mult, sizeof(float), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); // day strcpy(tmp_str, "DAY"); tmp_len = strlen(tmp_str); - fwrite(&tmp_len, sizeof(char), 1, out_data_files[file_idx].fh); + fwrite(&tmp_len, sizeof(char), 1, (*streams)[stream_idx].fh); fwrite(tmp_str, sizeof(char), tmp_len, - out_data_files[file_idx].fh); - fwrite(&tmp_type, sizeof(char), 1, out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); + fwrite(&tmp_type, sizeof(char), 1, + (*streams)[stream_idx].fh); fwrite(&tmp_mult, sizeof(float), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); - if (global.out_dt < SEC_PER_DAY) { + if ((*streams)[stream_idx].agg_alarm.is_subdaily) { // sec strcpy(tmp_str, "SEC"); tmp_len = strlen(tmp_str); fwrite(&tmp_len, sizeof(char), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(tmp_str, sizeof(char), tmp_len, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(&tmp_type, sizeof(char), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(&tmp_mult, sizeof(float), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); } // Loop over this output file's data variables - for (var_idx = 0; - var_idx < out_data_files[file_idx].nvars; + for (var_idx = 0; var_idx < (*streams)[stream_idx].nvars; var_idx++) { + varid = (*streams)[stream_idx].varid[var_idx]; // Loop over this variable's elements for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; + elem_idx < out_metadata[varid].nelem; elem_idx++) { - if (out_data[out_data_files[file_idx].varid[var_idx]].nelem - > - 1) { - sprintf(tmp_str, "%s_%d", - out_data[out_data_files[file_idx].varid[var_idx]].varname, + if (out_metadata[varid].nelem > 1) { + sprintf(tmp_str, "%s_%d", out_metadata[varid].varname, elem_idx); } else { - strcpy(tmp_str, - out_data[out_data_files[file_idx].varid[var_idx]].varname); + strcpy(tmp_str, out_metadata[varid].varname); } tmp_len = strlen(tmp_str); fwrite(&tmp_len, sizeof(char), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); fwrite(tmp_str, sizeof(char), tmp_len, - out_data_files[file_idx].fh); - tmp_type = - out_data[out_data_files[file_idx].varid[var_idx]].type; + (*streams)[stream_idx].fh); + tmp_type = (*streams)[stream_idx].type[var_idx]; fwrite(&tmp_type, sizeof(char), 1, - out_data_files[file_idx].fh); - tmp_mult = - out_data[out_data_files[file_idx].varid[var_idx]].mult; + (*streams)[stream_idx].fh); + tmp_mult = (*streams)[stream_idx].mult[var_idx]; fwrite(&tmp_mult, sizeof(float), 1, - out_data_files[file_idx].fh); + (*streams)[stream_idx].fh); } } } - } - else if (options.OUT_FORMAT == ASCII) { - // ASCII header format: - // - // # NRECS: (nrecs) - // # DT: (dt) - // # STARTDATE: yyyy-mm-dd hh:00:00 - // # ALMA_OUTPUT: (0 or 1) - // # NVARS: (Nvars) - // # VARNAME VARNAME VARNAME ... - // - // where - // nrecs = Number of records in the file - // dt = Output time step length in seconds - // start date = Date and time of first record of file - // ALMA_OUTPUT = Indicates units of the variables; 0 = standard VIC units; 1 = ALMA units - // Nvars = Number of variables in the file, including date fields - - // Loop over output files - for (file_idx = 0; file_idx < options.Noutfiles; file_idx++) { + else if ((*streams)[stream_idx].file_format == ASCII) { + // ASCII header format: + // + // # NRECS: (nrecs) + // # STARTDATE: yyyy-mm-dd hh:00:00 + // # NVARS: (nvars) + // # VARNAME VARNAME VARNAME ... + // + // where + // nrecs = Number of records in the file + // start date = Date and time of first record of file + // nvars = Number of variables in the file, including date fields + // Header part 1: Global attributes - Nvars = out_data_files[file_idx].nvars; - if (global.out_dt < SEC_PER_DAY) { - Nvars += 4; + nvars = (*streams)[stream_idx].nvars; + if ((*streams)[stream_idx].agg_alarm.is_subdaily) { + nvars += 4; } else { - Nvars += 3; + nvars += 3; } - fprintf(out_data_files[file_idx].fh, "# SIMULATION: %s\n", - out_data_files[file_idx].prefix); - fprintf(out_data_files[file_idx].fh, "# MODEL_VERSION: %s\n", + fprintf((*streams)[stream_idx].fh, "# SIMULATION: %s\n", + (*streams)[stream_idx].prefix); + fprintf((*streams)[stream_idx].fh, "# MODEL_VERSION: %s\n", SHORT_VERSION); - fprintf(out_data_files[file_idx].fh, "# ALMA_UNITS: %s\n", - tmp_ALMA_OUTPUT ? "True" : "False"); // Header part 2: Variables // Write the date - if (global.out_dt < SEC_PER_DAY) { + if ((*streams)[stream_idx].agg_alarm.is_subdaily) { // Write year, month, day, and sec - fprintf(out_data_files[file_idx].fh, + fprintf((*streams)[stream_idx].fh, "YEAR\tMONTH\tDAY\tSEC\t"); } else { // Only write year, month, and day - fprintf(out_data_files[file_idx].fh, "YEAR\tMONTH\tDAY\t"); + fprintf((*streams)[stream_idx].fh, "YEAR\tMONTH\tDAY\t"); } // Loop over this output file's data variables - for (var_idx = 0; - var_idx < out_data_files[file_idx].nvars; + for (var_idx = 0; var_idx < (*streams)[stream_idx].nvars; var_idx++) { + varid = (*streams)[stream_idx].varid[var_idx]; // Loop over this variable's elements for (elem_idx = 0; - elem_idx < - out_data[out_data_files[file_idx].varid[var_idx]].nelem; + elem_idx < out_metadata[varid].nelem; elem_idx++) { if (!(var_idx == 0 && elem_idx == 0)) { - fprintf(out_data_files[file_idx].fh, "\t "); + fprintf((*streams)[stream_idx].fh, "\t "); } - fprintf(out_data_files[file_idx].fh, "%s", - out_data[out_data_files[file_idx].varid[var_idx]].varname); - if (out_data[out_data_files[file_idx].varid[var_idx]].nelem - > - 1) { - fprintf(out_data_files[file_idx].fh, "_%d", elem_idx); + fprintf((*streams)[stream_idx].fh, "%s", + out_metadata[varid].varname); + if (out_metadata[varid].nelem > 1) { + fprintf((*streams)[stream_idx].fh, "_%d", + elem_idx); } } } - fprintf(out_data_files[file_idx].fh, "\n"); + fprintf((*streams)[stream_idx].fh, "\n"); + } + else { + log_err("Unrecognized OUT_FORMAT option"); } - } - else { - log_err("Unrecognized OUT_FORMAT option"); } } diff --git a/vic/drivers/classic/src/write_output.c b/vic/drivers/classic/src/write_output.c index ada71a11d..d9b2acbd5 100644 --- a/vic/drivers/classic/src/write_output.c +++ b/vic/drivers/classic/src/write_output.c @@ -30,105 +30,18 @@ * @brief Write output data and convert units if necessary. *****************************************************************************/ void -write_output(out_data_struct *out_data, - out_data_file_struct *out_data_files, - dmy_struct *dmy, - int rec) +write_output(stream_struct **streams, + dmy_struct *dmy) { - extern global_param_struct global_param; - extern option_struct options; + extern option_struct options; - unsigned i; - size_t index; - double out_dt_sec; - int v; + size_t stream_idx; - out_dt_sec = global_param.out_dt; - - /*********************************************** - Change of units for ALMA-compliant output - ***********************************************/ - if (options.ALMA_OUTPUT) { - out_data[OUT_BASEFLOW].aggdata[0] /= out_dt_sec; - out_data[OUT_EVAP].aggdata[0] /= out_dt_sec; - out_data[OUT_EVAP_BARE].aggdata[0] /= out_dt_sec; - out_data[OUT_EVAP_CANOP].aggdata[0] /= out_dt_sec; - out_data[OUT_INFLOW].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_BF_IN].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_BF_IN_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_BF_OUT].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_BF_OUT_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_CHAN_IN].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_CHAN_IN_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_CHAN_OUT].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_CHAN_OUT_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_DSTOR].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_DSTOR_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_DSWE].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_DSWE_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_EVAP].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_EVAP_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_ICE_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_LAKE_PREC_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_RCHRG].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_RCHRG_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_RO_IN].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_RO_IN_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_VAPFLX].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_VAPFLX_V].aggdata[0] /= out_dt_sec; - out_data[OUT_LAKE_SURF_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_PREC].aggdata[0] /= out_dt_sec; - out_data[OUT_RAINF].aggdata[0] /= out_dt_sec; - out_data[OUT_REFREEZE].aggdata[0] /= out_dt_sec; - out_data[OUT_RUNOFF].aggdata[0] /= out_dt_sec; - out_data[OUT_SNOW_MELT].aggdata[0] /= out_dt_sec; - out_data[OUT_SNOWF].aggdata[0] /= out_dt_sec; - out_data[OUT_SUB_BLOWING].aggdata[0] /= out_dt_sec; - out_data[OUT_SUB_CANOP].aggdata[0] /= out_dt_sec; - out_data[OUT_SUB_SNOW].aggdata[0] /= out_dt_sec; - out_data[OUT_SUB_SNOW].aggdata[0] += out_data[OUT_SUB_CANOP].aggdata[0]; - out_data[OUT_SUB_SURFACE].aggdata[0] /= out_dt_sec; - out_data[OUT_TRANSP_VEG].aggdata[0] /= out_dt_sec; - out_data[OUT_BARESOILT].aggdata[0] += CONST_TKFRZ; - out_data[OUT_SNOW_PACK_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_SNOW_SURF_TEMP].aggdata[0] += CONST_TKFRZ; - for (index = 0; index < options.Nlayer; index++) { - out_data[OUT_SOIL_TEMP].aggdata[index] += CONST_TKFRZ; - } - for (index = 0; index < options.Nnode; index++) { - out_data[OUT_SOIL_TNODE].aggdata[index] += CONST_TKFRZ; - out_data[OUT_SOIL_TNODE_WL].aggdata[index] += CONST_TKFRZ; - } - out_data[OUT_SURF_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_VEGT].aggdata[0] += CONST_TKFRZ; - out_data[OUT_FDEPTH].aggdata[0] /= CM_PER_M; - out_data[OUT_TDEPTH].aggdata[0] /= CM_PER_M; - out_data[OUT_DELTACC].aggdata[0] *= out_dt_sec; - out_data[OUT_DELTAH].aggdata[0] *= out_dt_sec; - out_data[OUT_AIR_TEMP].aggdata[0] += CONST_TKFRZ; - out_data[OUT_PRESSURE].aggdata[0] *= PA_PER_KPA; - out_data[OUT_VP].aggdata[0] *= PA_PER_KPA; - out_data[OUT_VPD].aggdata[0] *= PA_PER_KPA; - } - - /************* - Write Data - *************/ - if (rec >= global_param.skipyear) { - if (options.OUT_FORMAT == BINARY) { - for (v = 0; v < N_OUTVAR_TYPES; v++) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] *= out_data[v].mult; - } - } - } - write_data(out_data_files, out_data, dmy, global_param.out_dt); - } - - // Reset the agg data - for (v = 0; v < N_OUTVAR_TYPES; v++) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] = 0; + // Write data + for (stream_idx = 0; stream_idx < options.Noutstreams; stream_idx++) { + if (raise_alarm(&(*streams)[stream_idx].agg_alarm, dmy)) { + write_data(&((*streams)[stream_idx]), dmy); + reset_stream((&(*streams)[stream_idx]), dmy); } } } diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 8f99b7f33..25d2513d8 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -435,49 +435,5 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Output Data:\n"); fprintf(LOG_DEST, "Result dir:\t\t%s\n", filenames.result_dir); - fprintf(LOG_DEST, "OUT_STEP\t\t%f\n", global_param.out_dt); - if (options.ALMA_OUTPUT) { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tFALSE\n"); - } - if (options.OUT_FORMAT == NETCDF3_CLASSIC) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF3_CLASSIC\n"); - } - else if (options.OUT_FORMAT == NETCDF3_64BIT_OFFSET) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF3_64BIT_OFFSET\n"); - } - else if (options.OUT_FORMAT == NETCDF4_CLASSIC) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF4_CLASSIC\n"); - } - else if (options.OUT_FORMAT == NETCDF4) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tNETCDF4\n"); - } - if (options.COMPRESS) { - fprintf(LOG_DEST, "COMPRESS\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "COMPRESS\t\tFALSE\n"); - } - if (options.MOISTFRACT) { - fprintf(LOG_DEST, "MOISTFRACT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "MOISTFRACT\t\tFALSE\n"); - } - if (options.PRT_HEADER) { - fprintf(LOG_DEST, "PRT_HEADER\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_HEADER\t\tFALSE\n"); - } - if (options.PRT_SNOW_BAND) { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tFALSE\n"); - } - fprintf(LOG_DEST, "SKIPYEAR\t\t%d\n", global_param.skipyear); fprintf(LOG_DEST, "\n"); } diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 48eec7423..b5a886ada 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -107,160 +107,95 @@ get_global_param(FILE *gp) } else if (strcasecmp("CALENDAR", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - global_param.calendar = calendar_from_chars(flgstr); + global_param.calendar = str_to_calendar(flgstr); } else if (strcasecmp("OUT_TIME_UNITS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - global_param.time_units = timeunits_from_chars(flgstr); + global_param.time_units = str_to_timeunits(flgstr); } else if (strcasecmp("FULL_ENERGY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.FULL_ENERGY = true; - } - else { - options.FULL_ENERGY = false; - } + options.FULL_ENERGY = str_to_bool(flgstr); } else if (strcasecmp("FROZEN_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.FROZEN_SOIL = true; + options.FROZEN_SOIL = str_to_bool(flgstr); + // TODO: move these steps to a option validation + if (options.FROZEN_SOIL) { options.QUICK_FLUX = false; } else { - options.FROZEN_SOIL = false; options.IMPLICIT = false; options.EXP_TRANS = false; } } else if (strcasecmp("QUICK_FLUX", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_FLUX = true; - } - else { - options.QUICK_FLUX = false; - } + options.QUICK_FLUX = str_to_bool(flgstr); } else if (strcasecmp("QUICK_SOLVE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.QUICK_SOLVE = true; - } - else { - options.QUICK_SOLVE = false; - } + options.QUICK_SOLVE = str_to_bool(flgstr); } else if ((strcasecmp("NOFLUX", optstr) == 0) || (strcasecmp("NO_FLUX", optstr) == 0)) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { - options.NOFLUX = true; - } - else { - options.NOFLUX = false; + options.NOFLUX = str_to_bool(flgstr); } } else if (strcasecmp("IMPLICIT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.IMPLICIT = true; - } - else { - options.IMPLICIT = false; - } + options.IMPLICIT = str_to_bool(flgstr); } else if (strcasecmp("EXP_TRANS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.EXP_TRANS = true; - } - else { - options.EXP_TRANS = false; - } + options.EXP_TRANS = str_to_bool(flgstr); } else if (strcasecmp("SNOW_DENSITY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("DENS_SNTHRM", flgstr) == 0) { options.SNOW_DENSITY = DENS_SNTHRM; } - else { + else if (strcasecmp("DENS_BRAS", flgstr) == 0) { options.SNOW_DENSITY = DENS_BRAS; } + else { + log_err("Unknown SNOW_DENSITY option: %s", flgstr); + } } else if (strcasecmp("BLOWING", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING = true; - } - else { - options.BLOWING = false; - } + options.BLOWING = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_VAR_THRESHOLD", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_VAR_THRESHOLD = true; - } - else { - options.BLOWING_VAR_THRESHOLD = false; - } + options.BLOWING_VAR_THRESHOLD = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_CALC_PROB", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_CALC_PROB = true; - } - else { - options.BLOWING_CALC_PROB = false; - } + options.BLOWING_CALC_PROB = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SIMPLE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SIMPLE = true; - } - else { - options.BLOWING_SIMPLE = false; - } + options.BLOWING_SIMPLE = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_FETCH", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_FETCH = true; - } - else { - options.BLOWING_FETCH = false; - } + options.BLOWING_FETCH = str_to_bool(flgstr); } else if (strcasecmp("BLOWING_SPATIAL_WIND", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.BLOWING_SPATIAL_WIND = true; - } - else { - options.BLOWING_SPATIAL_WIND = false; - } + options.BLOWING_SPATIAL_WIND = str_to_bool(flgstr); } else if (strcasecmp("CORRPREC", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CORRPREC = true; - } - else { - options.CORRPREC = false; - } + options.CORRPREC = str_to_bool(flgstr); } else if (strcasecmp("CLOSE_ENERGY", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CLOSE_ENERGY = true; - } - else { - options.CLOSE_ENERGY = false; - } + options.CLOSE_ENERGY = str_to_bool(flgstr); } else if (strcasecmp("COMPUTE_TREELINE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -286,6 +221,9 @@ get_global_param(FILE *gp) else if (strcasecmp("AR_410", flgstr) == 0) { options.AERO_RESIST_CANSNOW = AR_410; } + else { + log_err("Unknown AERO_RESIST_CANSNOW option: %s", flgstr); + } } else if (strcasecmp("GRND_FLUX_TYPE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -295,6 +233,9 @@ get_global_param(FILE *gp) else if (strcasecmp("GF_410", flgstr) == 0) { options.GRND_FLUX_TYPE = GF_410; } + else { + log_err("Unknown GRND_FLUX_TYPE option: %s", flgstr); + } } else if (strcasecmp("SPATIAL_FROST", optstr) == 0) { sscanf(cmdstr, "%*s %s %s", flgstr, flgstr2); @@ -308,51 +249,34 @@ get_global_param(FILE *gp) } else if (strcasecmp("SPATIAL_SNOW", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SPATIAL_SNOW = true; - } - else { - options.SPATIAL_SNOW = false; - } + options.SPATIAL_SNOW = str_to_bool(flgstr); } else if (strcasecmp("TFALLBACK", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.TFALLBACK = true; - } - else { - options.TFALLBACK = false; - } + options.TFALLBACK = str_to_bool(flgstr); } else if (strcasecmp("SHARE_LAYER_MOIST", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.SHARE_LAYER_MOIST = true; - } - else { - options.SHARE_LAYER_MOIST = false; - } + options.SHARE_LAYER_MOIST = str_to_bool(flgstr); } else if (strcasecmp("CANOPY_LAYERS", optstr) == 0) { sscanf(cmdstr, "%*s %zu", &options.Ncanopy); } else if (strcasecmp("CARBON", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.CARBON = true; - } - else { - options.CARBON = false; - } + options.CARBON = str_to_bool(flgstr); } else if (strcasecmp("RC_MODE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("RC_PHOTO", flgstr) == 0) { options.RC_MODE = RC_PHOTO; } - else { + else if (strcasecmp("RC_JARVIS", flgstr) == 0) { options.RC_MODE = RC_JARVIS; } + else { + log_err("Unknown RC_MODE option: %s", flgstr); + } } /************************************* @@ -494,39 +418,27 @@ get_global_param(FILE *gp) if (strcasecmp("NIJSSEN2001", flgstr) == 0) { options.BASEFLOW = NIJSSEN2001; } - else { + else if (strcasecmp("ARNO", flgstr) == 0) { options.BASEFLOW = ARNO; } + else { + log_err("Unknown BASEFLOW option: %s", flgstr); + } } else if (strcasecmp("JULY_TAVG_SUPPLIED", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.JULY_TAVG_SUPPLIED = false; - } - else { - options.JULY_TAVG_SUPPLIED = true; - } + options.JULY_TAVG_SUPPLIED = str_to_bool(flgstr); } else if (strcasecmp("ORGANIC_FRACT", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.ORGANIC_FRACT = false; - } - else { - options.ORGANIC_FRACT = true; - } + options.ORGANIC_FRACT = str_to_bool(flgstr); } else if (strcasecmp("VEGLIB", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veglib); } else if (strcasecmp("VEGLIB_PHOTO", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.VEGLIB_PHOTO = true; - } - else { - options.VEGLIB_PHOTO = false; - } + options.VEGLIB_PHOTO = str_to_bool(flgstr); } else if (strcasecmp("VEGPARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.veg); @@ -601,12 +513,7 @@ get_global_param(FILE *gp) } else if (strcasecmp("LAKE_PROFILE", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("FALSE", flgstr) == 0) { - options.LAKE_PROFILE = false; - } - else { - options.LAKE_PROFILE = true; - } + options.LAKE_PROFILE = str_to_bool(flgstr); } /************************************* @@ -615,39 +522,6 @@ get_global_param(FILE *gp) else if (strcasecmp("RESULT_DIR", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.result_dir); } - else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { - sscanf(cmdstr, "%*s %zu", &global_param.output_steps_per_day); - } - else if (strcasecmp("SKIPYEAR", optstr) == 0) { - sscanf(cmdstr, "%*s %hu", &global_param.skipyear); - } - else if (strcasecmp("ALMA_OUTPUT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.ALMA_OUTPUT = true; - } - else { - options.ALMA_OUTPUT = false; - } - } - else if (strcasecmp("MOISTFRACT", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.MOISTFRACT = true; - } - else { - options.MOISTFRACT = false; - } - } - else if (strcasecmp("PRT_SNOW_BAND", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (strcasecmp("TRUE", flgstr) == 0) { - options.PRT_SNOW_BAND = true; - } - else { - options.PRT_SNOW_BAND = false; - } - } /************************************* Define output file contents @@ -658,6 +532,15 @@ get_global_param(FILE *gp) else if (strcasecmp("OUTVAR", optstr) == 0) { ; // do nothing } + else if (strcasecmp("AGGFREQ", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("COMPRESS", optstr) == 0) { + ; // do nothing + } + else if (strcasecmp("OUT_FORMAT", optstr) == 0) { + ; // do nothing + } // vegetation history not yet implemented in image mode // TBD: feature in VIC 4.2 that has been ported to classic // mode, but that does not exist in image mode (yet) @@ -668,77 +551,6 @@ get_global_param(FILE *gp) "in image mode"); } - /************************************* - Fail when deprecated options are used. - *************************************/ - else if (strcasecmp("TIME_STEP", optstr) == 0) { - log_err("TIME_STEP has been replaced with MODEL_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("SNOW_STEP", optstr) == 0) { - log_err("SNOW_STEP has been replaced with SNOW_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("OUT_STEP", optstr) == 0) { - log_err("OUT_STEP has been replaced with OUTPUT_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("FORCE_DT", optstr) == 0) { - log_err("FORCE_DT has been replaced with FORCE_STEPS_PER_DAY, " - "update your global parameter file accordingly"); - } - else if (strcasecmp("NLAYER", optstr) == 0) { - log_err("NLAYER has been deprecated in the image driver"); - } - else if (strcasecmp("FORCE_FORMAT", optstr) == 0) { - log_err("FORCE_FORMAT has been deprecated in the image driver"); - } - else if (strcasecmp("FORCE_ENDIAN", optstr) == 0) { - log_err("FORCE_ENDIAN has been deprecated in the image driver"); - } - else if (strcasecmp("GRID_DECIMAL", optstr) == 0) { - log_err("GRID_DECIMAL has been deprecated in the image driver"); - } - else if (strcasecmp("BINARY_STATE_FILE", optstr) == 0) { - log_err( - "BINARY_STATE_FILE has been deprecated in the image driver"); - } - else if (strcasecmp("RESOLUTION", optstr) == 0) { - log_err("RESOLUTION has been deprecated in the image driver"); - } - else if (strcasecmp("EQUAL_AREA", optstr) == 0) { - log_err("EQUAL_AREA has been deprecated in the image driver"); - } - else if (strcasecmp("CONTINUEONERROR", optstr) == 0) { - log_err( - "CONTINUEONERROR has been deprecated in the image driver"); - } - else if (strcasecmp("BINARY_OUTPUT", optstr) == 0) { - log_err("BINARY_OUTPUT has been deprecated in the image driver"); - } - else if (strcasecmp("COMPRESS", optstr) == 0) { - log_err("COMPRESS has been deprecated in the image driver"); - } - else if (strcasecmp("PRT_HEADER", optstr) == 0) { - log_err("PRT_HEADER has been deprecated in the image driver"); - } - else if (strcasecmp("FORCE_STEPS_PER_DAY", optstr) == 0) { - log_err( - "FORCE_STEPS_PER_DAY has been deprecated in the image driver"); - } - else if (strcasecmp("FORCEYEAR", optstr) == 0) { - log_err("FORCEYEAR has been deprecated in the image driver"); - } - else if (strcasecmp("FORCEMONTH", optstr) == 0) { - log_err("FORCEMONTH has been deprecated in the image driver"); - } - else if (strcasecmp("FORCEDAY", optstr) == 0) { - log_err("FORCEDAY has been deprecated in the image driver"); - } - else if (strcasecmp("FORCESEC", optstr) == 0) { - log_err("FORCESEC has been deprecated in the image driver"); - } - /************************************* Fail when classic driver specific options are used *************************************/ @@ -895,47 +707,6 @@ get_global_param(FILE *gp) global_param.atmos_dt = SEC_PER_DAY / (double) global_param.atmos_steps_per_day; - // Validate the output step - if (global_param.output_steps_per_day == 0) { - global_param.output_steps_per_day = global_param.model_steps_per_day; - } - if (global_param.output_steps_per_day > global_param.model_steps_per_day) { - log_err("Invalid value for OUTPUT_STEPS_PER_DAY (%zu). " - "OUTPUT_STEPS_PER_DAY must be <= MODEL_STEPS_PER_DAY (%zu)", - global_param.output_steps_per_day, - global_param.model_steps_per_day); - } - else if (global_param.model_steps_per_day % - global_param.output_steps_per_day != 0) { - log_err("Invalid value for OUTPUT_STEPS_PER_DAY (%zu). " - "MODEL_STEPS_PER_DAY (%zu) must be a multiple of " - "OUTPUT_STEPS_PER_DAY.", - global_param.output_steps_per_day, - global_param.model_steps_per_day); - } - else if (global_param.output_steps_per_day != 1 && - global_param.output_steps_per_day < MIN_SUBDAILY_STEPS_PER_DAY) { - log_err("The specified number of output steps per day (%zu) > 1 and < " - "the minimum number of subdaily steps per day (%d). Make " - "sure that the global file defines OUTPUT_STEPS_PER_DAY of at " - "least (%d).", global_param.model_steps_per_day, - MIN_SUBDAILY_STEPS_PER_DAY, - MIN_SUBDAILY_STEPS_PER_DAY); - } - else if (global_param.output_steps_per_day > - MAX_SUBDAILY_STEPS_PER_DAY) { - log_err("The specified number of model steps per day (%zu) > the " - "the maximum number of subdaily steps per day (%d). Make " - "sure that the global file defines MODEL_STEPS_PER_DAY of at " - "most (%d).", global_param.model_steps_per_day, - MAX_SUBDAILY_STEPS_PER_DAY, - MAX_SUBDAILY_STEPS_PER_DAY); - } - else { - global_param.out_dt = SEC_PER_DAY / - (double) global_param.output_steps_per_day; - } - // set NR and NF NF = global_param.snow_steps_per_day / global_param.model_steps_per_day; if (NF == 1) { @@ -1285,9 +1056,6 @@ get_global_param(FILE *gp) if (options.SAVE_STATE && options.STATE_FORMAT == UNSET_FILE_FORMAT) { options.STATE_FORMAT = NETCDF4_CLASSIC; } - if (options.OUT_FORMAT == UNSET_FILE_FORMAT) { - options.OUT_FORMAT = NETCDF4_CLASSIC; - } /********************************* Output major options diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index f4d5f25c7..3507993b3 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -337,7 +337,7 @@ vic_force(void) global_param.forceoffset[1] += NF; } - + // allocate memory for t_offset t_offset = malloc(local_domain.ncells_active * sizeof(*t_offset)); if (dvar == NULL) { @@ -483,7 +483,7 @@ get_forcing_file_info(param_set_struct *param_set, get_nc_var_attr(filenames.forcing[0], "time", "calendar", &calendar_char); // parse the calendar string and check to make sure it matches the global clock - calendar = calendar_from_chars(calendar_char); + calendar = str_to_calendar(calendar_char); // parse the time units parse_nc_time_units(nc_unit_chars, &time_units, &nc_origin_dmy); @@ -527,8 +527,8 @@ get_forcing_file_info(param_set_struct *param_set, param_set->force_steps_per_day[file_num]) } if (calendar != global_param.calendar) { - log_err("Calendar in forcing file does not match the calendar of " - "VIC's clock: %s", calendar_char); + log_err("Calendar in forcing file (%s) does not match the calendar of " + "VIC's clock", calendar_char); } // Free attribute character arrays diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index ccc0bd6d6..fab5ce1ce 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -44,25 +44,27 @@ MPI_Comm MPI_COMM_VIC = MPI_COMM_WORLD; MPI_Datatype mpi_global_struct_type; MPI_Datatype mpi_filenames_struct_type; MPI_Datatype mpi_location_struct_type; -MPI_Datatype mpi_nc_file_struct_type; +MPI_Datatype mpi_alarm_struct_type; MPI_Datatype mpi_option_struct_type; MPI_Datatype mpi_param_struct_type; int *mpi_map_local_array_sizes = NULL; int *mpi_map_global_array_offsets = NULL; int mpi_rank; int mpi_size; -nc_file_struct nc_hist_file; -nc_var_struct nc_vars[N_OUTVAR_TYPES]; option_struct options; -out_data_struct **out_data; parameters_struct param; param_set_struct param_set; -save_data_struct *save_data; soil_con_struct *soil_con = NULL; veg_con_map_struct *veg_con_map = NULL; veg_con_struct **veg_con = NULL; veg_hist_struct **veg_hist = NULL; veg_lib_struct **veg_lib = NULL; +metadata_struct state_metadata[N_STATE_VARS]; +metadata_struct out_metadata[N_OUTVAR_TYPES]; +save_data_struct *save_data; // [ncells] +double ***out_data = NULL; // [ncells, nvars, nelem] +stream_struct *output_streams = NULL; // [nstreams] +nc_file_struct *nc_hist_files = NULL; // [nstreams] rout_struct rout; // Routing routine (extension) /****************************************************************************** @@ -93,7 +95,7 @@ main(int argc, initialize_mpi(); // process command line arguments - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { cmd_proc(argc, argv, filenames.global); } @@ -119,7 +121,7 @@ main(int argc, vic_populate_model_state(); // initialize output structures - vic_init_output(); + vic_init_output(&(dmy[0])); // loop over all timesteps for (current = 0; current < global_param.nrecs; current++) { @@ -130,17 +132,15 @@ main(int argc, vic_image_run(&(dmy[current])); // run routing over the domain - rout_run(); // Routing routine (extension) - - // if output: - if (check_write_flag(current)) { - vic_write(&(dmy[current])); - } +// rout_run(); // Routing routine (extension) + // Write history files + vic_write_output(&(dmy[current])); + // if output (routing) rout_write(); // Routing routine (extension) - // if save: + // Write state file if (check_save_state_flag(current)) { vic_store(&(dmy[current])); } diff --git a/vic/drivers/image/src/vic_image_start.c b/vic/drivers/image/src/vic_image_start.c index e8acf47af..5a2ee4f12 100644 --- a/vic/drivers/image/src/vic_image_start.c +++ b/vic/drivers/image/src/vic_image_start.c @@ -39,7 +39,7 @@ vic_image_start(void) // Initialize structures initialize_global_structures(); - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // Read the global parameter file filep.globalparam = open_file(filenames.global, "r"); get_global_param(filep.globalparam); diff --git a/vic/drivers/python/src/display_current_settings.c b/vic/drivers/python/src/display_current_settings.c index 7a398f02b..0514149b3 100644 --- a/vic/drivers/python/src/display_current_settings.c +++ b/vic/drivers/python/src/display_current_settings.c @@ -416,43 +416,5 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Output Data:\n"); fprintf(LOG_DEST, "Result dir:\t\t%s\n", filenames.result_dir); - fprintf(LOG_DEST, "OUT_STEP\t\t%f\n", global_param.out_dt); - if (options.ALMA_OUTPUT) { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "ALMA_OUTPUT\t\tFALSE\n"); - } - if (options.OUT_FORMAT == ASCII) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tASCII\n"); - } - else if (options.OUT_FORMAT == BINARY) { - fprintf(LOG_DEST, "OUT_FORMAT\t\tBINARY\n"); - } - if (options.COMPRESS) { - fprintf(LOG_DEST, "COMPRESS\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "COMPRESS\t\tFALSE\n"); - } - if (options.MOISTFRACT) { - fprintf(LOG_DEST, "MOISTFRACT\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "MOISTFRACT\t\tFALSE\n"); - } - if (options.PRT_HEADER) { - fprintf(LOG_DEST, "PRT_HEADER\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_HEADER\t\tFALSE\n"); - } - if (options.PRT_SNOW_BAND) { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tTRUE\n"); - } - else { - fprintf(LOG_DEST, "PRT_SNOW_BAND\t\tFALSE\n"); - } - fprintf(LOG_DEST, "SKIPYEAR\t\t%d\n", global_param.skipyear); fprintf(LOG_DEST, "\n"); } diff --git a/vic/drivers/python/src/globals.c b/vic/drivers/python/src/globals.c index 11f30a5bc..76f5ae5cf 100644 --- a/vic/drivers/python/src/globals.c +++ b/vic/drivers/python/src/globals.c @@ -40,3 +40,4 @@ parameters_struct param; filenames_struct filenames; filep_struct filep; param_set_struct param_set; +metadata_struct out_metadata[N_OUTVAR_TYPES]; diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 25cd61b3c..93c431ada 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -30,8 +30,21 @@ #include #include +// Define maximum array sizes for driver level objects +#define MAX_FORCE_FILES 2 +#define MAX_OUTPUT_STREAMS 20 + +// Output compression setting +#define COMPRESSION_LVL_UNSET -1 +#define COMPRESSION_LVL_DEFAULT 5 + +// Default ouput values +#define OUT_MULT_DEFAULT 0 // Why is this not 1? +#define OUT_ASCII_FORMAT_DEFAULT "%.4f" + + /****************************************************************************** - * @brief Met file formats + * @brief File formats *****************************************************************************/ enum { @@ -115,6 +128,8 @@ enum OUT_SNOW_DEPTH, /**< depth of snow pack [cm] */ OUT_SOIL_ICE, /**< soil ice content [mm] for each soil layer */ OUT_SOIL_LIQ, /**< soil liquid content [mm] for each soil layer */ + OUT_SOIL_ICE_FRAC, /**< soil ice content fraction of column volume [1] for each soil layer */ + OUT_SOIL_LIQ_FRAC, /**< soil liquid content fraction of column volume [1] for each soil layer */ OUT_SOIL_MOIST, /**< soil total moisture content [mm] for each soil layer */ OUT_SOIL_WET, /**< vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ OUT_SURFSTOR, /**< storage of liquid water and ice (not snow) on surface (ponding) [mm] */ @@ -124,76 +139,76 @@ enum OUT_ZWT, /**< water table position [cm] (zwt within lowest unsaturated layer) */ OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ // Water Balance Terms - fluxes - OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] (ALMA_OUTPUT: [mm/s]) */ + OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] */ OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ OUT_DELSOILMOIST, /**< change in soil water content [mm] */ OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ OUT_DELSWE, /**< change in snow water equivalent [mm] */ - OUT_DISCHARGE, /**< river discharge [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_EVAP, /**< total net evaporation [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_INFLOW, /**< moisture that reaches top of soil column [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] (ALMA_OUTPUT: [m3/s]) */ - OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_PREC, /**< incoming precipitation [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_RAINF, /**< rainfall [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_REFREEZE, /**< refreezing of water in the snow [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_RUNOFF, /**< surface runoff [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SNOW_MELT, /**< snow melt [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SNOWF, /**< snowfall [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] (ALMA_OUTPUT: [mm/s]) */ + OUT_DISCHARGE, /**< river discharge [m3]) */ + OUT_EVAP, /**< total net evaporation [mm] */ + OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ + OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ + OUT_INFLOW, /**< moisture that reaches top of soil column [mm] */ + OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] */ + OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] */ + OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] */ + OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] */ + OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] */ + OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] */ + OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] */ + OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] */ + OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] */ + OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ + OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] */ + OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] */ + OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] */ + OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] */ + OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] */ + OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] */ + OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] */ + OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] */ + OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] */ + OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] */ + OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] */ + OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] */ + OUT_PREC, /**< incoming precipitation [mm] */ + OUT_RAINF, /**< rainfall [mm] */ + OUT_REFREEZE, /**< refreezing of water in the snow [mm] */ + OUT_RUNOFF, /**< surface runoff [mm] */ + OUT_SNOW_MELT, /**< snow melt [mm] */ + OUT_SNOWF, /**< snowfall [mm] */ + OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] */ + OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] */ + OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] */ + OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] */ + OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] */ OUT_WATER_ERROR, /**< water budget error [mm] */ // Energy Balance Terms - state variables OUT_ALBEDO, /**< average surface albedo [fraction] */ - OUT_BARESOILT, /**< bare soil surface temperature [C] (ALMA_OUTPUT: [K]) */ - OUT_FDEPTH, /**< depth of freezing fronts [cm] (ALMA_OUTPUT: [m]) for each freezing front */ - OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] (ALMA_OUTPUT: [K]) */ - OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] (ALMA_OUTPUT: [K]) */ + OUT_BARESOILT, /**< bare soil surface temperature [C] */ + OUT_FDEPTH, /**< depth of freezing fronts [cm] */ + OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] */ + OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] */ OUT_RAD_TEMP, /**< average radiative surface temperature [K] */ OUT_SALBEDO, /**< snow pack albedo [fraction] */ - OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] (ALMA_OUTPUT: [K]) */ - OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] (ALMA_OUTPUT: [K]) */ + OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] */ + OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] */ OUT_SNOWT_FBFLAG, /**< snow surface temperature fallback flag */ - OUT_SOIL_TEMP, /**< soil temperature [C] (ALMA_OUTPUT: [K]) for each soil layer */ - OUT_SOIL_TNODE, /**< soil temperature [C] (ALMA_OUTPUT: [K]) for each soil thermal node */ - OUT_SOIL_TNODE_WL, /**< soil temperature [C] (ALMA_OUTPUT: [K]) for each soil thermal node in the wetland */ + OUT_SOIL_TEMP, /**< soil temperature [C] */ + OUT_SOIL_TNODE, /**< soil temperature [C] */ + OUT_SOIL_TNODE_WL, /**< soil temperature [C] */ OUT_SOILT_FBFLAG, /**< soil temperature flag for each soil thermal node */ - OUT_SURF_TEMP, /**< average surface temperature [C] (ALMA_OUTPUT: [K]) */ + OUT_SURF_TEMP, /**< average surface temperature [C] */ OUT_SURFT_FBFLAG, /**< surface temperature flag */ OUT_TCAN_FBFLAG, /**< Tcanopy flag */ - OUT_TDEPTH, /**< depth of thawing fronts [cm] (ALMA_OUTPUT: [m]) for each thawing front */ + OUT_TDEPTH, /**< depth of thawing fronts [cm] */ OUT_TFOL_FBFLAG, /**< Tfoliage flag */ - OUT_VEGT, /**< average vegetation canopy temperature [C] (ALMA_OUTPUT: [K]) */ + OUT_VEGT, /**< average vegetation canopy temperature [C] */ // Energy Balance Terms - fluxes OUT_ADV_SENS, /**< net sensible flux advected to snow pack [W/m2] */ OUT_ADVECTION, /**< advected energy [W/m2] */ - OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] (ALMA_OUTPUT: [J/m2]) */ - OUT_DELTAH, /**< rate of change in heat storage [W/m2] (ALMA_OUTPUT: [J/m2]) */ + OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] */ + OUT_DELTAH, /**< rate of change in heat storage [W/m2] */ OUT_ENERGY_ERROR, /**< energy budget error [W/m2] */ OUT_FUSION, /**< net energy used to melt/freeze soil moisture [W/m2] */ OUT_GRND_FLUX, /**< net heat flux into ground [W/m2] */ @@ -214,7 +229,7 @@ enum OUT_AERO_RESIST, /**< "scene"canopy aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribute surface resistance)*/ OUT_AERO_RESIST1, /**< surface aerodynamic resistance [s/m] */ OUT_AERO_RESIST2, /**< overstory aerodynamic resistance [s/m] */ - OUT_AIR_TEMP, /**< air temperature [C] (ALMA_OUTPUT: [K])*/ + OUT_AIR_TEMP, /**< air temperature [C] */ OUT_CATM, /**< atmospheric CO2 concentrtaion [ppm]*/ OUT_DENSITY, /**< near-surface atmospheric density [kg/m3]*/ OUT_FCANOPY, /**< fractional area covered by plant canopy [fraction] */ @@ -222,13 +237,13 @@ enum OUT_LAI, /**< leaf area index [m2/m2] */ OUT_LWDOWN, /**< incoming longwave [W/m2] */ OUT_PAR, /**< incoming photosynthetically active radiation [W/m2] */ - OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] (ALMA_OUTPUT: [Pa])*/ + OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] */ OUT_QAIR, /**< specific humidity [kg/kg] */ OUT_REL_HUMID, /**< relative humidity [%]*/ OUT_SWDOWN, /**< incoming shortwave [W/m2] */ OUT_SURF_COND, /**< surface conductance [m/s] */ - OUT_VP, /**< near surface vapor pressure [kPa] (ALMA_OUTPUT: [Pa]) */ - OUT_VPD, /**< near surface vapor pressure deficit [kPa] (ALMA_OUTPUT: [Pa]) */ + OUT_VP, /**< near surface vapor pressure [kPa] */ + OUT_VPD, /**< near surface vapor pressure deficit [kPa] */ OUT_WIND, /**< near surface wind speed [m/s] */ // Band-specific quantities OUT_ADV_SENS_BAND, /**< net sensible heat flux advected to snow pack [W/m2] */ @@ -248,9 +263,9 @@ enum OUT_SNOW_COVER_BAND, /**< fractional area of snow cover [fraction] */ OUT_SNOW_DEPTH_BAND, /**< depth of snow pack [cm] */ OUT_SNOW_FLUX_BAND, /**< energy flux through snow pack [W/m2] */ - OUT_SNOW_MELT_BAND, /**< snow melt [mm] (ALMA_OUTPUT: [mm/s]) */ - OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] (ALMA_OUTPUT: [K]) */ - OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] (ALMA_OUTPUT: [K]) */ + OUT_SNOW_MELT_BAND, /**< snow melt [mm] */ + OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] */ + OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] */ OUT_SWE_BAND, /**< snow water equivalent in snow pack [mm] */ // Carbon-Cycling Terms OUT_APAR, /**< absorbed PAR [W/m2] */ @@ -268,6 +283,78 @@ enum N_OUTVAR_TYPES /**< used as a loop counter*/ }; +/****************************************************************************** + * @brief Output state variable. + *****************************************************************************/ +enum +{ + STATE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_SOIL_ICE, /**< ice content */ + STATE_CANOPY_WATER, /**< dew storage: tmpval = veg_var[veg][band].Wdew; */ + STATE_ANNUALNPP, /**< cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; */ + STATE_ANNUALNPPPREV, /**< previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; */ + STATE_CLITTER, /**< litter carbon: tmpval = cell[veg][band].CLitter; */ + STATE_CINTER, /**< intermediate carbon: tmpval = cell[veg][band].CInter; */ + STATE_CSLOW, /**< slow carbon: tmpval = cell[veg][band].CSlow; */ + STATE_SNOW_AGE, /**< snow age: snow[veg][band].last_snow */ + STATE_SNOW_MELT_STATE, /**< melting state: (int)snow[veg][band].MELTING */ + STATE_SNOW_COVERAGE, /**< snow covered fraction: snow[veg][band].coverage */ + STATE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: snow[veg][band].swq */ + STATE_SNOW_SURF_TEMP, /**< snow surface temperature: snow[veg][band].surf_temp */ + STATE_SNOW_SURF_WATER, /**< snow surface water: snow[veg][band].surf_water */ + STATE_SNOW_PACK_TEMP, /**< snow pack temperature: snow[veg][band].pack_temp */ + STATE_SNOW_PACK_WATER, /**< snow pack water: snow[veg][band].pack_water */ + STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ + STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ + STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ + STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ + STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ + STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ + STATE_ENERGY_SNOW_FLUX, /**< Thermal flux through the snow pack: energy[veg][band].snow_flux */ + STATE_LAKE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_LAKE_SOIL_ICE, /**< ice content */ + STATE_LAKE_CLITTER, /**< litter carbon: tmpval = lake_var.soil.CLitter; */ + STATE_LAKE_CINTER, /**< intermediate carbon: tmpval = lake_var.soil.CInter; */ + STATE_LAKE_CSLOW, /**< slow carbon: tmpval = lake_var.soil.CSlow; */ + STATE_LAKE_SNOW_AGE, /**< snow age: lake_var.snow.last_snow */ + STATE_LAKE_SNOW_MELT_STATE, /**< melting state: (int)lake_var.snow.MELTING */ + STATE_LAKE_SNOW_COVERAGE, /**< snow covered fraction: lake_var.snow.coverage */ + STATE_LAKE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: lake_var.snow.swq */ + STATE_LAKE_SNOW_SURF_TEMP, /**< snow surface temperature: lake_var.snow.surf_temp */ + STATE_LAKE_SNOW_SURF_WATER, /**< snow surface water: lake_var.snow.surf_water */ + STATE_LAKE_SNOW_PACK_TEMP, /**< snow pack temperature: lake_var.snow.pack_temp */ + STATE_LAKE_SNOW_PACK_WATER, /**< snow pack water: lake_var.snow.pack_water */ + STATE_LAKE_SNOW_DENSITY, /**< snow density: lake_var.snow.density */ + STATE_LAKE_SNOW_COLD_CONTENT, /**< snow cold content: lake_var.snow.coldcontent */ + STATE_LAKE_SNOW_CANOPY, /**< snow canopy storage: lake_var.snow.snow_canopy */ + STATE_LAKE_SOIL_NODE_TEMP, /**< soil node temperatures: lake_var.energy.T[nidx] */ + STATE_LAKE_ACTIVE_LAYERS, /**< lake active layers: lake_var.activenod */ + STATE_LAKE_LAYER_DZ, /**< lake layer thickness: lake_var.dz */ + STATE_LAKE_SURF_LAYER_DZ, /**< lake surface layer thickness: lake_var.surfdz */ + STATE_LAKE_DEPTH, /**< lake depth: lake_var.ldepth */ + STATE_LAKE_LAYER_SURF_AREA, /**< lake layer surface areas: lake_var.surface[ndix] */ + STATE_LAKE_SURF_AREA, /**< lake surface area: lake_var.sarea */ + STATE_LAKE_VOLUME, /**< lake volume: lake_var.volume */ + STATE_LAKE_LAYER_TEMP, /**< lake layer temperatures: lake_var.temp[nidx] */ + STATE_LAKE_AVERAGE_TEMP, /**< vertical average lake temperature: lake_var.tempavg */ + STATE_LAKE_ICE_AREA_FRAC, /**< lake ice area fraction: lake_var.areai */ + STATE_LAKE_ICE_AREA_FRAC_NEW, /**< new lake ice area fraction: lake_var.new_ice_area */ + STATE_LAKE_ICE_WATER_EQUIVALENT, /**< lake ice water equivalent: lake_var.ice_water_eq */ + STATE_LAKE_ICE_HEIGHT, /**< lake ice height: lake_var.hice */ + STATE_LAKE_ICE_TEMP, /**< lake ice temperature: lake_var.tempi */ + STATE_LAKE_ICE_SWE, /**< lake ice snow water equivalent: lake_var.swe */ + STATE_LAKE_ICE_SNOW_SURF_TEMP, /**< lake ice snow surface temperature: lake_var.surf_temp */ + STATE_LAKE_ICE_SNOW_PACK_TEMP, /**< lake ice snow pack temperature: lake_var.pack_temp */ + STATE_LAKE_ICE_SNOW_COLD_CONTENT, /**< lake ice snow coldcontent: lake_var.coldcontent */ + STATE_LAKE_ICE_SNOW_SURF_WATER, /**< lake ice snow surface water: lake_var.surf_water */ + STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ + STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ + STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_STATE_VARS /**< used as a loop counter*/ +}; + /****************************************************************************** * @brief Output BINARY format types @@ -288,14 +375,31 @@ enum *****************************************************************************/ enum { + AGG_TYPE_DEFAULT, /**< Default aggregation type */ AGG_TYPE_AVG, /**< average over agg interval */ AGG_TYPE_BEG, /**< value at beginning of agg interval */ AGG_TYPE_END, /**< value at end of agg interval */ AGG_TYPE_MAX, /**< maximum value over agg interval */ AGG_TYPE_MIN, /**< minimum value over agg interval */ - AGG_TYPE_SUM /**< sum over agg interval */ + AGG_TYPE_SUM /**< sum over agg interval */ }; +/****************************************************************************** + * @brief Frequency flags for raising alarms/flags + *****************************************************************************/ +enum +{ + FREQ_NEVER, /**< Flag for never raising alarm */ + FREQ_NSTEPS, /**< Flag for raising alarm every nsteps */ + FREQ_NSECONDS, /**< Flag for raising alarm every nseconds */ + FREQ_NMINUTES, /**< Flag for raising alarm every nminutes */ + FREQ_NHOURS, /**< Flag for raising alarm every nhours */ + FREQ_NDAYS, /**< Flag for raising alarm every ndays */ + FREQ_NMONTHS, /**< Flag for raising alarm every nmonths */ + FREQ_NYEARS, /**< Flag for raising alarm every nyears */ + FREQ_DATE, /**< Flag for raising alarm on a specific date */ + FREQ_END /**< Flag for raising alarm at the end of a simulation */ +}; /****************************************************************************** * @brief Codes for displaying version information @@ -334,6 +438,44 @@ enum time_units TIME_UNITS_DAYS }; +/****************************************************************************** + * @brief file structures + *****************************************************************************/ +typedef struct { + FILE *forcing[MAX_FORCE_FILES]; /**< atmospheric forcing data files */ + FILE *globalparam; /**< global parameters file */ + FILE *constants; /**< model constants parameter file */ + FILE *domain; /**< domain file */ + FILE *init_state; /**< initial model state file */ + FILE *lakeparam; /**< lake parameter file */ + FILE *snowband; /**< snow elevation band data file */ + FILE *soilparam; /**< soil parameters for all grid cells */ + FILE *statefile; /**< output model state file */ + FILE *veglib; /**< vegetation parameters for all vege types */ + FILE *vegparam; /**< fractional coverage info for grid cell */ + FILE *logfile; /**< log file */ +} filep_struct; + +/****************************************************************************** + * @brief This structure stores input and output filenames. + *****************************************************************************/ +typedef struct { + char forcing[MAX_FORCE_FILES][MAXSTRING]; /**< atmospheric forcing data file names */ + char f_path_pfx[MAX_FORCE_FILES][MAXSTRING]; /**< path and prefix for atmospheric forcing data file names */ + char global[MAXSTRING]; /**< global control file name */ + char domain[MAXSTRING]; /**< domain file name */ + char constants[MAXSTRING]; /**< model constants file name */ + char init_state[MAXSTRING]; /**< initial model state file name */ + char lakeparam[MAXSTRING]; /**< lake model constants file */ + char result_dir[MAXSTRING]; /**< directory where results will be written */ + char snowband[MAXSTRING]; /**< snow band parameter file name */ + char soil[MAXSTRING]; /**< soil parameter file name */ + char statefile[MAXSTRING]; /**< name of file in which to store model state */ + char veg[MAXSTRING]; /**< vegetation grid coverage file */ + char veglib[MAXSTRING]; /**< vegetation parameter library file */ + char log_path[MAXSTRING]; /**< Location to write log file to*/ +} filenames_struct; + /****************************************************************************** * @brief Stores forcing file input information. *****************************************************************************/ @@ -363,18 +505,44 @@ typedef struct { } param_set_struct; /****************************************************************************** - * @brief This structure stores output information for one output file. + * @brief This structure stores alarm information + *****************************************************************************/ +typedef struct { + unsigned int count; /**< current alarm count */ + int next; /**< next count to raise alarm at */ + unsigned int freq; /**< enum value to describing alarm frequency */ + int n; /**< variable that provides additional information with respect to alarm_freq */ + dmy_struct date; /**< date structure for when alarm_freq == FREQ_DATE */ + bool is_subdaily; /**< flag denoting if alarm will be raised more than once per day */ +} alarm_struct; + +/****************************************************************************** + * @brief This structure stores output information for one output stream. *****************************************************************************/ typedef struct { - char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ + size_t nvars; /**< number of variables to store in the file */ + size_t ngridcells; /**< number of grid cells in aggdata */ + char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ char filename[MAXSTRING]; /**< complete file name */ - FILE *fh; /**< filehandle */ - size_t nvars; /**< number of variables to store in the file */ - unsigned int *varid; /**< id numbers of the variables to store in the file - (a variable's id number is its index in the out_data array). - The order of the id numbers in the varid array - is the order in which the variables will be written. */ -} out_data_file_struct; + FILE *fh; /**< filehandle */ + unsigned short int file_format; /**< output file format */ + short int compress; /**< Compress output files in stream*/ + unsigned short int *type; /**< type, when written to a binary file; + OUT_TYPE_USINT = unsigned short int + OUT_TYPE_SINT = short int + OUT_TYPE_FLOAT = single precision floating point + OUT_TYPE_DOUBLE = double precision floating point */ + double *mult; /**< multiplier, when written to a binary file [shape=(nvars, )] */ + char **format; /**< format, when written to disk [shape=(nvars, )] */ + unsigned int *varid; /**< id numbers of the variables to store in the file + (a variable's id number is its index in the out_data array). + The order of the id numbers in the varid array + is the order in which the variables will be written. */ + unsigned short int *aggtype; /**< type of aggregation to use [shape=(nvars, )] */ + double ****aggdata; /**< array of aggregated data values [shape=(ngridcells, nvars, nelem, nbins)] */ + alarm_struct agg_alarm; /**< alaram for stream aggregation */ + alarm_struct write_alarm; /**< alaram for controlling stream write */ +} stream_struct; /****************************************************************************** * @brief This structure stores moisture state information for differencing @@ -389,31 +557,16 @@ typedef struct { } save_data_struct; /****************************************************************************** - * @brief This structure stores output information for one variable. + * @brief This structure stores metadata for individual variables *****************************************************************************/ typedef struct { char varname[MAXSTRING]; /**< name of variable */ - bool write; /**< FALSE = don't write; TRUE = write */ - char format[MAXSTRING]; /**< format, when written to an ascii file; - should match the desired fprintf format - specifier, e.g. %.4f */ - unsigned short int type; /**< type, when written to a binary file; - OUT_TYPE_USunsigned short = unsigned short int - OUT_TYPE_SINT = short int - OUT_TYPE_FLOAT = single precision floating point - OUT_TYPE_DOUBLE = double precision floating point */ - double mult; /**< multiplier, when written to a binary file */ - unsigned short int aggtype; /**< type of aggregation to use; - AGG_TYPE_AVG = take average value over agg interval - AGG_TYPE_BEG = take value at beginning of agg interval - AGG_TYPE_END = take value at end of agg interval - AGG_TYPE_MAX = take maximum value over agg interval - AGG_TYPE_MIN = take minimum value over agg interval - AGG_TYPE_SUM = take sum over agg interval */ - unsigned int nelem; /**< number of data values */ - double *data; /**< array of data values */ - double *aggdata; /**< array of aggregated data values */ -} out_data_struct; + char long_name[MAXSTRING]; /**< name of variable */ + char standard_name[MAXSTRING]; /**< cf long_name of variable */ + char units[MAXSTRING]; /**< units of variable */ + char description[MAXSTRING]; /**< descripition of variable */ + size_t nelem; /**< number of data values */ +} metadata_struct; /****************************************************************************** * @brief This structure holds all variables needed for the error handling @@ -425,8 +578,8 @@ typedef struct { energy_bal_struct *energy; filep_struct filep; size_t rec; - out_data_struct *out_data; - out_data_file_struct *out_data_files; + double **out_data; + stream_struct *output_streams; snow_data_struct *snow; soil_con_struct soil_con; veg_con_struct *veg_con; @@ -434,34 +587,40 @@ typedef struct { } Error_struct; double air_density(double t, double p); +void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, + double ***out_data); double all_30_day_from_dmy(dmy_struct *dmy); double all_leap_from_dmy(dmy_struct *dmy); +void alloc_aggdata(stream_struct *stream); +void alloc_out_data(size_t ngridcells, double ****out_data); double average(double *ar, size_t n); double calc_energy_balance_error(double, double, double, double, double); void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); double calc_water_balance_error(double, double, double, double); -unsigned short int calendar_from_chars(char *cal_chars); +bool cell_method_from_agg_type(unsigned short int aggtype, char cell_method[]); bool check_write_flag(int rec); void collect_eb_terms(energy_bal_struct, snow_data_struct, cell_data_struct, - double, double, double, int, int, double, int, int, - double *, double, out_data_struct *); + double, double, double, bool, bool, double, bool, int, + double *, double, double **); void collect_wb_terms(cell_data_struct, veg_var_struct, snow_data_struct, - double, double, double, int, double, int, double *, - double *, out_data_struct *); + double, double, double, bool, double, bool, double *, + double *, double **); void compute_derived_state_vars(all_vars_struct *, soil_con_struct *, veg_con_struct *); void compute_lake_params(lake_con_struct *, soil_con_struct); void compute_treeline(atmos_data_struct *, dmy_struct *, double, double *, bool *); size_t count_force_vars(FILE *gp); +void count_nstreams_nvars(FILE *gp, size_t *nstreams, size_t nvars[]); void cmd_proc(int argc, char **argv, char *globalfilename); -void compress_files(char string[]); -out_data_struct *create_output_list(void); +void compress_files(char string[], short int level); +stream_struct create_outstream(stream_struct *output_streams); void get_current_datetime(char *cdt); double date2num(double origin, dmy_struct *date, double tzoffset, unsigned short int calendar, unsigned short int time_units); void dmy_all_30_day(double julian, dmy_struct *dmy); void dmy_all_leap(double julian, dmy_struct *dmy); +bool dmy_equal(dmy_struct *a, dmy_struct *b); void dmy_julian_day(double julian, unsigned short int calendar, dmy_struct *dmy); void dmy_no_leap_day(double julian, dmy_struct *dmy); @@ -471,21 +630,27 @@ void display_current_settings(int); double fractional_day_from_dmy(dmy_struct *dmy); void free_all_vars(all_vars_struct *all_vars, int Nveg); void free_dmy(dmy_struct **dmy); -void free_out_data(out_data_struct **); +void free_out_data(size_t ngridcells, double ***out_data); +void free_streams(stream_struct **streams); void free_vegcon(veg_con_struct **veg_con); void generate_default_state(all_vars_struct *, soil_con_struct *, veg_con_struct *); void generate_default_lake_state(all_vars_struct *, soil_con_struct *, lake_con_struct); +void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); void get_parameters(FILE *paramfile); -void init_output_list(out_data_struct *out_data, int write, char *format, - int type, double mult); +void init_output_list(double **out_data, int write, char *format, int type, + double mult); void initialize_energy(energy_bal_struct **energy, size_t nveg); void initialize_filenames(void); void initialize_fileps(void); void initialize_global(void); void initialize_options(void); void initialize_parameters(void); +void initialize_save_data(all_vars_struct *all_vars, atmos_data_struct *atmos, + soil_con_struct *soil_con, veg_con_struct *veg_con, + veg_lib_struct *veg_lib, lake_con_struct *lake_con, + double **out_data, save_data_struct *save_data); void initialize_snow(snow_data_struct **snow, size_t veg_num); void initialize_soil(cell_data_struct **cell, size_t veg_num); void initialize_time(void); @@ -509,7 +674,8 @@ void parse_nc_time_units(char *nc_unit_chars, unsigned short int *units, dmy_struct *dmy); void put_data(all_vars_struct *, atmos_data_struct *, soil_con_struct *, veg_con_struct *, veg_lib_struct *veg_lib, lake_con_struct *, - out_data_struct *, save_data_struct *, int); + double **out_data, save_data_struct *); +void print_alarm(alarm_struct *alarm); void print_cell_data(cell_data_struct *cell, size_t nlayers, size_t nfrost); void print_dmy(dmy_struct *dmy); void print_energy_bal(energy_bal_struct *eb, size_t nnodes, size_t nfronts); @@ -524,14 +690,16 @@ void print_layer_data_states(layer_data_struct *ldata, size_t nfrost); void print_layer_data_fluxes(layer_data_struct *ldata); void print_license(void); void print_option(option_struct *option); -void print_out_data(out_data_struct *out, size_t nelem); -void print_out_data_file(out_data_file_struct *outf); +void print_out_data(double **out_data, metadata_struct *metadata); +void print_out_metadata(metadata_struct *metadata, size_t nvars); +void print_output_streams(stream_struct *outf); void print_param_set(param_set_struct *param_set); void print_parameters(parameters_struct *param); void print_save_data(save_data_struct *save); void print_snow_data(snow_data_struct *snow); void print_soil_con(soil_con_struct *scon, size_t nlayers, size_t nnodes, size_t nfrost, size_t nbands, size_t nzwt); +void print_stream(stream_struct *stream, metadata_struct *metadata); void print_veg_con(veg_con_struct *vcon, size_t nroots, char blowing, char lake, char carbon, size_t ncanopy); void print_veg_lib(veg_lib_struct *vlib, char carbon); @@ -539,16 +707,40 @@ void print_veg_var(veg_var_struct *vvar, size_t ncanopy); void print_version(char *); void print_usage(char *); double q_to_vp(double q, double p); -int set_output_var(out_data_file_struct *, int, int, out_data_struct *, char *, - int, char *, int, double); +bool raise_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_stream(stream_struct *stream, dmy_struct *dmy_current); +void set_output_var(stream_struct *stream, char *varname, size_t varnum, + char *format, unsigned short int type, double mult, + unsigned short int aggtype); +unsigned int get_default_outvar_aggtype(unsigned int varid); +void set_alarm(dmy_struct *dmy_current, unsigned int freq, void *value, + alarm_struct *alarm); +void set_output_defaults(stream_struct **output_streams, + dmy_struct *dmy_current, + unsigned short default_file_format); +void set_output_met_data_info(); +void setup_stream(stream_struct *stream, size_t nvars, size_t ngridcells); void soil_moisture_from_water_table(soil_con_struct *soil_con, size_t nlayers); void sprint_dmy(char *str, dmy_struct *dmy); -unsigned short int timeunits_from_chars(char *units_chars); +void str_from_calendar(unsigned short int calendar, char *calendar_str); +void str_from_time_units(unsigned short int time_units, char *unit_str); +unsigned short int str_to_agg_type(char aggstr[]); +void str_to_ascii_format(char *format); +bool str_to_bool(char str[]); +unsigned short int str_to_calendar(char *cal_chars); +unsigned short int str_to_freq_flag(char freq[]); +double str_to_out_mult(char multstr[]); +unsigned short int str_to_out_type(char typestr[]); +unsigned short int str_to_timeunits(char units_chars[]); +void strpdmy(const char *s, const char *format, dmy_struct *dmy); +double time_delta(dmy_struct *dmy_current, unsigned short int freq, int n); int update_step_vars(all_vars_struct *, veg_con_struct *, veg_hist_struct *); int invalid_date(unsigned short int calendar, dmy_struct *dmy); void validate_parameters(void); +void validate_streams(stream_struct **stream); char will_it_snow(double *t, double t_offset, double max_snow_temp, double *prcp, size_t n); -void zero_output_list(out_data_struct *); +void zero_output_list(double **); #endif diff --git a/vic/drivers/shared_all/include/vic_version.h b/vic/drivers/shared_all/include/vic_version.h index f92fa9848..859286767 100644 --- a/vic/drivers/shared_all/include/vic_version.h +++ b/vic/drivers/shared_all/include/vic_version.h @@ -27,7 +27,7 @@ #ifndef VIC_VERSION_H #define VIC_VERSION_H -#define STR_HELPER(x) #x +#define STR_HELPER(x) # x #define STR(x) STR_HELPER(x) #ifndef VERSION @@ -67,7 +67,8 @@ #elif defined(__GNUC__) || defined(__GNUG__) /* GNU GCC/G++. --------------------------------------------- */ # define COMPILER "gcc" -# define COMPILER_VERSION STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR( \ + __GNUC_PATCHLEVEL__) #elif defined(__PGI) /* Portland Group PGCC/PGCPP. ------------------------------- */ diff --git a/vic/drivers/shared_all/src/agg_data.c b/vic/drivers/shared_all/src/agg_data.c new file mode 100644 index 000000000..99228e66a --- /dev/null +++ b/vic/drivers/shared_all/src/agg_data.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Initialize output structures. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Perform temporal aggregation on stream data + *****************************************************************************/ +void +agg_stream_data(stream_struct *stream, + dmy_struct *dmy_current, + double ***out_data) +{ + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + alarm_struct *alarm; + size_t i; + size_t j; + size_t k; + size_t nelem; + unsigned int varid; + + alarm = &(stream->agg_alarm); + + alarm->count++; + + for (i = 0; i < stream->ngridcells; i++) { + for (j = 0; j < stream->nvars; j++) { + varid = stream->varid[j]; + nelem = out_metadata[varid].nelem; + + // Instantaneous at the beginning of the period + if ((stream->aggtype[j] == AGG_TYPE_END) && + (raise_alarm(alarm, dmy_current))) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] = out_data[i][varid][k]; + } + } + // Instantaneous at the end of the period + else if ((stream->aggtype[j] == AGG_TYPE_BEG) && + (alarm->count == 1)) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] = out_data[i][varid][k]; + } + } + // Sum over the period + else if ((stream->aggtype[j] == AGG_TYPE_SUM) || + (stream->aggtype[j] == AGG_TYPE_AVG)) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] += out_data[i][varid][k]; + } + } + // Maximum over the period + else if (stream->aggtype[j] == AGG_TYPE_MAX) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] = + max(stream->aggdata[i][j][k][0], out_data[i][varid][k]); + } + } + // Minimum over the period + else if (stream->aggtype[j] == AGG_TYPE_MIN) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] = + min(stream->aggdata[i][j][k][0], out_data[i][varid][k]); + } + } + // Average over the period if counter is full + if ((stream->aggtype[j] == AGG_TYPE_AVG) && + (raise_alarm(alarm, dmy_current))) { + for (k = 0; k < nelem; k++) { + stream->aggdata[i][j][k][0] /= (double) alarm->count; + } + } + } + } +} diff --git a/vic/drivers/shared_all/src/alarms.c b/vic/drivers/shared_all/src/alarms.c new file mode 100644 index 000000000..cfb7b316d --- /dev/null +++ b/vic/drivers/shared_all/src/alarms.c @@ -0,0 +1,122 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This file includes routines that calculate and raise alarms for writing + * history and state files. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief This routine resets an alarm + *****************************************************************************/ +void +reset_alarm(alarm_struct *alarm, + dmy_struct *dmy_current) +{ + extern global_param_struct global_param; + + alarm->count = 0; + + if ((alarm->freq == FREQ_NEVER) || (alarm->freq == FREQ_NSTEPS) || + (alarm->freq == FREQ_DATE) || (alarm->freq == FREQ_END)) { + ; // Do nothing, already set + } + else { + alarm->next = global_param.model_steps_per_day * time_delta(dmy_current, + alarm->freq, + alarm->n); + } +} + +/****************************************************************************** + * @brief This routine raises an alarm + *****************************************************************************/ +bool +raise_alarm(alarm_struct *alarm, + dmy_struct *dmy_current) +{ + if ((int) alarm->count == alarm->next) { + return true; + } + else if ((alarm->freq == FREQ_DATE) && + (dmy_equal(dmy_current, &(alarm->date)))) { + return true; + } + else { + return false; + } +} + +/****************************************************************************** + * @brief This routine sets an alarm + *****************************************************************************/ +void +set_alarm(dmy_struct *dmy_current, + unsigned int freq, + void *value, + alarm_struct *alarm) +{ + extern global_param_struct global_param; + + alarm->count = 0; + alarm->next = MISSING; + alarm->freq = freq; + alarm->n = MISSING; + + if (freq == FREQ_NSTEPS) { + alarm->n = *((int*) value); + alarm->next = alarm->n; + if (alarm->n <= 0) { + log_err("invalid n (%d) provided to set_alarm", alarm->n); + } + } + else if ((freq == FREQ_NSECONDS) || (freq == FREQ_NMINUTES) || + (freq == FREQ_NHOURS) || (freq == FREQ_NDAYS) || + (freq == FREQ_NMONTHS) || (freq == FREQ_NYEARS)) { + alarm->n = *((int*) value); + if (alarm->n <= 0) { + log_err("invalid n (%d) provided to set_alarm", alarm->n); + } + } + else if (freq == FREQ_DATE) { + alarm->date = *((dmy_struct*) value); + } + else if ((freq == FREQ_NEVER) || (freq == FREQ_END)) { + ; // Do nothing + } + else { + log_err("Did not recognize the frequency value %u", freq); + } + + // Set alarm->next via reset_alarm + reset_alarm(alarm, dmy_current); + + // Set subdaily attribute + if (alarm->next < (int) global_param.model_steps_per_day) { + alarm->is_subdaily = true; + } + else { + alarm->is_subdaily = false; + } +} diff --git a/vic/drivers/shared_all/src/cmd_proc.c b/vic/drivers/shared_all/src/cmd_proc.c index 1e8d0c673..9baa0d6b0 100644 --- a/vic/drivers/shared_all/src/cmd_proc.c +++ b/vic/drivers/shared_all/src/cmd_proc.c @@ -59,12 +59,12 @@ cmd_proc(int argc, case 'v': /** Version information **/ display_current_settings(DISP_VERSION); - exit(0); + exit(EXIT_SUCCESS); break; case 'o': /** Compile-time options information **/ display_current_settings(DISP_COMPILE_TIME); - exit(0); + exit(EXIT_SUCCESS); break; case 'g': /** Global Parameters File **/ @@ -83,7 +83,7 @@ cmd_proc(int argc, fprintf(stderr, "ERROR: Must set global control file using the '-g' flag\n"); print_usage(argv[0]); - exit(1); + exit(EXIT_FAILURE); } } diff --git a/vic/drivers/shared_all/src/compress_files.c b/vic/drivers/shared_all/src/compress_files.c index cb719a9eb..429fb0757 100644 --- a/vic/drivers/shared_all/src/compress_files.c +++ b/vic/drivers/shared_all/src/compress_files.c @@ -30,11 +30,21 @@ * @brief This subroutine compresses the file "string" using a system call. *****************************************************************************/ void -compress_files(char string[]) +compress_files(char string[], + short int level) { char command[MAXSTRING]; - /** uncompress and open zipped file **/ - sprintf(command, "nice gzip -f %s &", string); + // Compress the file + if (level == COMPRESSION_LVL_DEFAULT) { + sprintf(command, "nice gzip -f %s &", string); + } + else if (level != COMPRESSION_LVL_UNSET) { + sprintf(command, "nice gzip -%d -f %s &", level, string); + } + else if (level <= 0) { + log_err("Invalid compression level for gzip, must be an integer 1-9"); + } + system(command); } diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 666e3d668..9f0eaf5ec 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -44,11 +44,11 @@ generate_default_state(all_vars_struct *all_vars, size_t band; size_t lidx; size_t k; - size_t tmpTshape[] = { + size_t tmpTshape[] = { options.Nlayer, options.Nnode, options.Nfrost + 1 }; - size_t tmpZshape[] = { + size_t tmpZshape[] = { options.Nlayer, options.Nnode }; double Cv; diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c new file mode 100644 index 000000000..7e301f374 --- /dev/null +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -0,0 +1,1504 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This routine sets the metadata structure for VIC output variables + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Set output met data information + *****************************************************************************/ +void +set_output_met_data_info() +{ + size_t v; + + extern option_struct options; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + // Build the list of supported output variables + + // Set missing and/or default values + for (v = 0; v < N_OUTVAR_TYPES; v++) { + // Set default string values + strcpy(out_metadata[v].varname, MISSING_S); + strcpy(out_metadata[v].long_name, MISSING_S); + strcpy(out_metadata[v].standard_name, MISSING_S); + strcpy(out_metadata[v].units, MISSING_S); + strcpy(out_metadata[v].description, MISSING_S); + // Set default number of elements + out_metadata[v].nelem = 1; + } + + // Water Balance Terms - state variables + /* saturated area fraction */ + strcpy(out_metadata[OUT_ASAT].varname, "OUT_ASAT"); + strcpy(out_metadata[OUT_ASAT].long_name, "asat"); + strcpy(out_metadata[OUT_ASAT].standard_name, "saturated_area_fraction"); + strcpy(out_metadata[OUT_ASAT].units, "1"); + strcpy(out_metadata[OUT_ASAT].description, "saturated area fraction"); + + /* lake surface area as fraction of grid cell area [fraction] */ + strcpy(out_metadata[OUT_LAKE_AREA_FRAC].varname, "OUT_LAKE_AREA_FRAC"); + strcpy(out_metadata[OUT_LAKE_AREA_FRAC].long_name, "lake_area_frac"); + strcpy(out_metadata[OUT_LAKE_AREA_FRAC].standard_name, + "lake_area_fraction"); + strcpy(out_metadata[OUT_LAKE_AREA_FRAC].units, "1"); + strcpy(out_metadata[OUT_LAKE_AREA_FRAC].description, + "lake surface area as fraction of grid cell area"); + + /* lake depth [m] */ + strcpy(out_metadata[OUT_LAKE_DEPTH].varname, "OUT_LAKE_DEPTH"); + strcpy(out_metadata[OUT_LAKE_DEPTH].long_name, "lake_depth"); + strcpy(out_metadata[OUT_LAKE_DEPTH].standard_name, "lake_depth"); + strcpy(out_metadata[OUT_LAKE_DEPTH].units, "m"); + strcpy(out_metadata[OUT_LAKE_DEPTH].description, "lake depth"); + + /* moisture stored as lake ice [mm] */ + strcpy(out_metadata[OUT_LAKE_ICE].varname, "OUT_LAKE_ICE"); + strcpy(out_metadata[OUT_LAKE_ICE].long_name, "lake_ice"); + strcpy(out_metadata[OUT_LAKE_ICE].standard_name, "lake_ice"); + strcpy(out_metadata[OUT_LAKE_ICE].units, "mm"); + strcpy(out_metadata[OUT_LAKE_ICE].description, + "moisture stored as lake ice"); + + /* fractional coverage of lake ice [fraction] */ + strcpy(out_metadata[OUT_LAKE_ICE_FRACT].varname, "OUT_LAKE_ICE_FRACT"); + strcpy(out_metadata[OUT_LAKE_ICE_FRACT].long_name, "lake_ice_fract"); + strcpy(out_metadata[OUT_LAKE_ICE_FRACT].standard_name, + "lake_ice_area_fraction"); + strcpy(out_metadata[OUT_LAKE_ICE_FRACT].units, "1"); + strcpy(out_metadata[OUT_LAKE_ICE_FRACT].description, + "fractional coverage of lake ice"); + + /* thickness of lake ice [cm] */ + strcpy(out_metadata[OUT_LAKE_ICE_HEIGHT].varname, "OUT_LAKE_ICE_HEIGHT"); + strcpy(out_metadata[OUT_LAKE_ICE_HEIGHT].long_name, "lake_ice_height"); + strcpy(out_metadata[OUT_LAKE_ICE_HEIGHT].standard_name, "lake_ice_height"); + strcpy(out_metadata[OUT_LAKE_ICE_HEIGHT].units, "cm"); + strcpy(out_metadata[OUT_LAKE_ICE_HEIGHT].description, + "thickness of lake ice"); + + /* liquid water stored in lake [mm over lake area?] */ + strcpy(out_metadata[OUT_LAKE_MOIST].varname, "OUT_LAKE_MOIST"); + strcpy(out_metadata[OUT_LAKE_MOIST].long_name, "lake_moist"); + strcpy(out_metadata[OUT_LAKE_MOIST].standard_name, "lake_moisture"); + strcpy(out_metadata[OUT_LAKE_MOIST].units, "mm"); + strcpy(out_metadata[OUT_LAKE_MOIST].description, + "liquid water stored in lake"); + + /* lake surface area [m2] */ + strcpy(out_metadata[OUT_LAKE_SURF_AREA].varname, "OUT_LAKE_SURF_AREA"); + strcpy(out_metadata[OUT_LAKE_SURF_AREA].long_name, "lake_surf_area"); + strcpy(out_metadata[OUT_LAKE_SURF_AREA].standard_name, "lake_area"); + strcpy(out_metadata[OUT_LAKE_SURF_AREA].units, "m2"); + strcpy(out_metadata[OUT_LAKE_SURF_AREA].description, "lake surface area"); + + /* liquid water equivalent of snow on top of lake ice [m over lake ice] */ + strcpy(out_metadata[OUT_LAKE_SWE].varname, "OUT_LAKE_SWE"); + strcpy(out_metadata[OUT_LAKE_SWE].long_name, "lake_swe"); + strcpy(out_metadata[OUT_LAKE_SWE].standard_name, + "lwe_thickness_of_snow_on_lake"); + strcpy(out_metadata[OUT_LAKE_SWE].units, "m"); + strcpy(out_metadata[OUT_LAKE_SWE].description, + "liquid water equivalent of snow on top of lake ice"); + + /* river discharge [m3] */ + strcpy(out_metadata[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); + strcpy(out_metadata[OUT_DISCHARGE].long_name, "river discharge"); + strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river discharge"); + strcpy(out_metadata[OUT_DISCHARGE].units, "m3"); + strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); + + /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ + strcpy(out_metadata[OUT_LAKE_SWE_V].varname, "OUT_LAKE_SWE_V"); + strcpy(out_metadata[OUT_LAKE_SWE_V].long_name, "lake_swe_v"); + strcpy(out_metadata[OUT_LAKE_SWE_V].standard_name, + "lwe_volume_of_snow_on_lake"); + strcpy(out_metadata[OUT_LAKE_SWE_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_SWE_V].description, + "liquid water equivalent of snow on top of lake ice"); + + /* lake volume [m3] */ + strcpy(out_metadata[OUT_LAKE_VOLUME].varname, "OUT_LAKE_VOLUME"); + strcpy(out_metadata[OUT_LAKE_VOLUME].long_name, "lake_volume"); + strcpy(out_metadata[OUT_LAKE_VOLUME].standard_name, "lake_volume"); + strcpy(out_metadata[OUT_LAKE_VOLUME].units, "m3"); + strcpy(out_metadata[OUT_LAKE_VOLUME].description, "lake volume"); + + /* root zone soil moisture [mm] */ + strcpy(out_metadata[OUT_ROOTMOIST].varname, "OUT_ROOTMOIST"); + strcpy(out_metadata[OUT_ROOTMOIST].long_name, "rootmoist"); + strcpy(out_metadata[OUT_ROOTMOIST].standard_name, + "soil_moisture_in_root_zone"); + strcpy(out_metadata[OUT_ROOTMOIST].units, "mm"); + strcpy(out_metadata[OUT_ROOTMOIST].description, "root zone soil moisture"); + + /* fraction of soil moisture (by mass) that is ice, for each soil layer */ + strcpy(out_metadata[OUT_SMFROZFRAC].varname, "OUT_SMFROZFRAC"); + strcpy(out_metadata[OUT_SMFROZFRAC].long_name, "smfrozfrac"); + strcpy(out_metadata[OUT_SMFROZFRAC].standard_name, + "soil_moisture_ice_fraction"); + strcpy(out_metadata[OUT_SMFROZFRAC].units, "1"); + strcpy(out_metadata[OUT_SMFROZFRAC].description, + "fraction of soil moisture (by mass) that is ice, for each soil layer"); + + /* fraction of soil moisture (by mass) that is liquid, for each soil layer */ + strcpy(out_metadata[OUT_SMLIQFRAC].varname, "OUT_SMLIQFRAC"); + strcpy(out_metadata[OUT_SMLIQFRAC].long_name, "smliqfrac"); + strcpy(out_metadata[OUT_SMLIQFRAC].standard_name, + "soil_moisture_liquid_fraction"); + strcpy(out_metadata[OUT_SMLIQFRAC].units, "1"); + strcpy(out_metadata[OUT_SMLIQFRAC].description, + "fraction of soil moisture (by mass) that is liquid, for each soil layer"); + + /* snow interception storage in canopy [mm] */ + strcpy(out_metadata[OUT_SNOW_CANOPY].varname, "OUT_SNOW_CANOPY"); + strcpy(out_metadata[OUT_SNOW_CANOPY].long_name, "snow_canopy"); + strcpy(out_metadata[OUT_SNOW_CANOPY].standard_name, + "lwe_thickness_of_canopy_intercepted_snow"); + strcpy(out_metadata[OUT_SNOW_CANOPY].units, "mm"); + strcpy(out_metadata[OUT_SNOW_CANOPY].description, + "snow interception storage in canopy"); + + /* fractional area of snow cover [fraction] */ + strcpy(out_metadata[OUT_SNOW_COVER].varname, "OUT_SNOW_COVER"); + strcpy(out_metadata[OUT_SNOW_COVER].long_name, "snow_cover"); + strcpy(out_metadata[OUT_SNOW_COVER].standard_name, + "snow_cover_area_fraction"); + strcpy(out_metadata[OUT_SNOW_COVER].units, "1"); + strcpy(out_metadata[OUT_SNOW_COVER].description, + "fractional area of snow cover"); + + /* depth of snow pack [cm] */ + strcpy(out_metadata[OUT_SNOW_DEPTH].varname, "OUT_SNOW_DEPTH"); + strcpy(out_metadata[OUT_SNOW_DEPTH].long_name, "snow_depth"); + strcpy(out_metadata[OUT_SNOW_DEPTH].standard_name, "thickness_of_snow"); + strcpy(out_metadata[OUT_SNOW_DEPTH].units, "cm"); + strcpy(out_metadata[OUT_SNOW_DEPTH].description, "depth of snow pack"); + + /* soil ice content [mm] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_ICE].varname, "OUT_SOIL_ICE"); + strcpy(out_metadata[OUT_SOIL_ICE].long_name, "soil_ice"); + strcpy(out_metadata[OUT_SOIL_ICE].standard_name, "soil_moisture_ice_depth"); + strcpy(out_metadata[OUT_SOIL_ICE].units, "mm"); + strcpy(out_metadata[OUT_SOIL_ICE].description, + "soil ice content for each soil layer"); + + /* soil liquid moisture content [mm] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_LIQ].varname, "OUT_SOIL_LIQ"); + strcpy(out_metadata[OUT_SOIL_LIQ].long_name, "soil_liq"); + strcpy(out_metadata[OUT_SOIL_LIQ].standard_name, + "soil_moisture_liquid_depth"); + strcpy(out_metadata[OUT_SOIL_LIQ].units, "mm"); + strcpy(out_metadata[OUT_SOIL_LIQ].description, + "soil liquid moisture content for each soil layer"); + + /* soil ice content [1] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_ICE_FRAC].varname, "OUT_SOIL_ICE_FRAC"); + strcpy(out_metadata[OUT_SOIL_ICE_FRAC].long_name, "soil_ice_frac"); + strcpy(out_metadata[OUT_SOIL_ICE_FRAC].standard_name, + "soil_moisture_ice_depth_fraction"); + strcpy(out_metadata[OUT_SOIL_ICE_FRAC].units, "1"); + strcpy(out_metadata[OUT_SOIL_ICE_FRAC].description, + "soil ice content fraction for each soil layer"); + + /* soil liquid moisture content [1] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_LIQ_FRAC].varname, "OUT_SOIL_LIQ_FRAC"); + strcpy(out_metadata[OUT_SOIL_LIQ_FRAC].long_name, "soil_liq_frac"); + strcpy(out_metadata[OUT_SOIL_LIQ_FRAC].standard_name, + "soil_moisture_liquid_depth_fraction"); + strcpy(out_metadata[OUT_SOIL_LIQ_FRAC].units, "1"); + strcpy(out_metadata[OUT_SOIL_LIQ_FRAC].description, + "soil liquid moisture content fraction for each soil layer"); + + /* soil total moisture content [mm] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_MOIST].varname, "OUT_SOIL_MOIST"); + strcpy(out_metadata[OUT_SOIL_MOIST].long_name, "soil_moist"); + strcpy(out_metadata[OUT_SOIL_MOIST].standard_name, "soil_moisture"); + strcpy(out_metadata[OUT_SOIL_MOIST].units, "mm"); + strcpy(out_metadata[OUT_SOIL_MOIST].description, + "soil total moisture content"); + + /* vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ + strcpy(out_metadata[OUT_SOIL_WET].varname, "OUT_SOIL_WET"); + strcpy(out_metadata[OUT_SOIL_WET].long_name, "soil_wet"); + strcpy(out_metadata[OUT_SOIL_WET].standard_name, + "soil_moisture_wetness_fraction"); + strcpy(out_metadata[OUT_SOIL_WET].units, "1"); + strcpy(out_metadata[OUT_SOIL_WET].description, + "vertical average of (soil moisture - wilting point)/(maximum " + "soil moisture - wilting point)"); + + /* storage of liquid water on surface (ponding) [mm] */ + strcpy(out_metadata[OUT_SURFSTOR].varname, "OUT_SURFSTOR"); + strcpy(out_metadata[OUT_SURFSTOR].long_name, "surfstor"); + strcpy(out_metadata[OUT_SURFSTOR].standard_name, + "surface_liquid_water_storage"); + strcpy(out_metadata[OUT_SURFSTOR].units, "mm"); + strcpy(out_metadata[OUT_SURFSTOR].description, + "storage of liquid water on surface (ponding)"); + + /* fraction of soil surface that is frozen [fraction] */ + strcpy(out_metadata[OUT_SURF_FROST_FRAC].varname, "OUT_SURF_FROST_FRAC"); + strcpy(out_metadata[OUT_SURF_FROST_FRAC].long_name, "surf_frost_frac"); + strcpy(out_metadata[OUT_SURF_FROST_FRAC].standard_name, + "frozen_soil_surface_fraction"); + strcpy(out_metadata[OUT_SURF_FROST_FRAC].units, "1"); + strcpy(out_metadata[OUT_SURF_FROST_FRAC].description, + "fraction of soil surface that is frozen"); + + /* snow water equivalent in snow pack [mm] */ + strcpy(out_metadata[OUT_SWE].varname, "OUT_SWE"); + strcpy(out_metadata[OUT_SWE].long_name, "swe"); + strcpy(out_metadata[OUT_SWE].standard_name, "lwe_thickness_of_snow"); + strcpy(out_metadata[OUT_SWE].units, "mm"); + strcpy(out_metadata[OUT_SWE].description, + "snow water equivalent in snow pack"); + + /* total moisture interception storage in canopy [mm] */ + strcpy(out_metadata[OUT_WDEW].varname, "OUT_WDEW"); + strcpy(out_metadata[OUT_WDEW].long_name, "wdew"); + strcpy(out_metadata[OUT_WDEW].standard_name, + "soil_moisture_storage_depth_in_canopy"); + strcpy(out_metadata[OUT_WDEW].units, "mm"); + strcpy(out_metadata[OUT_WDEW].description, + "total moisture interception storage in canopy"); + + /* water table position [cm] (zwt within lowest unsaturated layer) */ + strcpy(out_metadata[OUT_ZWT].varname, "OUT_ZWT"); + strcpy(out_metadata[OUT_ZWT].long_name, "zwt"); + strcpy(out_metadata[OUT_ZWT].standard_name, + "water_table_position_lowest_layer"); + strcpy(out_metadata[OUT_ZWT].units, "cm"); + strcpy(out_metadata[OUT_ZWT].description, + "water table position (zwt within lowest unsaturated layer)"); + + /* lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ + strcpy(out_metadata[OUT_ZWT_LUMPED].varname, "OUT_ZWT_LUMPED"); + strcpy(out_metadata[OUT_ZWT_LUMPED].long_name, "zwt_lumped"); + strcpy(out_metadata[OUT_ZWT_LUMPED].standard_name, + "lumped_water_table_position"); + strcpy(out_metadata[OUT_ZWT_LUMPED].units, "cm"); + strcpy(out_metadata[OUT_ZWT_LUMPED].description, + "lumped water table position (zwt of total moisture across all layers, lumped together)"); + + // Water Balance Terms - fluxes + /* baseflow out of the bottom layer [mm] */ + strcpy(out_metadata[OUT_BASEFLOW].varname, "OUT_BASEFLOW"); + strcpy(out_metadata[OUT_BASEFLOW].long_name, "baseflow"); + strcpy(out_metadata[OUT_BASEFLOW].standard_name, "baseflow_amount"); + strcpy(out_metadata[OUT_BASEFLOW].units, "mm"); + strcpy(out_metadata[OUT_BASEFLOW].description, + "baseflow out of the bottom layer"); + + /* change in canopy interception storage [mm] */ + strcpy(out_metadata[OUT_DELINTERCEPT].varname, "OUT_DELINTERCEPT"); + strcpy(out_metadata[OUT_DELINTERCEPT].long_name, "delintercept"); + strcpy(out_metadata[OUT_DELINTERCEPT].standard_name, + "change_in_canopy_interception_amount"); + strcpy(out_metadata[OUT_DELINTERCEPT].units, "mm"); + strcpy(out_metadata[OUT_DELINTERCEPT].description, + "change in canopy interception storage"); + + /* change in soil water content [mm] */ + strcpy(out_metadata[OUT_DELSOILMOIST].varname, "OUT_DELSOILMOIST"); + strcpy(out_metadata[OUT_DELSOILMOIST].long_name, "delsoilmoist"); + strcpy(out_metadata[OUT_DELSOILMOIST].standard_name, + "change_in_soil_water_amount"); + strcpy(out_metadata[OUT_DELSOILMOIST].units, "mm"); + strcpy(out_metadata[OUT_DELSOILMOIST].description, + "change in soil water content"); + + /* change in snow water equivalent [mm] */ + strcpy(out_metadata[OUT_DELSWE].varname, "OUT_DELSWE"); + strcpy(out_metadata[OUT_DELSWE].long_name, "delswe"); + strcpy(out_metadata[OUT_DELSWE].standard_name, + "change_in_snow_lwe_thickness"); + strcpy(out_metadata[OUT_DELSWE].units, "mm"); + strcpy(out_metadata[OUT_DELSWE].description, + "change in snow water equivalent"); + + /* change in surface liquid water storage [mm] */ + strcpy(out_metadata[OUT_DELSURFSTOR].varname, "OUT_DELSURFSTOR"); + strcpy(out_metadata[OUT_DELSURFSTOR].long_name, "delsurfstor"); + strcpy(out_metadata[OUT_DELSURFSTOR].standard_name, + "change_in_surface_liquid_water_storage"); + strcpy(out_metadata[OUT_DELSURFSTOR].units, "mm"); + strcpy(out_metadata[OUT_DELSURFSTOR].description, + "change in surface liquid water storage"); + + /* total net evaporation [mm] */ + strcpy(out_metadata[OUT_EVAP].varname, "OUT_EVAP"); + strcpy(out_metadata[OUT_EVAP].long_name, "evap"); + strcpy(out_metadata[OUT_EVAP].standard_name, "water_evaporation_flux_net"); + strcpy(out_metadata[OUT_EVAP].units, "mm"); + strcpy(out_metadata[OUT_EVAP].description, "total net evaporation"); + + /* net evaporation from bare soil [mm] */ + strcpy(out_metadata[OUT_EVAP_BARE].varname, "OUT_EVAP_BARE"); + strcpy(out_metadata[OUT_EVAP_BARE].long_name, "evap_bare"); + strcpy(out_metadata[OUT_EVAP_BARE].standard_name, + "water_evaporation_from_soil"); + strcpy(out_metadata[OUT_EVAP_BARE].units, "mm"); + strcpy(out_metadata[OUT_EVAP_BARE].description, + "net evaporation from bare soil"); + + /* net evaporation from canopy interception [mm] */ + strcpy(out_metadata[OUT_EVAP_CANOP].varname, "OUT_EVAP_CANOP"); + strcpy(out_metadata[OUT_EVAP_CANOP].long_name, "evap_canop"); + strcpy(out_metadata[OUT_EVAP_CANOP].standard_name, + "water_evaporation_from_canopy"); + strcpy(out_metadata[OUT_EVAP_CANOP].units, "mm"); + strcpy(out_metadata[OUT_EVAP_CANOP].description, + "net evaporation from canopy interception"); + + /* moisture that reaches top of soil column [mm] */ + strcpy(out_metadata[OUT_INFLOW].varname, "OUT_INFLOW"); + strcpy(out_metadata[OUT_INFLOW].long_name, "inflow"); + strcpy(out_metadata[OUT_INFLOW].standard_name, "soil_column_inflow"); + strcpy(out_metadata[OUT_INFLOW].units, "mm"); + strcpy(out_metadata[OUT_INFLOW].description, + "moisture that reaches top of soil column"); + + /* incoming baseflow from lake catchment [mm] */ + strcpy(out_metadata[OUT_LAKE_BF_IN].varname, "OUT_LAKE_BF_IN"); + strcpy(out_metadata[OUT_LAKE_BF_IN].long_name, "lake_bf_in"); + strcpy(out_metadata[OUT_LAKE_BF_IN].standard_name, "infiltration_amount"); + strcpy(out_metadata[OUT_LAKE_BF_IN].units, "mm"); + strcpy(out_metadata[OUT_LAKE_BF_IN].description, + "oisture that reaches top of soil column"); + + /* incoming volumetric baseflow from lake catchment [m3] */ + strcpy(out_metadata[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); + strcpy(out_metadata[OUT_LAKE_BF_IN_V].long_name, "lake_bf_in_v"); + strcpy(out_metadata[OUT_LAKE_BF_IN_V].standard_name, + "baseflow_volume_from_lake_catchment"); + strcpy(out_metadata[OUT_LAKE_BF_IN_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_BF_IN_V].description, + "incoming volumetric baseflow from lake catchment"); + + /* outgoing baseflow lake [mm] */ + strcpy(out_metadata[OUT_LAKE_BF_OUT].varname, "OUT_LAKE_BF_OUT"); + strcpy(out_metadata[OUT_LAKE_BF_OUT].long_name, "lake_bf_out"); + strcpy(out_metadata[OUT_LAKE_BF_OUT].standard_name, + "baseflow_outgoing_lake"); + strcpy(out_metadata[OUT_LAKE_BF_OUT].units, "mm"); + strcpy(out_metadata[OUT_LAKE_BF_OUT].description, + "outgoing baseflow lake"); + + /* outgoing volumetric baseflow from lake [m3] */ + strcpy(out_metadata[OUT_LAKE_BF_OUT_V].varname, "OUT_LAKE_BF_OUT_V"); + strcpy(out_metadata[OUT_LAKE_BF_OUT_V].long_name, "lake_bf_out_v"); + strcpy(out_metadata[OUT_LAKE_BF_OUT_V].standard_name, + "baseflow_outgoing_volume_lake"); + strcpy(out_metadata[OUT_LAKE_BF_OUT_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_BF_OUT_V].description, + "outgoing volumetric baseflow from lake"); + + /* channel inflow into lake [mm] */ + strcpy(out_metadata[OUT_LAKE_CHAN_IN].varname, "OUT_LAKE_CHAN_IN"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN].long_name, "lake_chan_in"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN].standard_name, + "channel_inflow_into_lake"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN].units, "mm"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN].description, + "channel inflow into lake"); + + /* volumetric channel inflow into lake [m3] */ + strcpy(out_metadata[OUT_LAKE_CHAN_IN_V].varname, "OUT_LAKE_CHAN_IN_V"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN_V].long_name, "lake_chan_in_v"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN_V].standard_name, + "channel_inflow_volume_into_lake"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_CHAN_IN_V].description, + "volumetric channel inflow into lake"); + + /* channel outflow from lake [mm] */ + strcpy(out_metadata[OUT_LAKE_CHAN_OUT].varname, "OUT_LAKE_CHAN_OUT"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT].long_name, "lake_chan_out"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT].standard_name, + "channel_outflow_from_lake"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT].units, "mm"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT].description, + "channel outflow from lake"); + + /* volumetric channel outflow from lake [m3] */ + strcpy(out_metadata[OUT_LAKE_CHAN_OUT_V].varname, "OUT_LAKE_CHAN_OUT_V"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT_V].long_name, "lake_chan_out_v"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT_V].standard_name, + "channel_outflow_volume_from_lake"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_CHAN_OUT_V].description, + "volumetric channel outflow from lake"); + + /* change in lake moisture storage (liquid plus ice cover) [mm] */ + strcpy(out_metadata[OUT_LAKE_DSTOR].varname, "OUT_LAKE_DSTOR"); + strcpy(out_metadata[OUT_LAKE_DSTOR].long_name, "lake_dstor"); + strcpy(out_metadata[OUT_LAKE_DSTOR].standard_name, + "change_in_lake_moisture_amount"); + strcpy(out_metadata[OUT_LAKE_DSTOR].units, "mm"); + strcpy(out_metadata[OUT_LAKE_DSTOR].description, + "change in lake moisture storage (liquid plus ice cover)"); + + /* volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ + strcpy(out_metadata[OUT_LAKE_DSTOR_V].varname, "OUT_LAKE_DSTOR_V"); + strcpy(out_metadata[OUT_LAKE_DSTOR_V].long_name, "lake_dstor_v"); + strcpy(out_metadata[OUT_LAKE_DSTOR_V].standard_name, + "change_in_lake_moisture_volume"); + strcpy(out_metadata[OUT_LAKE_DSTOR_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_DSTOR_V].description, + "volumetric change in lake moisture storage (liquid plus ice cover)"); + + /* change in snowpack on top of lake ice [mm] */ + strcpy(out_metadata[OUT_LAKE_DSWE].varname, "OUT_LAKE_DSWE"); + strcpy(out_metadata[OUT_LAKE_DSWE].long_name, "lake_dswe"); + strcpy(out_metadata[OUT_LAKE_DSWE].standard_name, + "change_in_snow_lwe_thickness_on_lake_ice"); + strcpy(out_metadata[OUT_LAKE_DSWE].units, "mm"); + strcpy(out_metadata[OUT_LAKE_DSWE].description, + "change in snowpack on top of lake ice"); + + /* volumetric change in snowpack on top of lake ice [m3] */ + strcpy(out_metadata[OUT_LAKE_DSWE_V].varname, "OUT_LAKE_DSWE_V"); + strcpy(out_metadata[OUT_LAKE_DSWE_V].long_name, "lake_dswe_v"); + strcpy(out_metadata[OUT_LAKE_DSWE_V].standard_name, + "change_in_snow_lwe_volume_on_lake_ice"); + strcpy(out_metadata[OUT_LAKE_DSWE_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_DSWE_V].description, + "volumetric change in snowpack on top of lake ice"); + + /* net evaporation from lake surface [mm] */ + strcpy(out_metadata[OUT_LAKE_EVAP].varname, "OUT_LAKE_EVAP"); + strcpy(out_metadata[OUT_LAKE_EVAP].long_name, "lake_evap"); + strcpy(out_metadata[OUT_LAKE_EVAP].standard_name, + "water_evaporation_from_lake"); + strcpy(out_metadata[OUT_LAKE_EVAP].units, "mm"); + strcpy(out_metadata[OUT_LAKE_EVAP].description, + "net evaporation from lake surface"); + + /* net volumetric evaporation from lake surface [m3] */ + strcpy(out_metadata[OUT_LAKE_EVAP_V].varname, "OUT_LAKE_EVAP_V"); + strcpy(out_metadata[OUT_LAKE_EVAP_V].long_name, "lake_evap_v"); + strcpy(out_metadata[OUT_LAKE_EVAP_V].standard_name, + "water_evaporation_volume_from_lake"); + strcpy(out_metadata[OUT_LAKE_EVAP_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_EVAP_V].description, + "net volumetric evaporation from lake surface"); + + /* volumetric precipitation over lake surface [m3] */ + strcpy(out_metadata[OUT_LAKE_PREC_V].varname, "OUT_LAKE_PREC_V"); + strcpy(out_metadata[OUT_LAKE_PREC_V].long_name, "lake_prec_v"); + strcpy(out_metadata[OUT_LAKE_PREC_V].standard_name, + "precipitation_over_lake_volume"); + strcpy(out_metadata[OUT_LAKE_PREC_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_PREC_V].description, + "volumetric precipitation over lake surface"); + + /* recharge from lake to surrounding wetland [mm] */ + strcpy(out_metadata[OUT_LAKE_RCHRG].varname, "OUT_LAKE_RCHRG"); + strcpy(out_metadata[OUT_LAKE_RCHRG].long_name, "lake_rchrg"); + strcpy(out_metadata[OUT_LAKE_RCHRG].standard_name, + "recharge_from_lake_to_wetland"); + strcpy(out_metadata[OUT_LAKE_RCHRG].units, "mm"); + strcpy(out_metadata[OUT_LAKE_RCHRG].description, + "recharge from lake to surrounding wetland"); + + /* volumetric recharge from lake to surrounding wetland [m3] */ + strcpy(out_metadata[OUT_LAKE_RCHRG_V].varname, "OUT_LAKE_RCHRG_V"); + strcpy(out_metadata[OUT_LAKE_RCHRG_V].long_name, "lake_rchrg_v"); + strcpy(out_metadata[OUT_LAKE_RCHRG_V].standard_name, ""); + strcpy(out_metadata[OUT_LAKE_RCHRG_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_RCHRG_V].description, + "volumetric recharge from lake to surrounding wetland"); + + /* incoming runoff from lake catchment [mm] */ + strcpy(out_metadata[OUT_LAKE_RO_IN].varname, "OUT_LAKE_RO_IN"); + strcpy(out_metadata[OUT_LAKE_RO_IN].long_name, "lake_ro_in"); + strcpy(out_metadata[OUT_LAKE_RO_IN].standard_name, + "recharge_volume_from_lake_to_wetland"); + strcpy(out_metadata[OUT_LAKE_RO_IN].units, "mm"); + strcpy(out_metadata[OUT_LAKE_RO_IN].description, + "incoming runoff from lake catchment"); + + /* incoming volumetric runoff from lake catchment [m3] */ + strcpy(out_metadata[OUT_LAKE_RO_IN_V].varname, "OUT_LAKE_RO_IN_V"); + strcpy(out_metadata[OUT_LAKE_RO_IN_V].long_name, "lake_ro_in_v"); + strcpy(out_metadata[OUT_LAKE_RO_IN_V].standard_name, + "runoff_volume_from_lake_catchment"); + strcpy(out_metadata[OUT_LAKE_RO_IN_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_RO_IN_V].description, + "incoming volumetric runoff from lake catchment"); + + /* sublimation from lake snow pack [mm] */ + strcpy(out_metadata[OUT_LAKE_VAPFLX].varname, "OUT_LAKE_VAPFLX"); + strcpy(out_metadata[OUT_LAKE_VAPFLX].long_name, "lake_vapflx"); + strcpy(out_metadata[OUT_LAKE_VAPFLX].standard_name, + "water_sublimation_flux_from_lake_snow"); + strcpy(out_metadata[OUT_LAKE_VAPFLX].units, "mm"); + strcpy(out_metadata[OUT_LAKE_VAPFLX].description, + "sublimation from lake snow pack"); + + /* volumetric sublimation from lake snow pack [m3] */ + strcpy(out_metadata[OUT_LAKE_VAPFLX_V].varname, "OUT_LAKE_VAPFLX_V"); + strcpy(out_metadata[OUT_LAKE_VAPFLX_V].long_name, "lake_vapflx_v"); + strcpy(out_metadata[OUT_LAKE_VAPFLX_V].standard_name, + "water_sublimation_flux_volume_from_lake_snow"); + strcpy(out_metadata[OUT_LAKE_VAPFLX_V].units, "m3"); + strcpy(out_metadata[OUT_LAKE_VAPFLX_V].description, + "volumetric sublimation from lake snow pack"); + + /* Potential evapotranspiration (= area-weighted sum of potential + transpiration and potential soil evaporation). [mm] */ + strcpy(out_metadata[OUT_PET].varname, "OUT_PET"); + strcpy(out_metadata[OUT_PET].long_name, "pet"); + strcpy(out_metadata[OUT_PET].standard_name, + "water_potential_evaporation_amount"); + strcpy(out_metadata[OUT_PET].units, "mm"); + strcpy(out_metadata[OUT_PET].description, + "Potential evapotranspiration (= area-weighted sum of potential " + "transpiration and potential soil evaporation)"); + + /* incoming precipitation [mm] */ + strcpy(out_metadata[OUT_PREC].varname, "OUT_PREC"); + strcpy(out_metadata[OUT_PREC].long_name, "prec"); + strcpy(out_metadata[OUT_PREC].standard_name, "precipitation_amount"); + strcpy(out_metadata[OUT_PREC].units, "mm"); + strcpy(out_metadata[OUT_PREC].description, "incoming precipitation"); + + /* rainfall [mm] */ + strcpy(out_metadata[OUT_RAINF].varname, "OUT_RAINF"); + strcpy(out_metadata[OUT_RAINF].long_name, "rainf"); + strcpy(out_metadata[OUT_RAINF].standard_name, "rainfall_amount"); + strcpy(out_metadata[OUT_RAINF].units, "mm"); + strcpy(out_metadata[OUT_RAINF].description, "liquid rainfall amount"); + + /* refreezing of water in the snow [mm] */ + strcpy(out_metadata[OUT_REFREEZE].varname, "OUT_REFREEZE"); + strcpy(out_metadata[OUT_REFREEZE].long_name, "refreeze"); + strcpy(out_metadata[OUT_REFREEZE].standard_name, + "lwe_thickness_of_refreezing_water_in_snow"); + strcpy(out_metadata[OUT_REFREEZE].units, "mm"); + strcpy(out_metadata[OUT_REFREEZE].description, + "refreezing of water in the snow"); + + /* surface runoff [mm] */ + strcpy(out_metadata[OUT_RUNOFF].varname, "OUT_RUNOFF"); + strcpy(out_metadata[OUT_RUNOFF].long_name, "runoff"); + strcpy(out_metadata[OUT_RUNOFF].standard_name, "runoff_amount"); + strcpy(out_metadata[OUT_RUNOFF].units, "mm"); + strcpy(out_metadata[OUT_RUNOFF].description, "surface runoff"); + + /* snow melt [mm] */ + strcpy(out_metadata[OUT_SNOW_MELT].varname, "OUT_SNOW_MELT"); + strcpy(out_metadata[OUT_SNOW_MELT].long_name, "snow_melt"); + strcpy(out_metadata[OUT_SNOW_MELT].standard_name, "snow_melt_amount"); + strcpy(out_metadata[OUT_SNOW_MELT].units, "mm"); + strcpy(out_metadata[OUT_SNOW_MELT].description, "snow melt"); + + /* snowfall [mm] */ + strcpy(out_metadata[OUT_SNOWF].varname, "OUT_SNOWF"); + strcpy(out_metadata[OUT_SNOWF].long_name, "snowf"); + strcpy(out_metadata[OUT_SNOWF].standard_name, "snowfall_lwe_amount"); + strcpy(out_metadata[OUT_SNOWF].units, "mm"); + strcpy(out_metadata[OUT_SNOWF].description, "snowfall"); + + /* net sublimation of blowing snow [mm] */ + strcpy(out_metadata[OUT_SUB_BLOWING].varname, "OUT_SUB_BLOWING"); + strcpy(out_metadata[OUT_SUB_BLOWING].long_name, "sub_blowing"); + strcpy(out_metadata[OUT_SUB_BLOWING].standard_name, + "submlimation_amount_from_blowing_snow"); + strcpy(out_metadata[OUT_SUB_BLOWING].units, "mm"); + strcpy(out_metadata[OUT_SUB_BLOWING].description, + "net sublimation of blowing snow"); + + /* net sublimation from snow stored in canopy [mm] */ + strcpy(out_metadata[OUT_SUB_CANOP].varname, "OUT_SUB_CANOP"); + strcpy(out_metadata[OUT_SUB_CANOP].long_name, "sub_canop"); + strcpy(out_metadata[OUT_SUB_CANOP].standard_name, + "sublimation_amount_from_canopy_snow"); + strcpy(out_metadata[OUT_SUB_CANOP].units, "mm"); + strcpy(out_metadata[OUT_SUB_CANOP].description, + "net sublimation from snow stored in canopy"); + + /* net sublimation from snow pack (surface and blowing) [mm] */ + strcpy(out_metadata[OUT_SUB_SNOW].varname, "OUT_SUB_SNOW"); + strcpy(out_metadata[OUT_SUB_SNOW].long_name, "sub_snow"); + strcpy(out_metadata[OUT_SUB_SNOW].standard_name, + "sublimation_amount_from_snow_pack"); + strcpy(out_metadata[OUT_SUB_SNOW].units, "mm"); + strcpy(out_metadata[OUT_SUB_SNOW].description, + "net sublimation from snow pack (surface and blowing)"); + + /* net sublimation from snow pack surface [mm] */ + strcpy(out_metadata[OUT_SUB_SURFACE].varname, "OUT_SUB_SURFACE"); + strcpy(out_metadata[OUT_SUB_SURFACE].long_name, "sub_surface"); + strcpy(out_metadata[OUT_SUB_SURFACE].standard_name, + "sublimation_amount_from_snow_pack_surface"); + strcpy(out_metadata[OUT_SUB_SURFACE].units, "mm"); + strcpy(out_metadata[OUT_SUB_SURFACE].description, + "net sublimation from snow pack surface"); + + /* net transpiration from vegetation [mm] */ + strcpy(out_metadata[OUT_TRANSP_VEG].varname, "OUT_TRANSP_VEG"); + strcpy(out_metadata[OUT_TRANSP_VEG].long_name, "transp_veg"); + strcpy(out_metadata[OUT_TRANSP_VEG].standard_name, "transpiration_amount"); + strcpy(out_metadata[OUT_TRANSP_VEG].units, "mm"); + strcpy(out_metadata[OUT_TRANSP_VEG].description, + "net transpiration from vegetation"); + + // Energy Balance Terms - state variables + /* albedo [fraction] */ + strcpy(out_metadata[OUT_ALBEDO].varname, "OUT_ALBEDO"); + strcpy(out_metadata[OUT_ALBEDO].long_name, "albedo"); + strcpy(out_metadata[OUT_ALBEDO].standard_name, "surface_albedo"); + strcpy(out_metadata[OUT_ALBEDO].units, "1"); + strcpy(out_metadata[OUT_ALBEDO].description, "albedo"); + + /* bare soil surface temperature [C] */ + strcpy(out_metadata[OUT_BARESOILT].varname, "OUT_BARESOILT"); + strcpy(out_metadata[OUT_BARESOILT].long_name, "baresoilt"); + strcpy(out_metadata[OUT_BARESOILT].standard_name, + "surface_temperature_bare_soil"); + strcpy(out_metadata[OUT_BARESOILT].units, "C"); + strcpy(out_metadata[OUT_BARESOILT].description, + "bare soil surface temperature"); + + /* depth of freezing fronts [cm] for each freezing front */ + strcpy(out_metadata[OUT_FDEPTH].varname, "OUT_FDEPTH"); + strcpy(out_metadata[OUT_FDEPTH].long_name, "fdepth"); + strcpy(out_metadata[OUT_FDEPTH].standard_name, "freezing_fronts_depth"); + strcpy(out_metadata[OUT_FDEPTH].units, "cm"); + strcpy(out_metadata[OUT_FDEPTH].description, + "depth of freezing fronts for each freezing front"); + + /* lake ice temperature [K] */ + strcpy(out_metadata[OUT_LAKE_ICE_TEMP].varname, "OUT_LAKE_ICE_TEMP"); + strcpy(out_metadata[OUT_LAKE_ICE_TEMP].long_name, "lake_ice_temp"); + strcpy(out_metadata[OUT_LAKE_ICE_TEMP].standard_name, + "lake_ice_temperature"); + strcpy(out_metadata[OUT_LAKE_ICE_TEMP].units, "K"); + strcpy(out_metadata[OUT_LAKE_ICE_TEMP].description, "lake ice temperature"); + + /* lake surface temperature [K] */ + strcpy(out_metadata[OUT_LAKE_SURF_TEMP].varname, "OUT_LAKE_SURF_TEMP"); + strcpy(out_metadata[OUT_LAKE_SURF_TEMP].long_name, "lake_surf_temp"); + strcpy(out_metadata[OUT_LAKE_SURF_TEMP].standard_name, + "lake_surface_temperature"); + strcpy(out_metadata[OUT_LAKE_SURF_TEMP].units, "K"); + strcpy(out_metadata[OUT_LAKE_SURF_TEMP].description, + "lake surface temperature"); + + /* average radiative surface temperature [K] */ + strcpy(out_metadata[OUT_RAD_TEMP].varname, "OUT_RAD_TEMP"); + strcpy(out_metadata[OUT_RAD_TEMP].long_name, "rad_temp"); + strcpy(out_metadata[OUT_RAD_TEMP].standard_name, + "surface_radiative_temperature"); + strcpy(out_metadata[OUT_RAD_TEMP].units, "K"); + strcpy(out_metadata[OUT_RAD_TEMP].description, + "average radiative surface temperature"); + + /* snow albedo [fraction] */ + strcpy(out_metadata[OUT_SALBEDO].varname, "OUT_SALBEDO"); + strcpy(out_metadata[OUT_SALBEDO].long_name, "salbedo"); + strcpy(out_metadata[OUT_SALBEDO].standard_name, "snow_albedo"); + strcpy(out_metadata[OUT_SALBEDO].units, "1"); + strcpy(out_metadata[OUT_SALBEDO].description, "snow albedo"); + + /* snow pack temperature [C] */ + strcpy(out_metadata[OUT_SNOW_PACK_TEMP].varname, "OUT_SNOW_PACK_TEMP"); + strcpy(out_metadata[OUT_SNOW_PACK_TEMP].long_name, "snow_pack_temp"); + strcpy(out_metadata[OUT_SNOW_PACK_TEMP].standard_name, + "snow_pack_temperature"); + strcpy(out_metadata[OUT_SNOW_PACK_TEMP].units, "C"); + strcpy(out_metadata[OUT_SNOW_PACK_TEMP].description, + "snow pack temperature"); + + /* snow surface temperature [C] */ + strcpy(out_metadata[OUT_SNOW_SURF_TEMP].varname, "OUT_SNOW_SURF_TEMP"); + strcpy(out_metadata[OUT_SNOW_SURF_TEMP].long_name, "snow_surf_temp"); + strcpy(out_metadata[OUT_SNOW_SURF_TEMP].standard_name, + "snow_surface_temperature"); + strcpy(out_metadata[OUT_SNOW_SURF_TEMP].units, "C"); + strcpy(out_metadata[OUT_SNOW_SURF_TEMP].description, + "snow surface temperature"); + + /* snow surface temperature flag */ + strcpy(out_metadata[OUT_SNOWT_FBFLAG].varname, "OUT_SNOWT_FBFLAG"); + strcpy(out_metadata[OUT_SNOWT_FBFLAG].long_name, "snowt_fbflag"); + strcpy(out_metadata[OUT_SNOWT_FBFLAG].standard_name, + "snow_surface_temperature_flag"); + strcpy(out_metadata[OUT_SNOWT_FBFLAG].units, "1"); + strcpy(out_metadata[OUT_SNOWT_FBFLAG].description, + "snow surface temperature flag"); + + /* soil temperature [C] for each soil layer */ + strcpy(out_metadata[OUT_SOIL_TEMP].varname, "OUT_SOIL_TEMP"); + strcpy(out_metadata[OUT_SOIL_TEMP].long_name, "soil_temp"); + strcpy(out_metadata[OUT_SOIL_TEMP].standard_name, "soil_temperature"); + strcpy(out_metadata[OUT_SOIL_TEMP].units, "C"); + strcpy(out_metadata[OUT_SOIL_TEMP].description, + "soil temperature for each soil layer"); + + /* soil temperature [C] for each soil thermal node */ + strcpy(out_metadata[OUT_SOIL_TNODE].varname, "OUT_SOIL_TNODE"); + strcpy(out_metadata[OUT_SOIL_TNODE].long_name, "soil_tnode"); + strcpy(out_metadata[OUT_SOIL_TNODE].standard_name, "soil_temperature"); + strcpy(out_metadata[OUT_SOIL_TNODE].units, "C"); + strcpy(out_metadata[OUT_SOIL_TNODE].description, + "soil temperature for each soil thermal node"); + + /* soil temperature [C] for each soil thermal node in the wetland */ + strcpy(out_metadata[OUT_SOIL_TNODE_WL].varname, "OUT_SOIL_TNODE_WL"); + strcpy(out_metadata[OUT_SOIL_TNODE_WL].long_name, "soil_tnode_wl"); + strcpy(out_metadata[OUT_SOIL_TNODE_WL].standard_name, "soil_temperature"); + strcpy(out_metadata[OUT_SOIL_TNODE_WL].units, "C"); + strcpy(out_metadata[OUT_SOIL_TNODE_WL].description, + "soil temperature for each soil thermal node in the wetland"); + + /* soil temperature flag for each soil thermal node */ + strcpy(out_metadata[OUT_SOILT_FBFLAG].varname, "OUT_SOILT_FBFLAG"); + strcpy(out_metadata[OUT_SOILT_FBFLAG].long_name, "soilt_fbflag"); + strcpy(out_metadata[OUT_SOILT_FBFLAG].standard_name, + "soil_temperature_flag"); + strcpy(out_metadata[OUT_SOILT_FBFLAG].units, "1"); + strcpy(out_metadata[OUT_SOILT_FBFLAG].description, + "soil temperature flag for each soil thermal node"); + + /* average surface temperature [C] */ + strcpy(out_metadata[OUT_SURF_TEMP].varname, "OUT_SURF_TEMP"); + strcpy(out_metadata[OUT_SURF_TEMP].long_name, "surf_temp"); + strcpy(out_metadata[OUT_SURF_TEMP].standard_name, "surface_temperature"); + strcpy(out_metadata[OUT_SURF_TEMP].units, "C"); + strcpy(out_metadata[OUT_SURF_TEMP].description, + "average surface temperature"); + + /* surface temperature flag */ + strcpy(out_metadata[OUT_SURFT_FBFLAG].varname, "OUT_SURFT_FBFLAG"); + strcpy(out_metadata[OUT_SURFT_FBFLAG].long_name, "surft_fbflag"); + strcpy(out_metadata[OUT_SURFT_FBFLAG].standard_name, + "surface_temperature_flag"); + strcpy(out_metadata[OUT_SURFT_FBFLAG].units, "1"); + strcpy(out_metadata[OUT_SURFT_FBFLAG].description, + "surface temperature flag"); + + /* Tcanopy flag */ + strcpy(out_metadata[OUT_TCAN_FBFLAG].varname, "OUT_TCAN_FBFLAG"); + strcpy(out_metadata[OUT_TCAN_FBFLAG].long_name, "tcan_fbflag"); + strcpy(out_metadata[OUT_TCAN_FBFLAG].standard_name, + "canopy_temperature_flag"); + strcpy(out_metadata[OUT_TCAN_FBFLAG].units, "1"); + strcpy(out_metadata[OUT_TCAN_FBFLAG].description, + "Canopy temperature fallback flag"); + + /* depth of thawing fronts [cm] for each thawing front */ + strcpy(out_metadata[OUT_TDEPTH].varname, "OUT_TDEPTH"); + strcpy(out_metadata[OUT_TDEPTH].long_name, "tdepth"); + strcpy(out_metadata[OUT_TDEPTH].standard_name, "depth_of_thawing_fronts"); + strcpy(out_metadata[OUT_TDEPTH].units, "cm"); + strcpy(out_metadata[OUT_TDEPTH].description, + "depth of thawing fronts for each thawing front"); + + /* Tfoliage flag */ + strcpy(out_metadata[OUT_TFOL_FBFLAG].varname, "OUT_TFOL_FBFLAG"); + strcpy(out_metadata[OUT_TFOL_FBFLAG].long_name, "tfol_fbflag"); + strcpy(out_metadata[OUT_TFOL_FBFLAG].standard_name, + "foliage_temperature_flag"); + strcpy(out_metadata[OUT_TFOL_FBFLAG].units, "1"); + strcpy(out_metadata[OUT_TFOL_FBFLAG].description, + "foilage temperature fallback flag"); + + /* average vegetation canopy temperature [C] */ + strcpy(out_metadata[OUT_VEGT].varname, "OUT_VEGT"); + strcpy(out_metadata[OUT_VEGT].long_name, "vegt"); + strcpy(out_metadata[OUT_VEGT].standard_name, "canopy_temperature"); + strcpy(out_metadata[OUT_VEGT].units, "C"); + strcpy(out_metadata[OUT_TFOL_FBFLAG].description, + "average vegetation canopy temperature"); + + // Energy Balance Terms - fluxes + /* net sensible heat advected to snow pack [W m-2] */ + strcpy(out_metadata[OUT_ADV_SENS].varname, "OUT_ADV_SENS"); + strcpy(out_metadata[OUT_ADV_SENS].long_name, "adv_sens"); + strcpy(out_metadata[OUT_ADV_SENS].standard_name, + "net_sensible_heat_flux_to_snow_pack"); + strcpy(out_metadata[OUT_ADV_SENS].units, "W m-2"); + strcpy(out_metadata[OUT_ADV_SENS].description, + "net sensible heat advected to snow pack"); + + /* advected energy [W m-2] */ + strcpy(out_metadata[OUT_ADVECTION].varname, "OUT_ADVECTION"); + strcpy(out_metadata[OUT_ADVECTION].long_name, "advection"); + strcpy(out_metadata[OUT_ADVECTION].standard_name, "advected_energy"); + strcpy(out_metadata[OUT_ADVECTION].units, "W m-2"); + strcpy(out_metadata[OUT_ADVECTION].description, "advected energy "); + + /* rate of change in cold content in snow pack [W m-2] */ + strcpy(out_metadata[OUT_DELTACC].varname, "OUT_DELTACC"); + strcpy(out_metadata[OUT_DELTACC].long_name, "deltacc"); + strcpy(out_metadata[OUT_DELTACC].standard_name, + "rate_change_in_snow_pack_cold_content"); + strcpy(out_metadata[OUT_DELTACC].units, "W m-2"); + strcpy(out_metadata[OUT_DELTACC].description, + "rate of change in cold content in snow pack"); + + /* rate of change in heat storage [W m-2] */ + strcpy(out_metadata[OUT_DELTAH].varname, "OUT_DELTAH"); + strcpy(out_metadata[OUT_DELTAH].long_name, "deltah"); + strcpy(out_metadata[OUT_DELTAH].standard_name, + "rate_change_in_heat_storage"); + strcpy(out_metadata[OUT_DELTAH].units, "W m-2"); + strcpy(out_metadata[OUT_DELTAH].description, + "rate of change in heat storage"); + + /* energy budget error [W m-2] */ + strcpy(out_metadata[OUT_ENERGY_ERROR].varname, "OUT_ENERGY_ERROR"); + strcpy(out_metadata[OUT_ENERGY_ERROR].long_name, "energy_error"); + strcpy(out_metadata[OUT_ENERGY_ERROR].standard_name, "energy_budget_error"); + strcpy(out_metadata[OUT_ENERGY_ERROR].units, "W m-2"); + strcpy(out_metadata[OUT_ENERGY_ERROR].description, "energy budget error"); + + /* water budget error [mm] */ + strcpy(out_metadata[OUT_WATER_ERROR].varname, "OUT_WATER_ERROR"); + strcpy(out_metadata[OUT_WATER_ERROR].long_name, "water_error"); + strcpy(out_metadata[OUT_WATER_ERROR].standard_name, "water_budget_error"); + strcpy(out_metadata[OUT_WATER_ERROR].units, "mm"); + strcpy(out_metadata[OUT_WATER_ERROR].description, "water budget error"); + + /* net energy used to melt/freeze soil moisture [W m-2] */ + strcpy(out_metadata[OUT_FUSION].varname, "OUT_FUSION"); + strcpy(out_metadata[OUT_FUSION].long_name, "fusion"); + strcpy(out_metadata[OUT_FUSION].standard_name, + "energy_of_fusion_in_soil_moisture"); + strcpy(out_metadata[OUT_FUSION].units, "W m-2"); + strcpy(out_metadata[OUT_FUSION].description, + "net energy used to melt/freeze soil moisture"); + + /* net heat flux into ground [W m-2] */ + strcpy(out_metadata[OUT_GRND_FLUX].varname, "OUT_GRND_FLUX"); + strcpy(out_metadata[OUT_GRND_FLUX].long_name, "grnd_flux"); + strcpy(out_metadata[OUT_GRND_FLUX].standard_name, + "downward_heat_flux_in_soil"); + strcpy(out_metadata[OUT_GRND_FLUX].units, "W m-2"); + strcpy(out_metadata[OUT_GRND_FLUX].description, + "net heat flux into ground"); + + /* incoming longwave flux at surface (under veg) [W m-2] */ + strcpy(out_metadata[OUT_IN_LONG].varname, "OUT_IN_LONG"); + strcpy(out_metadata[OUT_IN_LONG].long_name, "in_long"); + strcpy(out_metadata[OUT_IN_LONG].standard_name, + "downwelling_longwave_flux_at_ground_surface"); + strcpy(out_metadata[OUT_IN_LONG].units, "W m-2"); + strcpy(out_metadata[OUT_IN_LONG].description, + "incoming longwave flux at surface (under veg)"); + + /* net upward latent heat flux [W m-2] */ + strcpy(out_metadata[OUT_LATENT].varname, "OUT_LATENT"); + strcpy(out_metadata[OUT_LATENT].long_name, "latent"); + strcpy(out_metadata[OUT_LATENT].standard_name, + "surface_upward_latent_heat_flux"); + strcpy(out_metadata[OUT_LATENT].units, "W m-2"); + strcpy(out_metadata[OUT_LATENT].description, "net upward latent heat flux"); + + /* net upward latent heat flux from sublimation [W m-2] */ + strcpy(out_metadata[OUT_LATENT_SUB].varname, "OUT_LATENT_SUB"); + strcpy(out_metadata[OUT_LATENT_SUB].long_name, "latent_sub"); + strcpy(out_metadata[OUT_LATENT_SUB].standard_name, + "surface_net_latent_heat_flux_from_sublimation"); + strcpy(out_metadata[OUT_LATENT_SUB].units, "W m-2"); + strcpy(out_metadata[OUT_LATENT_SUB].description, + "net upward latent heat flux from sublimation"); + + /* energy of fusion (melting) [W m-2] */ + strcpy(out_metadata[OUT_MELT_ENERGY].varname, "OUT_MELT_ENERGY"); + strcpy(out_metadata[OUT_MELT_ENERGY].long_name, "melt_energy"); + strcpy(out_metadata[OUT_MELT_ENERGY].standard_name, "energy_of_fusion"); + strcpy(out_metadata[OUT_MELT_ENERGY].units, "W m-2"); + strcpy(out_metadata[OUT_MELT_ENERGY].description, + "energy of fusion (melting)"); + + /* net downward longwave flux [W m-2] */ + strcpy(out_metadata[OUT_LWNET].varname, "OUT_LWNET"); + strcpy(out_metadata[OUT_LWNET].long_name, "lwnet"); + strcpy(out_metadata[OUT_LWNET].standard_name, + "net_downward_longwave_flux_at_surface"); + strcpy(out_metadata[OUT_LWNET].units, "W m-2"); + strcpy(out_metadata[OUT_LWNET].description, "net downward longwave flux"); + + /* net downward shortwave flux [W m-2] */ + strcpy(out_metadata[OUT_SWNET].varname, "OUT_SWNET"); + strcpy(out_metadata[OUT_SWNET].long_name, "swnet"); + strcpy(out_metadata[OUT_SWNET].standard_name, + "net_downward_shortwave_flux_at_surface"); + strcpy(out_metadata[OUT_SWNET].units, "W m-2"); + strcpy(out_metadata[OUT_SWNET].description, "net downward shortwave flux"); + + /* net downward radiation flux [W m-2] */ + strcpy(out_metadata[OUT_R_NET].varname, "OUT_R_NET"); + strcpy(out_metadata[OUT_R_NET].long_name, "r_net"); + strcpy(out_metadata[OUT_R_NET].standard_name, + "net_downward_radiation_flux_at_surface"); + strcpy(out_metadata[OUT_R_NET].units, "W m-2"); + strcpy(out_metadata[OUT_R_NET].description, "net downward radiation flux"); + + /* net energy used to refreeze liquid water in snowpack [W m-2] */ + strcpy(out_metadata[OUT_RFRZ_ENERGY].varname, "OUT_RFRZ_ENERGY"); + strcpy(out_metadata[OUT_RFRZ_ENERGY].long_name, "rfrz_energy"); + strcpy(out_metadata[OUT_RFRZ_ENERGY].standard_name, + "net_energy_used_to_refreeze_water_in_snowpack"); + strcpy(out_metadata[OUT_RFRZ_ENERGY].units, "W m-2"); + strcpy(out_metadata[OUT_RFRZ_ENERGY].description, + "net energy used to refreeze liquid water in snowpack"); + + /* net upward sensible heat flux [W m-2] */ + strcpy(out_metadata[OUT_SENSIBLE].varname, "OUT_SENSIBLE"); + strcpy(out_metadata[OUT_SENSIBLE].long_name, "sensible"); + strcpy(out_metadata[OUT_SENSIBLE].standard_name, + "surface_upward_net_sensible_heat_flux"); + strcpy(out_metadata[OUT_SENSIBLE].units, "W m-2"); + strcpy(out_metadata[OUT_SENSIBLE].description, + "net upward sensible heat flux"); + + /* energy flux through snow pack [W m-2] */ + strcpy(out_metadata[OUT_SNOW_FLUX].varname, "OUT_SNOW_FLUX"); + strcpy(out_metadata[OUT_SNOW_FLUX].long_name, "snow_flux"); + strcpy(out_metadata[OUT_SNOW_FLUX].standard_name, + "energy_flux_through_snow_pack"); + strcpy(out_metadata[OUT_SNOW_FLUX].units, "W m-2"); + strcpy(out_metadata[OUT_SNOW_FLUX].description, + "energy flux through snow pack"); + + // Miscellaneous Terms + + /* "scene" aerodynamic conductance [m/s] (tiles with overstory contribute + overstory conductance; others contribue surface conductance) */ + strcpy(out_metadata[OUT_AERO_COND].varname, "OUT_AERO_COND"); + strcpy(out_metadata[OUT_AERO_COND].long_name, "aero_cond"); + strcpy(out_metadata[OUT_AERO_COND].standard_name, + "aerodynamic_conductance"); + strcpy(out_metadata[OUT_AERO_COND].units, "m/s"); + strcpy(out_metadata[OUT_AERO_COND].description, + "scene aerodynamic conductance (tiles with overstory contribute " + "overstory conductance; others contribue surface conductance)"); + + /* surface aerodynamic conductance [m/s] */ + strcpy(out_metadata[OUT_AERO_COND1].varname, "OUT_AERO_COND1"); + strcpy(out_metadata[OUT_AERO_COND1].long_name, "aero_cond1"); + strcpy(out_metadata[OUT_AERO_COND1].standard_name, + "aerodynamic_conductance_surface"); + strcpy(out_metadata[OUT_AERO_COND1].units, "m/s"); + strcpy(out_metadata[OUT_AERO_COND1].description, + "surface aerodynamic conductance"); + + /* overstory aerodynamic conductance [m/s] */ + strcpy(out_metadata[OUT_AERO_COND2].varname, "OUT_AERO_COND2"); + strcpy(out_metadata[OUT_AERO_COND2].long_name, "aero_cond2"); + strcpy(out_metadata[OUT_AERO_COND2].standard_name, + "aerodynamic_conductance_overstory"); + strcpy(out_metadata[OUT_AERO_COND2].units, "m/s"); + strcpy(out_metadata[OUT_AERO_COND2].description, + "overstory aerodynamic conductance"); + + /* "scene" aerodynamic resistance [s m-1] (tiles with overstory contribute overstory resistance; others contribue surface resistance)*/ + strcpy(out_metadata[OUT_AERO_RESIST].varname, "OUT_AERO_RESIST"); + strcpy(out_metadata[OUT_AERO_RESIST].long_name, "aero_resist"); + strcpy(out_metadata[OUT_AERO_RESIST].standard_name, + "aerodynamic_resistance"); + strcpy(out_metadata[OUT_AERO_RESIST].units, "s m-1"); + strcpy(out_metadata[OUT_AERO_RESIST].description, + "scene aerodynamic resistance (tiles with overstory contribute overstory resistance; others contribue surface resistance)"); + + /* surface aerodynamic resistance [m/s] */ + strcpy(out_metadata[OUT_AERO_RESIST1].varname, "OUT_AERO_RESIST1"); + strcpy(out_metadata[OUT_AERO_RESIST1].long_name, "aero_resist1"); + strcpy(out_metadata[OUT_AERO_RESIST1].standard_name, + "aerodynamic_resistance_surface"); + strcpy(out_metadata[OUT_AERO_RESIST1].units, "s m-1"); + strcpy(out_metadata[OUT_AERO_RESIST1].description, + "surface aerodynamic resistance"); + + /* overstory aerodynamic resistance [m/s] */ + strcpy(out_metadata[OUT_AERO_RESIST2].varname, "OUT_AERO_RESIST2"); + strcpy(out_metadata[OUT_AERO_RESIST2].long_name, "aero_resist2"); + strcpy(out_metadata[OUT_AERO_RESIST2].standard_name, + "aerodynamic_resistance_overstory"); + strcpy(out_metadata[OUT_AERO_RESIST2].units, "s m-1"); + strcpy(out_metadata[OUT_AERO_RESIST2].description, + "overstory aerodynamic resistance"); + + /* air temperature [C] */ + strcpy(out_metadata[OUT_AIR_TEMP].varname, "OUT_AIR_TEMP"); + strcpy(out_metadata[OUT_AIR_TEMP].long_name, "air_temp"); + strcpy(out_metadata[OUT_AIR_TEMP].standard_name, "air_temperature"); + strcpy(out_metadata[OUT_AIR_TEMP].units, "C"); + strcpy(out_metadata[OUT_AIR_TEMP].description, "air temperature"); + + /* atmospheric CO2 concentration [ppm] */ + strcpy(out_metadata[OUT_CATM].varname, "OUT_CATM"); + strcpy(out_metadata[OUT_CATM].long_name, "catm"); + strcpy(out_metadata[OUT_CATM].standard_name, + "concentration_of_carbon_dioxide_in_air"); + strcpy(out_metadata[OUT_CATM].units, "ppm"); + strcpy(out_metadata[OUT_CATM].description, "atmospheric CO2 concentration"); + + /* near-surface atmospheric density [kg m-3] */ + strcpy(out_metadata[OUT_DENSITY].varname, "OUT_DENSITY"); + strcpy(out_metadata[OUT_DENSITY].long_name, "density"); + strcpy(out_metadata[OUT_DENSITY].standard_name, "air_density"); + strcpy(out_metadata[OUT_DENSITY].units, "kg m-3"); + strcpy(out_metadata[OUT_DENSITY].description, + "near-surface atmospheric density"); + + /* fractional area covered by plant canopy [fraction] */ + strcpy(out_metadata[OUT_FCANOPY].varname, "OUT_FCANOPY"); + strcpy(out_metadata[OUT_FCANOPY].long_name, "fcanopy"); + strcpy(out_metadata[OUT_FCANOPY].standard_name, + "canopy_cover_area_fraction"); + strcpy(out_metadata[OUT_FCANOPY].units, "1"); + strcpy(out_metadata[OUT_FCANOPY].description, + "fractional area covered by plant canopy"); + + /* fraction of incoming shortwave that is direct [fraction] */ + strcpy(out_metadata[OUT_FDIR].varname, "OUT_FDIR"); + strcpy(out_metadata[OUT_FDIR].long_name, "fdir"); + strcpy(out_metadata[OUT_FDIR].standard_name, + "fraction_of_incoming_shorwave_radiation_that_is_direct"); + strcpy(out_metadata[OUT_FDIR].units, "1"); + strcpy(out_metadata[OUT_FDIR].description, + "fraction of incoming shortwave that is direct"); + + /* leaf area index [1] */ + strcpy(out_metadata[OUT_LAI].varname, "OUT_LAI"); + strcpy(out_metadata[OUT_LAI].long_name, "lai"); + strcpy(out_metadata[OUT_LAI].standard_name, "leaf_area_index"); + strcpy(out_metadata[OUT_LAI].units, "1"); + strcpy(out_metadata[OUT_LAI].description, "leaf area index"); + + /* incoming longwave [W m-2] */ + strcpy(out_metadata[OUT_LWDOWN].varname, "OUT_LWDOWN"); + strcpy(out_metadata[OUT_LWDOWN].long_name, "lwdown"); + strcpy(out_metadata[OUT_LWDOWN].standard_name, + "downwelling_longwave_flux_in_air"); + strcpy(out_metadata[OUT_LWDOWN].units, "W m-2"); + strcpy(out_metadata[OUT_LWDOWN].description, "incoming longwave"); + + /* incoming photosynthetically active radiation [W m-2] */ + strcpy(out_metadata[OUT_PAR].varname, "OUT_PAR"); + strcpy(out_metadata[OUT_PAR].long_name, "par"); + strcpy(out_metadata[OUT_PAR].standard_name, + "surface_downwelling_photosynthetic_radiative_flux_in_air"); + strcpy(out_metadata[OUT_PAR].units, "W m-2"); + strcpy(out_metadata[OUT_PAR].description, + "incoming photosynthetically active radiation"); + + /* near surface atmospheric pressure [kPa] */ + strcpy(out_metadata[OUT_PRESSURE].varname, "OUT_PRESSURE"); + strcpy(out_metadata[OUT_PRESSURE].long_name, "pressure"); + strcpy(out_metadata[OUT_PRESSURE].standard_name, "surface_air_pressure"); + strcpy(out_metadata[OUT_PRESSURE].units, "kPa"); + strcpy(out_metadata[OUT_PRESSURE].description, + "near surface atmospheric pressure"); + + /* specific humidity [kg/kg] */ + strcpy(out_metadata[OUT_QAIR].varname, "OUT_QAIR"); + strcpy(out_metadata[OUT_QAIR].long_name, "qair"); + strcpy(out_metadata[OUT_QAIR].standard_name, "specific_humidity"); + strcpy(out_metadata[OUT_QAIR].units, "1"); + strcpy(out_metadata[OUT_QAIR].description, "specific humidity"); + + /* relative humidity [fraction]*/ + strcpy(out_metadata[OUT_REL_HUMID].varname, "OUT_REL_HUMID"); + strcpy(out_metadata[OUT_REL_HUMID].long_name, "rel_humid"); + strcpy(out_metadata[OUT_REL_HUMID].standard_name, "relative_humidity"); + strcpy(out_metadata[OUT_REL_HUMID].units, "1"); + strcpy(out_metadata[OUT_REL_HUMID].description, "relative humidity"); + + /* incoming shortwave [W m-2] */ + strcpy(out_metadata[OUT_SWDOWN].varname, "OUT_SWDOWN"); + strcpy(out_metadata[OUT_SWDOWN].long_name, "swdown"); + strcpy(out_metadata[OUT_SWDOWN].standard_name, "incoming shortwave"); + strcpy(out_metadata[OUT_SWDOWN].units, "W m-2"); + strcpy(out_metadata[OUT_SWDOWN].description, "incoming shortwave"); + + /* surface conductance [m/s] */ + strcpy(out_metadata[OUT_SURF_COND].varname, "OUT_SURF_COND"); + strcpy(out_metadata[OUT_SURF_COND].long_name, "surf_cond"); + strcpy(out_metadata[OUT_SURF_COND].standard_name, + "surface_conductance"); + strcpy(out_metadata[OUT_SURF_COND].units, "m s-1"); + strcpy(out_metadata[OUT_SURF_COND].description, "surface conductance"); + + /* near surface vapor pressure [kPa] */ + strcpy(out_metadata[OUT_VP].varname, "OUT_VP"); + strcpy(out_metadata[OUT_VP].long_name, "vp"); + strcpy(out_metadata[OUT_VP].standard_name, "water_vapor_pressure"); + strcpy(out_metadata[OUT_VP].units, "kPa"); + strcpy(out_metadata[OUT_VP].description, "near surface vapor pressure"); + + /* near surface vapor pressure deficit [kPa] */ + strcpy(out_metadata[OUT_VPD].varname, "OUT_VPD"); + strcpy(out_metadata[OUT_VPD].long_name, "vpd"); + strcpy(out_metadata[OUT_VPD].standard_name, + "water_vapor_saturation_deficit"); + strcpy(out_metadata[OUT_VPD].units, "kPa"); + strcpy(out_metadata[OUT_VPD].description, + "near surface vapor pressure deficit"); + + /* near surface wind speed [m/s] */ + strcpy(out_metadata[OUT_WIND].varname, "OUT_WIND"); + strcpy(out_metadata[OUT_WIND].long_name, "wind"); + strcpy(out_metadata[OUT_WIND].standard_name, "wind_speed"); + strcpy(out_metadata[OUT_WIND].units, "m s-1"); + strcpy(out_metadata[OUT_WIND].description, "near surface wind speed"); + + // Carbon-cycling Terms + /* absorbed PAR [W m-2] */ + strcpy(out_metadata[OUT_APAR].varname, "OUT_APAR"); + strcpy(out_metadata[OUT_APAR].long_name, "apar"); + strcpy(out_metadata[OUT_APAR].standard_name, + "absorbed_surface_diffuse_downwelling_photosynthetic_radiative_flux"); + strcpy(out_metadata[OUT_APAR].units, "W m-2"); + strcpy(out_metadata[OUT_APAR].description, "absorbed PAR"); + + /* gross primary productivity [g C/m2s] */ + strcpy(out_metadata[OUT_GPP].varname, "OUT_GPP"); + strcpy(out_metadata[OUT_GPP].long_name, "gpp"); + strcpy(out_metadata[OUT_GPP].standard_name, + "gross_primary_productivity_of_biomass_expressed_as_carbon"); + strcpy(out_metadata[OUT_GPP].units, "g m-2 s-1"); + strcpy(out_metadata[OUT_GPP].description, "gross primary productivity"); + + /* autotrophic respiration [g C/m2s] */ + strcpy(out_metadata[OUT_RAUT].varname, "OUT_RAUT"); + strcpy(out_metadata[OUT_RAUT].long_name, "raut"); + strcpy(out_metadata[OUT_RAUT].standard_name, + "autotrophic_respiration_carbon_flux"); + strcpy(out_metadata[OUT_RAUT].units, "g m-2 s-1"); + strcpy(out_metadata[OUT_RAUT].description, "autotrophic respiration"); + + /* net primary productivity [g C/m2s] */ + strcpy(out_metadata[OUT_NPP].varname, "OUT_NPP"); + strcpy(out_metadata[OUT_NPP].long_name, "npp"); + strcpy(out_metadata[OUT_NPP].standard_name, + "net_primary_productivity_of_biomass_expressed_as_carbon"); + strcpy(out_metadata[OUT_NPP].units, "g m-2 s-1"); + strcpy(out_metadata[OUT_NPP].description, "et primary productivity"); + + /* flux of carbon from living biomass into soil [g C/m2d] */ + strcpy(out_metadata[OUT_LITTERFALL].varname, "OUT_LITTERFALL"); + strcpy(out_metadata[OUT_LITTERFALL].long_name, "litterfall"); + strcpy(out_metadata[OUT_LITTERFALL].standard_name, + "carbon_mass_flux_into_soil_from_litter"); + strcpy(out_metadata[OUT_LITTERFALL].units, "g m-2 d-1"); + strcpy(out_metadata[OUT_LITTERFALL].description, + "flux of carbon from living biomass into soil"); + + /* heterotrophic respiration [g C/m2d] */ + strcpy(out_metadata[OUT_RHET].varname, "OUT_RHET"); + strcpy(out_metadata[OUT_RHET].long_name, "rhet"); + strcpy(out_metadata[OUT_RHET].standard_name, "heterotrophic_respiration"); + strcpy(out_metadata[OUT_RHET].units, "g m-2 d-1"); + strcpy(out_metadata[OUT_RHET].description, "heterotrophic respiration"); + + /* net ecosystem exchange [g C/m2d] */ + strcpy(out_metadata[OUT_NEE].varname, "OUT_NEE"); + strcpy(out_metadata[OUT_NEE].long_name, "nee"); + strcpy(out_metadata[OUT_NEE].standard_name, + "net_ecosystem_exhanged_expressed_as_carbon"); + strcpy(out_metadata[OUT_NEE].units, "g m-2 d-1"); + strcpy(out_metadata[OUT_NEE].description, "net ecosystem exchange"); + + /* litter pool carbon density [g C/m2] */ + strcpy(out_metadata[OUT_CLITTER].varname, "OUT_CLITTER"); + strcpy(out_metadata[OUT_CLITTER].long_name, "clitter"); + strcpy(out_metadata[OUT_CLITTER].standard_name, "litter_carbon_content"); + strcpy(out_metadata[OUT_CLITTER].units, "g m-2"); + strcpy(out_metadata[OUT_CLITTER].description, "litter pool carbon density"); + + /* intermediate pool carbon density [g C/m2] */ + strcpy(out_metadata[OUT_CINTER].varname, "OUT_CINTER"); + strcpy(out_metadata[OUT_CINTER].long_name, "cinter"); + strcpy(out_metadata[OUT_CINTER].standard_name, + "intermediate_pool_carbon_content"); + strcpy(out_metadata[OUT_CINTER].units, "g m-2"); + strcpy(out_metadata[OUT_CINTER].description, + "intermediate pool carbon density"); + + /* slow pool carbon density [g C/m2] */ + strcpy(out_metadata[OUT_CSLOW].varname, "OUT_CSLOW"); + strcpy(out_metadata[OUT_CSLOW].long_name, "cslow"); + strcpy(out_metadata[OUT_CSLOW].standard_name, "slow_pool_carbon_content"); + strcpy(out_metadata[OUT_CSLOW].units, "g m-2"); + strcpy(out_metadata[OUT_CSLOW].description, "slow pool carbon density"); + + // Band-specific quantities + /* net sensible heat flux advected to snow pack [W m-2] */ + strcpy(out_metadata[OUT_ADV_SENS_BAND].varname, "OUT_ADV_SENS_BAND"); + strcpy(out_metadata[OUT_ADV_SENS_BAND].long_name, "adv_sens_band"); + strcpy(out_metadata[OUT_ADV_SENS_BAND].standard_name, + out_metadata[OUT_ADV_SENS].standard_name); + strcpy(out_metadata[OUT_ADV_SENS_BAND].units, + out_metadata[OUT_ADV_SENS].units); + strcpy(out_metadata[OUT_ADV_SENS_BAND].description, + out_metadata[OUT_ADV_SENS].description); + + strcpy(out_metadata[OUT_ADV_SENS].varname, "OUT_ADV_SENS"); + strcpy(out_metadata[OUT_ADV_SENS].long_name, "adv_sens"); + strcpy(out_metadata[OUT_ADV_SENS].standard_name, + "net_sensible_heat_flux_to_snow_pack"); + strcpy(out_metadata[OUT_ADV_SENS].units, "W m-2"); + strcpy(out_metadata[OUT_ADV_SENS].description, + "net sensible heat advected to snow pack"); + + /* advected energy [W m-2] */ + strcpy(out_metadata[OUT_ADVECTION_BAND].varname, "OUT_ADVECTION_BAND"); + strcpy(out_metadata[OUT_ADVECTION_BAND].long_name, "advection_band"); + strcpy(out_metadata[OUT_ADVECTION_BAND].standard_name, + out_metadata[OUT_ADVECTION].standard_name); + strcpy(out_metadata[OUT_ADVECTION_BAND].units, + out_metadata[OUT_ADVECTION].units); + strcpy(out_metadata[OUT_ADVECTION_BAND].description, + out_metadata[OUT_ADVECTION].description); + + /* albedo [fraction] */ + strcpy(out_metadata[OUT_ALBEDO_BAND].varname, "OUT_ALBEDO_BAND"); + strcpy(out_metadata[OUT_ALBEDO_BAND].long_name, "albedo_band"); + strcpy(out_metadata[OUT_ALBEDO_BAND].standard_name, + out_metadata[OUT_ALBEDO].standard_name); + strcpy(out_metadata[OUT_ALBEDO_BAND].units, out_metadata[OUT_ALBEDO].units); + strcpy(out_metadata[OUT_ALBEDO_BAND].description, + out_metadata[OUT_ALBEDO].description); + + /* change in cold content in snow pack [W m-2] */ + strcpy(out_metadata[OUT_DELTACC_BAND].varname, "OUT_DELTACC_BAND"); + strcpy(out_metadata[OUT_DELTACC_BAND].long_name, "deltacc_band"); + strcpy(out_metadata[OUT_DELTACC_BAND].standard_name, + out_metadata[OUT_DELTACC].standard_name); + strcpy(out_metadata[OUT_DELTACC_BAND].units, + out_metadata[OUT_DELTACC].units); + strcpy(out_metadata[OUT_DELTACC_BAND].description, + out_metadata[OUT_DELTACC].description); + + /* net heat flux into ground [W m-2] */ + strcpy(out_metadata[OUT_GRND_FLUX_BAND].varname, "OUT_GRND_FLUX_BAND"); + strcpy(out_metadata[OUT_GRND_FLUX_BAND].long_name, "grnd_flux_band"); + strcpy(out_metadata[OUT_GRND_FLUX_BAND].standard_name, + out_metadata[OUT_GRND_FLUX].standard_name); + strcpy(out_metadata[OUT_GRND_FLUX_BAND].units, + out_metadata[OUT_GRND_FLUX].units); + strcpy(out_metadata[OUT_GRND_FLUX_BAND].description, + out_metadata[OUT_GRND_FLUX].description); + + /* incoming longwave flux at surface (under veg) [W m-2] */ + strcpy(out_metadata[OUT_IN_LONG_BAND].varname, "OUT_IN_LONG_BAND"); + strcpy(out_metadata[OUT_IN_LONG_BAND].long_name, "in_long_band"); + strcpy(out_metadata[OUT_IN_LONG_BAND].standard_name, + out_metadata[OUT_IN_LONG].standard_name); + strcpy(out_metadata[OUT_IN_LONG_BAND].units, + out_metadata[OUT_IN_LONG].units); + strcpy(out_metadata[OUT_IN_LONG_BAND].description, + out_metadata[OUT_IN_LONG].description); + + /* net upward latent heat flux [W m-2] */ + strcpy(out_metadata[OUT_LATENT_BAND].varname, "OUT_LATENT_BAND"); + strcpy(out_metadata[OUT_LATENT_BAND].long_name, "latent_band"); + strcpy(out_metadata[OUT_LATENT_BAND].standard_name, + out_metadata[OUT_LATENT].standard_name); + strcpy(out_metadata[OUT_LATENT_BAND].units, out_metadata[OUT_LATENT].units); + strcpy(out_metadata[OUT_LATENT_BAND].description, + out_metadata[OUT_LATENT].description); + + /* net upward latent heat flux from sublimation [W m-2] */ + strcpy(out_metadata[OUT_LATENT_SUB_BAND].varname, "OUT_LATENT_SUB_BAND"); + strcpy(out_metadata[OUT_LATENT_SUB_BAND].long_name, "latent_sub_band"); + strcpy(out_metadata[OUT_LATENT_SUB_BAND].standard_name, + out_metadata[OUT_LATENT_SUB].standard_name); + strcpy(out_metadata[OUT_LATENT_SUB_BAND].units, + out_metadata[OUT_LATENT_SUB].units); + strcpy(out_metadata[OUT_LATENT_SUB_BAND].description, + out_metadata[OUT_LATENT_SUB].description); + + /* energy of fusion (melting) [W m-2] */ + strcpy(out_metadata[OUT_MELT_ENERGY_BAND].varname, "OUT_MELT_ENERGY_BAND"); + strcpy(out_metadata[OUT_MELT_ENERGY_BAND].long_name, "melt_energy_band"); + strcpy(out_metadata[OUT_MELT_ENERGY_BAND].standard_name, + out_metadata[OUT_MELT_ENERGY].standard_name); + strcpy(out_metadata[OUT_MELT_ENERGY_BAND].units, + out_metadata[OUT_MELT_ENERGY].units); + strcpy(out_metadata[OUT_MELT_ENERGY_BAND].description, + out_metadata[OUT_MELT_ENERGY].description); + + /* net downward longwave flux [W m-2] */ + strcpy(out_metadata[OUT_LWNET_BAND].varname, "OUT_LWNET_BAND"); + strcpy(out_metadata[OUT_LWNET_BAND].long_name, "lwnet_band"); + strcpy(out_metadata[OUT_LWNET_BAND].standard_name, + out_metadata[OUT_LWNET].standard_name); + strcpy(out_metadata[OUT_LWNET_BAND].units, out_metadata[OUT_LWNET].units); + strcpy(out_metadata[OUT_LWNET_BAND].description, + out_metadata[OUT_LWNET].description); + + /* net downward shortwave flux [W m-2] */ + strcpy(out_metadata[OUT_SWNET_BAND].varname, "OUT_SWNET_BAND"); + strcpy(out_metadata[OUT_SWNET_BAND].long_name, "swnet_band"); + strcpy(out_metadata[OUT_SWNET_BAND].standard_name, + out_metadata[OUT_SWNET].standard_name); + strcpy(out_metadata[OUT_SWNET_BAND].units, out_metadata[OUT_SWNET].units); + strcpy(out_metadata[OUT_SWNET_BAND].description, + out_metadata[OUT_SWNET].description); + + /* net energy used to refreeze liquid water in snowpack [W m-2] */ + strcpy(out_metadata[OUT_RFRZ_ENERGY_BAND].varname, "OUT_RFRZ_ENERGY_BAND"); + strcpy(out_metadata[OUT_RFRZ_ENERGY_BAND].long_name, "rfrz_energy_band"); + strcpy(out_metadata[OUT_RFRZ_ENERGY_BAND].standard_name, + out_metadata[OUT_RFRZ_ENERGY].standard_name); + strcpy(out_metadata[OUT_RFRZ_ENERGY_BAND].units, + out_metadata[OUT_RFRZ_ENERGY].units); + strcpy(out_metadata[OUT_RFRZ_ENERGY_BAND].description, + out_metadata[OUT_RFRZ_ENERGY].description); + + /* net upward sensible heat flux [W m-2] */ + strcpy(out_metadata[OUT_SENSIBLE_BAND].varname, "OUT_SENSIBLE_BAND"); + strcpy(out_metadata[OUT_SENSIBLE_BAND].long_name, "sensible_band"); + strcpy(out_metadata[OUT_SENSIBLE_BAND].standard_name, + out_metadata[OUT_SENSIBLE].standard_name); + strcpy(out_metadata[OUT_SENSIBLE_BAND].units, + out_metadata[OUT_SENSIBLE].units); + strcpy(out_metadata[OUT_SENSIBLE_BAND].description, + out_metadata[OUT_SENSIBLE].description); + + /* snow interception storage in canopy [mm] */ + strcpy(out_metadata[OUT_SNOW_CANOPY_BAND].varname, "OUT_SNOW_CANOPY_BAND"); + strcpy(out_metadata[OUT_SNOW_CANOPY_BAND].long_name, "snow_canopy_band"); + strcpy(out_metadata[OUT_SNOW_CANOPY_BAND].standard_name, + out_metadata[OUT_SNOW_CANOPY].standard_name); + strcpy(out_metadata[OUT_SNOW_CANOPY_BAND].units, + out_metadata[OUT_SNOW_CANOPY].units); + strcpy(out_metadata[OUT_SNOW_CANOPY_BAND].description, + out_metadata[OUT_SNOW_CANOPY].description); + + /* fractional area of snow cover [fraction] */ + strcpy(out_metadata[OUT_SNOW_COVER_BAND].varname, "OUT_SNOW_COVER_BAND"); + strcpy(out_metadata[OUT_SNOW_COVER_BAND].long_name, "snow_cover_band"); + strcpy(out_metadata[OUT_SNOW_COVER_BAND].standard_name, + out_metadata[OUT_SNOW_COVER].standard_name); + strcpy(out_metadata[OUT_SNOW_COVER_BAND].units, + out_metadata[OUT_SNOW_COVER].units); + strcpy(out_metadata[OUT_SNOW_COVER_BAND].description, + out_metadata[OUT_SNOW_COVER].description); + + /* depth of snow pack [cm] */ + strcpy(out_metadata[OUT_SNOW_DEPTH_BAND].varname, "OUT_SNOW_DEPTH_BAND"); + strcpy(out_metadata[OUT_SNOW_DEPTH_BAND].long_name, "snow_depth_band"); + strcpy(out_metadata[OUT_SNOW_DEPTH_BAND].standard_name, + out_metadata[OUT_SNOW_DEPTH].standard_name); + strcpy(out_metadata[OUT_SNOW_DEPTH_BAND].units, + out_metadata[OUT_SNOW_DEPTH].units); + strcpy(out_metadata[OUT_SNOW_DEPTH_BAND].description, + out_metadata[OUT_SNOW_DEPTH].description); + + /* energy flux through snow pack [W m-2] */ + strcpy(out_metadata[OUT_SNOW_FLUX_BAND].varname, "OUT_SNOW_FLUX_BAND"); + strcpy(out_metadata[OUT_SNOW_FLUX_BAND].long_name, "snow_flux_band"); + strcpy(out_metadata[OUT_SNOW_FLUX_BAND].standard_name, + out_metadata[OUT_SNOW_FLUX].standard_name); + strcpy(out_metadata[OUT_SNOW_FLUX_BAND].units, + out_metadata[OUT_SNOW_FLUX].units); + strcpy(out_metadata[OUT_SNOW_FLUX_BAND].description, + out_metadata[OUT_SNOW_FLUX].description); + + /* snow melt [mm] */ + strcpy(out_metadata[OUT_SNOW_MELT_BAND].varname, "OUT_SNOW_MELT_BAND"); + strcpy(out_metadata[OUT_SNOW_MELT_BAND].long_name, "snow_melt_band"); + strcpy(out_metadata[OUT_SNOW_MELT_BAND].standard_name, + out_metadata[OUT_SNOW_MELT].standard_name); + strcpy(out_metadata[OUT_SNOW_MELT_BAND].units, + out_metadata[OUT_SNOW_MELT].units); + strcpy(out_metadata[OUT_SNOW_MELT_BAND].description, + out_metadata[OUT_SNOW_MELT].description); + + /* snow pack temperature [C] */ + strcpy(out_metadata[OUT_SNOW_PACKT_BAND].varname, "OUT_SNOW_PACKT_BAND"); + strcpy(out_metadata[OUT_SNOW_PACKT_BAND].long_name, "snow_packt_band"); + strcpy(out_metadata[OUT_SNOW_PACKT_BAND].standard_name, + out_metadata[OUT_SNOW_PACK_TEMP].standard_name); + strcpy(out_metadata[OUT_SNOW_PACKT_BAND].units, + out_metadata[OUT_SNOW_PACK_TEMP].units); + strcpy(out_metadata[OUT_SNOW_PACKT_BAND].description, + out_metadata[OUT_SNOW_PACK_TEMP].description); + + /* snow surface temperature [C] */ + strcpy(out_metadata[OUT_SNOW_SURFT_BAND].varname, "OUT_SNOW_SURFT_BAND"); + strcpy(out_metadata[OUT_SNOW_SURFT_BAND].long_name, "snow_surft_band"); + strcpy(out_metadata[OUT_SNOW_SURFT_BAND].standard_name, + out_metadata[OUT_SNOW_SURF_TEMP].standard_name); + strcpy(out_metadata[OUT_SNOW_SURFT_BAND].units, + out_metadata[OUT_SNOW_SURF_TEMP].units); + strcpy(out_metadata[OUT_SNOW_SURFT_BAND].description, + out_metadata[OUT_SNOW_SURF_TEMP].description); + + /* snow water equivalent in snow pack [mm] */ + strcpy(out_metadata[OUT_SWE_BAND].varname, "OUT_SWE_BAND"); + strcpy(out_metadata[OUT_SWE_BAND].long_name, "swe_band"); + strcpy(out_metadata[OUT_SWE_BAND].standard_name, + out_metadata[OUT_SWE].standard_name); + strcpy(out_metadata[OUT_SWE_BAND].units, out_metadata[OUT_SWE].units); + strcpy(out_metadata[OUT_SWE_BAND].description, + out_metadata[OUT_SWE].description); + + if (options.FROZEN_SOIL) { + out_metadata[OUT_FDEPTH].nelem = MAX_FRONTS; + out_metadata[OUT_TDEPTH].nelem = MAX_FRONTS; + } + + out_metadata[OUT_SMLIQFRAC].nelem = options.Nlayer; + out_metadata[OUT_SMFROZFRAC].nelem = options.Nlayer; + out_metadata[OUT_SOIL_ICE].nelem = options.Nlayer; + out_metadata[OUT_SOIL_LIQ].nelem = options.Nlayer; + out_metadata[OUT_SOIL_MOIST].nelem = options.Nlayer; + out_metadata[OUT_SOIL_TEMP].nelem = options.Nlayer; + out_metadata[OUT_SOIL_TNODE].nelem = options.Nnode; + out_metadata[OUT_SOIL_TNODE_WL].nelem = options.Nnode; + out_metadata[OUT_SOILT_FBFLAG].nelem = options.Nnode; + out_metadata[OUT_ADV_SENS_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_ADVECTION_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_ALBEDO_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_DELTACC_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_GRND_FLUX_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_IN_LONG_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_LATENT_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_LATENT_SUB_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_MELT_ENERGY_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_LWNET_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SWNET_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_RFRZ_ENERGY_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SENSIBLE_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_CANOPY_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_COVER_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_DEPTH_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_FLUX_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_MELT_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_PACKT_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SNOW_SURFT_BAND].nelem = options.SNOW_BAND; + out_metadata[OUT_SWE_BAND].nelem = options.SNOW_BAND; +} diff --git a/vic/drivers/shared_all/src/initialize_global.c b/vic/drivers/shared_all/src/initialize_global.c index a7f9915fc..b61457f7b 100644 --- a/vic/drivers/shared_all/src/initialize_global.c +++ b/vic/drivers/shared_all/src/initialize_global.c @@ -46,7 +46,6 @@ initialize_global() global_param.snow_steps_per_day = 0; global_param.runoff_steps_per_day = 0; global_param.atmos_steps_per_day = 0; - global_param.output_steps_per_day = 1; global_param.nrecs = 0; global_param.startyear = 0; global_param.startmonth = 0; @@ -65,12 +64,10 @@ initialize_global() global_param.forceskip[i] = 0; global_param.forceoffset[i] = 0; } - global_param.skipyear = 0; global_param.stateyear = 0; global_param.statemonth = 0; global_param.stateday = 0; global_param.statesec = 0; - global_param.out_dt = SEC_PER_DAY; global_param.calendar = CALENDAR_STANDARD; global_param.time_units = TIME_UNITS_DAYS; global_param.time_origin_num = MISSING; diff --git a/vic/drivers/shared_all/src/initialize_options.c b/vic/drivers/shared_all/src/initialize_options.c index b9b4d7361..528af2e5d 100644 --- a/vic/drivers/shared_all/src/initialize_options.c +++ b/vic/drivers/shared_all/src/initialize_options.c @@ -94,11 +94,5 @@ initialize_options() options.INIT_STATE = false; options.SAVE_STATE = false; // output options - options.ALMA_OUTPUT = false; - options.OUT_FORMAT = UNSET_FILE_FORMAT; - options.COMPRESS = false; - options.MOISTFRACT = false; - options.Noutfiles = 2; - options.PRT_HEADER = false; - options.PRT_SNOW_BAND = false; + options.Noutstreams = 2; } diff --git a/vic/drivers/shared_all/src/input_tools.c b/vic/drivers/shared_all/src/input_tools.c new file mode 100644 index 000000000..2e34cdf7b --- /dev/null +++ b/vic/drivers/shared_all/src/input_tools.c @@ -0,0 +1,392 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This file includes routines to help parse and process VIC input files. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief String to bool conversion + *****************************************************************************/ +bool +str_to_bool(char str[]) +{ + if (strcasecmp("TRUE", str) == 0) { + return true; + } + else if (strcasecmp("FALSE", str) == 0) { + return false; + } + else { + log_err("%s is neither TRUE nor FALSE", str); + } +} + +/****************************************************************************** + * @brief This routine determines the counts the number of output variables + in each output file specified in the global parameter file. + *****************************************************************************/ +void +count_nstreams_nvars(FILE *gp, + size_t *nstreams, + size_t nvars[]) +{ + unsigned long start_position; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + size_t i; + + // Figure out where we are in the input file + fflush(gp); + start_position = ftell(gp); + + // read the first line + fgets(cmdstr, MAXSTRING, gp); + + // initialize nstreams and nvars + *nstreams = 0; + for (i = 0; i < MAX_OUTPUT_STREAMS; i++) { + nvars[i] = 0; + } + + // Loop through the lines + while (!feof(gp)) { + if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { + // line is not blank or a comment + sscanf(cmdstr, "%s", optstr); + + // if the line starts with OUTFILE, increment nstreams + if (strcasecmp("OUTFILE", optstr) == 0) { + (*nstreams)++; + if (*nstreams > MAX_OUTPUT_STREAMS) { + log_err("Too many output streams specified."); + } + } + + // if the line starts with OUTVAR, add another variable to nvars + if (strcasecmp("OUTVAR", optstr) == 0) { + nvars[*nstreams - 1]++; + } + } + fgets(cmdstr, MAXSTRING, gp); + } + + // put the position in the file back to where we started + fseek(gp, start_position, SEEK_SET); +} + +/****************************************************************************** + * @brief Convert string version of AGG_TYPE_* to enum value + *****************************************************************************/ +unsigned short int +str_to_agg_type(char aggstr[]) +{ + if ((strcasecmp("", aggstr) == 0) || (strcasecmp("*", aggstr) == 0)) { + return AGG_TYPE_DEFAULT; + } + else { + if (strcasecmp("AGG_TYPE_AVG", aggstr) == 0) { + return AGG_TYPE_AVG; + } + else if (strcasecmp("AGG_TYPE_BEG", aggstr) == 0) { + return AGG_TYPE_BEG; + } + else if (strcasecmp("AGG_TYPE_END", aggstr) == 0) { + return AGG_TYPE_END; + } + else if (strcasecmp("AGG_TYPE_MAX", aggstr) == 0) { + return AGG_TYPE_MAX; + } + else if (strcasecmp("AGG_TYPE_MIN", aggstr) == 0) { + return AGG_TYPE_MIN; + } + else if (strcasecmp("AGG_TYPE_SUM", aggstr) == 0) { + return AGG_TYPE_SUM; + } + else { + log_err("Unknown aggregation type found: %s", aggstr); + } + } +} + +/****************************************************************************** + * @brief Convert string version of OUT_TYPE* to enum value + *****************************************************************************/ +unsigned short int +str_to_out_type(char typestr[]) +{ + if ((strcasecmp("", typestr) == 0) || (strcasecmp("*", typestr) == 0)) { + return OUT_TYPE_DEFAULT; + } + else { + if (strcasecmp("OUT_TYPE_USINT", typestr) == 0) { + return OUT_TYPE_USINT; + } + else if (strcasecmp("OUT_TYPE_SINT", typestr) == 0) { + return OUT_TYPE_SINT; + } + else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { + return OUT_TYPE_FLOAT; + } + else if (strcasecmp("OUT_TYPE_DOUBLE", typestr) == 0) { + return OUT_TYPE_DOUBLE; + } + else { + log_err("Unknown out type found: %s", typestr); + } + } +} + +/****************************************************************************** + * @brief Convert string version of mult to double + *****************************************************************************/ +double +str_to_out_mult(char multstr[]) +{ + if ((strcasecmp("", multstr) == 0) || (strcasecmp("*", multstr) == 0)) { + return OUT_MULT_DEFAULT; + } + else { + return (double) atof(multstr); + } +} + +/****************************************************************************** + * @brief Convert string version of frequency flags to enum value + *****************************************************************************/ +unsigned short int +str_to_freq_flag(char freq[]) +{ + if (strcasecmp("NEVER", freq) == 0) { + return FREQ_NEVER; + } + else if (strcasecmp("NSTEPS", freq) == 0) { + return FREQ_NSTEPS; + } + else if (strcasecmp("NSECONDS", freq) == 0) { + return FREQ_NSECONDS; + } + else if (strcasecmp("NMINUTES", freq) == 0) { + return FREQ_NMINUTES; + } + else if (strcasecmp("NHOURS", freq) == 0) { + return FREQ_NHOURS; + } + else if (strcasecmp("NDAYS", freq) == 0) { + return FREQ_NDAYS; + } + else if (strcasecmp("NMONTHS", freq) == 0) { + return FREQ_NMONTHS; + } + else if (strcasecmp("NYEARS", freq) == 0) { + return FREQ_NYEARS; + } + else if (strcasecmp("DATE", freq) == 0) { + return FREQ_DATE; + } + else if (strcasecmp("END", freq) == 0) { + return FREQ_END; + } + else { + log_err("Unknown frequency flag found: %s", freq); + } +} + +/****************************************************************************** + * @brief Convert string version of frequency flags to enum value + *****************************************************************************/ +void +str_to_ascii_format(char *format) +{ + if ((strcasecmp("", format) == 0) || (strcasecmp("*", format) == 0)) { + strcpy(format, OUT_ASCII_FORMAT_DEFAULT); + } + // else do nothing +} + +/****************************************************************************** + * @brief Parse chars of calendar and return calendar integer + * @return enum integer representing calendar + *****************************************************************************/ +unsigned short int +str_to_calendar(char *cal_chars) +{ + if (strcasecmp("STANDARD", cal_chars) == 0) { + return CALENDAR_STANDARD; + } + else if (strcasecmp("GREGORIAN", cal_chars) == 0) { + return CALENDAR_GREGORIAN; + } + else if (strcasecmp("PROLEPTIC_GREGORIAN", cal_chars) == 0) { + return CALENDAR_PROLEPTIC_GREGORIAN; + } + else if ((strcasecmp("NOLEAP", cal_chars) == 0) || + (strcasecmp("NO_LEAP", cal_chars) == 0)) { + return CALENDAR_NOLEAP; + } + else if (strcasecmp("365_DAY", cal_chars) == 0) { + return CALENDAR_365_DAY; + } + else if (strcasecmp("360_DAY", cal_chars) == 0) { + return CALENDAR_360_DAY; + } + else if (strcasecmp("JULIAN", cal_chars) == 0) { + return CALENDAR_JULIAN; + } + else if (strcasecmp("ALL_LEAP", cal_chars) == 0) { + return CALENDAR_ALL_LEAP; + } + else if (strcasecmp("366_DAY", cal_chars) == 0) { + return CALENDAR_366_DAY; + } + else { + log_err("Unknown calendar specified: %s", cal_chars); + } +} + +/****************************************************************************** + * @brief Parse chars of time units and return time units integer + * @return enum integer representing time units + *****************************************************************************/ +unsigned short int +str_to_timeunits(char units_chars[]) +{ + if (strcasecmp("SECONDS", units_chars) == 0) { + return TIME_UNITS_SECONDS; + } + else if (strcasecmp("MINUTES", units_chars) == 0) { + return TIME_UNITS_MINUTES; + } + else if (strcasecmp("HOURS", units_chars) == 0) { + return TIME_UNITS_HOURS; + } + else if (strcasecmp("DAYS", units_chars) == 0) { + return TIME_UNITS_DAYS; + } + else { + log_err("Unknown time units specified: %s", units_chars); + } +} + +/****************************************************************************** + * @brief Convert enum time units to string + *****************************************************************************/ +void +str_from_time_units(unsigned short int time_units, + char *unit_str) +{ + if (time_units == TIME_UNITS_SECONDS) { + sprintf(unit_str, "seconds"); + } + else if (time_units == TIME_UNITS_MINUTES) { + sprintf(unit_str, "minutes"); + } + else if (time_units == TIME_UNITS_HOURS) { + sprintf(unit_str, "hours"); + } + else if (time_units == TIME_UNITS_DAYS) { + sprintf(unit_str, "days"); + } + else { + log_err("Invalid value, or no value for OUT_TIME_UNITS (%d).", + time_units); + } +} + +/****************************************************************************** + * @brief get CF calendar string based on enum calendar value + *****************************************************************************/ +void +str_from_calendar(unsigned short int calendar, + char *calendar_str) +{ + if (calendar == CALENDAR_STANDARD) { + sprintf(calendar_str, "standard"); + } + else if (calendar == CALENDAR_GREGORIAN) { + sprintf(calendar_str, "gregorian"); + } + else if (calendar == CALENDAR_PROLEPTIC_GREGORIAN) { + sprintf(calendar_str, "proleptic_gregorian"); + } + else if (calendar == CALENDAR_NOLEAP) { + sprintf(calendar_str, "noleap"); + } + else if (calendar == CALENDAR_365_DAY) { + sprintf(calendar_str, "365_day"); + } + else if (calendar == CALENDAR_360_DAY) { + sprintf(calendar_str, "360_day"); + } + else if (calendar == CALENDAR_JULIAN) { + sprintf(calendar_str, "julian"); + } + else if (calendar == CALENDAR_ALL_LEAP) { + sprintf(calendar_str, "all_leap"); + } + else if (calendar == CALENDAR_366_DAY) { + sprintf(calendar_str, "366_day"); + } + else { + log_err("Invalid, or no calendar specified"); + } +} + +/****************************************************************************** + * @brief determine if the aggtype is a cell_method, if so fill the cell_method + argument with the "cell_method" CF string attriubute + * @return bool true if aggtype is a windowed aggregation, otherwise false + *****************************************************************************/ +bool +cell_method_from_agg_type(unsigned short int aggtype, + char cell_method[]) +{ + if (aggtype == AGG_TYPE_AVG) { + strcpy(cell_method, "time: mean"); + return true; + } + else if (aggtype == AGG_TYPE_MAX) { + strcpy(cell_method, "time: maximum"); + return true; + } + else if (aggtype == AGG_TYPE_MIN) { + strcpy(cell_method, "time: minimum"); + return true; + } + else if (aggtype == AGG_TYPE_SUM) { + strcpy(cell_method, "time: sum"); + return true; + } + else if (aggtype == AGG_TYPE_END) { + strcpy(cell_method, "time: end"); + return true; + } + else if (aggtype == AGG_TYPE_BEG) { + strcpy(cell_method, "time: beg"); + return true; + } + else { + return false; + } +} diff --git a/vic/drivers/shared_all/src/output_list_utils.c b/vic/drivers/shared_all/src/output_list_utils.c deleted file mode 100644 index 00cd0ecbf..000000000 --- a/vic/drivers/shared_all/src/output_list_utils.c +++ /dev/null @@ -1,439 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * This routine creates the list of output variables. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief This routine creates the list of output variables. - *****************************************************************************/ -out_data_struct * -create_output_list() -{ - extern option_struct options; - int v; - out_data_struct *out_data; - - out_data = calloc(N_OUTVAR_TYPES, sizeof(*out_data)); - - // Build the list of supported output variables - - // Water Balance Terms - state variables - strcpy(out_data[OUT_ASAT].varname, "OUT_ASAT"); /* saturated area fraction */ - strcpy(out_data[OUT_LAKE_AREA_FRAC].varname, "OUT_LAKE_AREA_FRAC"); /* lake surface area as fraction of grid cell area [fraction] */ - strcpy(out_data[OUT_LAKE_DEPTH].varname, "OUT_LAKE_DEPTH"); /* lake depth [m] */ - strcpy(out_data[OUT_LAKE_ICE].varname, "OUT_LAKE_ICE"); /* moisture stored as lake ice [mm] */ - strcpy(out_data[OUT_LAKE_ICE_FRACT].varname, "OUT_LAKE_ICE_FRACT"); /* fractional coverage of lake ice [fraction] */ - strcpy(out_data[OUT_LAKE_ICE_HEIGHT].varname, "OUT_LAKE_ICE_HEIGHT"); /* thickness of lake ice [cm] */ - strcpy(out_data[OUT_LAKE_MOIST].varname, "OUT_LAKE_MOIST"); /* liquid water stored in lake [mm over lake area?] */ - strcpy(out_data[OUT_LAKE_SURF_AREA].varname, "OUT_LAKE_SURF_AREA"); /* lake surface area [m2] */ - strcpy(out_data[OUT_LAKE_SWE].varname, "OUT_LAKE_SWE"); /* liquid water equivalent of snow on top of lake ice [m over lake ice] */ - strcpy(out_data[OUT_LAKE_SWE_V].varname, "OUT_LAKE_SWE_V"); /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ - strcpy(out_data[OUT_LAKE_VOLUME].varname, "OUT_LAKE_VOLUME"); /* lake volume [m3] */ - strcpy(out_data[OUT_ROOTMOIST].varname, "OUT_ROOTMOIST"); /* root zone soil moisture [mm] */ - strcpy(out_data[OUT_SMFROZFRAC].varname, "OUT_SMFROZFRAC"); /* fraction of soil moisture (by mass) that is ice, for each soil layer */ - strcpy(out_data[OUT_SMLIQFRAC].varname, "OUT_SMLIQFRAC"); /* fraction of soil moisture (by mass) that is liquid, for each soil layer */ - strcpy(out_data[OUT_SNOW_CANOPY].varname, "OUT_SNOW_CANOPY"); /* snow interception storage in canopy [mm] */ - strcpy(out_data[OUT_SNOW_COVER].varname, "OUT_SNOW_COVER"); /* fractional area of snow cover [fraction] */ - strcpy(out_data[OUT_SNOW_DEPTH].varname, "OUT_SNOW_DEPTH"); /* depth of snow pack [cm] */ - strcpy(out_data[OUT_SOIL_ICE].varname, "OUT_SOIL_ICE"); /* soil ice content [mm] for each soil layer */ - strcpy(out_data[OUT_SOIL_LIQ].varname, "OUT_SOIL_LIQ"); /* soil liquid moisture content [mm] for each soil layer */ - strcpy(out_data[OUT_SOIL_MOIST].varname, "OUT_SOIL_MOIST"); /* soil total moisture content [mm] for each soil layer */ - strcpy(out_data[OUT_SOIL_WET].varname, "OUT_SOIL_WET"); /* vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ - strcpy(out_data[OUT_SURFSTOR].varname, "OUT_SURFSTOR"); /* storage of liquid water on surface (ponding) [mm] */ - strcpy(out_data[OUT_SURF_FROST_FRAC].varname, "OUT_SURF_FROST_FRAC"); /* fraction of soil surface that is frozen [fraction] */ - strcpy(out_data[OUT_SWE].varname, "OUT_SWE"); /* snow water equivalent in snow pack [mm] */ - strcpy(out_data[OUT_WDEW].varname, "OUT_WDEW"); /* total moisture interception storage in canopy [mm] */ - strcpy(out_data[OUT_ZWT].varname, "OUT_ZWT"); /* water table position [cm] (zwt within lowest unsaturated layer) */ - strcpy(out_data[OUT_ZWT_LUMPED].varname, "OUT_ZWT_LUMPED"); /* lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ - - // Water Balance Terms - fluxes - strcpy(out_data[OUT_BASEFLOW].varname, "OUT_BASEFLOW"); /* baseflow out of the bottom layer [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_DELINTERCEPT].varname, "OUT_DELINTERCEPT"); /* change in canopy interception storage [mm] */ - strcpy(out_data[OUT_DELSOILMOIST].varname, "OUT_DELSOILMOIST"); /* change in soil water content [mm] */ - strcpy(out_data[OUT_DELSWE].varname, "OUT_DELSWE"); /* change in snow water equivalent [mm] */ - strcpy(out_data[OUT_DELSURFSTOR].varname, "OUT_DELSURFSTOR"); /* change in surface liquid water storage [mm] */ - strcpy(out_data[OUT_EVAP].varname, "OUT_EVAP"); /* total net evaporation [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_EVAP_BARE].varname, "OUT_EVAP_BARE"); /* net evaporation from bare soil [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_EVAP_CANOP].varname, "OUT_EVAP_CANOP"); /* net evaporation from canopy interception [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_INFLOW].varname, "OUT_INFLOW"); /* moisture that reaches top of soil column [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); /* river discharge [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_BF_IN].varname, "OUT_LAKE_BF_IN"); /* incoming baseflow from lake catchment [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); /* incoming volumetric baseflow from lake catchment [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_BF_OUT].varname, "OUT_LAKE_BF_OUT"); /* outgoing baseflow lake [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_BF_OUT_V].varname, "OUT_LAKE_BF_OUT_V"); /* outgoing volumetric baseflow from lake [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_CHAN_IN].varname, "OUT_LAKE_CHAN_IN"); /* channel inflow into lake [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_CHAN_IN_V].varname, "OUT_LAKE_CHAN_IN_V"); /* volumetric channel inflow into lake [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_CHAN_OUT].varname, "OUT_LAKE_CHAN_OUT"); /* channel outflow from lake [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_CHAN_OUT_V].varname, "OUT_LAKE_CHAN_OUT_V"); /* volumetric channel outflow from lake [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_DSTOR].varname, "OUT_LAKE_DSTOR"); /* change in lake moisture storage (liquid plus ice cover) [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_DSTOR_V].varname, "OUT_LAKE_DSTOR_V"); /* volumetric change in lake moisture storage (liquid plus ice cover) [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_DSWE].varname, "OUT_LAKE_DSWE"); /* change in snowpack on top of lake ice [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_DSWE_V].varname, "OUT_LAKE_DSWE_V"); /* volumetric change in snowpack on top of lake ice [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_EVAP].varname, "OUT_LAKE_EVAP"); /* net evaporation from lake surface [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_EVAP_V].varname, "OUT_LAKE_EVAP_V"); /* net volumetric evaporation from lake surface [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_PREC_V].varname, "OUT_LAKE_PREC_V"); /* volumetric precipitation over lake surface [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_RCHRG].varname, "OUT_LAKE_RCHRG"); /* recharge from lake to surrounding wetland [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_RCHRG_V].varname, "OUT_LAKE_RCHRG_V"); /* volumetric recharge from lake to surrounding wetland [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_RO_IN].varname, "OUT_LAKE_RO_IN"); /* incoming runoff from lake catchment [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_RO_IN_V].varname, "OUT_LAKE_RO_IN_V"); /* incoming volumetric runoff from lake catchment [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_LAKE_VAPFLX].varname, "OUT_LAKE_VAPFLX"); /* sublimation from lake snow pack [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_LAKE_VAPFLX_V].varname, "OUT_LAKE_VAPFLX_V"); /* volumetric sublimation from lake snow pack [m3] (ALMA_OUTPUT: [m3/s]) */ - strcpy(out_data[OUT_PET].varname, "OUT_PET"); /* Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_PREC].varname, "OUT_PREC"); /* incoming precipitation [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_RAINF].varname, "OUT_RAINF"); /* rainfall [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_REFREEZE].varname, "OUT_REFREEZE"); /* refreezing of water in the snow [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_RUNOFF].varname, "OUT_RUNOFF"); /* surface runoff [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SNOW_MELT].varname, "OUT_SNOW_MELT"); /* snow melt [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SNOWF].varname, "OUT_SNOWF"); /* snowfall [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SUB_BLOWING].varname, "OUT_SUB_BLOWING"); /* net sublimation of blowing snow [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SUB_CANOP].varname, "OUT_SUB_CANOP"); /* net sublimation from snow stored in canopy [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SUB_SNOW].varname, "OUT_SUB_SNOW"); /* net sublimation from snow pack (surface and blowing) [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SUB_SURFACE].varname, "OUT_SUB_SURFACE"); /* net sublimation from snow pack surface [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_TRANSP_VEG].varname, "OUT_TRANSP_VEG"); /* net transpiration from vegetation [mm] (ALMA_OUTPUT: [mm/s]) */ - - // Energy Balance Terms - state variables - strcpy(out_data[OUT_ALBEDO].varname, "OUT_ALBEDO"); /* albedo [fraction] */ - strcpy(out_data[OUT_BARESOILT].varname, "OUT_BARESOILT"); /* bare soil surface temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_FDEPTH].varname, "OUT_FDEPTH"); /* depth of freezing fronts [cm] (ALMA_OUTPUT: [m]) for each freezing front */ - strcpy(out_data[OUT_LAKE_ICE_TEMP].varname, "OUT_LAKE_ICE_TEMP"); /* lake ice temperature [K] */ - strcpy(out_data[OUT_LAKE_SURF_TEMP].varname, "OUT_LAKE_SURF_TEMP"); /* lake surface temperature [K] */ - strcpy(out_data[OUT_RAD_TEMP].varname, "OUT_RAD_TEMP"); /* average radiative surface temperature [K] */ - strcpy(out_data[OUT_SALBEDO].varname, "OUT_SALBEDO"); /* snow albedo [fraction] */ - strcpy(out_data[OUT_SNOW_PACK_TEMP].varname, "OUT_SNOW_PACK_TEMP"); /* snow pack temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_SNOW_SURF_TEMP].varname, "OUT_SNOW_SURF_TEMP"); /* snow surface temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_SNOWT_FBFLAG].varname, "OUT_SNOWT_FBFLAG"); /* snow surface temperature flag */ - strcpy(out_data[OUT_SOIL_TEMP].varname, "OUT_SOIL_TEMP"); /* soil temperature [C] (ALMA_OUTPUT: [K]) for each soil layer */ - strcpy(out_data[OUT_SOIL_TNODE].varname, "OUT_SOIL_TNODE"); /* soil temperature [C] (ALMA_OUTPUT: [K]) for each soil thermal node */ - strcpy(out_data[OUT_SOIL_TNODE_WL].varname, "OUT_SOIL_TNODE_WL"); /* soil temperature [C] (ALMA_OUTPUT: [K]) for each soil thermal node in the wetland */ - strcpy(out_data[OUT_SOILT_FBFLAG].varname, "OUT_SOILT_FBFLAG"); /* soil temperature flag for each soil thermal node */ - strcpy(out_data[OUT_SURF_TEMP].varname, "OUT_SURF_TEMP"); /* average surface temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_SURFT_FBFLAG].varname, "OUT_SURFT_FBFLAG"); /* surface temperature flag */ - strcpy(out_data[OUT_TCAN_FBFLAG].varname, "OUT_TCAN_FBFLAG"); /* Tcanopy flag */ - strcpy(out_data[OUT_TDEPTH].varname, "OUT_TDEPTH"); /* depth of thawing fronts [cm] (ALMA_OUTPUT: [m]) for each thawing front */ - strcpy(out_data[OUT_TFOL_FBFLAG].varname, "OUT_TFOL_FBFLAG"); /* Tfoliage flag */ - strcpy(out_data[OUT_VEGT].varname, "OUT_VEGT"); /* average vegetation canopy temperature [C] (ALMA_OUTPUT: [K]) */ - - // Energy Balance Terms - fluxes - strcpy(out_data[OUT_ADV_SENS].varname, "OUT_ADV_SENS"); /* net sensible heat advected to snow pack [W/m2] */ - strcpy(out_data[OUT_ADVECTION].varname, "OUT_ADVECTION"); /* advected energy [W/m2] */ - strcpy(out_data[OUT_DELTACC].varname, "OUT_DELTACC"); /* rate of change in cold content in snow pack [W/m2] */ - strcpy(out_data[OUT_DELTAH].varname, "OUT_DELTAH"); /* rate of change in heat storage [W/m2] */ - strcpy(out_data[OUT_ENERGY_ERROR].varname, "OUT_ENERGY_ERROR"); /* energy budget error [W/m2] */ - strcpy(out_data[OUT_WATER_ERROR].varname, "OUT_WATER_ERROR"); /* water budget error [mm] */ - strcpy(out_data[OUT_FUSION].varname, "OUT_FUSION"); /* net energy used to melt/freeze soil moisture [W/m2] */ - strcpy(out_data[OUT_GRND_FLUX].varname, "OUT_GRND_FLUX"); /* net heat flux into ground [W/m2] */ - strcpy(out_data[OUT_IN_LONG].varname, "OUT_IN_LONG"); /* incoming longwave flux at surface (under veg) [W/m2] */ - strcpy(out_data[OUT_LATENT].varname, "OUT_LATENT"); /* net upward latent heat flux [W/m2] */ - strcpy(out_data[OUT_LATENT_SUB].varname, "OUT_LATENT_SUB"); /* net upward latent heat flux from sublimation [W/m2] */ - strcpy(out_data[OUT_MELT_ENERGY].varname, "OUT_MELT_ENERGY"); /* energy of fusion (melting) [W/m2] */ - strcpy(out_data[OUT_LWNET].varname, "OUT_LWNET"); /* net downward longwave flux [W/m2] */ - strcpy(out_data[OUT_SWNET].varname, "OUT_SWNET"); /* net downward shortwave flux [W/m2] */ - strcpy(out_data[OUT_R_NET].varname, "OUT_R_NET"); /* net downward radiation flux [W/m2] */ - strcpy(out_data[OUT_RFRZ_ENERGY].varname, "OUT_RFRZ_ENERGY"); /* net energy used to refreeze liquid water in snowpack [W/m2] */ - strcpy(out_data[OUT_SENSIBLE].varname, "OUT_SENSIBLE"); /* net upward sensible heat flux [W/m2] */ - strcpy(out_data[OUT_SNOW_FLUX].varname, "OUT_SNOW_FLUX"); /* energy flux through snow pack [W/m2] */ - - // Miscellaneous Terms - strcpy(out_data[OUT_AERO_COND].varname, "OUT_AERO_COND"); /* "scene" aerodynamic conductance [m/s] (tiles with overstory contribute overstory conductance; others contribue surface conductance) */ - strcpy(out_data[OUT_AERO_COND1].varname, "OUT_AERO_COND1"); /* surface aerodynamic conductance [m/s] */ - strcpy(out_data[OUT_AERO_COND2].varname, "OUT_AERO_COND2"); /* overstory aerodynamic conductance [m/s] */ - strcpy(out_data[OUT_AERO_RESIST].varname, "OUT_AERO_RESIST"); /* "scene" aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribue surface resistance)*/ - strcpy(out_data[OUT_AERO_RESIST1].varname, "OUT_AERO_RESIST1"); /* surface aerodynamic resistance [m/s] */ - strcpy(out_data[OUT_AERO_RESIST2].varname, "OUT_AERO_RESIST2"); /* overstory aerodynamic resistance [m/s] */ - strcpy(out_data[OUT_AIR_TEMP].varname, "OUT_AIR_TEMP"); /* air temperature [C] */ - strcpy(out_data[OUT_CATM].varname, "OUT_CATM"); /* atmospheric CO2 concentration [ppm] */ - strcpy(out_data[OUT_DENSITY].varname, "OUT_DENSITY"); /* near-surface atmospheric density [kg/m3] */ - strcpy(out_data[OUT_FCANOPY].varname, "OUT_FCANOPY"); /* fractional area covered by plant canopy [fraction] */ - strcpy(out_data[OUT_FDIR].varname, "OUT_FDIR"); /* fraction of incoming shortwave that is direct [fraction] */ - strcpy(out_data[OUT_LAI].varname, "OUT_LAI"); /* leaf area index [m2/m2] */ - strcpy(out_data[OUT_LWDOWN].varname, "OUT_LWDOWN"); /* incoming longwave [W/m2] */ - strcpy(out_data[OUT_PAR].varname, "OUT_PAR"); /* incoming photosynthetically active radiation [W/m2] */ - strcpy(out_data[OUT_PRESSURE].varname, "OUT_PRESSURE"); /* near surface atmospheric pressure [kPa] */ - strcpy(out_data[OUT_QAIR].varname, "OUT_QAIR"); /* specific humidity [kg/kg] */ - strcpy(out_data[OUT_REL_HUMID].varname, "OUT_REL_HUMID"); /* relative humidity [fraction]*/ - strcpy(out_data[OUT_SWDOWN].varname, "OUT_SWDOWN"); /* incoming shortwave [W/m2] */ - strcpy(out_data[OUT_SURF_COND].varname, "OUT_SURF_COND"); /* surface conductance [m/s] */ - strcpy(out_data[OUT_VP].varname, "OUT_VP"); /* near surface vapor pressure [kPa] */ - strcpy(out_data[OUT_VPD].varname, "OUT_VPD"); /* near surface vapor pressure deficit [kPa] */ - strcpy(out_data[OUT_WIND].varname, "OUT_WIND"); /* near surface wind speed [m/s] */ - - // Carbon-cycling Terms - strcpy(out_data[OUT_APAR].varname, "OUT_APAR"); /* absorbed PAR [W/m2] */ - strcpy(out_data[OUT_GPP].varname, "OUT_GPP"); /* gross primary productivity [g C/m2s] */ - strcpy(out_data[OUT_RAUT].varname, "OUT_RAUT"); /* autotrophic respiration [g C/m2s] */ - strcpy(out_data[OUT_NPP].varname, "OUT_NPP"); /* net primary productivity [g C/m2s] */ - strcpy(out_data[OUT_LITTERFALL].varname, "OUT_LITTERFALL"); /* flux of carbon from living biomass into soil [g C/m2d] */ - strcpy(out_data[OUT_RHET].varname, "OUT_RHET"); /* heterotrophic respiration [g C/m2d] */ - strcpy(out_data[OUT_NEE].varname, "OUT_NEE"); /* net ecosystem exchange [g C/m2d] */ - strcpy(out_data[OUT_CLITTER].varname, "OUT_CLITTER"); /* litter pool carbon density [g C/m2] */ - strcpy(out_data[OUT_CINTER].varname, "OUT_CINTER"); /* intermediate pool carbon density [g C/m2] */ - strcpy(out_data[OUT_CSLOW].varname, "OUT_CSLOW"); /* slow pool carbon density [g C/m2] */ - - // Band-specific quantities - strcpy(out_data[OUT_ADV_SENS_BAND].varname, "OUT_ADV_SENS_BAND"); /* net sensible heat flux advected to snow pack [W/m2] */ - strcpy(out_data[OUT_ADVECTION_BAND].varname, "OUT_ADVECTION_BAND"); /* advected energy [W/m2] */ - strcpy(out_data[OUT_ALBEDO_BAND].varname, "OUT_ALBEDO_BAND"); /* albedo [fraction] */ - strcpy(out_data[OUT_DELTACC_BAND].varname, "OUT_DELTACC_BAND"); /* change in cold content in snow pack [W/m2] */ - strcpy(out_data[OUT_GRND_FLUX_BAND].varname, "OUT_GRND_FLUX_BAND"); /* net heat flux into ground [W/m2] */ - strcpy(out_data[OUT_IN_LONG_BAND].varname, "OUT_IN_LONG_BAND"); /* incoming longwave flux at surface (under veg) [W/m2] */ - strcpy(out_data[OUT_LATENT_BAND].varname, "OUT_LATENT_BAND"); /* net upward latent heat flux [W/m2] */ - strcpy(out_data[OUT_LATENT_SUB_BAND].varname, "OUT_LATENT_SUB_BAND"); /* net upward latent heat flux from sublimation [W/m2] */ - strcpy(out_data[OUT_MELT_ENERGY_BAND].varname, "OUT_MELT_ENERGY_BAND"); /* energy of fusion (melting) [W/m2] */ - strcpy(out_data[OUT_LWNET_BAND].varname, "OUT_LWNET_BAND"); /* net downward longwave flux [W/m2] */ - strcpy(out_data[OUT_SWNET_BAND].varname, "OUT_SWNET_BAND"); /* net downward shortwave flux [W/m2] */ - strcpy(out_data[OUT_RFRZ_ENERGY_BAND].varname, "OUT_RFRZ_ENERGY_BAND"); /* net energy used to refreeze liquid water in snowpack [W/m2] */ - strcpy(out_data[OUT_SENSIBLE_BAND].varname, "OUT_SENSIBLE_BAND"); /* net upward sensible heat flux [W/m2] */ - strcpy(out_data[OUT_SNOW_CANOPY_BAND].varname, "OUT_SNOW_CANOPY_BAND"); /* snow interception storage in canopy [mm] */ - strcpy(out_data[OUT_SNOW_COVER_BAND].varname, "OUT_SNOW_COVER_BAND"); /* fractional area of snow cover [fraction] */ - strcpy(out_data[OUT_SNOW_DEPTH_BAND].varname, "OUT_SNOW_DEPTH_BAND"); /* depth of snow pack [cm] */ - strcpy(out_data[OUT_SNOW_FLUX_BAND].varname, "OUT_SNOW_FLUX_BAND"); /* energy flux through snow pack [W/m2] */ - strcpy(out_data[OUT_SNOW_MELT_BAND].varname, "OUT_SNOW_MELT_BAND"); /* snow melt [mm] (ALMA_OUTPUT: [mm/s]) */ - strcpy(out_data[OUT_SNOW_PACKT_BAND].varname, "OUT_SNOW_PACKT_BAND"); /* snow pack temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_SNOW_SURFT_BAND].varname, "OUT_SNOW_SURFT_BAND"); /* snow surface temperature [C] (ALMA_OUTPUT: [K]) */ - strcpy(out_data[OUT_SWE_BAND].varname, "OUT_SWE_BAND"); /* snow water equivalent in snow pack [mm] */ - - // Set number of elements - default is 1 - for (v = 0; v < N_OUTVAR_TYPES; v++) { - out_data[v].nelem = 1; - } - if (options.FROZEN_SOIL) { - out_data[OUT_FDEPTH].nelem = MAX_FRONTS; - out_data[OUT_TDEPTH].nelem = MAX_FRONTS; - } - out_data[OUT_SMLIQFRAC].nelem = options.Nlayer; - out_data[OUT_SMFROZFRAC].nelem = options.Nlayer; - out_data[OUT_SOIL_ICE].nelem = options.Nlayer; - out_data[OUT_SOIL_LIQ].nelem = options.Nlayer; - out_data[OUT_SOIL_MOIST].nelem = options.Nlayer; - out_data[OUT_SOIL_TEMP].nelem = options.Nlayer; - out_data[OUT_SOIL_TNODE].nelem = options.Nnode; - out_data[OUT_SOIL_TNODE_WL].nelem = options.Nnode; - out_data[OUT_SOILT_FBFLAG].nelem = options.Nnode; - out_data[OUT_ADV_SENS_BAND].nelem = options.SNOW_BAND; - out_data[OUT_ADVECTION_BAND].nelem = options.SNOW_BAND; - out_data[OUT_ALBEDO_BAND].nelem = options.SNOW_BAND; - out_data[OUT_DELTACC_BAND].nelem = options.SNOW_BAND; - out_data[OUT_GRND_FLUX_BAND].nelem = options.SNOW_BAND; - out_data[OUT_IN_LONG_BAND].nelem = options.SNOW_BAND; - out_data[OUT_LATENT_BAND].nelem = options.SNOW_BAND; - out_data[OUT_LATENT_SUB_BAND].nelem = options.SNOW_BAND; - out_data[OUT_MELT_ENERGY_BAND].nelem = options.SNOW_BAND; - out_data[OUT_LWNET_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SWNET_BAND].nelem = options.SNOW_BAND; - out_data[OUT_RFRZ_ENERGY_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SENSIBLE_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_CANOPY_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_COVER_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_DEPTH_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_FLUX_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_MELT_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_PACKT_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SNOW_SURFT_BAND].nelem = options.SNOW_BAND; - out_data[OUT_SWE_BAND].nelem = options.SNOW_BAND; - - // Set aggregation method - default is to average over the interval - for (v = 0; v < N_OUTVAR_TYPES; v++) { - out_data[v].aggtype = AGG_TYPE_AVG; - } - out_data[OUT_ASAT].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_AREA_FRAC].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_DEPTH].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_ICE].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_ICE_FRACT].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_ICE_HEIGHT].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_MOIST].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_SURF_AREA].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_SWE].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_SWE_V].aggtype = AGG_TYPE_END; - out_data[OUT_LAKE_VOLUME].aggtype = AGG_TYPE_END; - out_data[OUT_ROOTMOIST].aggtype = AGG_TYPE_END; - out_data[OUT_SMFROZFRAC].aggtype = AGG_TYPE_END; - out_data[OUT_SMLIQFRAC].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_CANOPY].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_COVER].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_DEPTH].aggtype = AGG_TYPE_END; - out_data[OUT_SOIL_ICE].aggtype = AGG_TYPE_END; - out_data[OUT_SOIL_LIQ].aggtype = AGG_TYPE_END; - out_data[OUT_SOIL_MOIST].aggtype = AGG_TYPE_END; - out_data[OUT_SOIL_WET].aggtype = AGG_TYPE_END; - out_data[OUT_SURFSTOR].aggtype = AGG_TYPE_END; - out_data[OUT_SURF_FROST_FRAC].aggtype = AGG_TYPE_END; - out_data[OUT_SWE].aggtype = AGG_TYPE_END; - out_data[OUT_WDEW].aggtype = AGG_TYPE_END; - out_data[OUT_ZWT].aggtype = AGG_TYPE_END; - out_data[OUT_ZWT_LUMPED].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_CANOPY_BAND].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_COVER_BAND].aggtype = AGG_TYPE_END; - out_data[OUT_SNOW_DEPTH_BAND].aggtype = AGG_TYPE_END; - out_data[OUT_SWE_BAND].aggtype = AGG_TYPE_END; - out_data[OUT_BASEFLOW].aggtype = AGG_TYPE_SUM; - out_data[OUT_DELINTERCEPT].aggtype = AGG_TYPE_SUM; - out_data[OUT_DELSOILMOIST].aggtype = AGG_TYPE_SUM; - out_data[OUT_DELSWE].aggtype = AGG_TYPE_SUM; - out_data[OUT_DELSURFSTOR].aggtype = AGG_TYPE_SUM; - out_data[OUT_EVAP].aggtype = AGG_TYPE_SUM; - out_data[OUT_EVAP_BARE].aggtype = AGG_TYPE_SUM; - out_data[OUT_EVAP_CANOP].aggtype = AGG_TYPE_SUM; - out_data[OUT_INFLOW].aggtype = AGG_TYPE_SUM; - out_data[OUT_DISCHARGE].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_BF_IN].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_BF_IN_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_BF_OUT].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_BF_OUT_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_CHAN_IN].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_CHAN_IN_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_CHAN_OUT].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_CHAN_OUT_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_DSTOR].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_DSTOR_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_DSWE].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_DSWE_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_EVAP].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_EVAP_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_PREC_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_RCHRG].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_RCHRG_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_RO_IN].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_RO_IN_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_VAPFLX].aggtype = AGG_TYPE_SUM; - out_data[OUT_LAKE_VAPFLX_V].aggtype = AGG_TYPE_SUM; - out_data[OUT_PET].aggtype = AGG_TYPE_SUM; - out_data[OUT_PREC].aggtype = AGG_TYPE_SUM; - out_data[OUT_RAINF].aggtype = AGG_TYPE_SUM; - out_data[OUT_REFREEZE].aggtype = AGG_TYPE_SUM; - out_data[OUT_RUNOFF].aggtype = AGG_TYPE_SUM; - out_data[OUT_SNOW_MELT].aggtype = AGG_TYPE_SUM; - out_data[OUT_SNOWF].aggtype = AGG_TYPE_SUM; - out_data[OUT_SUB_BLOWING].aggtype = AGG_TYPE_SUM; - out_data[OUT_SUB_CANOP].aggtype = AGG_TYPE_SUM; - out_data[OUT_SUB_SNOW].aggtype = AGG_TYPE_SUM; - out_data[OUT_SUB_SURFACE].aggtype = AGG_TYPE_SUM; - out_data[OUT_TRANSP_VEG].aggtype = AGG_TYPE_SUM; - out_data[OUT_DELTACC_BAND].aggtype = AGG_TYPE_SUM; - out_data[OUT_SNOW_MELT].aggtype = AGG_TYPE_SUM; - out_data[OUT_SNOWT_FBFLAG].aggtype = AGG_TYPE_SUM; - out_data[OUT_SOILT_FBFLAG].aggtype = AGG_TYPE_SUM; - out_data[OUT_SURFT_FBFLAG].aggtype = AGG_TYPE_SUM; - out_data[OUT_TCAN_FBFLAG].aggtype = AGG_TYPE_SUM; - out_data[OUT_TFOL_FBFLAG].aggtype = AGG_TYPE_SUM; - - // Allocate space for data - for (v = 0; v < N_OUTVAR_TYPES; v++) { - out_data[v].data = - calloc(out_data[v].nelem, sizeof(*(out_data[v].data))); - out_data[v].aggdata = - calloc(out_data[v].nelem, sizeof(*(out_data[v].aggdata))); - } - - // Initialize data values - init_output_list(out_data, false, "%.4f", OUT_TYPE_FLOAT, 1); - - return out_data; -} - -/****************************************************************************** - * @brief This routine initializes the output information for all output - * variables. - *****************************************************************************/ -void -init_output_list(out_data_struct *out_data, - int write, - char *format, - int type, - double mult) -{ - int varid; - size_t i; - - for (varid = 0; varid < N_OUTVAR_TYPES; varid++) { - out_data[varid].write = write; - strcpy(out_data[varid].format, format); - out_data[varid].type = type; - out_data[varid].mult = mult; - for (i = 0; i < out_data[varid].nelem; i++) { - out_data[varid].data[i] = 0; - } - } -} - -/****************************************************************************** - * @brief This routine updates the output information for a given output - * variable. - *****************************************************************************/ -int -set_output_var(out_data_file_struct *out_data_files, - int write, - int filenum, - out_data_struct *out_data, - char *varname, - int varnum, - char *format, - int type, - double mult) -{ - int varid; - int found = false; - int status = 0; - - for (varid = 0; varid < N_OUTVAR_TYPES; varid++) { - if (strcmp(out_data[varid].varname, varname) == 0) { - found = true; - out_data[varid].write = write; - if (strcmp(format, "*") != 0) { - strcpy(out_data[varid].format, format); - } - if (type != 0) { - out_data[varid].type = type; - } - if (mult != 0) { - out_data[varid].mult = mult; - } - out_data_files[filenum].varid[varnum] = varid; - } - } - if (!found) { - status = -1; - log_err("set_output_var: \"%s\" was not found in the list of " - "supported output variable names. Please use the exact name " - "listed in vic_driver_shared.h.", varname); - } - return status; -} - -/****************************************************************************** - * @brief This routine frees the memory in the out_data array. - *****************************************************************************/ -void -free_out_data(out_data_struct **out_data) -{ - int varid; - - for (varid = 0; varid < N_OUTVAR_TYPES; varid++) { - free((char*) (*out_data)[varid].data); - free((char*) (*out_data)[varid].aggdata); - } - free((char*) (*out_data)); -} diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index 7260c98d8..e735d2bd7 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -304,7 +304,6 @@ print_global_param(global_param_struct *gp) fprintf(LOG_DEST, "\tdt : %.4f\n", gp->dt); fprintf(LOG_DEST, "\tsnow_dt : %.4f\n", gp->snow_dt); fprintf(LOG_DEST, "\trunoff_dt : %.4f\n", gp->runoff_dt); - fprintf(LOG_DEST, "\tout_dt : %.4f\n", gp->out_dt); fprintf(LOG_DEST, "\tmodel_steps_per_day : %zu\n", gp->model_steps_per_day); fprintf(LOG_DEST, "\tsnow_steps_per_day : %zu\n", gp->snow_steps_per_day); fprintf(LOG_DEST, "\trunoff_steps_per_day: %zu\n", @@ -323,7 +322,6 @@ print_global_param(global_param_struct *gp) fprintf(LOG_DEST, "\tforceyear[%zd] : %hu\n", i, gp->forceyear[i]); } fprintf(LOG_DEST, "\tnrecs : %zu\n", gp->nrecs); - fprintf(LOG_DEST, "\tskipyear : %hu\n", gp->skipyear); fprintf(LOG_DEST, "\tstartday : %hu\n", gp->startday); fprintf(LOG_DEST, "\tstartsec : %u\n", gp->startsec); fprintf(LOG_DEST, "\tstartmonth : %hu\n", gp->startmonth); @@ -540,54 +538,106 @@ print_option(option_struct *option) fprintf(LOG_DEST, "\tSTATE_FORMAT : %d\n", option->STATE_FORMAT); fprintf(LOG_DEST, "\tINIT_STATE : %d\n", option->INIT_STATE); fprintf(LOG_DEST, "\tSAVE_STATE : %d\n", option->SAVE_STATE); - fprintf(LOG_DEST, "\tALMA_OUTPUT : %d\n", option->ALMA_OUTPUT); - fprintf(LOG_DEST, "\tOUT_FORMAT : %d\n", option->OUT_FORMAT); - fprintf(LOG_DEST, "\tCOMPRESS : %d\n", option->COMPRESS); - fprintf(LOG_DEST, "\tMOISTFRACT : %d\n", option->MOISTFRACT); - fprintf(LOG_DEST, "\tNoutfiles : %zu\n", option->Noutfiles); - fprintf(LOG_DEST, "\tPRT_HEADER : %d\n", option->PRT_HEADER); - fprintf(LOG_DEST, "\tPRT_SNOW_BAND : %d\n", option->PRT_SNOW_BAND); + fprintf(LOG_DEST, "\tNoutstreams : %zu\n", option->Noutstreams); } /****************************************************************************** * @brief Print out data structure. *****************************************************************************/ void -print_out_data(out_data_struct *out, - size_t nelem) +print_out_data(double **out_data, + metadata_struct *metadata) { size_t i; + size_t j; fprintf(LOG_DEST, "out_data:\n"); - fprintf(LOG_DEST, "\tvarname: %s\n", out->varname); - fprintf(LOG_DEST, "\twrite: %d\n", out->write); - fprintf(LOG_DEST, "\tformat: %s\n", out->format); - fprintf(LOG_DEST, "\ttype: %d\n", out->type); - fprintf(LOG_DEST, "\tmult: %.4f\n", out->mult); - fprintf(LOG_DEST, "\tnelem: %d\n", out->nelem); - fprintf(LOG_DEST, "\tdata:"); - for (i = 0; i < nelem; i++) { - fprintf(LOG_DEST, "\t%.4f", out->data[i]); + + for (i = 0; i < N_OUTVAR_TYPES; i++) { + fprintf(LOG_DEST, "\tvarname: %s\n", metadata[i].varname); + fprintf(LOG_DEST, "\t\tnelem: %zu\n", metadata[i].nelem); + fprintf(LOG_DEST, "\t\tdata:"); + for (j = 0; j < metadata[i].nelem; j++) { + fprintf(LOG_DEST, "\t%.4f", out_data[i][j]); + } + fprintf(LOG_DEST, "\n"); } fprintf(LOG_DEST, "\n"); - fprintf(LOG_DEST, "\taggdata:"); - for (i = 0; i < nelem; i++) { - fprintf(LOG_DEST, "\t%.4f", out->aggdata[i]); - } +} + +/****************************************************************************** + * @brief Print stream_file_struct. + *****************************************************************************/ +void +print_stream(stream_struct *stream, + metadata_struct *metadata) +{ + size_t i; + unsigned int varid; + + fprintf(LOG_DEST, "stream_file_struct:\n"); + + fprintf(LOG_DEST, "\tprefix: %s\n", stream->prefix); + fprintf(LOG_DEST, "\tfilename: %s\n", stream->filename); + fprintf(LOG_DEST, "\tfh: %p\n", stream->fh); + fprintf(LOG_DEST, "\tfile_format: %hu\n", stream->file_format); + fprintf(LOG_DEST, "\tnvars: %zu\n", stream->nvars); + 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"); + 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", + i, varid, metadata[varid].varname, + stream->type[i], stream->mult[i], stream->format[i], + stream->aggtype[i]); + } + fprintf(LOG_DEST, "\taggdata shape: (%zu, %zu, nelem, 1)\n", + stream->ngridcells, stream->nvars); + fprintf(LOG_DEST, "\n"); } /****************************************************************************** - * @brief Print out data file structure. + * @brief Print stream_file_struct. *****************************************************************************/ void -print_out_data_file(out_data_file_struct *outf) +print_alarm(alarm_struct *alarm) { - fprintf(LOG_DEST, "\tprefix: %s\n", outf->prefix); - fprintf(LOG_DEST, "\tfilename: %s\n", outf->filename); - fprintf(LOG_DEST, "\tfh: %p\n", outf->fh); - fprintf(LOG_DEST, "\tnvars: %zu\n", outf->nvars); - fprintf(LOG_DEST, "\tvarid: %p\n", outf->varid); + fprintf(LOG_DEST, "alarm_struct:\n"); + fprintf(LOG_DEST, "\tcount: %u\n", alarm->count); + fprintf(LOG_DEST, "\tnext: %d\n", alarm->next); + fprintf(LOG_DEST, "\tfreq: %u\n", alarm->freq); + fprintf(LOG_DEST, "\tn: %d\n", alarm->n); + fprintf(LOG_DEST, "\tis_subdaily: %s\n", + alarm->is_subdaily ? "true" : "false"); + fprintf(LOG_DEST, "\tdate: \n "); + print_dmy(&(alarm->date)); + + fprintf(LOG_DEST, "\n"); +} + +/****************************************************************************** + * @brief Print stream_file_struct. + *****************************************************************************/ +void +print_out_metadata(metadata_struct *metadata, + size_t nvars) +{ + size_t i; + + fprintf(LOG_DEST, "metadata_struct: \n"); + + for (i = 0; i < nvars; i++) { + fprintf(LOG_DEST, "\t%s (%zu)\n", metadata[i].varname, i); + fprintf(LOG_DEST, "\t\tlong_name: %s\n", metadata[i].long_name); + fprintf(LOG_DEST, "\t\tunits: %s\n", metadata[i].units); + fprintf(LOG_DEST, "\t\tdescription: %s\n", metadata[i].description); + fprintf(LOG_DEST, "\t\tnelem: %zu\n", metadata[i].nelem); + } + fprintf(LOG_DEST, "\n"); } /****************************************************************************** diff --git a/vic/drivers/shared_all/src/put_data.c b/vic/drivers/shared_all/src/put_data.c index d820a8a44..cea32433b 100644 --- a/vic/drivers/shared_all/src/put_data.c +++ b/vic/drivers/shared_all/src/put_data.c @@ -38,9 +38,8 @@ put_data(all_vars_struct *all_vars, veg_con_struct *veg_con, veg_lib_struct *veg_lib, lake_con_struct *lake_con, - out_data_struct *out_data, - save_data_struct *save_data, - int rec) + double **out_data, + save_data_struct *save_data) { extern global_param_struct global_param; extern option_struct options; @@ -50,9 +49,9 @@ put_data(all_vars_struct *all_vars, size_t index; size_t band; size_t Nbands; - int overstory; - int HasVeg; - int IsWet; + bool overstory; + bool HasVeg; + bool IsWet; bool *AboveTreeLine; double *AreaFract; double *depth; @@ -70,11 +69,8 @@ put_data(all_vars_struct *all_vars, double TreeAdjustFactor[MAX_BANDS]; double ThisAreaFract; double ThisTreeAdjust; - int v; size_t i; double dt_sec; - double out_dt_sec; - unsigned int out_step_ratio; cell_data_struct **cell; energy_bal_struct **energy; @@ -94,8 +90,6 @@ put_data(all_vars_struct *all_vars, frost_fract = soil_con->frost_fract; frost_slope = soil_con->frost_slope; dt_sec = global_param.dt; - out_dt_sec = global_param.out_dt; - out_step_ratio = (unsigned int) (out_dt_sec / dt_sec); // Compute treeline adjustment factors for (band = 0; band < options.SNOW_BAND; band++) { @@ -120,7 +114,7 @@ put_data(all_vars_struct *all_vars, else { TreeAdjustFactor[band] = 1.; } - if (TreeAdjustFactor[band] != 1 && rec == 0) { + if (TreeAdjustFactor[band] != 1) { log_warn("Tree adjust factor for band %zu is equal to %f.", band, TreeAdjustFactor[band]); } @@ -135,36 +129,36 @@ put_data(all_vars_struct *all_vars, zero_output_list(out_data); // Set output versions of input forcings - out_data[OUT_AIR_TEMP].data[0] = atmos->air_temp[NR]; - out_data[OUT_DENSITY].data[0] = atmos->density[NR]; - out_data[OUT_LWDOWN].data[0] = atmos->longwave[NR]; - out_data[OUT_PREC].data[0] = atmos->out_prec; // mm over grid cell - out_data[OUT_PRESSURE].data[0] = atmos->pressure[NR] / PA_PER_KPA; - out_data[OUT_QAIR].data[0] = CONST_EPS * atmos->vp[NR] / - atmos->pressure[NR]; - out_data[OUT_RAINF].data[0] = atmos->out_rain; // mm over grid cell - out_data[OUT_REL_HUMID].data[0] = FRACT_TO_PERCENT * atmos->vp[NR] / - (atmos->vp[NR] + atmos->vpd[NR]); + out_data[OUT_AIR_TEMP][0] = atmos->air_temp[NR]; + out_data[OUT_DENSITY][0] = atmos->density[NR]; + out_data[OUT_LWDOWN][0] = atmos->longwave[NR]; + out_data[OUT_PREC][0] = atmos->out_prec; // mm over grid cell + out_data[OUT_PRESSURE][0] = atmos->pressure[NR] / PA_PER_KPA; + out_data[OUT_QAIR][0] = CONST_EPS * atmos->vp[NR] / + atmos->pressure[NR]; + out_data[OUT_RAINF][0] = atmos->out_rain; // mm over grid cell + out_data[OUT_REL_HUMID][0] = FRACT_TO_PERCENT * atmos->vp[NR] / + (atmos->vp[NR] + atmos->vpd[NR]); if (options.LAKES && lake_con->Cl[0] > 0) { - out_data[OUT_LAKE_CHAN_IN].data[0] = atmos->channel_in[NR]; // mm over grid cell + out_data[OUT_LAKE_CHAN_IN][0] = atmos->channel_in[NR]; // mm over grid cell } else { - out_data[OUT_LAKE_CHAN_IN].data[0] = 0; + out_data[OUT_LAKE_CHAN_IN][0] = 0; } - out_data[OUT_SWDOWN].data[0] = atmos->shortwave[NR]; - out_data[OUT_SNOWF].data[0] = atmos->out_snow; // mm over grid cell - out_data[OUT_VP].data[0] = atmos->vp[NR] / PA_PER_KPA; - out_data[OUT_VPD].data[0] = atmos->vpd[NR] / PA_PER_KPA; - out_data[OUT_WIND].data[0] = atmos->wind[NR]; + out_data[OUT_SWDOWN][0] = atmos->shortwave[NR]; + out_data[OUT_SNOWF][0] = atmos->out_snow; // mm over grid cell + out_data[OUT_VP][0] = atmos->vp[NR] / PA_PER_KPA; + out_data[OUT_VPD][0] = atmos->vpd[NR] / PA_PER_KPA; + out_data[OUT_WIND][0] = atmos->wind[NR]; if (options.CARBON) { - out_data[OUT_CATM].data[0] = atmos->Catm[NR] / PPM_to_MIXRATIO; - out_data[OUT_FDIR].data[0] = atmos->fdir[NR]; - out_data[OUT_PAR].data[0] = atmos->par[NR]; + out_data[OUT_CATM][0] = atmos->Catm[NR] / PPM_to_MIXRATIO; + out_data[OUT_FDIR][0] = atmos->fdir[NR]; + out_data[OUT_PAR][0] = atmos->par[NR]; } else { - out_data[OUT_CATM].data[0] = MISSING; - out_data[OUT_FDIR].data[0] = MISSING; - out_data[OUT_PAR].data[0] = MISSING; + out_data[OUT_CATM][0] = MISSING; + out_data[OUT_FDIR][0] = MISSING; + out_data[OUT_PAR][0] = MISSING; } /**************************************** @@ -174,13 +168,13 @@ put_data(all_vars_struct *all_vars, Cv = veg_con[veg].Cv; Clake = 0; Nbands = options.SNOW_BAND; - IsWet = 0; + IsWet = false; if (veg < veg_con[0].vegetat_type_num) { - HasVeg = 1; + HasVeg = true; } else { - HasVeg = 0; + HasVeg = false; } if (Cv > 0) { @@ -188,7 +182,7 @@ put_data(all_vars_struct *all_vars, if (options.LAKES && veg_con[veg].LAKE) { Clake = lake_var.sarea / lake_con->basin[0]; Nbands = 1; - IsWet = 1; + IsWet = true; } overstory = veg_lib[veg_con[veg].veg_class].overstory; @@ -257,11 +251,10 @@ put_data(all_vars_struct *all_vars, out_data); // Store Wetland-Specific Variables - if (IsWet) { // Wetland soil temperatures for (i = 0; i < options.Nnode; i++) { - out_data[OUT_SOIL_TNODE_WL].data[i] = + out_data[OUT_SOIL_TNODE_WL][i] = energy[veg][band].T[i]; } } @@ -331,102 +324,107 @@ put_data(all_vars_struct *all_vars, // Lake ice if (lake_var.new_ice_area > 0.0) { - out_data[OUT_LAKE_ICE].data[0] = + out_data[OUT_LAKE_ICE][0] = (lake_var.ice_water_eq / lake_var.new_ice_area) * CONST_RHOICE / CONST_RHOFW; - out_data[OUT_LAKE_ICE_TEMP].data[0] = + out_data[OUT_LAKE_ICE_TEMP][0] = lake_var.tempi; - out_data[OUT_LAKE_ICE_HEIGHT].data[0] = + out_data[OUT_LAKE_ICE_HEIGHT][0] = lake_var.hice; - out_data[OUT_LAKE_SWE].data[0] = lake_var.swe / - lake_var.areai; // m over lake ice - out_data[OUT_LAKE_SWE_V].data[0] = lake_var.swe; // m3 + out_data[OUT_LAKE_SWE][0] = lake_var.swe / + lake_var.areai; // m over lake ice + out_data[OUT_LAKE_SWE_V][0] = lake_var.swe; // m3 } else { - out_data[OUT_LAKE_ICE].data[0] = 0.0; - out_data[OUT_LAKE_ICE_TEMP].data[0] = 0.0; - out_data[OUT_LAKE_ICE_HEIGHT].data[0] = 0.0; - out_data[OUT_LAKE_SWE].data[0] = 0.0; - out_data[OUT_LAKE_SWE_V].data[0] = 0.0; + out_data[OUT_LAKE_ICE][0] = 0.0; + out_data[OUT_LAKE_ICE_TEMP][0] = 0.0; + out_data[OUT_LAKE_ICE_HEIGHT][0] = 0.0; + out_data[OUT_LAKE_SWE][0] = 0.0; + out_data[OUT_LAKE_SWE_V][0] = 0.0; } - out_data[OUT_LAKE_DSWE_V].data[0] = lake_var.swe - - lake_var.swe_save; // m3 - out_data[OUT_LAKE_DSWE].data[0] = - (lake_var.swe - - lake_var.swe_save) * MM_PER_M / - soil_con->cell_area; // mm over gridcell + out_data[OUT_LAKE_DSWE_V][0] = lake_var.swe - + lake_var.swe_save; // m3 + // same as OUT_LAKE_MOIST + out_data[OUT_LAKE_DSWE][0] = + (lake_var.swe - lake_var.swe_save) * MM_PER_M / + soil_con->cell_area; // Lake dimensions - out_data[OUT_LAKE_AREA_FRAC].data[0] = Cv * Clake; - out_data[OUT_LAKE_DEPTH].data[0] = lake_var.ldepth; - out_data[OUT_LAKE_SURF_AREA].data[0] = lake_var.sarea; - if (out_data[OUT_LAKE_SURF_AREA].data[0] > 0) { - out_data[OUT_LAKE_ICE_FRACT].data[0] = + out_data[OUT_LAKE_AREA_FRAC][0] = Cv * Clake; + out_data[OUT_LAKE_DEPTH][0] = lake_var.ldepth; + out_data[OUT_LAKE_SURF_AREA][0] = lake_var.sarea; + if (out_data[OUT_LAKE_SURF_AREA][0] > 0) { + out_data[OUT_LAKE_ICE_FRACT][0] = lake_var.new_ice_area / - out_data[OUT_LAKE_SURF_AREA].data[0]; + out_data[OUT_LAKE_SURF_AREA][0]; } else { - out_data[OUT_LAKE_ICE_FRACT].data[0] = 0.; + out_data[OUT_LAKE_ICE_FRACT][0] = 0.; } - out_data[OUT_LAKE_VOLUME].data[0] = lake_var.volume; - out_data[OUT_LAKE_DSTOR_V].data[0] = lake_var.volume - - lake_var. - volume_save; - out_data[OUT_LAKE_DSTOR].data[0] = - (lake_var.volume - - lake_var.volume_save) * MM_PER_M / - soil_con->cell_area; // mm over gridcell + out_data[OUT_LAKE_VOLUME][0] = lake_var.volume; + out_data[OUT_LAKE_DSTOR_V][0] = lake_var.volume - + lake_var. + volume_save; + // mm over gridcell + out_data[OUT_LAKE_DSTOR][0] = + (lake_var.volume - lake_var.volume_save) * + MM_PER_M / + soil_con->cell_area; // Other lake characteristics - out_data[OUT_LAKE_SURF_TEMP].data[0] = lake_var.temp[0]; - if (out_data[OUT_LAKE_SURF_AREA].data[0] > 0) { - out_data[OUT_LAKE_MOIST].data[0] = - (lake_var.volume / - soil_con->cell_area) * MM_PER_M; // mm over gridcell - out_data[OUT_SURFSTOR].data[0] = - (lake_var.volume / - soil_con->cell_area) * MM_PER_M; // same as OUT_LAKE_MOIST + out_data[OUT_LAKE_SURF_TEMP][0] = lake_var.temp[0]; + if (out_data[OUT_LAKE_SURF_AREA][0] > 0) { + // mm over gridcell + out_data[OUT_LAKE_MOIST][0] = + (lake_var.volume / soil_con->cell_area) * + MM_PER_M; + // same as OUT_LAKE_MOIST + out_data[OUT_SURFSTOR][0] = + (lake_var.volume / soil_con->cell_area) * + MM_PER_M; } else { - out_data[OUT_LAKE_MOIST].data[0] = 0; - out_data[OUT_SURFSTOR].data[0] = 0; + out_data[OUT_LAKE_MOIST][0] = 0; + out_data[OUT_SURFSTOR][0] = 0; } // Lake moisture fluxes - out_data[OUT_LAKE_BF_IN_V].data[0] = + out_data[OUT_LAKE_BF_IN_V][0] = lake_var.baseflow_in; // m3 - out_data[OUT_LAKE_BF_OUT_V].data[0] = + out_data[OUT_LAKE_BF_OUT_V][0] = lake_var.baseflow_out; // m3 - out_data[OUT_LAKE_CHAN_IN_V].data[0] = + out_data[OUT_LAKE_CHAN_IN_V][0] = lake_var.channel_in; // m3 - out_data[OUT_LAKE_CHAN_OUT_V].data[0] = + out_data[OUT_LAKE_CHAN_OUT_V][0] = lake_var.runoff_out; // m3 - out_data[OUT_LAKE_EVAP_V].data[0] = lake_var.evapw; // m3 - out_data[OUT_LAKE_PREC_V].data[0] = lake_var.prec; // m3 - out_data[OUT_LAKE_RCHRG_V].data[0] = lake_var.recharge; // m3 - out_data[OUT_LAKE_RO_IN_V].data[0] = lake_var.runoff_in; // m3 - out_data[OUT_LAKE_VAPFLX_V].data[0] = + out_data[OUT_LAKE_EVAP_V][0] = lake_var.evapw; // m3 + out_data[OUT_LAKE_PREC_V][0] = lake_var.prec; // m3 + out_data[OUT_LAKE_RCHRG_V][0] = lake_var.recharge; // m3 + out_data[OUT_LAKE_RO_IN_V][0] = lake_var.runoff_in; // m3 + out_data[OUT_LAKE_VAPFLX_V][0] = lake_var.vapor_flux; // m3 - out_data[OUT_LAKE_BF_IN].data[0] = + out_data[OUT_LAKE_BF_IN][0] = lake_var.baseflow_in * MM_PER_M / soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_BF_OUT].data[0] = + out_data[OUT_LAKE_BF_OUT][0] = lake_var.baseflow_out * MM_PER_M / soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_CHAN_OUT].data[0] = + out_data[OUT_LAKE_CHAN_OUT][0] = lake_var.runoff_out * MM_PER_M / soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_EVAP].data[0] = lake_var.evapw * - MM_PER_M / - soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_RCHRG].data[0] = lake_var.recharge * - MM_PER_M / - soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_RO_IN].data[0] = lake_var.runoff_in * - MM_PER_M / - soil_con->cell_area; // mm over gridcell - out_data[OUT_LAKE_VAPFLX].data[0] = + // mm over gridcell + 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 * + MM_PER_M / + soil_con->cell_area; + // mm over gridcell + out_data[OUT_LAKE_RO_IN][0] = lake_var.runoff_in * + MM_PER_M / + soil_con->cell_area; + out_data[OUT_LAKE_VAPFLX][0] = lake_var.vapor_flux * MM_PER_M / soil_con->cell_area; // mm over gridcell } // End if options.LAKES etc. @@ -441,128 +439,104 @@ put_data(all_vars_struct *all_vars, *****************************************/ // Normalize quantities that aren't present over entire grid cell if (cv_baresoil > 0) { - out_data[OUT_BARESOILT].data[0] /= cv_baresoil; + out_data[OUT_BARESOILT][0] /= cv_baresoil; } if (cv_veg > 0) { - out_data[OUT_VEGT].data[0] /= cv_veg; + out_data[OUT_VEGT][0] /= cv_veg; } if (cv_overstory > 0) { - out_data[OUT_AERO_COND2].data[0] /= cv_overstory; + out_data[OUT_AERO_COND2][0] /= cv_overstory; } if (cv_snow > 0) { - out_data[OUT_SALBEDO].data[0] /= cv_snow; - out_data[OUT_SNOW_SURF_TEMP].data[0] /= cv_snow; - out_data[OUT_SNOW_PACK_TEMP].data[0] /= cv_snow; + out_data[OUT_SALBEDO][0] /= cv_snow; + out_data[OUT_SNOW_SURF_TEMP][0] /= cv_snow; + out_data[OUT_SNOW_PACK_TEMP][0] /= cv_snow; } // Radiative temperature - out_data[OUT_RAD_TEMP].data[0] = pow(out_data[OUT_RAD_TEMP].data[0], 0.25); + out_data[OUT_RAD_TEMP][0] = pow(out_data[OUT_RAD_TEMP][0], 0.25); // Aerodynamic conductance and resistance - if (out_data[OUT_AERO_COND1].data[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST1].data[0] = 1 / - out_data[OUT_AERO_COND1].data[0]; + if (out_data[OUT_AERO_COND1][0] > DBL_EPSILON) { + out_data[OUT_AERO_RESIST1][0] = 1 / out_data[OUT_AERO_COND1][0]; } else { - out_data[OUT_AERO_RESIST1].data[0] = param.HUGE_RESIST; + out_data[OUT_AERO_RESIST1][0] = param.HUGE_RESIST; } - if (out_data[OUT_AERO_COND2].data[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST2].data[0] = 1 / - out_data[OUT_AERO_COND2].data[0]; + if (out_data[OUT_AERO_COND2][0] > DBL_EPSILON) { + out_data[OUT_AERO_RESIST2][0] = 1 / out_data[OUT_AERO_COND2][0]; } else { - out_data[OUT_AERO_RESIST2].data[0] = param.HUGE_RESIST; + out_data[OUT_AERO_RESIST2][0] = param.HUGE_RESIST; } - if (out_data[OUT_AERO_COND].data[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST].data[0] = 1 / out_data[OUT_AERO_COND].data[0]; + if (out_data[OUT_AERO_COND][0] > DBL_EPSILON) { + out_data[OUT_AERO_RESIST][0] = 1 / out_data[OUT_AERO_COND][0]; } else { - out_data[OUT_AERO_RESIST].data[0] = param.HUGE_RESIST; + out_data[OUT_AERO_RESIST][0] = param.HUGE_RESIST; } /***************************************** Compute derived variables *****************************************/ // Water balance terms - out_data[OUT_DELSOILMOIST].data[0] = 0; + out_data[OUT_DELSOILMOIST][0] = 0; for (index = 0; index < options.Nlayer; index++) { - out_data[OUT_SOIL_MOIST].data[index] = - out_data[OUT_SOIL_LIQ].data[index] + - out_data[OUT_SOIL_ICE].data[index]; - out_data[OUT_DELSOILMOIST].data[0] += - out_data[OUT_SOIL_MOIST].data[index]; - - out_data[OUT_SMLIQFRAC].data[index] = - out_data[OUT_SOIL_LIQ].data[index] / - out_data[OUT_SOIL_MOIST].data[index]; - out_data[OUT_SMFROZFRAC].data[index] = 1 - - out_data[OUT_SMLIQFRAC].data[ - index]; - } - if (rec >= 0) { - out_data[OUT_DELSOILMOIST].data[0] -= save_data->total_soil_moist; - out_data[OUT_DELSWE].data[0] = out_data[OUT_SWE].data[0] + - out_data[OUT_SNOW_CANOPY].data[0] - - save_data->swe; - out_data[OUT_DELINTERCEPT].data[0] = out_data[OUT_WDEW].data[0] - - save_data->wdew; - out_data[OUT_DELSURFSTOR].data[0] = out_data[OUT_SURFSTOR].data[0] - - save_data->surfstor; - } + out_data[OUT_SOIL_MOIST][index] = + out_data[OUT_SOIL_LIQ][index] + + out_data[OUT_SOIL_ICE][index]; + out_data[OUT_DELSOILMOIST][0] += + out_data[OUT_SOIL_MOIST][index]; + + out_data[OUT_SMLIQFRAC][index] = out_data[OUT_SOIL_LIQ][index] / + out_data[OUT_SOIL_MOIST][index]; + out_data[OUT_SMFROZFRAC][index] = 1 - out_data[OUT_SMLIQFRAC][index]; + } + out_data[OUT_DELSOILMOIST][0] -= save_data->total_soil_moist; + out_data[OUT_DELSWE][0] = out_data[OUT_SWE][0] + + out_data[OUT_SNOW_CANOPY][0] - + save_data->swe; + out_data[OUT_DELINTERCEPT][0] = out_data[OUT_WDEW][0] - save_data->wdew; + out_data[OUT_DELSURFSTOR][0] = out_data[OUT_SURFSTOR][0] - + save_data->surfstor; // Energy terms - out_data[OUT_REFREEZE].data[0] = - (out_data[OUT_RFRZ_ENERGY].data[0] / CONST_LATICE) * dt_sec; - out_data[OUT_R_NET].data[0] = out_data[OUT_SWNET].data[0] + - out_data[OUT_LWNET].data[0]; + out_data[OUT_REFREEZE][0] = + (out_data[OUT_RFRZ_ENERGY][0] / CONST_LATICE) * dt_sec; + out_data[OUT_R_NET][0] = out_data[OUT_SWNET][0] + out_data[OUT_LWNET][0]; // Save current moisture state for use in next time step save_data->total_soil_moist = 0; for (index = 0; index < options.Nlayer; index++) { - save_data->total_soil_moist += out_data[OUT_SOIL_MOIST].data[index]; + save_data->total_soil_moist += out_data[OUT_SOIL_MOIST][index]; } - save_data->surfstor = out_data[OUT_SURFSTOR].data[0]; - save_data->swe = out_data[OUT_SWE].data[0] + - out_data[OUT_SNOW_CANOPY].data[0]; - save_data->wdew = out_data[OUT_WDEW].data[0]; + save_data->surfstor = out_data[OUT_SURFSTOR][0]; + save_data->swe = out_data[OUT_SWE][0] + out_data[OUT_SNOW_CANOPY][0]; + save_data->wdew = out_data[OUT_WDEW][0]; // Carbon Terms if (options.CARBON) { - out_data[OUT_RHET].data[0] *= dt_sec / SEC_PER_DAY; // convert to gC/m2d - out_data[OUT_NEE].data[0] = out_data[OUT_NPP].data[0] - - out_data[OUT_RHET].data[0]; + out_data[OUT_RHET][0] *= dt_sec / SEC_PER_DAY; // convert to gC/m2d + out_data[OUT_NEE][0] = out_data[OUT_NPP][0] - out_data[OUT_RHET][0]; } /******************** Check Water Balance ********************/ - inflow = out_data[OUT_PREC].data[0] + out_data[OUT_LAKE_CHAN_IN].data[0]; // mm over grid cell - outflow = out_data[OUT_EVAP].data[0] + out_data[OUT_RUNOFF].data[0] + - out_data[OUT_BASEFLOW].data[0]; // mm over grid cell + inflow = out_data[OUT_PREC][0] + out_data[OUT_LAKE_CHAN_IN][0]; // mm over grid cell + outflow = out_data[OUT_EVAP][0] + out_data[OUT_RUNOFF][0] + + out_data[OUT_BASEFLOW][0]; // mm over grid cell storage = 0.; for (index = 0; index < options.Nlayer; index++) { - if (options.MOISTFRACT) { - storage += - (out_data[OUT_SOIL_LIQ].data[index] + - out_data[OUT_SOIL_ICE].data[index]) * - depth[index] * MM_PER_M; - } - else { - storage += out_data[OUT_SOIL_LIQ].data[index] + - out_data[OUT_SOIL_ICE].data[index]; - } - } - storage += out_data[OUT_SWE].data[0] + out_data[OUT_SNOW_CANOPY].data[0] + - out_data[OUT_WDEW].data[0] + out_data[OUT_SURFSTOR].data[0]; - if (rec > 0) { - out_data[OUT_WATER_ERROR].data[0] = calc_water_balance_error(inflow, - outflow, - storage, - save_data->total_moist_storage); - } - else { - out_data[OUT_WATER_ERROR].data[0] = 0.; + storage += out_data[OUT_SOIL_LIQ][index] + + out_data[OUT_SOIL_ICE][index]; } + 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); // Store total storage for next timestep save_data->total_moist_storage = storage; @@ -571,76 +545,23 @@ put_data(all_vars_struct *all_vars, Check Energy Balance ********************/ if (options.FULL_ENERGY) { - out_data[OUT_ENERGY_ERROR].data[0] = \ - calc_energy_balance_error(out_data[OUT_SWNET].data[0] + - out_data[OUT_LWNET].data[0], - out_data[OUT_LATENT].data[0] + - out_data[OUT_LATENT_SUB].data[0], - out_data[OUT_SENSIBLE].data[0] + - out_data[OUT_ADV_SENS].data[0], - out_data[OUT_GRND_FLUX].data[0] + - out_data[OUT_DELTAH].data[0] + - out_data[OUT_FUSION].data[0], - out_data[OUT_ADVECTION].data[0] - - out_data[OUT_DELTACC].data[0] + - out_data[OUT_SNOW_FLUX].data[0] + - out_data[OUT_RFRZ_ENERGY].data[0]); - } - else { - out_data[OUT_ENERGY_ERROR].data[0] = MISSING; - } - - /****************************************************************************************** - Return to parent function if this was just an initialization of wb and eb storage terms - ******************************************************************************************/ - if (rec < 0) { - return; - } - - /******************** - Temporal Aggregation - ********************/ - for (v = 0; v < N_OUTVAR_TYPES; v++) { - if (out_data[v].aggtype == AGG_TYPE_END) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] = out_data[v].data[i]; - } - } - else if (out_data[v].aggtype == AGG_TYPE_SUM) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] += out_data[v].data[i]; - } - } - else if (out_data[v].aggtype == AGG_TYPE_AVG) { - for (i = 0; i < out_data[v].nelem; i++) { - out_data[v].aggdata[i] += out_data[v].data[i] / - (double) out_step_ratio; - } - } - } - - if (out_data[OUT_AERO_COND].aggdata[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST].aggdata[0] = - 1 / out_data[OUT_AERO_COND].aggdata[0]; - } - else { - out_data[OUT_AERO_RESIST].aggdata[0] = param.HUGE_RESIST; - } - - if (out_data[OUT_AERO_COND1].aggdata[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST1].aggdata[0] = - 1 / out_data[OUT_AERO_COND1].aggdata[0]; + out_data[OUT_ENERGY_ERROR][0] = \ + calc_energy_balance_error(out_data[OUT_SWNET][0] + + out_data[OUT_LWNET][0], + out_data[OUT_LATENT][0] + + out_data[OUT_LATENT_SUB][0], + out_data[OUT_SENSIBLE][0] + + out_data[OUT_ADV_SENS][0], + out_data[OUT_GRND_FLUX][0] + + out_data[OUT_DELTAH][0] + + out_data[OUT_FUSION][0], + out_data[OUT_ADVECTION][0] - + out_data[OUT_DELTACC][0] + + out_data[OUT_SNOW_FLUX][0] + + out_data[OUT_RFRZ_ENERGY][0]); } else { - out_data[OUT_AERO_RESIST1].aggdata[0] = param.HUGE_RESIST; - } - - if (out_data[OUT_AERO_COND2].aggdata[0] > DBL_EPSILON) { - out_data[OUT_AERO_RESIST2].aggdata[0] = - 1 / out_data[OUT_AERO_COND2].aggdata[0]; - } - else { - out_data[OUT_AERO_RESIST2].aggdata[0] = param.HUGE_RESIST; + out_data[OUT_ENERGY_ERROR][0] = MISSING; } } @@ -654,12 +575,12 @@ collect_wb_terms(cell_data_struct cell, double Cv, double AreaFract, double TreeAdjustFactor, - int HasVeg, + bool HasVeg, double lakefactor, - int overstory, + bool overstory, double *depth, double *frost_fract, - out_data_struct *out_data) + double **out_data) { extern option_struct options; extern parameters_struct param; @@ -680,62 +601,62 @@ collect_wb_terms(cell_data_struct cell, for (index = 0; index < options.Nlayer; index++) { tmp_evap += cell.layer[index].evap; if (HasVeg) { - out_data[OUT_EVAP_BARE].data[0] += cell.layer[index].evap * - cell.layer[index].bare_evap_frac - * - AreaFactor; - out_data[OUT_TRANSP_VEG].data[0] += cell.layer[index].evap * - (1 - - cell.layer[index]. - bare_evap_frac) * AreaFactor; + 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].data[0] += cell.layer[index].evap * - AreaFactor; + out_data[OUT_EVAP_BARE][0] += cell.layer[index].evap * + AreaFactor; } } tmp_evap += snow.vapor_flux * MM_PER_M; - out_data[OUT_SUB_SNOW].data[0] += snow.vapor_flux * MM_PER_M * AreaFactor; - out_data[OUT_SUB_SURFACE].data[0] += snow.surface_flux * MM_PER_M * - AreaFactor; - out_data[OUT_SUB_BLOWING].data[0] += snow.blowing_flux * MM_PER_M * - AreaFactor; + out_data[OUT_SUB_SNOW][0] += snow.vapor_flux * MM_PER_M * AreaFactor; + out_data[OUT_SUB_SURFACE][0] += snow.surface_flux * MM_PER_M * + AreaFactor; + out_data[OUT_SUB_BLOWING][0] += snow.blowing_flux * MM_PER_M * + AreaFactor; if (HasVeg) { tmp_evap += snow.canopy_vapor_flux * MM_PER_M; - out_data[OUT_SUB_CANOP].data[0] += snow.canopy_vapor_flux * MM_PER_M * - AreaFactor; + out_data[OUT_SUB_CANOP][0] += snow.canopy_vapor_flux * MM_PER_M * + AreaFactor; } if (HasVeg) { tmp_evap += veg_var.canopyevap; - out_data[OUT_EVAP_CANOP].data[0] += veg_var.canopyevap * AreaFactor; + out_data[OUT_EVAP_CANOP][0] += veg_var.canopyevap * AreaFactor; } - out_data[OUT_EVAP].data[0] += tmp_evap * AreaFactor; // mm over gridcell + out_data[OUT_EVAP][0] += tmp_evap * AreaFactor; // mm over gridcell /** record potential evap **/ - out_data[OUT_PET].data[0] += cell.pot_evap * AreaFactor; + out_data[OUT_PET][0] += cell.pot_evap * AreaFactor; /** record saturated area fraction **/ - out_data[OUT_ASAT].data[0] += cell.asat * AreaFactor; + out_data[OUT_ASAT][0] += cell.asat * AreaFactor; /** record runoff **/ - out_data[OUT_RUNOFF].data[0] += cell.runoff * AreaFactor; + out_data[OUT_RUNOFF][0] += cell.runoff * AreaFactor; /** record baseflow **/ - out_data[OUT_BASEFLOW].data[0] += cell.baseflow * AreaFactor; + out_data[OUT_BASEFLOW][0] += cell.baseflow * AreaFactor; /** record inflow **/ - out_data[OUT_INFLOW].data[0] += (cell.inflow) * AreaFactor; + out_data[OUT_INFLOW][0] += (cell.inflow) * AreaFactor; /** record canopy interception **/ if (HasVeg) { - out_data[OUT_WDEW].data[0] += veg_var.Wdew * AreaFactor; + out_data[OUT_WDEW][0] += veg_var.Wdew * AreaFactor; } /** record LAI **/ - out_data[OUT_LAI].data[0] += veg_var.LAI * AreaFactor; + out_data[OUT_LAI][0] += veg_var.LAI * AreaFactor; /** record fcanopy **/ - out_data[OUT_FCANOPY].data[0] += veg_var.fcanopy * AreaFactor; + out_data[OUT_FCANOPY][0] += veg_var.fcanopy * AreaFactor; /** record aerodynamic conductance and resistance **/ if (cell.aero_resist[0] > DBL_EPSILON) { @@ -744,7 +665,7 @@ collect_wb_terms(cell_data_struct cell, else { tmp_cond1 = param.HUGE_RESIST; } - out_data[OUT_AERO_COND1].data[0] += tmp_cond1; + out_data[OUT_AERO_COND1][0] += tmp_cond1; if (overstory) { if (cell.aero_resist[1] > DBL_EPSILON) { tmp_cond2 = (1 / cell.aero_resist[1]) * AreaFactor; @@ -752,11 +673,11 @@ collect_wb_terms(cell_data_struct cell, else { tmp_cond2 = param.HUGE_RESIST; } - out_data[OUT_AERO_COND2].data[0] += tmp_cond2; - out_data[OUT_AERO_COND].data[0] += tmp_cond2; + out_data[OUT_AERO_COND2][0] += tmp_cond2; + out_data[OUT_AERO_COND][0] += tmp_cond2; } else { - out_data[OUT_AERO_COND].data[0] += tmp_cond1; + out_data[OUT_AERO_COND][0] += tmp_cond1; } /** record layer moistures **/ @@ -768,23 +689,25 @@ collect_wb_terms(cell_data_struct cell, (cell.layer[index].ice[frost_area] * frost_fract[frost_area]); } tmp_moist -= tmp_ice; - if (options.MOISTFRACT) { - tmp_moist /= depth[index] * MM_PER_M; - tmp_ice /= depth[index] * MM_PER_M; - } - out_data[OUT_SOIL_LIQ].data[index] += tmp_moist * AreaFactor; - out_data[OUT_SOIL_ICE].data[index] += tmp_ice * AreaFactor; + + out_data[OUT_SOIL_LIQ][index] += tmp_moist * AreaFactor; + out_data[OUT_SOIL_ICE][index] += tmp_ice * AreaFactor; + + out_data[OUT_SOIL_LIQ][index] = tmp_moist * AreaFactor / depth[index] * + MM_PER_M; + out_data[OUT_SOIL_ICE][index] = tmp_ice * AreaFactor / depth[index] * + MM_PER_M; } - out_data[OUT_SOIL_WET].data[0] += cell.wetness * AreaFactor; - out_data[OUT_ROOTMOIST].data[0] += cell.rootmoist * AreaFactor; + out_data[OUT_SOIL_WET][0] += cell.wetness * AreaFactor; + out_data[OUT_ROOTMOIST][0] += cell.rootmoist * AreaFactor; /** record water table position **/ - out_data[OUT_ZWT].data[0] += cell.zwt * AreaFactor; - out_data[OUT_ZWT_LUMPED].data[0] += cell.zwt_lumped * AreaFactor; + out_data[OUT_ZWT][0] += cell.zwt * AreaFactor; + out_data[OUT_ZWT_LUMPED][0] += cell.zwt_lumped * AreaFactor; /** record layer temperatures **/ for (index = 0; index < options.Nlayer; index++) { - out_data[OUT_SOIL_TEMP].data[index] += cell.layer[index].T * AreaFactor; + out_data[OUT_SOIL_TEMP][index] += cell.layer[index].T * AreaFactor; } /***************************** @@ -792,49 +715,49 @@ collect_wb_terms(cell_data_struct cell, *****************************/ /** record snow water equivalence **/ - out_data[OUT_SWE].data[0] += snow.swq * AreaFactor * MM_PER_M; + out_data[OUT_SWE][0] += snow.swq * AreaFactor * MM_PER_M; /** record snowpack depth **/ - out_data[OUT_SNOW_DEPTH].data[0] += snow.depth * AreaFactor * CM_PER_M; + out_data[OUT_SNOW_DEPTH][0] += snow.depth * AreaFactor * CM_PER_M; /** record snowpack albedo, temperature **/ if (snow.swq > 0.0) { - out_data[OUT_SALBEDO].data[0] += snow.albedo * AreaFactor; - out_data[OUT_SNOW_SURF_TEMP].data[0] += snow.surf_temp * AreaFactor; - out_data[OUT_SNOW_PACK_TEMP].data[0] += snow.pack_temp * AreaFactor; + out_data[OUT_SALBEDO][0] += snow.albedo * AreaFactor; + out_data[OUT_SNOW_SURF_TEMP][0] += snow.surf_temp * AreaFactor; + out_data[OUT_SNOW_PACK_TEMP][0] += snow.pack_temp * AreaFactor; } /** record canopy intercepted snow **/ if (HasVeg) { - out_data[OUT_SNOW_CANOPY].data[0] += (snow.snow_canopy) * AreaFactor * - MM_PER_M; + out_data[OUT_SNOW_CANOPY][0] += (snow.snow_canopy) * AreaFactor * + MM_PER_M; } /** record snowpack melt **/ - out_data[OUT_SNOW_MELT].data[0] += snow.melt * AreaFactor; + out_data[OUT_SNOW_MELT][0] += snow.melt * AreaFactor; /** record snow cover fraction **/ - out_data[OUT_SNOW_COVER].data[0] += snow.coverage * AreaFactor; + out_data[OUT_SNOW_COVER][0] += snow.coverage * AreaFactor; /***************************** Record Carbon Cycling Variables *****************************/ if (options.CARBON) { - out_data[OUT_APAR].data[0] += veg_var.aPAR * AreaFactor; - out_data[OUT_GPP].data[0] += veg_var.GPP * CONST_MWC / MOLE_PER_KMOLE * - CONST_CDAY * - AreaFactor; - out_data[OUT_RAUT].data[0] += veg_var.Raut * CONST_MWC / - MOLE_PER_KMOLE * CONST_CDAY * - AreaFactor; - out_data[OUT_NPP].data[0] += veg_var.NPP * CONST_MWC / MOLE_PER_KMOLE * - CONST_CDAY * - AreaFactor; - out_data[OUT_LITTERFALL].data[0] += veg_var.Litterfall * AreaFactor; - out_data[OUT_RHET].data[0] += cell.RhTot * AreaFactor; - out_data[OUT_CLITTER].data[0] += cell.CLitter * AreaFactor; - out_data[OUT_CINTER].data[0] += cell.CInter * AreaFactor; - out_data[OUT_CSLOW].data[0] += cell.CSlow * AreaFactor; + out_data[OUT_APAR][0] += veg_var.aPAR * AreaFactor; + out_data[OUT_GPP][0] += veg_var.GPP * CONST_MWC / MOLE_PER_KMOLE * + CONST_CDAY * + AreaFactor; + out_data[OUT_RAUT][0] += veg_var.Raut * CONST_MWC / + MOLE_PER_KMOLE * CONST_CDAY * + AreaFactor; + out_data[OUT_NPP][0] += veg_var.NPP * CONST_MWC / MOLE_PER_KMOLE * + CONST_CDAY * + AreaFactor; + out_data[OUT_LITTERFALL][0] += veg_var.Litterfall * AreaFactor; + out_data[OUT_RHET][0] += cell.RhTot * AreaFactor; + out_data[OUT_CLITTER][0] += cell.CLitter * AreaFactor; + out_data[OUT_CINTER][0] += cell.CInter * AreaFactor; + out_data[OUT_CSLOW][0] += cell.CSlow * AreaFactor; } } @@ -848,14 +771,14 @@ collect_eb_terms(energy_bal_struct energy, double Cv, double AreaFract, double TreeAdjustFactor, - int HasVeg, - int IsWet, + bool HasVeg, + bool IsWet, double lakefactor, - int overstory, + bool overstory, int band, double *frost_fract, double frost_slope, - out_data_struct *out_data) + double **out_data) { extern option_struct options; double AreaFactor; @@ -875,12 +798,12 @@ collect_eb_terms(energy_bal_struct energy, if (options.FROZEN_SOIL) { for (index = 0; index < MAX_FRONTS; index++) { if (energy.fdepth[index] != MISSING) { - out_data[OUT_FDEPTH].data[index] += energy.fdepth[index] * - AreaFactor * CM_PER_M; + out_data[OUT_FDEPTH][index] += energy.fdepth[index] * + AreaFactor * CM_PER_M; } if (energy.tdepth[index] != MISSING) { - out_data[OUT_TDEPTH].data[index] += energy.tdepth[index] * - AreaFactor * CM_PER_M; + out_data[OUT_TDEPTH][index] += energy.tdepth[index] * + AreaFactor * CM_PER_M; } } } @@ -891,7 +814,7 @@ collect_eb_terms(energy_bal_struct energy, tmp_fract += frost_fract[frost_area]; } } - out_data[OUT_SURF_FROST_FRAC].data[0] += tmp_fract * AreaFactor; + out_data[OUT_SURF_FROST_FRAC][0] += tmp_fract * AreaFactor; tmp_fract = 0; if ((energy.T[0] + frost_slope / 2.) > 0) { @@ -924,113 +847,113 @@ collect_eb_terms(energy_bal_struct energy, /** record landcover temperature **/ if (!HasVeg) { // landcover is bare soil - out_data[OUT_BARESOILT].data[0] += + out_data[OUT_BARESOILT][0] += (rad_temp - CONST_TKFRZ) * AreaFactor; } else { // landcover is vegetation if (overstory && !snow.snow) { // here, rad_temp will be wrong since it will pick the understory temperature - out_data[OUT_VEGT].data[0] += energy.Tfoliage * AreaFactor; + out_data[OUT_VEGT][0] += energy.Tfoliage * AreaFactor; } else { - out_data[OUT_VEGT].data[0] += (rad_temp - CONST_TKFRZ) * AreaFactor; + out_data[OUT_VEGT][0] += (rad_temp - CONST_TKFRZ) * AreaFactor; } } /** record mean surface temperature [C] **/ - out_data[OUT_SURF_TEMP].data[0] += surf_temp * AreaFactor; + out_data[OUT_SURF_TEMP][0] += surf_temp * AreaFactor; /** record thermal node temperatures **/ for (index = 0; index < options.Nnode; index++) { - out_data[OUT_SOIL_TNODE].data[index] += energy.T[index] * AreaFactor; + out_data[OUT_SOIL_TNODE][index] += energy.T[index] * AreaFactor; } if (IsWet) { for (index = 0; index < options.Nnode; index++) { - out_data[OUT_SOIL_TNODE_WL].data[index] = energy.T[index]; + out_data[OUT_SOIL_TNODE_WL][index] = energy.T[index]; } } /** record temperature flags **/ - out_data[OUT_SURFT_FBFLAG].data[0] += energy.Tsurf_fbflag * AreaFactor; + out_data[OUT_SURFT_FBFLAG][0] += energy.Tsurf_fbflag * AreaFactor; for (index = 0; index < options.Nnode; index++) { - out_data[OUT_SOILT_FBFLAG].data[index] += energy.T_fbflag[index] * - AreaFactor; + out_data[OUT_SOILT_FBFLAG][index] += energy.T_fbflag[index] * + AreaFactor; } - out_data[OUT_SNOWT_FBFLAG].data[0] += snow.surf_temp_fbflag * AreaFactor; - out_data[OUT_TFOL_FBFLAG].data[0] += energy.Tfoliage_fbflag * AreaFactor; - out_data[OUT_TCAN_FBFLAG].data[0] += energy.Tcanopy_fbflag * AreaFactor; + out_data[OUT_SNOWT_FBFLAG][0] += snow.surf_temp_fbflag * AreaFactor; + out_data[OUT_TFOL_FBFLAG][0] += energy.Tfoliage_fbflag * AreaFactor; + out_data[OUT_TCAN_FBFLAG][0] += energy.Tcanopy_fbflag * AreaFactor; /** record net shortwave radiation **/ - out_data[OUT_SWNET].data[0] += energy.NetShortAtmos * AreaFactor; + out_data[OUT_SWNET][0] += energy.NetShortAtmos * AreaFactor; /** record net longwave radiation **/ - out_data[OUT_LWNET].data[0] += energy.NetLongAtmos * AreaFactor; + out_data[OUT_LWNET][0] += energy.NetLongAtmos * AreaFactor; /** record incoming longwave radiation at ground surface (under veg) **/ if (snow.snow && overstory) { - out_data[OUT_IN_LONG].data[0] += energy.LongOverIn * AreaFactor; + out_data[OUT_IN_LONG][0] += energy.LongOverIn * AreaFactor; } else { - out_data[OUT_IN_LONG].data[0] += energy.LongUnderIn * AreaFactor; + out_data[OUT_IN_LONG][0] += energy.LongUnderIn * AreaFactor; } /** record albedo **/ if (snow.snow && overstory) { - out_data[OUT_ALBEDO].data[0] += energy.AlbedoOver * AreaFactor; + out_data[OUT_ALBEDO][0] += energy.AlbedoOver * AreaFactor; } else { - out_data[OUT_ALBEDO].data[0] += energy.AlbedoUnder * AreaFactor; + out_data[OUT_ALBEDO][0] += energy.AlbedoUnder * AreaFactor; } /** record latent heat flux **/ - out_data[OUT_LATENT].data[0] -= energy.AtmosLatent * AreaFactor; + out_data[OUT_LATENT][0] -= energy.AtmosLatent * AreaFactor; /** record latent heat flux from sublimation **/ - out_data[OUT_LATENT_SUB].data[0] -= energy.AtmosLatentSub * AreaFactor; + out_data[OUT_LATENT_SUB][0] -= energy.AtmosLatentSub * AreaFactor; /** record sensible heat flux **/ - out_data[OUT_SENSIBLE].data[0] -= energy.AtmosSensible * AreaFactor; + out_data[OUT_SENSIBLE][0] -= energy.AtmosSensible * AreaFactor; /** record ground heat flux (+ heat storage) **/ - out_data[OUT_GRND_FLUX].data[0] -= energy.grnd_flux * AreaFactor; + out_data[OUT_GRND_FLUX][0] -= energy.grnd_flux * AreaFactor; /** record heat storage **/ - out_data[OUT_DELTAH].data[0] -= energy.deltaH * AreaFactor; + out_data[OUT_DELTAH][0] -= energy.deltaH * AreaFactor; /** record heat of fusion **/ - out_data[OUT_FUSION].data[0] -= energy.fusion * AreaFactor; + out_data[OUT_FUSION][0] -= energy.fusion * AreaFactor; /** record radiative effective temperature [K], emissivities set = 1.0 **/ - out_data[OUT_RAD_TEMP].data[0] += + out_data[OUT_RAD_TEMP][0] += ((rad_temp) * (rad_temp) * (rad_temp) * (rad_temp)) * AreaFactor; /** record snowpack cold content **/ - out_data[OUT_DELTACC].data[0] += energy.deltaCC * AreaFactor; + out_data[OUT_DELTACC][0] += energy.deltaCC * AreaFactor; /** record snowpack advection **/ if (snow.snow && overstory) { - out_data[OUT_ADVECTION].data[0] += energy.canopy_advection * AreaFactor; + out_data[OUT_ADVECTION][0] += energy.canopy_advection * AreaFactor; } - out_data[OUT_ADVECTION].data[0] += energy.advection * AreaFactor; + out_data[OUT_ADVECTION][0] += energy.advection * AreaFactor; /** record snow energy flux **/ - out_data[OUT_SNOW_FLUX].data[0] += energy.snow_flux * AreaFactor; + out_data[OUT_SNOW_FLUX][0] += energy.snow_flux * AreaFactor; /** record refreeze energy **/ if (snow.snow && overstory) { - out_data[OUT_RFRZ_ENERGY].data[0] += energy.canopy_refreeze * - AreaFactor; + out_data[OUT_RFRZ_ENERGY][0] += energy.canopy_refreeze * + AreaFactor; } - out_data[OUT_RFRZ_ENERGY].data[0] += energy.refreeze_energy * AreaFactor; + out_data[OUT_RFRZ_ENERGY][0] += energy.refreeze_energy * AreaFactor; /** record melt energy **/ - out_data[OUT_MELT_ENERGY].data[0] += energy.melt_energy * AreaFactor; + out_data[OUT_MELT_ENERGY][0] += energy.melt_energy * AreaFactor; /** record advected sensible heat energy **/ if (!overstory) { - out_data[OUT_ADV_SENS].data[0] -= energy.advected_sensible * AreaFactor; + out_data[OUT_ADV_SENS][0] -= energy.advected_sensible * AreaFactor; } /********************************** @@ -1038,86 +961,106 @@ collect_eb_terms(energy_bal_struct energy, **********************************/ /** record band snow water equivalent **/ - out_data[OUT_SWE_BAND].data[band] += snow.swq * Cv * lakefactor * MM_PER_M; + out_data[OUT_SWE_BAND][band] += snow.swq * Cv * lakefactor * MM_PER_M; /** record band snowpack depth **/ - out_data[OUT_SNOW_DEPTH_BAND].data[band] += snow.depth * Cv * lakefactor * - CM_PER_M; + out_data[OUT_SNOW_DEPTH_BAND][band] += snow.depth * Cv * lakefactor * + CM_PER_M; /** record band canopy intercepted snow **/ if (HasVeg) { - out_data[OUT_SNOW_CANOPY_BAND].data[band] += (snow.snow_canopy) * Cv * - lakefactor * MM_PER_M; + out_data[OUT_SNOW_CANOPY_BAND][band] += (snow.snow_canopy) * Cv * + lakefactor * MM_PER_M; } /** record band snow melt **/ - out_data[OUT_SNOW_MELT_BAND].data[band] += snow.melt * Cv * lakefactor; + out_data[OUT_SNOW_MELT_BAND][band] += snow.melt * Cv * lakefactor; /** record band snow coverage **/ - out_data[OUT_SNOW_COVER_BAND].data[band] += snow.coverage * Cv * lakefactor; + out_data[OUT_SNOW_COVER_BAND][band] += snow.coverage * Cv * lakefactor; /** record band cold content **/ - out_data[OUT_DELTACC_BAND].data[band] += energy.deltaCC * Cv * lakefactor; + out_data[OUT_DELTACC_BAND][band] += energy.deltaCC * Cv * lakefactor; /** record band advection **/ - out_data[OUT_ADVECTION_BAND].data[band] += energy.advection * Cv * - lakefactor; + out_data[OUT_ADVECTION_BAND][band] += energy.advection * Cv * + lakefactor; /** record band snow flux **/ - out_data[OUT_SNOW_FLUX_BAND].data[band] += energy.snow_flux * Cv * - lakefactor; + out_data[OUT_SNOW_FLUX_BAND][band] += energy.snow_flux * Cv * + lakefactor; /** record band refreeze energy **/ - out_data[OUT_RFRZ_ENERGY_BAND].data[band] += energy.refreeze_energy * Cv * - lakefactor; + out_data[OUT_RFRZ_ENERGY_BAND][band] += energy.refreeze_energy * Cv * + lakefactor; /** record band melt energy **/ - out_data[OUT_MELT_ENERGY_BAND].data[band] += energy.melt_energy * Cv * - lakefactor; + out_data[OUT_MELT_ENERGY_BAND][band] += energy.melt_energy * Cv * + lakefactor; /** record band advected sensble heat **/ - out_data[OUT_ADV_SENS_BAND].data[band] -= energy.advected_sensible * Cv * - lakefactor; + out_data[OUT_ADV_SENS_BAND][band] -= energy.advected_sensible * Cv * + lakefactor; /** record surface layer temperature **/ - out_data[OUT_SNOW_SURFT_BAND].data[band] += snow.surf_temp * Cv * - lakefactor; + out_data[OUT_SNOW_SURFT_BAND][band] += snow.surf_temp * Cv * + lakefactor; /** record pack layer temperature **/ - out_data[OUT_SNOW_PACKT_BAND].data[band] += snow.pack_temp * Cv * - lakefactor; + out_data[OUT_SNOW_PACKT_BAND][band] += snow.pack_temp * Cv * + lakefactor; /** record latent heat of sublimation **/ - out_data[OUT_LATENT_SUB_BAND].data[band] += energy.latent_sub * Cv * - lakefactor; + out_data[OUT_LATENT_SUB_BAND][band] += energy.latent_sub * Cv * + lakefactor; /** record band net downwards shortwave radiation **/ - out_data[OUT_SWNET_BAND].data[band] += energy.NetShortAtmos * Cv * - lakefactor; + out_data[OUT_SWNET_BAND][band] += energy.NetShortAtmos * Cv * + lakefactor; /** record band net downwards longwave radiation **/ - out_data[OUT_LWNET_BAND].data[band] += energy.NetLongAtmos * Cv * - lakefactor; + out_data[OUT_LWNET_BAND][band] += energy.NetLongAtmos * Cv * + lakefactor; /** record band albedo **/ if (snow.snow && overstory) { - out_data[OUT_ALBEDO_BAND].data[band] += energy.AlbedoOver * Cv * - lakefactor; + out_data[OUT_ALBEDO_BAND][band] += energy.AlbedoOver * Cv * + lakefactor; } else { - out_data[OUT_ALBEDO_BAND].data[band] += energy.AlbedoUnder * Cv * - lakefactor; + out_data[OUT_ALBEDO_BAND][band] += energy.AlbedoUnder * Cv * + lakefactor; } /** record band net latent heat flux **/ - out_data[OUT_LATENT_BAND].data[band] -= energy.latent * Cv * lakefactor; + out_data[OUT_LATENT_BAND][band] -= energy.latent * Cv * lakefactor; /** record band net sensible heat flux **/ - out_data[OUT_SENSIBLE_BAND].data[band] -= energy.sensible * Cv * lakefactor; + out_data[OUT_SENSIBLE_BAND][band] -= energy.sensible * Cv * lakefactor; /** record band net ground heat flux **/ - out_data[OUT_GRND_FLUX_BAND].data[band] -= energy.grnd_flux * Cv * - lakefactor; + out_data[OUT_GRND_FLUX_BAND][band] -= energy.grnd_flux * Cv * + lakefactor; +} + +/****************************************************************************** + * @brief Initialize the save data structure. + *****************************************************************************/ +void +initialize_save_data(all_vars_struct *all_vars, + atmos_data_struct *atmos, + soil_con_struct *soil_con, + veg_con_struct *veg_con, + veg_lib_struct *veg_lib, + lake_con_struct *lake_con, + double **out_data, + save_data_struct *save_data) +{ + // Calling put data will populate the save data storage terms + put_data(all_vars, atmos, soil_con, veg_con, veg_lib, lake_con, + out_data, save_data); + + zero_output_list(out_data); } /****************************************************************************** @@ -1153,34 +1096,3 @@ calc_energy_balance_error(double net_rad, return(error); } - -/****************************************************************************** - * @brief This subroutine checks if it is time to write an output file - *****************************************************************************/ -bool -check_write_flag(int rec) -{ - extern global_param_struct global_param; - - static unsigned int out_step_ratio; - static unsigned int step_count; - - - if (rec == 0) { - step_count = 0; - out_step_ratio = - (unsigned int) ((int) global_param.out_dt / (int) global_param.dt); - } - - if (rec >= 0) { - step_count++; - } - - // Output procedure (only execute when we've completed an output interval) - if (step_count == out_step_ratio) { - step_count = 0; - return true; - } - - return false; -} diff --git a/vic/drivers/shared_all/src/set_output_defaults.c b/vic/drivers/shared_all/src/set_output_defaults.c new file mode 100644 index 000000000..82c4769af --- /dev/null +++ b/vic/drivers/shared_all/src/set_output_defaults.c @@ -0,0 +1,294 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Set the output_stream and out_data structures to default values. These can + * be overridden by the user in the global control file. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Set the output_stream and out_data structures to default values. + These can be overridden by the user in the global control file. + *****************************************************************************/ +void +get_default_nstreams_nvars(size_t *nstreams, + size_t nvars[]) +{ + extern option_struct options; + + size_t streamnum; + + // Output files + (*nstreams) = 2; + if (options.FROZEN_SOIL) { + (*nstreams)++; + } + if (options.SNOW_BAND) { + (*nstreams)++; + } + if (options.LAKES) { + (*nstreams)++; + } + + streamnum = 0; + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + nvars[streamnum] = 26; + } + else { + nvars[streamnum] = 20; + } + + streamnum++; + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + nvars[streamnum] = 14; + } + else { + nvars[streamnum] = 4; + } + if (options.BLOWING) { + nvars += 3; + } + + if (options.FROZEN_SOIL) { + streamnum++; + nvars[streamnum] = 4; + } + if (options.SNOW_BAND) { + streamnum++; + if (options.FULL_ENERGY) { + nvars[streamnum] = 13; + } + else { + nvars[streamnum] = 9; + } + } + if (options.LAKES) { + streamnum++; + nvars[streamnum] = 8; + } +} + +/****************************************************************************** + * @brief Set the output_stream and out_data structures to default values. + These can be overridden by the user in the global control file. + *****************************************************************************/ +void +set_output_defaults(stream_struct **streams, + dmy_struct *dmy_current, + unsigned short default_file_format) +{ + extern option_struct options; + + size_t streamnum; + size_t varnum; + alarm_struct default_alarm; + int default_freq_n = 1; + + + set_alarm(dmy_current, FREQ_NDAYS, &default_freq_n, &default_alarm); + + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + (*streams)[streamnum].agg_alarm = default_alarm; + (*streams)[streamnum].file_format = default_file_format; + } + + // Variables in first file + streamnum = 0; + varnum = 0; + strcpy((*streams)[streamnum].prefix, "fluxes"); + set_output_var(&((*streams)[streamnum]), "OUT_PREC", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_EVAP", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_RUNOFF", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_BASEFLOW", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_WDEW", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SOIL_LIQ", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + set_output_var(&((*streams)[streamnum]), "OUT_RAD_TEMP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + set_output_var(&((*streams)[streamnum]), "OUT_SWNET", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_R_NET", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + set_output_var(&((*streams)[streamnum]), "OUT_LATENT", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + set_output_var(&((*streams)[streamnum]), "OUT_EVAP_CANOP", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_TRANSP_VEG", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_EVAP_BARE", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SUB_CANOP", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SUB_SNOW", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + set_output_var(&((*streams)[streamnum]), "OUT_SENSIBLE", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_GRND_FLUX", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_DELTAH", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_FUSION", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + set_output_var(&((*streams)[streamnum]), "OUT_AERO_RESIST", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SURF_TEMP", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_ALBEDO", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_REL_HUMID", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_IN_LONG", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_AIR_TEMP", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_WIND", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + + // Variables in second file + streamnum++; + varnum = 0; + strcpy((*streams)[streamnum].prefix, "snow"); + set_output_var(&((*streams)[streamnum]), "OUT_SWE", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_DEPTH", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_CANOPY", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_COVER", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + if (options.FULL_ENERGY || options.FROZEN_SOIL) { + set_output_var(&((*streams)[streamnum]), "OUT_ADVECTION", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_DELTACC", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_FLUX", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_RFRZ_ENERGY", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_MELT_ENERGY", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_ADV_SENS", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LATENT_SUB", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_SURF_TEMP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_PACK_TEMP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_MELT", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + if (options.BLOWING) { + set_output_var(&((*streams)[streamnum]), "OUT_SUB_BLOWING", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SUB_SURFACE", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SUB_SNOW", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + + // Variables in other files + if (options.FROZEN_SOIL) { + streamnum++; + varnum = 0; + strcpy((*streams)[streamnum].prefix, "fdepth"); + set_output_var(&((*streams)[streamnum]), "OUT_FDEPTH", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_TDEPTH", varnum++, "%.4f", + OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SOIL_MOIST", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SURF_FROST_FRAC", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + if (options.SNOW_BAND) { + streamnum++; + varnum = 0; + strcpy((*streams)[streamnum].prefix, "snowband"); + set_output_var(&((*streams)[streamnum]), "OUT_SWE_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_DEPTH_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_CANOPY_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + if (options.FULL_ENERGY) { + set_output_var(&((*streams)[streamnum]), "OUT_ADVECTION_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, + AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_DELTACC_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, + AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SNOW_FLUX_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, + AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_RFRZ_ENERGY_BAND", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, + AGG_TYPE_DEFAULT); + } + set_output_var(&((*streams)[streamnum]), "OUT_SWNET_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LWNET_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_ALBEDO_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LATENT_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_SENSIBLE_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_GRND_FLUX_BAND", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } + if (options.LAKES) { + streamnum++; + varnum = 0; + strcpy((*streams)[streamnum].prefix, "lake"); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_ICE_TEMP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_ICE_HEIGHT", + varnum++, "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_ICE_FRACT", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_DEPTH", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_SURF_AREA", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_VOLUME", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_SURF_TEMP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + set_output_var(&((*streams)[streamnum]), "OUT_LAKE_EVAP", varnum++, + "%.4f", OUT_TYPE_FLOAT, 1, AGG_TYPE_DEFAULT); + } +} diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c new file mode 100644 index 000000000..aa20c9e7e --- /dev/null +++ b/vic/drivers/shared_all/src/vic_history.c @@ -0,0 +1,475 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This routine contains routines for computing and saving VIC history files. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief This routine creates the list of output data. + *****************************************************************************/ +void +alloc_out_data(size_t ngridcells, + double ****out_data) +{ + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t i; + size_t j; + size_t k; + + *out_data = calloc(ngridcells, sizeof(*(*out_data))); + if ((*out_data) == NULL) { + log_err("Memory allocation error."); + } + + for (i = 0; i < ngridcells; i++) { + (*out_data)[i] = calloc(N_OUTVAR_TYPES, sizeof(*((*out_data)[i]))); + if ((*out_data)[i] == NULL) { + log_err("Memory allocation error."); + } + // Allocate space for data + for (j = 0; j < N_OUTVAR_TYPES; j++) { + (*out_data)[i][j] = + calloc(out_metadata[j].nelem, sizeof(*((*out_data)[i][j]))); + if ((*out_data)[i][j] == NULL) { + log_err("Memory allocation error."); + } + // initialize data member + for (k = 0; k < out_metadata[j].nelem; k++) { + (*out_data)[i][j][k] = 0; + } + } + } +} + +/****************************************************************************** + * @brief This routine creates the list of output streams. + *****************************************************************************/ +void +setup_stream(stream_struct *stream, + size_t nvars, + size_t ngridcells) +{ + size_t i; + int default_n = 1; + dmy_struct dmy_junk; + + // Set stream scalars + stream->nvars = nvars; + stream->ngridcells = ngridcells; + stream->file_format = UNSET_FILE_FORMAT; + stream->compress = false; + + // Set default agg alarm + set_alarm(&dmy_junk, FREQ_NDAYS, &default_n, &(stream->agg_alarm)); + + // Set default write alarm + set_alarm(&dmy_junk, FREQ_END, &default_n, &(stream->write_alarm)); + + // Allocate stream members of shape [nvars] + stream->varid = calloc(nvars, sizeof(*(stream->varid))); + if (stream->varid == NULL) { + log_err("Memory allocation error."); + } + stream->aggtype = calloc(nvars, sizeof(*(stream->aggtype))); + if (stream->aggtype == NULL) { + log_err("Memory allocation error."); + } + stream->type = calloc(nvars, sizeof(*(stream->type))); + if (stream->type == NULL) { + log_err("Memory allocation error."); + } + stream->mult = calloc(nvars, sizeof(*(stream->mult))); + if (stream->mult == NULL) { + log_err("Memory allocation error."); + } + // Question: do we have to dynamically allocate the length of each string + stream->format = calloc(nvars, sizeof(*(stream->format))); + if (stream->format == NULL) { + log_err("Memory allocation error."); + } + for (i = 0; i < nvars; i++) { + stream->format[i] = calloc(MAXSTRING, sizeof(*(stream->format[i]))); + if (stream->format[i] == NULL) { + log_err("Memory allocation error."); + } + } + // Initialize some of the stream members + // these will be overwritten in set_output_var + for (i = 0; i < nvars; i++) { + stream->type[i] = OUT_TYPE_DEFAULT; + stream->mult[i] = OUT_MULT_DEFAULT; + stream->aggtype[i] = AGG_TYPE_DEFAULT; + } +} + +/****************************************************************************** + * @brief This routine validates the streams. + *****************************************************************************/ +void +validate_streams(stream_struct **streams) +{ + extern option_struct options; + + size_t streamnum; + + // validate stream settings + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + if ((*streams)[streamnum].ngridcells < 1) { + log_err("Number of gridcells in stream is less than 1"); + } + if ((*streams)[streamnum].nvars < 1) { + log_err("Number of variables in stream is less than 1"); + } + if (strcasecmp("", ((*streams)[streamnum].prefix)) == 0) { + log_err("Stream prefix not set"); + } + if ((*streams)[streamnum].file_format == UNSET_FILE_FORMAT) { + log_err("Stream file_format not set"); + } + if ((*streams)[streamnum].type == NULL) { + log_err("Stream type array not allocated"); + } + if ((*streams)[streamnum].mult == NULL) { + log_err("Stream mult array not allocated"); + } + if ((*streams)[streamnum].varid == NULL) { + log_err("Stream varid array not allocated"); + } + if ((*streams)[streamnum].aggtype == NULL) { + log_err("Stream aggtype array not allocated"); + } + if ((*streams)[streamnum].aggdata == NULL) { + log_err("Stream agg_data array not allocated"); + } + } +} + +/****************************************************************************** + * @brief This routine allocates memory for the stream aggdata array. The + shape of this array is [ngridcells, nvars, nelems, nbins]. + *****************************************************************************/ +void +alloc_aggdata(stream_struct *stream) +{ + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t i; + size_t j; + size_t k; + size_t nelem; + + stream->aggdata = calloc(stream->ngridcells, sizeof(*(stream->aggdata))); + if (stream->aggdata == NULL) { + log_err("Memory allocation error."); + } + for (i = 0; i < stream->ngridcells; i++) { + stream->aggdata[i] = + calloc(stream->nvars, sizeof(*(stream->aggdata[i]))); + if (stream->aggdata[i] == NULL) { + log_err("Memory allocation error."); + } + for (j = 0; j < stream->nvars; j++) { + nelem = out_metadata[stream->varid[j]].nelem; + stream->aggdata[i][j] = + calloc(nelem, sizeof(*(stream->aggdata[i][j]))); + if (stream->aggdata[i][j] == NULL) { + log_err("Memory allocation error."); + } + for (k = 0; k < nelem; k++) { + // TODO: Also allocate for nbins, for now just setting to size 1 + stream->aggdata[i][j][k] = + calloc(1, sizeof(*(stream->aggdata[i][j][k]))); + if (stream->aggdata[i][j][k] == NULL) { + log_err("Memory allocation error."); + } + } + } + } +} + +/****************************************************************************** + * @brief This routine resets an output stream + *****************************************************************************/ +void +reset_stream(stream_struct *stream, + dmy_struct *dmy_current) +{ + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t i; + size_t j; + size_t k; + size_t varid; + + // Reset alarm to next agg period + reset_alarm(&(stream->agg_alarm), + dmy_current); + + // Set aggdata to zero + for (i = 0; i < stream->ngridcells; i++) { + for (j = 0; j < stream->nvars; j++) { + varid = stream->varid[j]; + for (k = 0; k < out_metadata[varid].nelem; k++) { + stream->aggdata[i][j][k][0] = 0.; + } + } + } +} + +/****************************************************************************** + * @brief This routine sets the default aggregation type for variables in an + output stream + *****************************************************************************/ +unsigned int +get_default_outvar_aggtype(unsigned int varid) +{ + unsigned int agg_type; + + switch (varid) { + // AGG_TYPE_END + case OUT_DISCHARGE: + case OUT_ASAT: + case OUT_LAKE_AREA_FRAC: + case OUT_LAKE_DEPTH: + case OUT_LAKE_ICE: + case OUT_LAKE_ICE_FRACT: + case OUT_LAKE_ICE_HEIGHT: + case OUT_LAKE_MOIST: + case OUT_LAKE_SURF_AREA: + case OUT_LAKE_SWE: + case OUT_LAKE_SWE_V: + case OUT_LAKE_VOLUME: + case OUT_ROOTMOIST: + case OUT_SMFROZFRAC: + case OUT_SMLIQFRAC: + case OUT_SNOW_CANOPY: + case OUT_SNOW_COVER: + case OUT_SNOW_DEPTH: + case OUT_SOIL_ICE: + case OUT_SOIL_LIQ: + case OUT_SOIL_MOIST: + case OUT_SOIL_WET: + case OUT_SURFSTOR: + case OUT_SURF_FROST_FRAC: + case OUT_SWE: + case OUT_WDEW: + case OUT_ZWT: + case OUT_ZWT_LUMPED: + case OUT_SNOW_CANOPY_BAND: + case OUT_SNOW_COVER_BAND: + case OUT_SNOW_DEPTH_BAND: + case OUT_SWE_BAND: + agg_type = AGG_TYPE_END; + break; + // AGG_TYPE_SUM + case OUT_BASEFLOW: + case OUT_DELINTERCEPT: + case OUT_DELSOILMOIST: + case OUT_DELSWE: + case OUT_DELSURFSTOR: + case OUT_EVAP: + case OUT_EVAP_BARE: + case OUT_EVAP_CANOP: + case OUT_INFLOW: + case OUT_LAKE_BF_IN: + case OUT_LAKE_BF_IN_V: + case OUT_LAKE_BF_OUT: + case OUT_LAKE_BF_OUT_V: + case OUT_LAKE_CHAN_IN: + case OUT_LAKE_CHAN_IN_V: + case OUT_LAKE_CHAN_OUT: + case OUT_LAKE_CHAN_OUT_V: + case OUT_LAKE_DSTOR: + case OUT_LAKE_DSTOR_V: + case OUT_LAKE_DSWE: + case OUT_LAKE_DSWE_V: + case OUT_LAKE_EVAP: + case OUT_LAKE_EVAP_V: + case OUT_LAKE_PREC_V: + case OUT_LAKE_RCHRG: + case OUT_LAKE_RCHRG_V: + case OUT_LAKE_RO_IN: + case OUT_LAKE_RO_IN_V: + case OUT_LAKE_VAPFLX: + case OUT_LAKE_VAPFLX_V: + case OUT_PET: + case OUT_PREC: + case OUT_RAINF: + case OUT_REFREEZE: + case OUT_RUNOFF: + case OUT_SNOWF: + case OUT_SUB_BLOWING: + case OUT_SUB_CANOP: + case OUT_SUB_SNOW: + case OUT_SUB_SURFACE: + case OUT_TRANSP_VEG: + case OUT_DELTACC_BAND: + case OUT_SNOW_MELT: + case OUT_SNOWT_FBFLAG: + case OUT_SOILT_FBFLAG: + case OUT_SURFT_FBFLAG: + case OUT_TCAN_FBFLAG: + case OUT_TFOL_FBFLAG: + agg_type = AGG_TYPE_SUM; + break; + default: + agg_type = AGG_TYPE_AVG; + } + return agg_type; +} + +/****************************************************************************** + * @brief This routine updates the output information for a given output + * variable. + *****************************************************************************/ +void +set_output_var(stream_struct *stream, + char *varname, + size_t varnum, + char *format, + unsigned short int type, + double mult, + unsigned short int aggtype) +{ + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + int varid; + int found = false; + + if (varnum >= stream->nvars) { + log_err("Invalid varnum %zu, must be less than the number of variables " + "in the stream %zu", varnum, stream->nvars); + } + // Find the output varid by looping through out_metadata, comparing to varname + for (varid = 0; varid < N_OUTVAR_TYPES; varid++) { + if (strcmp(out_metadata[varid].varname, varname) == 0) { + found = true; + break; + } + } + if (!found) { + log_err("set_output_var: \"%s\" was not found in the list of " + "supported output variable names. Please use the exact name " + "listed in vic_driver_shared.h.", varname); + } + // Set stream members + stream->varid[varnum] = varid; + // Format (ASCII only) + if ((strcmp(format, "*") != 0) || (strcmp(format, "") != 0)) { + strcpy(stream->format[varnum], format); + } + else { + strcpy(stream->format[varnum], "%.4f"); + } + // Output type (BINARY and netCDF) + if (type != OUT_TYPE_DEFAULT) { + stream->type[varnum] = type; + } + else { + stream->type[varnum] = OUT_TYPE_FLOAT; + } + // Mult (BINARY and netCDF) + if (mult != OUT_MULT_DEFAULT) { + stream->mult[varnum] = mult; + } + else { + stream->mult[varnum] = 1.; + } + // Aggregation type + if (aggtype != AGG_TYPE_DEFAULT) { + stream->aggtype[varnum] = aggtype; + } + else { + stream->aggtype[varnum] = get_default_outvar_aggtype(varid); + } +} + +/****************************************************************************** + * @brief This routine frees the memory in the streams array. + *****************************************************************************/ +void +free_streams(stream_struct **streams) +{ + extern option_struct options; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t streamnum; + size_t i; + size_t j; + size_t k; + size_t varid; + + // free output streams + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + // Free aggdata first + for (i = 0; i < (*streams)[streamnum].ngridcells; i++) { + for (j = 0; j < (*streams)[streamnum].nvars; j++) { + varid = (*streams)[streamnum].varid[j]; + for (k = 0; k < out_metadata[varid].nelem; k++) { + free((*streams)[streamnum].aggdata[i][j][k]); + } + free((*streams)[streamnum].aggdata[i][j]); + } + free((*streams)[streamnum].aggdata[i]); + } + for (j = 0; j < (*streams)[streamnum].nvars; j++) { + free((*streams)[streamnum].format[j]); + } + free((*streams)[streamnum].aggdata); + // free remaining arrays + free((*streams)[streamnum].type); + free((*streams)[streamnum].mult); + free((*streams)[streamnum].format); + free((*streams)[streamnum].varid); + free((*streams)[streamnum].aggtype); + } + free(*streams); +} + +/****************************************************************************** + * @brief This routine frees the memory in the out_data array. + *****************************************************************************/ +void +free_out_data(size_t ngridcells, + double ***out_data) +{ + size_t i; + size_t j; + + + if (out_data == NULL) { + return; + } + + for (i = 0; i < ngridcells; i++) { + for (j = 0; j < N_OUTVAR_TYPES; j++) { + free(out_data[i][j]); + } + free(out_data[i]); + } + + free(out_data); +} diff --git a/vic/drivers/shared_all/src/vic_time.c b/vic/drivers/shared_all/src/vic_time.c index ac9620dd5..bc616b7e0 100644 --- a/vic/drivers/shared_all/src/vic_time.c +++ b/vic/drivers/shared_all/src/vic_time.c @@ -697,6 +697,8 @@ initialize_time() // See make_dmy.c for more details on how global_param.time_origin_num is used. global_param.time_origin_num = date2num(0., &dmy, 0., global_param.calendar, TIME_UNITS_DAYS); + // Set the string representation of time_origin_num + strcpy(global_param.time_origin_str, "0001-01-01 00:00:00"); return; } @@ -773,70 +775,6 @@ dt_seconds_to_time_units(unsigned short int time_units, } } -/****************************************************************************** - * @brief Parse chars of calendar and return calendar integer - * @return enum integer representing calendar - *****************************************************************************/ -unsigned short int -calendar_from_chars(char *cal_chars) -{ - if (strcasecmp("STANDARD", cal_chars) == 0) { - return CALENDAR_STANDARD; - } - else if (strcasecmp("GREGORIAN", cal_chars) == 0) { - return CALENDAR_GREGORIAN; - } - else if (strcasecmp("PROLEPTIC_GREGORIAN", cal_chars) == 0) { - return CALENDAR_PROLEPTIC_GREGORIAN; - } - else if ((strcasecmp("NOLEAP", cal_chars) == 0) || - (strcasecmp("NO_LEAP", cal_chars) == 0)) { - return CALENDAR_NOLEAP; - } - else if (strcasecmp("365_DAY", cal_chars) == 0) { - return CALENDAR_365_DAY; - } - else if (strcasecmp("360_DAY", cal_chars) == 0) { - return CALENDAR_360_DAY; - } - else if (strcasecmp("JULIAN", cal_chars) == 0) { - return CALENDAR_JULIAN; - } - else if (strcasecmp("ALL_LEAP", cal_chars) == 0) { - return CALENDAR_ALL_LEAP; - } - else if (strcasecmp("366_DAY", cal_chars) == 0) { - return CALENDAR_366_DAY; - } - else { - log_err("Unknown calendar specified: %s", cal_chars); - } -} - -/****************************************************************************** - * @brief Parse chars of time units and return time units integer - * @return enum integer representing time units - *****************************************************************************/ -unsigned short int -timeunits_from_chars(char *units_chars) -{ - if (strcasecmp("SECONDS", units_chars) == 0) { - return TIME_UNITS_SECONDS; - } - else if (strcasecmp("MINUTES", units_chars) == 0) { - return TIME_UNITS_MINUTES; - } - else if (strcasecmp("HOURS", units_chars) == 0) { - return TIME_UNITS_HOURS; - } - else if (strcasecmp("DAYS", units_chars) == 0) { - return TIME_UNITS_DAYS; - } - else { - log_err("Unknown time units specified: %s", units_chars); - } -} - /****************************************************************************** * @brief Parse units string in format of " since " *****************************************************************************/ @@ -866,5 +804,113 @@ parse_nc_time_units(char *nc_unit_chars, // string is not present dmy->dayseconds = hours * SEC_PER_HOUR + minutes * SEC_PER_MIN + seconds; - *units = timeunits_from_chars(unit_chars); + *units = str_to_timeunits(unit_chars); +} + +/****************************************************************************** + * @brief This function calculates the time_delta in days from a frequency + and number of steps. + *****************************************************************************/ +double +time_delta(dmy_struct *dmy_current, + unsigned short int freq, + int n) +{ + extern global_param_struct global_param; + + double td, a, b; + dmy_struct dmy_next; + + // uniform timedeltas + if (freq == FREQ_NSECONDS) { + td = (double) n / (double) SEC_PER_DAY; + } + else if (freq == FREQ_NMINUTES) { + td = (double) n / (double) MIN_PER_DAY; + } + else if (freq == FREQ_NHOURS) { + td = (double) n / (double) HOURS_PER_DAY; + } + else if (freq == FREQ_NDAYS) { + td = (double) n; + } + // non-uniform timedeltas + else { + if (n < 1) { + log_err("Negative time delta's are not implemented yet") + } + + // copy dmy structure + dmy_next = *dmy_current; + + if (freq == FREQ_NMONTHS) { + dmy_next.month += n; + if (dmy_next.month > MONTHS_PER_YEAR) { + dmy_next.month -= MONTHS_PER_YEAR; + dmy_next.year += 1; + } + } + else if (freq == FREQ_NYEARS) { + dmy_next.year += n; + } + else { + log_err("Unknown frequency found during time_delta computation"); + } + + // Check to make sure this is a valid time + if (invalid_date(global_param.calendar, &dmy_next)) { + log_err("Invalid date found during time_delta computation"); + } + + // Get ordinal representation of these times + a = date2num(global_param.time_origin_num, dmy_current, 0, + global_param.calendar, TIME_UNITS_DAYS); + b = date2num(global_param.time_origin_num, &dmy_next, 0, + global_param.calendar, TIME_UNITS_DAYS); + td = b - a; + } + + return td; +} + +/****************************************************************************** + * @brief Compare two dmy_struct objects and return true if they are equal + *****************************************************************************/ +bool +dmy_equal(dmy_struct *a, + dmy_struct *b) +{ + if ((a->year == b->year) && + (a->month == b->month) && + (a->day == b->day) && + (a->dayseconds == b->dayseconds)) { + return true; + } + return false; +} + +/****************************************************************************** + * @brief convert a string representation of a date/time to a dmy_struct + *****************************************************************************/ +void +strpdmy(const char *s, + const char *format, + dmy_struct *dmy) +{ + struct tm t; + + // Initialize some of the time struct + t.tm_mon = 1; + t.tm_mday = 1; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; + + strptime(s, format, &t); + + dmy->year = t.tm_year + 1900; // tm_year is Year - 1900 + dmy->month = t.tm_mon + 1; // tm_month is [0-11] + dmy->day = t.tm_mday; + dmy->dayseconds = + (double) (t.tm_hour * SEC_PER_HOUR + t.tm_min * SEC_PER_MIN + t.tm_sec); } diff --git a/vic/drivers/shared_all/src/zero_output_list.c b/vic/drivers/shared_all/src/zero_output_list.c index e467f771c..e6a325e71 100644 --- a/vic/drivers/shared_all/src/zero_output_list.c +++ b/vic/drivers/shared_all/src/zero_output_list.c @@ -30,13 +30,15 @@ * @brief This routine resets the values of all output variables to 0. *****************************************************************************/ void -zero_output_list(out_data_struct *out_data) +zero_output_list(double **out_data) { - size_t varid, i; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + + size_t varid, i; for (varid = 0; varid < N_OUTVAR_TYPES; varid++) { - for (i = 0; i < out_data[varid].nelem; i++) { - out_data[varid].data[i] = 0; + for (i = 0; i < out_metadata[varid].nelem; i++) { + out_data[varid][i] = 0.; } } } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 720f80fa8..c8227062f 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -28,6 +28,7 @@ #define VIC_DRIVER_SHARED_IMAGE_H #include +#include #include #include @@ -89,16 +90,27 @@ typedef struct { domain_info_struct info; /**< structure storing domain file info */ } domain_struct; +/****************************************************************************** + * @brief Structure for netcdf variable information + *****************************************************************************/ +typedef struct { + int nc_varid; /**< variable netcdf id */ + int nc_type; /**< variable netcdf type */ + int nc_dimids[MAXDIMS]; /**< ids of dimensions */ + size_t nc_counts[MAXDIMS]; /**< size of dimid */ + size_t nc_dims; /**< number of dimensions */ +} nc_var_struct; + /****************************************************************************** * @brief Structure for netcdf file information. Initially to store * information for the output files (state and history) *****************************************************************************/ typedef struct { - char fname[MAXSTRING + 1]; char c_fillvalue; int i_fillvalue; double d_fillvalue; float f_fillvalue; + short int s_fillvalue; int nc_id; int band_dimid; int front_dimid; @@ -111,6 +123,7 @@ typedef struct { int root_zone_dimid; int time_dimid; int veg_dimid; + int time_varid; size_t band_size; size_t front_size; size_t frost_size; @@ -123,22 +136,9 @@ typedef struct { size_t time_size; size_t veg_size; bool open; + nc_var_struct *nc_vars; } nc_file_struct; -/****************************************************************************** - * @brief Structure for netcdf variable information - *****************************************************************************/ -typedef struct { - char nc_var_name[MAXSTRING]; /**< variable name */ - char nc_units[MAXSTRING]; /**< variable name */ - int nc_dimids[MAXDIMS]; /**< ids of dimensions */ - int nc_counts[MAXDIMS]; /**< size of dimid */ - int nc_type; /**< netcdf type */ - int nc_aggtype; /**< aggregation type as defined in vic_def.h */ - int nc_dims; /**< number of dimensions */ - int nc_write; /**< TRUE: write to file; FALSE: don't */ -} nc_var_struct; - /****************************************************************************** * @brief Structure for mapping the vegetation types for each grid cell as * stored in VIC's veg_con_struct to a regular array. @@ -159,7 +159,6 @@ void alloc_atmos(atmos_data_struct *atmos); void alloc_veg_hist(veg_hist_struct *veg_hist); double air_density(double t, double p); double average(double *ar, size_t n); -out_data_struct *create_output_list(void); void check_init_state_file(void); void free_atmos(atmos_data_struct *atmos); void free_veg_hist(veg_hist_struct *veg_hist); @@ -175,18 +174,24 @@ int get_nc_field_float(char *nc_name, char *var_name, size_t *start, size_t *count, float *var); int get_nc_field_int(char *nc_name, char *var_name, size_t *start, size_t *count, int *var); +int get_nc_dtype(unsigned short int dtype); int get_nc_mode(unsigned short int format); void initialize_domain(domain_struct *domain); void initialize_domain_info(domain_info_struct *info); void initialize_global_structures(void); -void initialize_history_file(nc_file_struct *nc); +void initialize_history_file(nc_file_struct *nc, stream_struct *stream, + dmy_struct *dmy_current); +void initialize_state_file(char *filename, nc_file_struct *nc_state_file); void initialize_location(location_struct *location); int initialize_model_state(all_vars_struct *all_vars, size_t Nveg, size_t Nnodes, double surf_temp, soil_con_struct *soil_con, veg_con_struct *veg_con); +void initialize_nc_file(nc_file_struct *nc_file, size_t nvars, + unsigned int *varids, unsigned short int *dtypes); void initialize_soil_con(soil_con_struct *soil_con); void initialize_veg_con(veg_con_struct *veg_con); -int parse_output_info(FILE *gp, out_data_struct **out_data); +void parse_output_info(FILE *gp, stream_struct **output_streams, + dmy_struct *dmy_current); void print_atmos_data(atmos_data_struct *atmos); void print_domain(domain_struct *domain, bool print_loc); void print_location(location_struct *location); @@ -194,25 +199,25 @@ void print_nc_file(nc_file_struct *nc); void print_nc_var(nc_var_struct *nc_var, size_t ndims); void print_veg_con_map(veg_con_map_struct *veg_con_map); void put_nc_attr(int nc_id, int var_id, const char *name, const char *value); -int put_nc_field_double(char *nc_name, bool *open, int *nc_id, double fillval, - int *dimids, int ndims, char *var_name, size_t *start, - size_t *count, double *var); -int put_nc_field_int(char *nc_name, bool *open, int *nc_id, int fillval, - int *dimids, int ndims, char *var_name, size_t *start, - size_t *count, int *var); void set_force_type(char *cmdstr, int file_num, int *field); void set_global_nc_attributes(int ncid, unsigned short int file_type); +void set_state_meta_data_info(); +void set_nc_var_dimids(unsigned int varid, nc_file_struct *nc_hist_file, + nc_var_struct *nc_var); +void set_nc_var_info(unsigned int varid, unsigned short int dtype, + nc_file_struct *nc_hist_file, nc_var_struct *nc_var); +void set_nc_state_file_info(nc_file_struct *nc_state_file); +void set_nc_state_var_info(nc_file_struct *nc_state_file); void sprint_location(char *str, location_struct *loc); void vic_alloc(void); void vic_finalize(void); void vic_image_run(dmy_struct *dmy_current); void vic_init(void); -void vic_init_output(void); -void vic_nc_info(nc_file_struct *nc_hist_file, out_data_struct **out_data, - nc_var_struct *nc_vars); +void vic_init_output(dmy_struct *dmy_current); void vic_restore(void); void vic_start(void); void vic_store(dmy_struct *dmy_current); -void vic_write(dmy_struct *dmy_current); - +void vic_write(stream_struct *stream, nc_file_struct *nc_hist_file, + dmy_struct *dmy_current); +void vic_write_output(dmy_struct *dmy); #endif diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index 937a5d0f6..95c849059 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -29,21 +29,25 @@ #include #include -#include + +#define VIC_MPI_ROOT 0 void create_MPI_filenames_struct_type(MPI_Datatype *mpi_type); void create_MPI_global_struct_type(MPI_Datatype *mpi_type); void create_MPI_location_struct_type(MPI_Datatype *mpi_type); -void create_MPI_nc_file_struct_type(MPI_Datatype *mpi_type); +void create_MPI_alarm_struct_type(MPI_Datatype *mpi_type); void create_MPI_option_struct_type(MPI_Datatype *mpi_type); void create_MPI_param_struct_type(MPI_Datatype *mpi_type); -void gather_put_nc_field_double(char *nc_name, bool *open, int *nc_id, - double fillval, int *dimids, int ndims, - char *var_name, size_t *start, size_t *count, - double *var); -void gather_put_nc_field_int(char *nc_name, bool *open, int *nc_id, int fillval, - int *dimids, int ndims, char *var_name, - size_t *start, size_t *count, int *var); +void gather_put_nc_field_double(int nc_id, int var_id, double fillval, + size_t *start, size_t *count, double *var); +void gather_put_nc_field_float(int nc_id, int var_id, float fillval, + size_t *start, size_t *count, float *var); +void gather_put_nc_field_int(int nc_id, int var_id, int fillval, size_t *start, + size_t *count, int *var); +void gather_put_nc_field_short(int nc_id, int var_id, short int fillval, + size_t *start, size_t *count, short int *var); +void gather_put_nc_field_schar(int nc_id, int var_id, char fillval, + size_t *start, size_t *count, char *var); void get_scatter_nc_field_double(char *nc_name, char *var_name, size_t *start, size_t *count, double *var); void get_scatter_nc_field_float(char *nc_name, char *var_name, size_t *start, diff --git a/vic/drivers/shared_image/include/vic_nc_log.h b/vic/drivers/shared_image/include/vic_nc_log.h new file mode 100644 index 000000000..8850f13c2 --- /dev/null +++ b/vic/drivers/shared_image/include/vic_nc_log.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * @section DESCRIPTION + * + * Logging macros for netcdf routines + * + * @section LICENSE + * + * Copyright (c) 2010, Zed A. Shaw and Mongrel2 Project Contributors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the Mongrel2 Project, Zed A. Shaw, nor the names + * of its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __vic_nc_log_h__ +#define __vic_nc_log_h__ + +#include + +// Macros for logging +#define clean_ncerrno(e) (e == 0 ? "None" : nc_strerror(e)) + +// Error Level is always active +#ifdef NO_LINENOS +#define log_ncerr(e, M, ...) print_trace(); fprintf(LOG_DEST, \ + "[ERROR] errno: %s: " M "\n", \ + clean_ncerrno(e), \ + ## __VA_ARGS__); \ + exit(EXIT_FAILURE); +#else +#define log_ncerr(e, M, ...) print_trace(); fprintf(LOG_DEST, \ + "[ERROR] %s:%d: errno: %s: " M " \n", \ + __FILE__, __LINE__, \ + clean_ncerrno(e), \ + ## __VA_ARGS__); \ + exit(EXIT_FAILURE); +#endif + +#define check_nc_status(A, M, ...) if (A != NC_NOERR) {log_ncerr(A, M, \ + ## __VA_ARGS__); \ + errno = 0; exit( \ + EXIT_FAILURE); } + +#endif diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index 33023a9d9..af3d48ea7 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -42,26 +42,20 @@ get_nc_field_double(char *nc_name, // open the netcdf file status = nc_open(nc_name, NC_NOWRITE, &nc_id); - if (status != NC_NOERR) { - log_err("Error opening %s", nc_name); - } + check_nc_status(status, "Error opening %s", nc_name); /* get NetCDF variable */ status = nc_inq_varid(nc_id, var_name, &var_id); - if (status != NC_NOERR) { - log_err("Error getting variable id for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting variable id for %s in %s", var_name, + nc_name); status = nc_get_vara_double(nc_id, var_id, start, count, var); - if (status != NC_NOERR) { - log_err("Error getting values for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting values for %s in %s", var_name, + nc_name); // close the netcdf file status = nc_close(nc_id); - if (status != NC_NOERR) { - log_err("Error closing %s", nc_name); - } + check_nc_status(status, "Error closing %s", nc_name); return status; } @@ -82,26 +76,20 @@ get_nc_field_float(char *nc_name, // open the netcdf file status = nc_open(nc_name, NC_NOWRITE, &nc_id); - if (status != NC_NOERR) { - log_err("Error opening %s", nc_name); - } + check_nc_status(status, "Error opening %s", nc_name); /* get NetCDF variable */ status = nc_inq_varid(nc_id, var_name, &var_id); - if (status != NC_NOERR) { - log_err("Error getting variable id for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting variable id for %s in %s", var_name, + nc_name); status = nc_get_vara_float(nc_id, var_id, start, count, var); - if (status != NC_NOERR) { - log_err("Error getting values for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting values for %s in %s", var_name, + nc_name); // close the netcdf file status = nc_close(nc_id); - if (status != NC_NOERR) { - log_err("Error closing %s", nc_name); - } + check_nc_status(status, "Error closing %s", nc_name); return status; } @@ -122,26 +110,20 @@ get_nc_field_int(char *nc_name, // open the netcdf file status = nc_open(nc_name, NC_NOWRITE, &nc_id); - if (status != NC_NOERR) { - log_err("Error opening %s", nc_name); - } + check_nc_status(status, "Error opening %s", nc_name); /* get NetCDF variable */ status = nc_inq_varid(nc_id, var_name, &var_id); - if (status != NC_NOERR) { - log_err("Error getting variable id for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting variable id for %s in %s", var_name, + nc_name); status = nc_get_vara_int(nc_id, var_id, start, count, var); - if (status != NC_NOERR) { - log_err("Error getting values for %s in %s", var_name, nc_name); - } + check_nc_status(status, "Error getting values for %s in %s", var_name, + nc_name); // close the netcdf file status = nc_close(nc_id); - if (status != NC_NOERR) { - log_err("Error closing %s", nc_name); - } + check_nc_status(status, "Error closing %s", nc_name); return status; } diff --git a/vic/drivers/shared_image/src/init_library.c b/vic/drivers/shared_image/src/init_library.c index c579c050d..725f4fe7a 100644 --- a/vic/drivers/shared_image/src/init_library.c +++ b/vic/drivers/shared_image/src/init_library.c @@ -176,7 +176,7 @@ initialize_global_structures(void) extern int mpi_rank; initialize_domain_info(&local_domain.info); - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { initialize_options(); initialize_global(); initialize_parameters(); diff --git a/vic/drivers/shared_image/src/parse_output_info.c b/vic/drivers/shared_image/src/parse_output_info.c index 82a0fced8..2f24b052f 100644 --- a/vic/drivers/shared_image/src/parse_output_info.c +++ b/vic/drivers/shared_image/src/parse_output_info.c @@ -30,43 +30,212 @@ /****************************************************************************** * @brief Get output info from global parameter file. *****************************************************************************/ -int -parse_output_info(FILE *gp, - out_data_struct **out_data) +void +parse_output_info(FILE *gp, + stream_struct **streams, + dmy_struct *dmy_current) { - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - char varname[MAXSTRING]; - bool found; - int outvarnum; - size_t i; + extern option_struct options; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + char flgstr[MAXSTRING]; + short int streamnum; + char varname[MAXSTRING]; + int outvarnum; + char freq_type_str[MAXSTRING]; + char freq_value_str[MAXSTRING]; + char format[MAXSTRING]; + char typestr[MAXSTRING]; + int type; + char multstr[MAXSTRING]; + char aggstr[MAXSTRING]; + double mult; + unsigned short int freq; + int freq_n; + dmy_struct freq_dmy; + unsigned short int agg_type; + int found; + + streamnum = -1; + + // rewind the global parameter file to the begining and parse only the + // output file info. rewind(gp); fgets(cmdstr, MAXSTRING, gp); - outvarnum = 0; + + /** Read through global control file to find output info **/ while (!feof(gp)) { - found = false; if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); - if (strcasecmp("OUTVAR", optstr) == 0) { - sscanf(cmdstr, "%*s %s", varname); - for (i = 0; i < N_OUTVAR_TYPES; i++) { - if (strcmp(out_data[0][i].varname, varname) == 0) { - found = true; - out_data[0][i].write = true; + + if (strcasecmp("OUTFILE", optstr) == 0) { + streamnum++; + if (streamnum >= (short int) options.Noutstreams) { + log_err("Found too many output files, was expecting " + "%zu but found %hu", options.Noutstreams, + streamnum); + } + + if (sscanf(cmdstr, "%*s %s", + (*streams)[streamnum].prefix) != 1) { + log_err("Invalid specification for OUTFILE"); + } + + // set default file format + (*streams)[streamnum].file_format = NETCDF4_CLASSIC; + + outvarnum = 0; + } + else if (strcasecmp("AGGFREQ", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"AGGFREQ\"."); + } + found = sscanf(cmdstr, "%*s %s %s", freq_type_str, + freq_value_str); + + if (!found) { + log_err("No arguments found after AGGFREQ"); + } + // parse the frequency string to an enum value + freq = str_to_freq_flag(freq_type_str); + + if (freq == FREQ_DATE) { + // Make sure we have a datestring + if (found != 2) { + log_err( + "AGGFREQ was set to DATE but no date string was found"); + } + // parse date from freq_value_str + strpdmy(freq_value_str, "%Y-%m-%d", &freq_dmy); + // set the alarm + set_alarm(dmy_current, freq, &freq_dmy, + (&(*streams)[streamnum].agg_alarm)); + } + else { + if (found != 2) { + // Default frequency is 1 + freq_n = 1; + } + else { + // get the frequency value as an integer + freq_n = atoi(freq_value_str); } + // set the alarm + set_alarm(dmy_current, freq, &freq_n, + (&(*streams)[streamnum].agg_alarm)); } + } + else if (strcasecmp("HISTFREQ", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"HISTFREQ\"."); + } + found = sscanf(cmdstr, "%*s %s %s", freq_type_str, + freq_value_str); + if (!found) { - log_err("\"%s\" was not found in the list of supported " - "output variable names. Please use " - "the exact name listed in vic_def.h.", - varname); + log_err("No arguments found after HISTFREQ"); } + // parse the frequency string to an enum value + freq = str_to_freq_flag(freq_type_str); + + if (freq == FREQ_DATE) { + // Make sure we have a datestring + if (found != 2) { + log_err( + "AGGFREQ was set to DATE but no date string was found"); + } + // parse date from freq_value_str + strpdmy(freq_value_str, "%Y-%m-%d", &freq_dmy); + // set the alarm + set_alarm(dmy_current, freq, &freq_dmy, + (&(*streams)[streamnum].write_alarm)); + } + else { + if (found != 2) { + // Default frequency is 1 + freq_n = 1; + } + else { + // get the frequency value as an integer + freq_n = atoi(freq_value_str); + } + // set the alarm + set_alarm(dmy_current, freq, &freq_n, + (&(*streams)[streamnum].write_alarm)); + } + } + else if (strcasecmp("COMPRESS", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"COMPRESS\"."); + } + sscanf(cmdstr, "%*s %s", flgstr); + if (strcasecmp("TRUE", flgstr) == 0) { + (*streams)[streamnum].compress = + COMPRESSION_LVL_DEFAULT; + } + else if (strcasecmp("FALSE", flgstr) == 0) { + (*streams)[streamnum].compress = 0; + } + else { + (*streams)[streamnum].compress = atoi(flgstr); + } + } + else if (strcasecmp("OUT_FORMAT", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"OUT_FORMAT\"."); + } + sscanf(cmdstr, "%*s %s", flgstr); + if (strcasecmp("NETCDF3_CLASSIC", flgstr) == 0) { + (*streams)[streamnum].file_format = NETCDF3_CLASSIC; + } + else if (strcasecmp("NETCDF3_64BIT_OFFSET", flgstr) == 0) { + (*streams)[streamnum].file_format = + NETCDF3_64BIT_OFFSET; + } + else if (strcasecmp("NETCDF4_CLASSIC", flgstr) == 0) { + (*streams)[streamnum].file_format = NETCDF4_CLASSIC; + } + else if (strcasecmp("NETCDF4", flgstr) == 0) { + (*streams)[streamnum].file_format = NETCDF4; + } + else { + log_err( + "Image driver file format must be a valid NETCDF format"); + } + } + else if (strcasecmp("OUTVAR", optstr) == 0) { + if (streamnum < 0) { + log_err("Error in global param file: \"OUTFILE\" must be " + "specified before you can specify \"OUTVAR\"."); + } + // parse outvar options + strcpy(varname, ""); + strcpy(format, ""); + strcpy(typestr, ""); + strcpy(multstr, ""); + strcpy(aggstr, ""); + found = sscanf(cmdstr, "%*s %s %s %s %s %s", varname, + format, typestr, multstr, aggstr); + if (!found) { + log_err("OUTVAR specified but no variable was listed"); + } + // interpret string options, set defaults if necessary + str_to_ascii_format(format); + agg_type = str_to_agg_type(aggstr); + type = str_to_out_type(typestr); + mult = str_to_out_mult(multstr); + + // Add OUTVAR to stream + set_output_var(&((*streams)[streamnum]), varname, outvarnum, + format, type, mult, agg_type); outvarnum++; } } fgets(cmdstr, MAXSTRING, gp); } - - return outvarnum; } diff --git a/vic/drivers/shared_image/src/print_library_shared_image.c b/vic/drivers/shared_image/src/print_library_shared_image.c index b4afc6eac..79bd445b9 100644 --- a/vic/drivers/shared_image/src/print_library_shared_image.c +++ b/vic/drivers/shared_image/src/print_library_shared_image.c @@ -125,7 +125,6 @@ void print_nc_file(nc_file_struct *nc) { fprintf(LOG_DEST, "nc_file:"); - fprintf(LOG_DEST, "\tfname : %s\n", nc->fname); fprintf(LOG_DEST, "\tc_fillvalue : %d\n", nc->c_fillvalue); fprintf(LOG_DEST, "\ti_fillvalue : %d\n", nc->i_fillvalue); fprintf(LOG_DEST, "\td_fillvalue : %.4f\n", nc->d_fillvalue); @@ -164,8 +163,8 @@ print_nc_var(nc_var_struct *nc_var, size_t i; fprintf(LOG_DEST, "nc_var:\n"); - fprintf(LOG_DEST, "\tnc_var_name: %s\n", nc_var->nc_var_name); - fprintf(LOG_DEST, "\tnc_units: %s\n", nc_var->nc_units); + fprintf(LOG_DEST, "\tnc_varid: %d\n", nc_var->nc_varid); + fprintf(LOG_DEST, "\tnc_type: %d\n", nc_var->nc_type); fprintf(LOG_DEST, "\tnc_dimids:"); for (i = 0; i < ndims; i++) { fprintf(LOG_DEST, "\t%d", nc_var->nc_dimids[i]); @@ -173,13 +172,10 @@ print_nc_var(nc_var_struct *nc_var, fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "\tnc_counts:"); for (i = 0; i < ndims; i++) { - fprintf(LOG_DEST, "\t%d", nc_var->nc_counts[i]); + fprintf(LOG_DEST, "\t%zu", nc_var->nc_counts[i]); } fprintf(LOG_DEST, "\n"); - fprintf(LOG_DEST, "\tnc_type: %d\n", nc_var->nc_type); - fprintf(LOG_DEST, "\tnc_aggtype: %d\n", nc_var->nc_aggtype); - fprintf(LOG_DEST, "\tnc_dims: %d\n", nc_var->nc_dims); - fprintf(LOG_DEST, "\tnc_write: %d\n", nc_var->nc_write); + fprintf(LOG_DEST, "\tnc_dims: %zu\n", nc_var->nc_dims); } /****************************************************************************** diff --git a/vic/drivers/shared_image/src/put_nc_attr.c b/vic/drivers/shared_image/src/put_nc_attr.c index f86ef6bb7..1e0597137 100644 --- a/vic/drivers/shared_image/src/put_nc_attr.c +++ b/vic/drivers/shared_image/src/put_nc_attr.c @@ -27,7 +27,7 @@ #include /****************************************************************************** - * @brief Put double precision data field to netCDF. + * @brief Put text attribute to netCDF. *****************************************************************************/ void put_nc_attr(int nc_id, diff --git a/vic/drivers/shared_image/src/put_nc_field.c b/vic/drivers/shared_image/src/put_nc_field.c deleted file mode 100644 index 12e634d68..000000000 --- a/vic/drivers/shared_image/src/put_nc_field.c +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Put data to netCDF. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Put double precision data field to netCDF. - *****************************************************************************/ -int -put_nc_field_double(char *nc_name, - bool *open, - int *nc_id, - double fillval, - int *dimids, - int ndims, - char *var_name, - size_t *start, - size_t *count, - double *var) -{ - int old_fill_mode; - int status; - int var_id; - - if (!(*open)) { - // open the netcdf file - status = nc_open(nc_name, - NC_WRITE | NC_NOCLOBBER | NC_NETCDF4 | NC_CLASSIC_MODEL, - nc_id); - if (status != NC_NOERR) { - log_err("Error opening %s", nc_name); - } - *open = true; - - // set the NC_FILL attribute - status = nc_set_fill(*nc_id, NC_FILL, &old_fill_mode); - if (status != NC_NOERR) { - log_err("Error setting fill value in %s", nc_name); - } - } - - /* get NetCDF variable */ - status = nc_inq_varid(*nc_id, var_name, &var_id); - if (status == NC_ENOTVAR) { - // enter define mode - status = nc_redef(*nc_id); - if (status != NC_NOERR) { - log_err("Error entering define mode in %s", nc_name); - } - // define the variable - status = nc_def_var(*nc_id, var_name, NC_DOUBLE, ndims, dimids, - &var_id); - if (status != NC_NOERR) { - log_err("Error defining variable %s in %s", var_name, nc_name); - } - // set the fill value attribute - status = nc_put_att_double(*nc_id, var_id, "_FillValue", NC_DOUBLE, 1, - &fillval); - if (status != NC_NOERR) { - log_err("Error putting _FillValue attribute to %s in %s", var_name, - nc_name) - } - // leave define mode - status = nc_enddef(*nc_id); - if (status != NC_NOERR) { - log_err("Error ending define mode for %s in %s", var_name, nc_name); - } - } - else if (status != NC_NOERR) { - log_err("Error getting variable id for %s in %s", var_name, nc_name); - } - - status = nc_put_vara_double(*nc_id, var_id, start, count, var); - if (status != NC_NOERR) { - log_err("Error writing values to %s in %s", var_name, nc_name); - } - - // keep the file open - - return status; -} - -/****************************************************************************** - * @brief Put integer data field to netCDF. - *****************************************************************************/ -int -put_nc_field_int(char *nc_name, - bool *open, - int *nc_id, - int fillval, - int *dimids, - int ndims, - char *var_name, - size_t *start, - size_t *count, - int *var) -{ - int old_fill_mode; - int status; - int var_id; - - if (!(*open)) { - // open the netcdf file - status = nc_open(nc_name, - NC_WRITE | NC_NOCLOBBER | NC_NETCDF4 | NC_CLASSIC_MODEL, - nc_id); - if (status != NC_NOERR) { - log_err("Error opening %s", nc_name); - } - *open = true; - - // set the NC_FILL attribute - status = nc_set_fill(*nc_id, NC_FILL, &old_fill_mode); - if (status != NC_NOERR) { - log_err("Error setting fill value in %s", nc_name); - } - } - - /* get NetCDF variable */ - status = nc_inq_varid(*nc_id, var_name, &var_id); - if (status == NC_ENOTVAR) { - // enter define mode - status = nc_redef(*nc_id); - if (status != NC_NOERR) { - log_err("Error entering define mode in %s", nc_name); - } - // define the variable - status = nc_def_var(*nc_id, var_name, NC_INT, ndims, dimids, - &var_id); - if (status != NC_NOERR) { - log_err("Error defining variable %s in %s", var_name, nc_name); - } - // set the fill value attribute - status = nc_put_att_int(*nc_id, var_id, "_FillValue", NC_INT, 1, - &fillval); - if (status != NC_NOERR) { - log_err("Error putting _FillValue attribute to %s in %s", var_name, - nc_name); - } - // leave define mode - status = nc_enddef(*nc_id); - if (status != NC_NOERR) { - log_err("Error ending define mode for %s in %s", var_name, nc_name); - } - } - else if (status != NC_NOERR) { - log_err("Error getting variable id for %s in %s", var_name, nc_name); - } - - status = nc_put_vara_int(*nc_id, var_id, start, count, var); - if (status != NC_NOERR) { - log_err("Error writing values to %s in %s", var_name, nc_name); - } - - // keep the file open - - return status; -} diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c new file mode 100644 index 000000000..5ed707d55 --- /dev/null +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -0,0 +1,699 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This routine sets the metadata structure for VIC state variables + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Set output met data information + *****************************************************************************/ +void +set_state_meta_data_info() +{ + size_t v; + + extern option_struct options; + extern metadata_struct state_metadata[N_STATE_VARS]; + + // Build the list of state variables + + // Set missing and/or default values + for (v = 0; v < N_STATE_VARS; v++) { + // Set default string values + strcpy(state_metadata[v].varname, MISSING_S); + strcpy(state_metadata[v].long_name, MISSING_S); + strcpy(state_metadata[v].standard_name, MISSING_S); + strcpy(state_metadata[v].units, MISSING_S); + strcpy(state_metadata[v].description, MISSING_S); + // Set default number of elements + state_metadata[v].nelem = 1; + } + + // STATE_SOIL_MOISTURE + strcpy(state_metadata[STATE_SOIL_MOISTURE].varname, "STATE_SOIL_MOISTURE"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].long_name, "soil_moisture"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].standard_name, + "soil_layer_moisture"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].units, "mm"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].description, + "soil total moisture contents including ice for each soil layer"); + + // STATE_SOIL_ICE + strcpy(state_metadata[STATE_SOIL_ICE].varname, "STATE_SOIL_ICE"); + strcpy(state_metadata[STATE_SOIL_ICE].long_name, "soil_ice"); + strcpy(state_metadata[STATE_SOIL_ICE].standard_name, + "soil_moisture_ice_depth"); + strcpy(state_metadata[STATE_SOIL_ICE].units, "mm"); + strcpy(state_metadata[STATE_SOIL_ICE].description, + "soil ice content for each soil layer"); + + // STATE_CANOPY_WATER + strcpy(state_metadata[STATE_CANOPY_WATER].varname, "STATE_CANOPY_WATER"); + strcpy(state_metadata[STATE_CANOPY_WATER].long_name, "canopy_water"); + strcpy(state_metadata[STATE_CANOPY_WATER].standard_name, "water_in_canopy"); + strcpy(state_metadata[STATE_CANOPY_WATER].units, "mm"); + strcpy(state_metadata[STATE_CANOPY_WATER].description, + "amount of water stored in the vegetation canopy"); + + if (options.CARBON) { + // STATE_ANNUALNPP + strcpy(state_metadata[STATE_ANNUALNPP].varname, "STATE_ANNUALNPP"); + strcpy(state_metadata[STATE_ANNUALNPP].long_name, "annualnpp"); + strcpy(state_metadata[STATE_ANNUALNPP].standard_name, + "running_total_annual_NPP"); + strcpy(state_metadata[STATE_ANNUALNPP].units, "g m-2"); + strcpy(state_metadata[STATE_ANNUALNPP].description, + "running total annual NPP"); + + // STATE_ANNUALNPPPREV + strcpy(state_metadata[STATE_ANNUALNPPPREV].varname, + "STATE_ANNUALNPPPREV"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].long_name, "annualnppprev"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].standard_name, + "previous_year_total_annual_NPP"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].units, "g m-2"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].description, + "total annual NPP from previous year"); + + // STATE_CLITTER + strcpy(state_metadata[STATE_CLITTER].varname, "STATE_CLITTER"); + strcpy(state_metadata[STATE_CLITTER].long_name, "clitter"); + strcpy(state_metadata[STATE_CLITTER].standard_name, + "carbon_in_litter_pool"); + strcpy(state_metadata[STATE_CLITTER].units, "g m-2"); + strcpy(state_metadata[STATE_CLITTER].description, + "carbon storage in litter pool"); + + // STATE_CINTER + strcpy(state_metadata[STATE_CINTER].varname, "STATE_CINTER"); + strcpy(state_metadata[STATE_CINTER].long_name, "cinter"); + strcpy(state_metadata[STATE_CINTER].standard_name, + "carbon_in_intermediate_pool"); + strcpy(state_metadata[STATE_CINTER].units, "g m-2"); + strcpy(state_metadata[STATE_CINTER].description, + "carbon storage in intermediate pool"); + + // STATE_CSLOW + strcpy(state_metadata[STATE_CSLOW].varname, "STATE_CSLOW"); + strcpy(state_metadata[STATE_CSLOW].long_name, "cslow"); + strcpy(state_metadata[STATE_CSLOW].standard_name, + "carbon_in_slow_pool"); + strcpy(state_metadata[STATE_CSLOW].units, "g m-2"); + strcpy(state_metadata[STATE_CSLOW].description, + "carbon storage in slow pool"); + } + // STATE_SNOW_AGE + strcpy(state_metadata[STATE_SNOW_AGE].varname, "STATE_SNOW_AGE"); + strcpy(state_metadata[STATE_SNOW_AGE].long_name, "snow_age"); + strcpy(state_metadata[STATE_SNOW_AGE].standard_name, + "age_since_last_new_snow"); + strcpy(state_metadata[STATE_SNOW_AGE].units, "model_time_step"); + strcpy(state_metadata[STATE_SNOW_AGE].description, + "number of model time steps since the last new snow"); + + // STATE_SNOW_MELT_STATE + strcpy(state_metadata[STATE_SNOW_MELT_STATE].varname, + "STATE_SNOW_MELT_STATE"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].long_name, "snow_melt_state"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].standard_name, + "snow_melting_phase"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].units, + "1 melting, 0 not melting"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].description, + "flag to indicate whether snowpack is in accumulation or melting phase"); + + // STATE_SNOW_COVERAGE + strcpy(state_metadata[STATE_SNOW_COVERAGE].varname, "STATE_SNOW_COVERAGE"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].long_name, "snow_coverage"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].standard_name, + "snow_coverage_fraction"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].units, "1"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].description, + "fraction of grid cell area covered by snow"); + + // STATE_SNOW_WATER_EQUIVALENT + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].varname, + "STATE_SNOW_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].long_name, + "snow_water_equivalent"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].standard_name, + "snow_water_equivalent"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].units, "m"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].description, + "snow water equivalent"); + + // STATE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].varname, + "STATE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].long_name, "snow_surf_temp"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].standard_name, + "snow_surface_temperature"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].description, + "snow surface layer temperature"); + + // STATE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_SNOW_SURF_WATER].varname, + "STATE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].long_name, "snow_surf_water"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].standard_name, + "snow_surface_liquid_water"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].description, + "liquid water content of the snow surface layer"); + + // STATE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].varname, + "STATE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].long_name, "snow_pack_temp"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].standard_name, + "snow_pack_temperature"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].description, + "snow pack layer temperature"); + + // STATE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_SNOW_PACK_WATER].varname, + "STATE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].long_name, "snow_pack_water"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].standard_name, + "snow_pack_liquid_water"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].description, + "liquid water content of the snow pack layer"); + + // STATE_SNOW_DENSITY + strcpy(state_metadata[STATE_SNOW_DENSITY].varname, "STATE_SNOW_DENSITY"); + strcpy(state_metadata[STATE_SNOW_DENSITY].long_name, "snow_density"); + strcpy(state_metadata[STATE_SNOW_DENSITY].standard_name, + "snowpack_density"); + strcpy(state_metadata[STATE_SNOW_DENSITY].units, "kg m-3"); + strcpy(state_metadata[STATE_SNOW_DENSITY].description, "snowpack density"); + + // STATE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].varname, + "STATE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].long_name, + "snow_cold_content"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].standard_name, + "snowpack_cold_content"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].description, + "snowpack cold content"); + + // STATE_SNOW_CANOPY + strcpy(state_metadata[STATE_SNOW_CANOPY].varname, "STATE_SNOW_CANOPY"); + strcpy(state_metadata[STATE_SNOW_CANOPY].long_name, "snow_canopy"); + strcpy(state_metadata[STATE_SNOW_CANOPY].standard_name, + "snow_water_equivalent_intercepted_in_canopy"); + strcpy(state_metadata[STATE_SNOW_CANOPY].units, "m"); + strcpy(state_metadata[STATE_SNOW_CANOPY].description, + "snow interception storage in canopy"); + + // STATE_SOIL_NODE_TEMP + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].varname, + "STATE_SOIL_NODE_TEMP"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].long_name, "soil_node_temp"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].standard_name, + "soil_node_temperature"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].units, "C"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].description, + "soil temperature of each soil thermal node"); + + // STATE_FOLIAGE_TEMPERATURE + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, + "STATE_FOLIAGE_TEMPERATURE"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].long_name, + "foliage_temperature"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].standard_name, + "foliage_temperature"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].units, "C"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].description, + "overstory vegetaion temperature"); + + // STATE_ENERGY_LONGUNDEROUT + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, + "STATE_ENERGY_LONGUNDEROUT"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].long_name, + "energy_longunderout"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].standard_name, + "longwave_out_from_understory"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].units, "W m-2"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].description, + "outgoing longwave flux from understory vegetation"); + + // STATE_ENERGY_SNOW_FLUX + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].varname, + "STATE_ENERGY_SNOW_FLUX"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].long_name, + "energy_snow_flux"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].standard_name, + "snowpack_thermal_flux"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].units, "W m-2"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].description, + "thermal flux through snowpack"); + + if (options.LAKES) { + // STATE_LAKE_SOIL_MOISTURE + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, + "STATE_LAKE_SOIL_MOISTURE"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].long_name, + "lake_soil_moisture"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].standard_name, + "lake_soil_moisture"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].units, "mm"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].description, + "soil moisture below lake"); + + // STATE_LAKE_SOIL_ICE + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].varname, + "STATE_LAKE_SOIL_ICE"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].long_name, "lake_soil_ice"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].standard_name, + "lake_soil_ice_content"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].units, "mm"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].description, + "soil ice content below lake"); + + if (options.CARBON) { + // STATE_LAKE_CLITTER + strcpy(state_metadata[STATE_LAKE_CLITTER].varname, + "STATE_LAKE_CLITTER"); + strcpy(state_metadata[STATE_LAKE_CLITTER].long_name, + "lake_clitter"); + strcpy(state_metadata[STATE_LAKE_CLITTER].standard_name, + "lake_carbon_in_litter_pool"); + strcpy(state_metadata[STATE_LAKE_CLITTER].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CLITTER].description, + "carbon storage in litter pool below lake"); + + // STATE_LAKE_CINTER + strcpy(state_metadata[STATE_LAKE_CINTER].varname, + "STATE_LAKE_CINTER"); + strcpy(state_metadata[STATE_LAKE_CINTER].long_name, "lake_cinter"); + strcpy(state_metadata[STATE_LAKE_CINTER].standard_name, + "lake_carbon_in_intermediate_pool"); + strcpy(state_metadata[STATE_LAKE_CINTER].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CINTER].description, + "carbon storage in intermediate pool below lake"); + + // STATE_LAKE_CSLOW + strcpy(state_metadata[STATE_LAKE_CSLOW].varname, + "STATE_LAKE_CSLOW"); + strcpy(state_metadata[STATE_LAKE_CSLOW].long_name, "lake_cslow"); + strcpy(state_metadata[STATE_LAKE_CSLOW].standard_name, + "lake_carbon_in_slow_pool"); + strcpy(state_metadata[STATE_LAKE_CSLOW].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CSLOW].description, + "carbon storage in slow pool below lake"); + } + + // STATE_LAKE_SNOW_AGE + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].varname, + "STATE_LAKE_SNOW_AGE"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].long_name, "lake_snow_age"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].standard_name, + "lake_age_since_last_new_snow"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].units, "model_time_step"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].description, + "number of model time steps since the last new snow on lake ice"); + + // STATE_LAKE_SNOW_MELT_STATE + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, + "STATE_LAKE_SNOW_MELT_STATE"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].long_name, + "lake_snow_melt_state"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].standard_name, + "lake_snow_melting_phase"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].units, + "1 melting, 0 not melting"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].description, + "flag to indicate whether snowpack is in accumulation or melting phase on lake ice"); + + // STATE_LAKE_SNOW_COVERAGE + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, + "STATE_LAKE_SNOW_COVERAGE"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].long_name, + "lake_snow_coverage"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].standard_name, + "lake_snow_coverage_fraction"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].units, "1"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].description, + "fraction of grid cell area covered by snow on lake ice"); + + // STATE_LAKE_SNOW_WATER_EQUIVALENT + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, + "STATE_LAKE_SNOW_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].long_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].standard_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].description, + "lake snow water equivalent on lake ice"); + + // STATE_LAKE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, + "STATE_LAKE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].long_name, + "lake_snow_surf_temp"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].description, + "snow surface layer temperature on lake ice"); + + // STATE_LAKE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, + "STATE_LAKE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].long_name, + "lake_snow_surf_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].description, + "liquid water content of the snow surface layer on lake ice"); + + // STATE_LAKE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, + "STATE_LAKE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].long_name, + "lake_snow_pack_temp"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].standard_name, + "lake_snow_pack_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].description, + "snow pack layer temperature on lake ice"); + + // STATE_LAKE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, + "STATE_LAKE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].long_name, + "lake_snow_pack_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].standard_name, + "lake_snow_surface_liquid_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].description, + "liquid water content of the snow surface layer on lake ice"); + + // STATE_LAKE_SNOW_DENSITY + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].varname, + "STATE_LAKE_SNOW_DENSITY"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].long_name, + "lake_snow_density"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].standard_name, + "lake_snowpack_density"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].units, "kg m-3"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].description, + "snowpack density on lake ice"); + + // STATE_LAKE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, + "STATE_LAKE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].long_name, + "lake_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].standard_name, + "lake_snowpack_cold_content"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].description, + "snowpack cold content on lake ice"); + + // STATE_LAKE_SNOW_CANOPY + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].varname, + "STATE_LAKE_SNOW_CANOPY"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].long_name, + "lake_snow_canopy"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].standard_name, + "lake_snow_water_equivalent_intercepted_in_canopy"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].description, + "snow interception storage in canopy on lake ice"); + + // STATE_LAKE_SOIL_NODE_TEMP + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, + "STATE_LAKE_SOIL_NODE_TEMP"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].long_name, + "lake_soil_node_temp"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].standard_name, + "lake_soil_node_temperature"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].description, + "soil temperature of each soil thermal node below lake"); + + // STATE_LAKE_ACTIVE_LAYERS + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, + "STATE_LAKE_ACTIVE_LAYERS"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].long_name, + "lake_active_layers"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].standard_name, + "lake_active_layers"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].units, "-"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].description, + "number of nodes whose corresponding layers currently contain water"); + + // STATE_LAKE_LAYER_DZ + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].varname, + "STATE_LAKE_LAYER_DZ"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].long_name, "lake_layer_dz"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].standard_name, + "lake_thickness_layer_below_surface"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].units, "m"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].description, + "vertical thickness of all horizontal lake water layers below the surface layer"); + + // STATE_LAKE_SURF_LAYER_DZ + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, + "STATE_LAKE_SURF_LAYER_DZ"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].long_name, + "lake_surf_layer_dz"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].standard_name, + "lake_thickness_surface_layer"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].units, "m"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].description, + "vertical thickness of surface water layer in lake"); + + // STATE_LAKE_DEPTH + strcpy(state_metadata[STATE_LAKE_DEPTH].varname, "STATE_LAKE_DEPTH"); + strcpy(state_metadata[STATE_LAKE_DEPTH].long_name, "lake_depth"); + strcpy(state_metadata[STATE_LAKE_DEPTH].standard_name, + "lake_liquid_water_depth"); + strcpy(state_metadata[STATE_LAKE_DEPTH].units, "m"); + strcpy(state_metadata[STATE_LAKE_DEPTH].description, + "distance from surface to deepest point in lake"); + + // STATE_LAKE_LAYER_SURF_AREA + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].varname, + "STATE_LAKE_LAYER_SURF_AREA"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].long_name, + "lake_layer_surf_area"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].standard_name, + "lake_node_surface_area"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].units, "m2"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].description, + "surface area of liquid water in lake at each node"); + + // STATE_LAKE_SURF_AREA + strcpy(state_metadata[STATE_LAKE_SURF_AREA].varname, + "STATE_LAKE_SURF_AREA"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].long_name, + "lake_surf_area"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].standard_name, + "lake_surface_area"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].units, "m2"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].description, + "surface area of liquid plus ice water on lake surface"); + + // STATE_LAKE_VOLUME + strcpy(state_metadata[STATE_LAKE_VOLUME].varname, "STATE_LAKE_VOLUME"); + strcpy(state_metadata[STATE_LAKE_VOLUME].long_name, "lake_volume"); + strcpy(state_metadata[STATE_LAKE_VOLUME].standard_name, "lake_volume"); + strcpy(state_metadata[STATE_LAKE_VOLUME].units, "m3"); + strcpy(state_metadata[STATE_LAKE_VOLUME].description, + "lake total volume including liquid water equivalent of lake ice"); + + // STATE_LAKE_LAYER_TEMP + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].varname, + "STATE_LAKE_LAYER_TEMP"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].long_name, + "lake_layer_temp"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].standard_name, + "lake_layer_temp"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].description, + "lake water temperature at each node"); + + // STATE_LAKE_AVERAGE_TEMP + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, + "STATE_LAKE_AVERAGE_TEMP"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].long_name, + "lake_average_temp"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].standard_name, + "lake_average_temperature"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].description, + "average liquid water temperature of entire lake"); + + // STATE_LAKE_ICE_AREA_FRAC + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, + "STATE_LAKE_ICE_AREA"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].long_name, + "lake_ice_area"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].standard_name, + "lake_ice_coverage"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].units, "m2"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].description, + "area of ice coverage on lake at beginning of time step"); + + // STATE_LAKE_ICE_AREA_FRAC_NEW + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, + "STATE_LAKE_ICE_AREA_NEW"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].long_name, + "lake_ice_area_new"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].standard_name, + "lake_ice_area_new"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].units, "m2"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].description, + "area of ice coverage on lake at end of time step"); + + // STATE_LAKE_ICE_WATER_EQUIVALENT + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].varname, + "STATE_LAKE_ICE_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].long_name, + "lake_ice_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].standard_name, + "lake_ice_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].units, "m3"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].description, + "liquid water equivalent volume of lake ice"); + + // STATE_LAKE_ICE_HEIGHT + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].varname, + "STATE_LAKE_ICE_HEIGHT"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].long_name, + "lake_ice_height"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].standard_name, + "lake_ice_height_thickest"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].description, + "lake ice height at ghickest point"); + + // STATE_LAKE_ICE_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].varname, + "STATE_LAKE_ICE_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].long_name, "lake_ice_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].standard_name, + "lake_ice_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].description, + "lake ice temperature"); + + // STATE_LAKE_ICE_SWE + strcpy(state_metadata[STATE_LAKE_ICE_SWE].varname, + "STATE_LAKE_ICE_SWE"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].long_name, "lake_ice_swe"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].standard_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].description, + "liquid water equivalent depth of lake snow"); + + // STATE_LAKE_ICE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, + "STATE_LAKE_ICE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].long_name, + "lake_ice_snow_surf_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].description, + "temperature of snow surface layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, + "STATE_LAKE_ICE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].long_name, + "lake_ice_snow_pack_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].standard_name, + "lake_ice_snow_pack_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].description, + "temperature of snow pack layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, + "STATE_LAKE_ICE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].long_name, + "lake_ice_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].standard_name, + "lake_ice_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].description, + "snowpack cold content of snow lake"); + + // STATE_LAKE_ICE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].varname, + "STATE_LAKE_ICE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].long_name, + "lake_ice_snow_surf_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].standard_name, + "lake_ice_snow_surface_liquid_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].description, + "liquid water content of surface snow layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].varname, + "STATE_LAKE_ICE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].long_name, + "lake_ice_snow_pack_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].standard_name, + "lake_ice_snow_pack_liquid_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].description, + "liquid water content of pack snow layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_ALBEDO + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, + "STATE_LAKE_ICE_SNOW_ALBEDO"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].long_name, + "lake_ice_snow_albedo"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].standard_name, + "lake_ice_snow_albedo"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].units, "1"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].description, + "albedo of lake snow"); + + // STATE_LAKE_ICE_SNOW_DEPTH + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, + "STATE_LAKE_ICE_SNOW_DEPTH"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].long_name, + "lake_ice_snow_depth"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].standard_name, + "lake_ice_snow_depth"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].description, + "depth of snow on lake ice"); + } +} diff --git a/vic/drivers/shared_image/src/vic_alloc.c b/vic/drivers/shared_image/src/vic_alloc.c index 2d0554d36..75101b23b 100644 --- a/vic/drivers/shared_image/src/vic_alloc.c +++ b/vic/drivers/shared_image/src/vic_alloc.c @@ -36,7 +36,7 @@ vic_alloc(void) extern atmos_data_struct *atmos; extern domain_struct local_domain; extern option_struct options; - extern out_data_struct **out_data; + extern double ***out_data; extern save_data_struct *save_data; extern soil_con_struct *soil_con; extern veg_con_map_struct *veg_con_map; @@ -200,8 +200,6 @@ vic_alloc(void) all_vars[i] = make_all_vars(veg_con_map[i].nv_active); - out_data[i] = create_output_list(); - // allocate memory for veg_hist veg_hist[i] = calloc(veg_con_map[i].nv_active, sizeof(*(veg_hist[i]))); for (j = 0; j < veg_con_map[i].nv_active; j++) { diff --git a/vic/drivers/shared_image/src/vic_finalize.c b/vic/drivers/shared_image/src/vic_finalize.c index fed41e768..b06cb272c 100644 --- a/vic/drivers/shared_image/src/vic_finalize.c +++ b/vic/drivers/shared_image/src/vic_finalize.c @@ -42,9 +42,10 @@ vic_finalize(void) extern int *mpi_map_local_array_sizes; extern int *mpi_map_global_array_offsets; extern int mpi_rank; - extern nc_file_struct nc_hist_file; + extern nc_file_struct *nc_hist_files; extern option_struct options; - extern out_data_struct **out_data; + extern double ***out_data; + extern stream_struct *output_streams; extern save_data_struct *save_data; extern soil_con_struct *soil_con; extern veg_con_map_struct *veg_con_map; @@ -54,7 +55,7 @@ vic_finalize(void) extern MPI_Datatype mpi_global_struct_type; extern MPI_Datatype mpi_filenames_struct_type; extern MPI_Datatype mpi_location_struct_type; - extern MPI_Datatype mpi_nc_file_struct_type; + extern MPI_Datatype mpi_alarm_struct_type; extern MPI_Datatype mpi_option_struct_type; extern MPI_Datatype mpi_param_struct_type; @@ -62,17 +63,20 @@ vic_finalize(void) size_t j; int status; + if (mpi_rank == 0) { // close the global parameter file fclose(filep.globalparam); // close the netcdf history file if it is still open - if (nc_hist_file.open == true) { - status = nc_close(nc_hist_file.nc_id); - if (status != NC_NOERR) { - log_err("Error closing history file %s", nc_hist_file.fname); + for (i = 0; i < options.Noutstreams; i++) { + if (nc_hist_files[i].open == true) { + status = nc_close(nc_hist_files[i].nc_id); + check_nc_status(status, "Error closing history file"); } + free(nc_hist_files[i].nc_vars); } + free(nc_hist_files); } for (i = 0; i < local_domain.ncells_active; i++) { @@ -91,13 +95,15 @@ vic_finalize(void) free_veg_hist(&(veg_hist[i][j])); } free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active); - free_out_data(&(out_data[i])); free(veg_con_map[i].vidx); free(veg_con_map[i].Cv); free(veg_con[i]); free(veg_hist[i]); free(veg_lib[i]); } + + free_streams(&output_streams); + free_out_data(local_domain.ncells_active, out_data); free(atmos); free(soil_con); free(veg_con_map); @@ -105,20 +111,20 @@ vic_finalize(void) free(veg_hist); free(veg_lib); free(all_vars); - free(out_data); free(save_data); free(local_domain.locations); - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { free(filter_active_cells); free(global_domain.locations); free(mpi_map_local_array_sizes); free(mpi_map_global_array_offsets); free(mpi_map_mapping_array); } + MPI_Type_free(&mpi_global_struct_type); MPI_Type_free(&mpi_filenames_struct_type); MPI_Type_free(&mpi_location_struct_type); - MPI_Type_free(&mpi_nc_file_struct_type); + MPI_Type_free(&mpi_alarm_struct_type); MPI_Type_free(&mpi_option_struct_type); MPI_Type_free(&mpi_param_struct_type); finalize_logging(); diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index 575986165..79b553540 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -36,9 +36,11 @@ vic_image_run(dmy_struct *dmy_current) extern all_vars_struct *all_vars; extern atmos_data_struct *atmos; extern domain_struct local_domain; + extern option_struct options; extern global_param_struct global_param; extern lake_con_struct lake_con; - extern out_data_struct **out_data; + extern double ***out_data; + extern stream_struct *output_streams; extern save_data_struct *save_data; extern soil_con_struct *soil_con; extern veg_con_struct **veg_con; @@ -61,7 +63,13 @@ vic_image_run(dmy_struct *dmy_current) vic_run(&(atmos[i]), &(all_vars[i]), dmy_current, &global_param, &lake_con, &(soil_con[i]), veg_con[i], veg_lib[i]); put_data(&(all_vars[i]), &(atmos[i]), &(soil_con[i]), veg_con[i], - veg_lib[i], &lake_con, out_data[i], &(save_data[i]), - current); + veg_lib[i], &lake_con, out_data[i], &(save_data[i])); + } + + // run routing over the domain + rout_run(); // Routing routine (extension) + + for (i = 0; i < options.Noutstreams; i++) { + agg_stream_data(&(output_streams[i]), dmy_current, out_data); } } diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 8357a7b87..0a6cb1a40 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1561,6 +1561,9 @@ vic_init(void) initialize_energy(all_vars[i].energy, nveg); } + // set state metadata structure + set_state_meta_data_info(); + // cleanup free(dvar); free(ivar); diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index 5106859db..fb917dcfd 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -24,6 +24,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ +#include +#include #include /****************************************************************************** @@ -31,117 +33,271 @@ * write *****************************************************************************/ void -vic_init_output(void) +vic_init_output(dmy_struct *dmy_current) { - extern all_vars_struct *all_vars; - extern atmos_data_struct *atmos; - extern domain_struct local_domain; - extern filep_struct filep; - extern global_param_struct global_param; - extern MPI_Comm MPI_COMM_VIC; - extern MPI_Datatype mpi_nc_file_struct_type; - extern int mpi_rank; - extern nc_file_struct nc_hist_file; - extern nc_var_struct nc_vars[N_OUTVAR_TYPES]; - extern lake_con_struct lake_con; - extern out_data_struct **out_data; - extern save_data_struct *save_data; - extern soil_con_struct *soil_con; - extern veg_con_struct **veg_con; - extern veg_lib_struct **veg_lib; - - int status; - size_t i; + extern all_vars_struct *all_vars; + extern atmos_data_struct *atmos; + extern domain_struct local_domain; + extern filep_struct filep; + extern MPI_Comm MPI_COMM_VIC; + extern int mpi_rank; + extern nc_file_struct *nc_hist_files; + extern lake_con_struct lake_con; + extern double ***out_data; + extern save_data_struct *save_data; + extern soil_con_struct *soil_con; + extern veg_con_struct **veg_con; + extern veg_lib_struct **veg_lib; + extern option_struct options; + extern MPI_Datatype mpi_alarm_struct_type; + extern stream_struct *output_streams; + + int status; + size_t i; + size_t streamnum; + size_t nstream_vars[MAX_OUTPUT_STREAMS]; + bool default_outputs = false; // initialize the output data structures - for (i = 0; i < local_domain.ncells_active; i++) { - put_data(&(all_vars[i]), &(atmos[i]), &(soil_con[i]), veg_con[i], - veg_lib[i], &lake_con, out_data[i], &(save_data[i]), - -global_param.nrecs); - } + set_output_met_data_info(); - if (mpi_rank == 0) { - // determine which variables will be written to the history file - parse_output_info(filep.globalparam, out_data); + // allocate out_data + alloc_out_data(local_domain.ncells_active, &out_data); - // open the netcdf history file - initialize_history_file(&nc_hist_file); + // initialize the save data structures + for (i = 0; i < local_domain.ncells_active; i++) { + initialize_save_data(&(all_vars[i]), &(atmos[i]), &(soil_con[i]), + veg_con[i], veg_lib[i], &lake_con, out_data[i], + &(save_data[i])); } - // broadcast which variables to write. - for (i = 0; i < N_OUTVAR_TYPES; i++) { - status = MPI_Bcast(&out_data[0][i].write, 1, MPI_C_BOOL, - 0, MPI_COMM_VIC); - if (status != MPI_SUCCESS) { - log_err("MPI error in vic_init_output(): %d\n", status); + if (mpi_rank == VIC_MPI_ROOT) { + // count the number of streams and variables in the global parameter file + count_nstreams_nvars(filep.globalparam, &(options.Noutstreams), + nstream_vars); + + // If there weren't any output streams specified, get the defaults + if (options.Noutstreams == 0) { + default_outputs = true; + get_default_nstreams_nvars(&(options.Noutstreams), nstream_vars); } } - // broadcast history file info. Only the master process will write to it, - // but the slave processes need some of the information to initialize as - // well (particularly which variables to write and dimension sizes) - status = MPI_Bcast(&nc_hist_file, 1, mpi_nc_file_struct_type, - 0, MPI_COMM_VIC); + // broadcast Noutstreams and nstream_vars + status = MPI_Bcast(&(options.Noutstreams), 1, MPI_AINT, VIC_MPI_ROOT, + MPI_COMM_VIC); if (status != MPI_SUCCESS) { - log_err("MPI error in vic_init_output(): %d\n", status); + log_err("MPI error %d\n", status); + } + status = MPI_Bcast(&(nstream_vars), MAX_OUTPUT_STREAMS, MPI_AINT, + VIC_MPI_ROOT, + MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error %d\n", status); + } + + // allocate output streams + output_streams = calloc(options.Noutstreams, sizeof(*output_streams)); + if (output_streams == NULL) { + log_err("Memory allocation error"); + } + // allocate netcdf history files array + nc_hist_files = calloc(options.Noutstreams, sizeof(*nc_hist_files)); + if (nc_hist_files == NULL) { + log_err("Memory allocation error"); } - // initialize netcdf info for output variables - vic_nc_info(&nc_hist_file, out_data, nc_vars); + // allocate memory for streams, initialize to default/missing values + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + setup_stream(&(output_streams[streamnum]), nstream_vars[streamnum], + local_domain.ncells_active); + } + + if (mpi_rank == VIC_MPI_ROOT) { + if (default_outputs) { + // determine which variables will be written to the history file + set_output_defaults(&output_streams, dmy_current, NETCDF4_CLASSIC); + } + else { + // set output defaults + parse_output_info(filep.globalparam, &output_streams, dmy_current); + } + } + + // Now broadcast the arrays of shape nvars + for (streamnum = 0; streamnum < options.Noutstreams; streamnum++) { + // prefix + status = MPI_Bcast(output_streams[streamnum].prefix, + MAXSTRING, MPI_CHAR, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to prefix: %d\n", status); + } + + // filename + status = MPI_Bcast(output_streams[streamnum].filename, + MAXSTRING, MPI_CHAR, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to filename: %d\n", status); + } + + // skip fh + + // file_format + status = MPI_Bcast(&(output_streams[streamnum].file_format), + 1, MPI_UNSIGNED_SHORT, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to file_format: %d\n", status); + } + + // compress + status = MPI_Bcast(&(output_streams[streamnum].compress), + 1, MPI_SHORT, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to compress: %d\n", status); + } + + // type + status = MPI_Bcast(output_streams[streamnum].type, + output_streams[streamnum].nvars, + MPI_UNSIGNED_SHORT, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to type: %d\n", status); + } + + // mult + status = MPI_Bcast(output_streams[streamnum].mult, + output_streams[streamnum].nvars, + MPI_DOUBLE, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to mult: %d\n", status); + } + + // format + status = MPI_Bcast(output_streams[streamnum].format, + output_streams[streamnum].nvars * MAXSTRING, + MPI_CHAR, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to format: %d\n", status); + } + + // varid + status = MPI_Bcast(output_streams[streamnum].varid, + output_streams[streamnum].nvars, + MPI_UNSIGNED, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to varid: %d\n", status); + } + + // aggtype + status = MPI_Bcast(output_streams[streamnum].aggtype, + output_streams[streamnum].nvars, MPI_UNSIGNED_SHORT, + VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error brodcasting to aggtype: %d\n", status); + } + + // skip agg data + + // Now brodcast the alarms + status = MPI_Bcast(&(output_streams[streamnum].agg_alarm), 1, + mpi_alarm_struct_type, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error %d\n", status); + } + status = MPI_Bcast(&(output_streams[streamnum].write_alarm), 1, + mpi_alarm_struct_type, VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error %d\n", status); + } + + // allocate agg data + alloc_aggdata(&(output_streams[streamnum])); + + // setup netcdf files + initialize_nc_file(&(nc_hist_files[streamnum]), + output_streams[streamnum].nvars, + output_streams[streamnum].varid, + output_streams[streamnum].type); + + if (mpi_rank == VIC_MPI_ROOT) { + // open the netcdf history file + initialize_history_file(&(nc_hist_files[streamnum]), + &(output_streams[streamnum]), + dmy_current); + } + } + // validate streams + validate_streams(&output_streams); } /****************************************************************************** * @brief Initialize history files *****************************************************************************/ void -initialize_history_file(nc_file_struct *nc) +initialize_history_file(nc_file_struct *nc, + stream_struct *stream, + dmy_struct *dmy_current) { extern filenames_struct filenames; extern domain_struct global_domain; extern option_struct options; extern global_param_struct global_param; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; int status; int old_fill_mode; - char str[100]; - char strUnit[6]; - char strCalendar[50]; + char str[MAXSTRING]; + char unit_str[MAXSTRING]; + char calendar_str[MAXSTRING]; + char cell_method[MAXSTRING]; size_t i; + size_t j; size_t ndims; size_t dcount[MAXDIMS]; size_t dstart[MAXDIMS]; int dimids[MAXDIMS]; - int time_var_id; int lon_var_id; int lat_var_id; + unsigned int varid; double *dvar; - sprintf(nc->fname, "%s", filenames.result_dir); - - nc->c_fillvalue = NC_FILL_CHAR; - nc->i_fillvalue = NC_FILL_INT; - nc->d_fillvalue = NC_FILL_DOUBLE; - nc->f_fillvalue = NC_FILL_FLOAT; - nc->band_size = options.SNOW_BAND; - nc->front_size = MAX_FRONTS; - nc->frost_size = options.Nfrost; - nc->layer_size = options.Nlayer; - nc->ni_size = global_domain.n_nx; - nc->nj_size = global_domain.n_ny; - nc->node_size = options.Nnode; - nc->root_zone_size = options.ROOT_ZONES; - nc->time_size = NC_UNLIMITED; - nc->veg_size = options.NVEGTYPES; + // This could be further refined but for now, I've choosen a file naming + // Convention that goes like this: + switch (stream->agg_alarm.freq) { + // If FREQ_NDAYS -- filename = result_dir/prefix.YYYY-MM-DD.nc + case FREQ_NDAYS: + sprintf(stream->filename, "%s/%s.%04d-%02d-%02d.nc", + filenames.result_dir, + stream->prefix, dmy_current->year, dmy_current->month, + dmy_current->day); + break; + case FREQ_NMONTHS: + // If FREQ_NMONTHS -- filename = result_dir/prefix.YYYY-MM.nc + sprintf(stream->filename, "%s/%s.%04d-%02d.nc", filenames.result_dir, + stream->prefix, dmy_current->year, dmy_current->month); + break; + case FREQ_NYEARS: + // If FREQ_NYEARS -- filename = result_dir/prefix.YYYY.nc + sprintf(stream->filename, "%s/%s.%04d.nc", filenames.result_dir, + stream->prefix, dmy_current->year); + break; + default: + // For all other cases -- filename = result_dir/prefix.YYYY-MM-DD-SSSSS.nc + sprintf(stream->filename, "%s/%s.%04d-%02d-%02d-%05u.nc", + filenames.result_dir, + stream->prefix, dmy_current->year, dmy_current->month, + dmy_current->day, dmy_current->dayseconds); + } // open the netcdf file - status = - nc_create(nc->fname, get_nc_mode(options.OUT_FORMAT), &(nc->nc_id)); - if (status != NC_NOERR) { - log_err("Error creating %s", nc->fname); - } + status = nc_create(stream->filename, + get_nc_mode(stream->file_format), + &(nc->nc_id)); + + check_nc_status(status, "Error creating %s", stream->filename); nc->open = true; // Set netcdf file global attributes @@ -149,145 +305,83 @@ initialize_history_file(nc_file_struct *nc) // set the NC_FILL attribute status = nc_set_fill(nc->nc_id, NC_FILL, &old_fill_mode); - if (status != NC_NOERR) { - log_err("Error setting fill value in %s", nc->fname); - } + check_nc_status(status, "Error setting fill value in %s", stream->filename); // define netcdf dimensions status = nc_def_dim(nc->nc_id, "snow_band", nc->band_size, &(nc->band_dimid)); - if (status != NC_NOERR) { - log_err("Error defining snow_band dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining snow_band dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "front", nc->front_size, &(nc->front_dimid)); - if (status != NC_NOERR) { - log_err("Error defining front dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining front dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "frost_area", nc->frost_size, &(nc->frost_dimid)); - if (status != NC_NOERR) { - log_err("Error defining frost_area dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining frost_area dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "nlayer", nc->layer_size, &(nc->layer_dimid)); - if (status != NC_NOERR) { - log_err("Error defining nlayer dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining nlayer dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, global_domain.info.x_dim, nc->ni_size, &(nc->ni_dimid)); - if (status != NC_NOERR) { - log_err("Error defining x dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining x dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, global_domain.info.y_dim, nc->nj_size, &(nc->nj_dimid)); - if (status != NC_NOERR) { - log_err("Error defining y dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining y dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "node", nc->node_size, &(nc->node_dimid)); - if (status != NC_NOERR) { - log_err("Error defining node dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining node dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "root_zone", nc->root_zone_size, &(nc->root_zone_dimid)); - if (status != NC_NOERR) { - log_err("Error defining root_zone dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining root_zone dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "veg_class", nc->veg_size, &(nc->veg_dimid)); - if (status != NC_NOERR) { - log_err("Error defining veg_class dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining veg_class dimenension in %s", + stream->filename); status = nc_def_dim(nc->nc_id, "time", nc->time_size, &(nc->time_dimid)); - if (status != NC_NOERR) { - log_err("Error defining time dimenension in %s", nc->fname); - } + check_nc_status(status, "Error defining time dimenension in %s", + stream->filename); // define the netcdf variable time status = nc_def_var(nc->nc_id, "time", NC_DOUBLE, 1, - &(nc->time_dimid), &(time_var_id)); - if (status != NC_NOERR) { - log_err("Error defining time variable in %s", nc->fname); - } - status = nc_put_att_text(nc->nc_id, time_var_id, "standard_name", + &(nc->time_dimid), &(nc->time_varid)); + check_nc_status(status, "Error defining time variable in %s", + stream->filename); + status = nc_put_att_text(nc->nc_id, nc->time_varid, "standard_name", strlen("time"), "time"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding attribute in %s", stream->filename); // adding units attribute to time variable - if (global_param.time_units == TIME_UNITS_SECONDS) { - sprintf(strUnit, "seconds"); - } - else if (global_param.time_units == TIME_UNITS_MINUTES) { - sprintf(strUnit, "minutes"); - } - else if (global_param.time_units == TIME_UNITS_HOURS) { - sprintf(strUnit, "hours"); - } - else if (global_param.time_units == TIME_UNITS_DAYS) { - sprintf(strUnit, "days"); - } - else { - log_err("Invalid value, or no value for OUT_TIME_UNITS (%d).", - global_param.time_units); - } + str_from_time_units(global_param.time_units, unit_str); - sprintf(str, "%s since 0001-01-01 00:00:00", strUnit); + sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); - status = nc_put_att_text(nc->nc_id, time_var_id, "units", + status = nc_put_att_text(nc->nc_id, nc->time_varid, "units", strlen(str), str); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding attribute in %s", stream->filename); // adding calendar attribute to time variable - if (global_param.calendar == CALENDAR_STANDARD) { - sprintf(strCalendar, "standard"); - } - else if (global_param.calendar == CALENDAR_GREGORIAN) { - sprintf(strCalendar, "gregorian"); - } - else if (global_param.calendar == CALENDAR_PROLEPTIC_GREGORIAN) { - sprintf(strCalendar, "proleptic_gregorian"); - } - else if (global_param.calendar == CALENDAR_NOLEAP) { - sprintf(strCalendar, "noleap"); - } - else if (global_param.calendar == CALENDAR_365_DAY) { - sprintf(strCalendar, "365_day"); - } - else if (global_param.calendar == CALENDAR_360_DAY) { - sprintf(strCalendar, "360_day"); - } - else if (global_param.calendar == CALENDAR_JULIAN) { - sprintf(strCalendar, "julian"); - } - else if (global_param.calendar == CALENDAR_ALL_LEAP) { - sprintf(strCalendar, "all_leap"); - } - else if (global_param.calendar == CALENDAR_366_DAY) { - sprintf(strCalendar, "366_day"); - } - else { - log_err("Invalid, or no calendar specified"); - } - status = nc_put_att_text(nc->nc_id, time_var_id, "calendar", - strlen(strCalendar), strCalendar); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + str_from_calendar(global_param.calendar, calendar_str); + + status = nc_put_att_text(nc->nc_id, nc->time_varid, "calendar", + strlen(calendar_str), calendar_str); + check_nc_status(status, "Error adding attribute in %s", stream->filename); ndims = global_domain.info.n_coord_dims; dstart[0] = 0; @@ -309,27 +403,25 @@ initialize_history_file(nc_file_struct *nc) } // define the netcdf variable longitude - status = nc_def_var(nc->nc_id, global_domain.info.lon_var, NC_DOUBLE, ndims, - dimids, &(lon_var_id)); - if (status != NC_NOERR) { - log_err("Error defining lon variable in %s", nc->fname); - } + status = + nc_def_var(nc->nc_id, global_domain.info.lon_var, NC_DOUBLE, ndims, + dimids, &(lon_var_id)); + check_nc_status(status, "Error defining lon variable in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lon_var_id, "long_name", strlen("longitude"), "longitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding longitude long_name attribute in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lon_var_id, "units", strlen("degrees_east"), "degrees_east"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding longitude units attribute in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lon_var_id, "standard_name", strlen("longitude"), "longitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, + "Error adding longitude standard_name attribute in %s", + stream->filename); if (global_domain.info.n_coord_dims == 1) { dimids[0] = nc->nj_dimid; @@ -339,36 +431,109 @@ initialize_history_file(nc_file_struct *nc) // define the netcdf variable latitude status = nc_def_var(nc->nc_id, global_domain.info.lat_var, NC_DOUBLE, ndims, dimids, &(lat_var_id)); - if (status != NC_NOERR) { - log_err("Error defining lat variable in %s", nc->fname); - } + check_nc_status(status, "Error defining lat variable in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lat_var_id, "long_name", strlen("latitude"), "latitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding latitude long_name attribute in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lat_var_id, "units", strlen("degrees_north"), "degrees_north"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); - } + check_nc_status(status, "Error adding latitude units attribute in %s", + stream->filename); status = nc_put_att_text(nc->nc_id, lat_var_id, "standard_name", strlen("latitude"), "latitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc->fname); + check_nc_status(status, + "Error adding latitude standard_name attribute in %s", + stream->filename); + + // create output variables + for (j = 0; j < stream->nvars; j++) { + varid = stream->varid[j]; + + set_nc_var_dimids(varid, nc, &(nc->nc_vars[j])); + + // define the variable + status = nc_def_var(nc->nc_id, + out_metadata[varid].varname, + nc->nc_vars[j].nc_type, + nc->nc_vars[j].nc_dims, + nc->nc_vars[j].nc_dimids, + &(nc->nc_vars[j].nc_varid)); + check_nc_status(status, "Error defining variable %s in %s. Status: %d", + out_metadata[varid].varname, stream->filename, status); + + // Add compression (only works for netCDF4 filetype) + if (stream->compress) { + status = nc_def_var_deflate(nc->nc_id, nc->nc_vars[j].nc_varid, + true, true, stream->compress); + check_nc_status( + status, + "Error setting compression level in %s for variable: %s", + stream->filename, out_metadata[varid].varname); + } + + // set the fill value attribute + switch (nc->nc_vars[j].nc_type) { + case NC_DOUBLE: + status = nc_put_att_double(nc->nc_id, nc->nc_vars[j].nc_varid, + "_FillValue", NC_DOUBLE, 1, + &(nc->d_fillvalue)); + break; + case NC_FLOAT: + status = nc_put_att_float(nc->nc_id, nc->nc_vars[j].nc_varid, + "_FillValue", NC_FLOAT, 1, + &(nc->f_fillvalue)); + break; + case NC_INT: + status = nc_put_att_int(nc->nc_id, nc->nc_vars[j].nc_varid, + "_FillValue", NC_INT, 1, + &(nc->i_fillvalue)); + break; + case NC_SHORT: + log_err("NC_SHORT not supported yet"); + break; + case NC_CHAR: + log_err("NC_CHAR not supported yet"); + break; + case NC_BYTE: + log_err("NC_BYTE not supported yet"); + break; + default: + log_err("NC_TYPE %d not supported at this time", + nc->nc_vars[j].nc_type); + } + // check status of fill value setting + check_nc_status(status, + "Error (%d) putting _FillValue attribute to %s in %s", + status, out_metadata[varid].varname, stream->filename); + + put_nc_attr(nc->nc_id, nc->nc_vars[j].nc_varid, "long_name", + out_metadata[varid].long_name); + put_nc_attr(nc->nc_id, nc->nc_vars[j].nc_varid, "standard_name", + out_metadata[varid].standard_name); + put_nc_attr(nc->nc_id, nc->nc_vars[j].nc_varid, "units", + out_metadata[varid].units); + put_nc_attr(nc->nc_id, nc->nc_vars[j].nc_varid, "description", + out_metadata[varid].description); + + if (cell_method_from_agg_type(stream->aggtype[j], cell_method)) { + put_nc_attr(nc->nc_id, nc->nc_vars[j].nc_varid, "cell_methods", + cell_method); + // NOTE: if cell_methods == variance, units should be ^2 + } } // leave define mode status = nc_enddef(nc->nc_id); - if (status != NC_NOERR) { - log_err("Error leaving define mode for %s", nc->fname); - } + check_nc_status(status, "Error leaving define mode for %s", + stream->filename); // fill the netcdf variables lat/lon if (global_domain.info.n_coord_dims == 1) { dvar = calloc(nc->ni_size, sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in vic_init_output()."); + log_err("Memory allocation error"); } dcount[0] = nc->ni_size; @@ -377,14 +542,13 @@ initialize_history_file(nc_file_struct *nc) } status = nc_put_vara_double(nc->nc_id, lon_var_id, dstart, dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc->fname); - } + check_nc_status(status, "Error adding data to lon in %s", + stream->filename); free(dvar); dvar = calloc(nc->nj_size, sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in vic_init_output()."); + log_err("Memory allocation error"); } dcount[0] = nc->nj_size; for (i = 0; i < nc->nj_size; i++) { @@ -394,15 +558,14 @@ initialize_history_file(nc_file_struct *nc) status = nc_put_vara_double(nc->nc_id, lat_var_id, dstart, dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc->fname); - } + check_nc_status(status, "Error adding data to lon in %s", + stream->filename); free(dvar); } else if (global_domain.info.n_coord_dims == 2) { dvar = calloc(nc->nj_size * nc->ni_size, sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in vic_init_output()."); + log_err("Memory allocation error"); } for (i = 0; i < nc->nj_size * nc->ni_size; i++) { @@ -410,18 +573,16 @@ initialize_history_file(nc_file_struct *nc) } status = nc_put_vara_double(nc->nc_id, lon_var_id, dstart, dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc->fname); - } + check_nc_status(status, "Error adding data to lon in %s", + stream->filename); for (i = 0; i < nc->nj_size * nc->ni_size; i++) { dvar[i] = (double) global_domain.locations[i].latitude; } status = nc_put_vara_double(nc->nc_id, lat_var_id, dstart, dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lat in %s", nc->fname); - } + check_nc_status(status, "Error adding data to lat in %s", + stream->filename); free(dvar); } @@ -430,42 +591,24 @@ initialize_history_file(nc_file_struct *nc) } } -/****************************************************************************** - * @brief Determine the netCDF file format - *****************************************************************************/ -int -get_nc_mode(unsigned short int format) -{ - if (format == NETCDF3_CLASSIC) { - return (NC_CLASSIC_MODEL); - } - else if (format == NETCDF3_64BIT_OFFSET) { - return (NC_64BIT_OFFSET); - } - else if (format == NETCDF4_CLASSIC) { - return (NC_NETCDF4 | NC_CLASSIC_MODEL); - } - else if (format == NETCDF4) { - return (NC_NETCDF4); - } - else { - log_err("Unrecognized netCDF file format"); - } -} - /****************************************************************************** * @brief Set global netcdf attributes (either history or state file) *****************************************************************************/ void -set_global_nc_attributes(int ncid, - unsigned short int file_type) +set_global_nc_attributes(int ncid, + unsigned short int + file_type) { - char tmpstr[MAXSTRING]; - char userstr[MAXSTRING]; - char hoststr[MAXSTRING]; - - time_t curr_date_time; - struct tm *timeinfo; + char tmpstr[MAXSTRING]; + char userstr[MAXSTRING]; + char hoststr[MAXSTRING]; + char mpistr[MPI_MAX_LIBRARY_VERSION_STRING]; + int len; + int status; + time_t curr_date_time; + struct tm *timeinfo; + uid_t uid; + struct passwd *pw; // datestr curr_date_time = time(NULL); @@ -475,9 +618,16 @@ set_global_nc_attributes(int ncid, timeinfo = localtime(&curr_date_time); // username - if (getlogin_r(userstr, MAXSTRING) != 0) { - // log_err("Error getting username"); + uid = geteuid(); + pw = getpwuid(uid); + + if (pw) { + strcpy(userstr, pw->pw_name); } + else { + strcpy(userstr, "unknown"); + } + // hostname if (gethostname(hoststr, MAXSTRING) != 0) { log_err("Error getting hostname"); @@ -505,12 +655,76 @@ set_global_nc_attributes(int ncid, "hydrologically Based Model of Land Surface Water and Energy " "Fluxes for GSMs, J. Geophys. Res., 99(D7), 14,415-14,428."); put_nc_attr(ncid, NC_GLOBAL, "comment", - "Output from the Variable Infiltration Capacity (VIC)" + "Output from the Variable Infiltration Capacity (VIC) " "Macroscale Hydrologic Model"); put_nc_attr(ncid, NC_GLOBAL, "Conventions", "CF-1.6"); + put_nc_attr(ncid, NC_GLOBAL, "netcdf_lib_version", nc_inq_libvers()); + status = MPI_Get_library_version(mpistr, &len); + if (status == MPI_SUCCESS) { + put_nc_attr(ncid, NC_GLOBAL, "mpi_lib_version", mpistr); + } // Useful attributes from VIC put_nc_attr(ncid, NC_GLOBAL, "VIC_Model_Version", VERSION); + put_nc_attr(ncid, NC_GLOBAL, "VIC_GIT_VERSION", GIT_VERSION); // TODO: pass in driver as an argmument to this function put_nc_attr(ncid, NC_GLOBAL, "VIC_Driver", "Image"); } + +/****************************************************************************** + * @brief Set global netcdf attributes (either history or state file) + *****************************************************************************/ +void +initialize_nc_file(nc_file_struct *nc_file, + size_t nvars, + unsigned int *varids, + unsigned short int *dtypes) +{ + extern option_struct options; + extern domain_struct global_domain; + + size_t i; + + // Set fill values + nc_file->c_fillvalue = NC_FILL_CHAR; + nc_file->s_fillvalue = NC_FILL_SHORT; + nc_file->i_fillvalue = NC_FILL_INT; + nc_file->d_fillvalue = NC_FILL_DOUBLE; + nc_file->f_fillvalue = NC_FILL_FLOAT; + + // set ids to MISSING + nc_file->nc_id = MISSING; + nc_file->band_dimid = MISSING; + nc_file->front_dimid = MISSING; + nc_file->frost_dimid = MISSING; + nc_file->lake_node_dimid = MISSING; + nc_file->layer_dimid = MISSING; + nc_file->ni_dimid = MISSING; + nc_file->nj_dimid = MISSING; + nc_file->node_dimid = MISSING; + nc_file->root_zone_dimid = MISSING; + nc_file->time_dimid = MISSING; + nc_file->veg_dimid = MISSING; + + // Set dimension sizes + nc_file->band_size = options.SNOW_BAND; + nc_file->front_size = MAX_FRONTS; + nc_file->frost_size = options.Nfrost; + nc_file->layer_size = options.Nlayer; + nc_file->ni_size = global_domain.n_nx; + nc_file->nj_size = global_domain.n_ny; + nc_file->node_size = options.Nnode; + nc_file->root_zone_size = options.ROOT_ZONES; + nc_file->time_size = NC_UNLIMITED; + nc_file->veg_size = options.NVEGTYPES; + + // allocate memory for nc_vars + nc_file->nc_vars = calloc(nvars, sizeof(*(nc_file->nc_vars))); + if (nc_file->nc_vars == NULL) { + log_err("Memory allocation error"); + } + + for (i = 0; i < nvars; i++) { + set_nc_var_info(varids[i], dtypes[i], nc_file, &(nc_file->nc_vars[i])); + } +} diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 2f677a5ee..6c5a7436e 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -35,9 +35,9 @@ initialize_mpi(void) extern MPI_Datatype mpi_global_struct_type; extern MPI_Datatype mpi_filenames_struct_type; extern MPI_Datatype mpi_location_struct_type; - extern MPI_Datatype mpi_nc_file_struct_type; extern MPI_Datatype mpi_option_struct_type; extern MPI_Datatype mpi_param_struct_type; + extern MPI_Datatype mpi_alarm_struct_type; extern MPI_Comm MPI_COMM_VIC; extern int mpi_rank; extern int mpi_size; @@ -58,7 +58,7 @@ initialize_mpi(void) create_MPI_global_struct_type(&mpi_global_struct_type); create_MPI_filenames_struct_type(&mpi_filenames_struct_type); create_MPI_location_struct_type(&mpi_location_struct_type); - create_MPI_nc_file_struct_type(&mpi_nc_file_struct_type); + create_MPI_alarm_struct_type(&mpi_alarm_struct_type); create_MPI_option_struct_type(&mpi_option_struct_type); create_MPI_param_struct_type(&mpi_param_struct_type); } @@ -83,7 +83,7 @@ create_MPI_global_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in global_param_struct - nitems = 33; + nitems = 31; blocklengths = malloc(nitems * sizeof(*blocklengths)); if (blocklengths == NULL) { log_err("Memory allocation error in create_MPI_global_struct_type().") @@ -132,10 +132,6 @@ create_MPI_global_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(global_param_struct, atmos_dt); mpi_types[i++] = MPI_DOUBLE; - // double out_dt; - offsets[i] = offsetof(global_param_struct, out_dt); - mpi_types[i++] = MPI_DOUBLE; - // size_t model_steps_per_day; offsets[i] = offsetof(global_param_struct, model_steps_per_day); mpi_types[i++] = MPI_AINT; @@ -152,10 +148,6 @@ create_MPI_global_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(global_param_struct, atmos_steps_per_day); mpi_types[i++] = MPI_AINT; - // size_t output_steps_per_day; - offsets[i] = offsetof(global_param_struct, output_steps_per_day); - mpi_types[i++] = MPI_AINT; - // unsigned short endday; offsets[i] = offsetof(global_param_struct, endday); mpi_types[i++] = MPI_UNSIGNED_SHORT; @@ -202,10 +194,6 @@ create_MPI_global_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(global_param_struct, nrecs); mpi_types[i++] = MPI_AINT; - // unsigned short int skipyear; - offsets[i] = offsetof(global_param_struct, skipyear); - mpi_types[i++] = MPI_UNSIGNED_SHORT; - // unsigned short int startday; offsets[i] = offsetof(global_param_struct, startday); mpi_types[i++] = MPI_UNSIGNED_SHORT; @@ -246,6 +234,11 @@ create_MPI_global_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(global_param_struct, time_origin_num); mpi_types[i++] = MPI_DOUBLE; + // char time_origin_str[MAXSTRING]; + offsets[i] = offsetof(global_param_struct, time_origin_str); + blocklengths[i] = MAXSTRING; + mpi_types[i++] = MPI_CHAR; + // make sure that the we have the right number of elements if (i != (size_t) nitems) { log_err("Miscount in create_MPI_global_struct_type(): " @@ -416,7 +409,7 @@ create_MPI_location_struct_type(MPI_Datatype *mpi_type) MPI_Aint *offsets; MPI_Datatype *mpi_types; - // nitems has to equal the number of elements in global_param_struct + // nitems has to equal the number of elements in location_struct nitems = 9; blocklengths = malloc(nitems * sizeof(*blocklengths)); if (blocklengths == NULL) { @@ -500,189 +493,6 @@ create_MPI_location_struct_type(MPI_Datatype *mpi_type) free(mpi_types); } -/****************************************************************************** - * @brief Create an MPI_Datatype that represents the nc_file_struct - * @details This allows MPI operations in which the entire nc_file_struct can - * be treated as an MPI_Datatype. NOTE: This function needs to be kept - * in-sync with the nc_file_struct data type in vic_driver_image.h. - * - * @param mpi_type MPI_Datatype that can be used in MPI operations - *****************************************************************************/ -void -create_MPI_nc_file_struct_type(MPI_Datatype *mpi_type) -{ - int nitems; // number of elements in struct - int status; - int *blocklengths; - size_t i; - MPI_Aint *offsets; - MPI_Datatype *mpi_types; - - // nitems has to equal the number of elements in nc_file_struct - nitems = 29; - blocklengths = malloc(nitems * sizeof(*blocklengths)); - if (blocklengths == NULL) { - log_err("Memory allocation error in create_MPI_nc_file_struct_type().") - } - - offsets = malloc(nitems * sizeof(*offsets)); - if (offsets == NULL) { - log_err("Memory allocation error in create_MPI_nc_file_struct_type().") - } - - mpi_types = malloc(nitems * sizeof(*mpi_types)); - if (mpi_types == NULL) { - log_err("Memory allocation error in create_MPI_nc_file_struct_type().") - } - - // only the first element in nc_file_struct is an array - i = 0; - blocklengths[i] = MAXSTRING + 1; - for (i = 1; i < (size_t) nitems; i++) { - blocklengths[i] = 1; - } - - // reset i - i = 0; - - // char fname[MAXSTRING + 1]; - offsets[i] = offsetof(nc_file_struct, fname); - mpi_types[i++] = MPI_CHAR; - - // char c_fillvalue; - offsets[i] = offsetof(nc_file_struct, c_fillvalue); - mpi_types[i++] = MPI_CHAR; - - // int i_fillvalue; - offsets[i] = offsetof(nc_file_struct, i_fillvalue); - mpi_types[i++] = MPI_INT; - - // double d_fillvalue; - offsets[i] = offsetof(nc_file_struct, d_fillvalue); - mpi_types[i++] = MPI_DOUBLE; - - // float f_fillvalue; - offsets[i] = offsetof(nc_file_struct, f_fillvalue); - mpi_types[i++] = MPI_FLOAT; - - // int nc_id; - offsets[i] = offsetof(nc_file_struct, nc_id); - mpi_types[i++] = MPI_INT; - - // int band_dimid; - offsets[i] = offsetof(nc_file_struct, band_dimid); - mpi_types[i++] = MPI_INT; - - // int front_dimid; - offsets[i] = offsetof(nc_file_struct, front_dimid); - mpi_types[i++] = MPI_INT; - - // int frost_dimid; - offsets[i] = offsetof(nc_file_struct, frost_dimid); - mpi_types[i++] = MPI_INT; - - // int lake_node_dimid; - offsets[i] = offsetof(nc_file_struct, lake_node_dimid); - mpi_types[i++] = MPI_INT; - - // int layer_dimid; - offsets[i] = offsetof(nc_file_struct, layer_dimid); - mpi_types[i++] = MPI_INT; - - // int ni_dimid; - offsets[i] = offsetof(nc_file_struct, ni_dimid); - mpi_types[i++] = MPI_INT; - - // int nj_dimid; - offsets[i] = offsetof(nc_file_struct, nj_dimid); - mpi_types[i++] = MPI_INT; - - // int node_dimid; - offsets[i] = offsetof(nc_file_struct, node_dimid); - mpi_types[i++] = MPI_INT; - - // int root_zone_dimid; - offsets[i] = offsetof(nc_file_struct, root_zone_dimid); - mpi_types[i++] = MPI_INT; - - // int time_dimid; - offsets[i] = offsetof(nc_file_struct, time_dimid); - mpi_types[i++] = MPI_INT; - - // int veg_dimid; - offsets[i] = offsetof(nc_file_struct, veg_dimid); - mpi_types[i++] = MPI_INT; - - // size_t band_size; - offsets[i] = offsetof(nc_file_struct, band_size); - mpi_types[i++] = MPI_AINT; - - // size_t front_size; - offsets[i] = offsetof(nc_file_struct, front_size); - mpi_types[i++] = MPI_AINT; - - // size_t frost_size; - offsets[i] = offsetof(nc_file_struct, frost_size); - mpi_types[i++] = MPI_AINT; - - // size_t lake_node_size; - offsets[i] = offsetof(nc_file_struct, lake_node_size); - mpi_types[i++] = MPI_AINT; - - // size_t layer_size; - offsets[i] = offsetof(nc_file_struct, layer_size); - mpi_types[i++] = MPI_AINT; - - // size_t ni_size; - offsets[i] = offsetof(nc_file_struct, ni_size); - mpi_types[i++] = MPI_AINT; - - // size_t nj_size; - offsets[i] = offsetof(nc_file_struct, nj_size); - mpi_types[i++] = MPI_AINT; - - // size_t node_size; - offsets[i] = offsetof(nc_file_struct, node_size); - mpi_types[i++] = MPI_AINT; - - // size_t root_zone_size; - offsets[i] = offsetof(nc_file_struct, root_zone_size); - mpi_types[i++] = MPI_AINT; - - // size_t time_size; - offsets[i] = offsetof(nc_file_struct, time_size); - mpi_types[i++] = MPI_AINT; - - // size_t veg_size; - offsets[i] = offsetof(nc_file_struct, veg_size); - mpi_types[i++] = MPI_AINT; - - // bool open; - offsets[i] = offsetof(nc_file_struct, open); - mpi_types[i++] = MPI_C_BOOL; - - // make sure that the we have the right number of elements - if (i != (size_t) nitems) { - log_err("Miscount in create_MPI_nc_file_struct_type(): " - "%zd not equal to %d\n", i, nitems); - } - - status = MPI_Type_create_struct(nitems, blocklengths, offsets, mpi_types, - mpi_type); - if (status != MPI_SUCCESS) { - log_err("MPI error in create_MPI_nc_file_struct_type(): %d\n", status); - } - status = MPI_Type_commit(mpi_type); - if (status != MPI_SUCCESS) { - log_err("MPI error in create_MPI_nc_file_struct_type(): %d\n", status); - } - - // cleanup - free(blocklengths); - free(offsets); - free(mpi_types); -} - /****************************************************************************** * @brief Create an MPI_Datatype that represents the option_struct * @details This allows MPI operations in which the entire option_struct can @@ -702,7 +512,7 @@ create_MPI_option_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in option_struct - nitems = 60; + nitems = 53; blocklengths = malloc(nitems * sizeof(*blocklengths)); if (blocklengths == NULL) { log_err("Memory allocation error in create_MPI_option_struct_type().") @@ -938,34 +748,6 @@ create_MPI_option_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(option_struct, SAVE_STATE); mpi_types[i++] = MPI_C_BOOL; - // bool ALMA_OUTPUT; - offsets[i] = offsetof(option_struct, ALMA_OUTPUT); - mpi_types[i++] = MPI_C_BOOL; - - // unsigned short OUT_FORMAT; - offsets[i] = offsetof(option_struct, OUT_FORMAT); - mpi_types[i++] = MPI_UNSIGNED_SHORT; - - // bool COMPRESS; - offsets[i] = offsetof(option_struct, COMPRESS); - mpi_types[i++] = MPI_C_BOOL; - - // bool MOISTFRACT; - offsets[i] = offsetof(option_struct, MOISTFRACT); - mpi_types[i++] = MPI_C_BOOL; - - // size_t Noutfiles; - offsets[i] = offsetof(option_struct, Noutfiles); - mpi_types[i++] = MPI_AINT; // note there is no MPI_SIZE_T equivalent - - // bool PRT_HEADER; - offsets[i] = offsetof(option_struct, PRT_HEADER); - mpi_types[i++] = MPI_C_BOOL; - - // bool PRT_SNOW_BAND; - offsets[i] = offsetof(option_struct, PRT_SNOW_BAND); - mpi_types[i++] = MPI_C_BOOL; - // make sure that the we have the right number of elements if (i != (size_t) nitems) { log_err("Miscount in create_MPI_option_struct_type(): " @@ -1670,6 +1452,179 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) free(mpi_types); } +/****************************************************************************** + * @brief Create an MPI_Datatype that represents the dmy_struct + * @details This allows MPI operations in which the entire dmy_struct + * can be treated as an MPI_Datatype. + * @param mpi_type MPI_Datatype that can be used in MPI operations + *****************************************************************************/ +void +create_MPI_dmy_struct_type(MPI_Datatype *mpi_type) +{ + int nitems; // number of elements in struct + int status; + int *blocklengths; + size_t i; + MPI_Aint *offsets; + MPI_Datatype *mpi_types; + + // nitems has to equal the number of elements in dmy_struct + nitems = 5; + blocklengths = malloc(nitems * sizeof(*blocklengths)); + if (blocklengths == NULL) { + log_err("Memory allocation error") + } + + offsets = malloc(nitems * sizeof(*offsets)); + if (offsets == NULL) { + log_err("Memory allocation error") + } + + mpi_types = malloc(nitems * sizeof(*mpi_types)); + if (mpi_types == NULL) { + log_err("Memory allocation error") + } + + // none of the elements in location_struct are arrays. + for (i = 0; i < (size_t) nitems; i++) { + blocklengths[i] = 1; + } + + // reset i + i = 0; + + // unsigned short int day; + offsets[i] = offsetof(dmy_struct, day); + mpi_types[i++] = MPI_UNSIGNED_SHORT; + + // unsigned short int day_in_year; + offsets[i] = offsetof(dmy_struct, day_in_year); + mpi_types[i++] = MPI_UNSIGNED_SHORT; + + // unsigned short int month; + offsets[i] = offsetof(dmy_struct, month); + mpi_types[i++] = MPI_UNSIGNED_SHORT; + + // int year; + offsets[i] = offsetof(dmy_struct, year); + mpi_types[i++] = MPI_INT; + + // unsigned int dayseconds; + offsets[i] = offsetof(dmy_struct, dayseconds); + mpi_types[i++] = MPI_UNSIGNED; + + // make sure that the we have the right number of elements + if (i != (size_t) nitems) { + log_err("Miscount: %zd not equal to %d\n", i, nitems); + } + + status = MPI_Type_create_struct(nitems, blocklengths, offsets, mpi_types, + mpi_type); + if (status != MPI_SUCCESS) { + log_err("MPI error: %d\n", status); + } + + status = MPI_Type_commit(mpi_type); + if (status != MPI_SUCCESS) { + log_err("MPI error: %d\n", status); + } + + // cleanup + free(blocklengths); + free(offsets); + free(mpi_types); +} + +/****************************************************************************** + * @brief Create an MPI_Datatype that represents the alarm_struct + * @details This allows MPI operations in which the entire alarm_struct + * can be treated as an MPI_Datatype. + * @param mpi_type MPI_Datatype that can be used in MPI operations + *****************************************************************************/ +void +create_MPI_alarm_struct_type(MPI_Datatype *mpi_type) +{ + int nitems; // number of elements in struct + int status; + int *blocklengths; + size_t i; + MPI_Aint *offsets; + MPI_Datatype *mpi_types; + MPI_Datatype mpi_dmy_type; + + // nitems has to equal the number of elements in alarm_struct + nitems = 6; + blocklengths = malloc(nitems * sizeof(*blocklengths)); + if (blocklengths == NULL) { + log_err("Memory allocation error") + } + + offsets = malloc(nitems * sizeof(*offsets)); + if (offsets == NULL) { + log_err("Memory allocation error") + } + + mpi_types = malloc(nitems * sizeof(*mpi_types)); + if (mpi_types == NULL) { + log_err("Memory allocation error") + } + + // none of the elements in location_struct are arrays. + for (i = 0; i < (size_t) nitems; i++) { + blocklengths[i] = 1; + } + + // reset i + i = 0; + + // unsigned int count; + offsets[i] = offsetof(alarm_struct, count); + mpi_types[i++] = MPI_UNSIGNED; + + // int next; + offsets[i] = offsetof(alarm_struct, next); + mpi_types[i++] = MPI_INT; + + // unsigned int freq; + offsets[i] = offsetof(alarm_struct, freq); + mpi_types[i++] = MPI_UNSIGNED; + + // int n; + offsets[i] = offsetof(alarm_struct, n); + mpi_types[i++] = MPI_INT; + + // dmy_struct date; + offsets[i] = offsetof(alarm_struct, date); + create_MPI_dmy_struct_type(&mpi_dmy_type); + mpi_types[i++] = mpi_dmy_type; + + // bool is_subdaily; + offsets[i] = offsetof(alarm_struct, is_subdaily); + mpi_types[i++] = MPI_C_BOOL; + + // make sure that the we have the right number of elements + if (i != (size_t) nitems) { + log_err("Miscount: %zd not equal to %d\n", i, nitems); + } + + status = MPI_Type_create_struct(nitems, blocklengths, offsets, mpi_types, + mpi_type); + if (status != MPI_SUCCESS) { + log_err("MPI error: %d\n", status); + } + + status = MPI_Type_commit(mpi_type); + if (status != MPI_SUCCESS) { + log_err("MPI error: %d\n", status); + } + + // cleanup + free(blocklengths); + free(offsets); + free(mpi_types); + MPI_Type_free(&mpi_dmy_type); +} + /****************************************************************************** * @brief Type-agnostic mapping function * @details Reorders the elements in 'from' to 'to' according to the ordering @@ -1792,13 +1747,9 @@ mpi_map_decomp_domain(size_t ncells, * master node *****************************************************************************/ void -gather_put_nc_field_double(char *nc_name, - bool *open, - int *nc_id, +gather_put_nc_field_double(int nc_id, + int var_id, double fillval, - int *dimids, - int ndims, - char *var_name, size_t *start, size_t *count, double *var) @@ -1818,26 +1769,24 @@ gather_put_nc_field_double(char *nc_name, size_t grid_size; size_t i; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { grid_size = global_domain.n_nx * global_domain.n_ny; dvar = malloc(grid_size * sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in gather_put_nc_field_double()."); + log_err("Memory allocation error."); } for (i = 0; i < grid_size; i++) { dvar[i] = fillval; } - dvar_gathered = malloc(global_domain.ncells_active * sizeof(*dvar_gathered)); if (dvar_gathered == NULL) { - log_err("Memory allocation error in gather_put_nc_field_double()."); + log_err("Memory allocation error."); } - dvar_remapped = malloc(global_domain.ncells_active * sizeof(*dvar_remapped)); if (dvar_remapped == NULL) { - log_err("Memory allocation error in gather_put_nc_field_double()."); + log_err("Memory allocation error."); } } // Gather the results from the nodes, result for the local node is in the @@ -1845,23 +1794,20 @@ gather_put_nc_field_double(char *nc_name, status = MPI_Gatherv(var, local_domain.ncells_active, MPI_DOUBLE, dvar_gathered, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { - fprintf(stderr, "MPI error in main(): %d\n", status); - exit(EXIT_FAILURE); + log_err("MPI error"); } - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // remap the array map(sizeof(double), global_domain.ncells_active, NULL, - mpi_map_mapping_array, - dvar_gathered, dvar_remapped); + mpi_map_mapping_array, dvar_gathered, dvar_remapped); // expand to full grid size map(sizeof(double), global_domain.ncells_active, NULL, - filter_active_cells, - dvar_remapped, dvar); - // write to file - put_nc_field_double(nc_name, open, nc_id, fillval, dimids, ndims, - var_name, start, count, dvar); + filter_active_cells, dvar_remapped, dvar); + + status = nc_put_vara_double(nc_id, var_id, start, count, dvar); + check_nc_status(status, "Error writing values"); // cleanup free(dvar); free(dvar_gathered); @@ -1869,19 +1815,93 @@ gather_put_nc_field_double(char *nc_name, } } +/****************************************************************************** + * @brief Gather and write double precision NetCDF field + * @details Values are gathered to the master node and then written from the + * master node + *****************************************************************************/ +void +gather_put_nc_field_float(int nc_id, + int var_id, + float fillval, + size_t *start, + size_t *count, + float *var) +{ + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + float *fvar = NULL; + float *fvar_gathered = NULL; + float *fvar_remapped = NULL; + size_t grid_size; + size_t i; + + debug("checkpoint"); + + if (mpi_rank == VIC_MPI_ROOT) { + grid_size = global_domain.n_nx * global_domain.n_ny; + fvar = malloc(grid_size * sizeof(*fvar)); + if (fvar == NULL) { + log_err("Memory allocation error."); + } + for (i = 0; i < grid_size; i++) { + fvar[i] = fillval; + } + fvar_gathered = + malloc(global_domain.ncells_active * sizeof(*fvar_gathered)); + if (fvar_gathered == NULL) { + log_err("Memory allocation error."); + } + fvar_remapped = + malloc(global_domain.ncells_active * sizeof(*fvar_remapped)); + if (fvar_remapped == NULL) { + log_err("Memory allocation error."); + } + } + // Gather the results from the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Gatherv(var, local_domain.ncells_active, MPI_FLOAT, + fvar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_FLOAT, + VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error"); + } + if (mpi_rank == VIC_MPI_ROOT) { + // remap the array + map(sizeof(float), global_domain.ncells_active, NULL, + mpi_map_mapping_array, fvar_gathered, fvar_remapped); + // expand to full grid size + map(sizeof(float), global_domain.ncells_active, NULL, + filter_active_cells, fvar_remapped, fvar); + + // write to file + status = nc_put_vara_float(nc_id, var_id, start, count, fvar); + check_nc_status(status, "Error writing values"); + + // cleanup + free(fvar); + free(fvar_gathered); + free(fvar_remapped); + } +} + /****************************************************************************** * @brief Gather and write integer NetCDF field * @details Values are gathered to the master node and then written from the * master node *****************************************************************************/ void -gather_put_nc_field_int(char *nc_name, - bool *open, - int *nc_id, +gather_put_nc_field_int(int nc_id, + int var_id, int fillval, - int *dimids, - int ndims, - char *var_name, size_t *start, size_t *count, int *var) @@ -1901,11 +1921,11 @@ gather_put_nc_field_int(char *nc_name, size_t grid_size; size_t i; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { grid_size = global_domain.n_nx * global_domain.n_ny; ivar = malloc(grid_size * sizeof(*ivar)); if (ivar == NULL) { - log_err("Memory allocation error in gather_put_nc_field_int()."); + log_err("Memory allocation error"); } for (i = 0; i < grid_size; i++) { ivar[i] = fillval; @@ -1914,13 +1934,13 @@ gather_put_nc_field_int(char *nc_name, ivar_gathered = malloc(global_domain.ncells_active * sizeof(*ivar_gathered)); if (ivar_gathered == NULL) { - log_err("Memory allocation error in gather_put_nc_field_int()."); + log_err("Memory allocation error"); } ivar_remapped = malloc(global_domain.ncells_active * sizeof(*ivar_remapped)); if (ivar_remapped == NULL) { - log_err("Memory allocation error in gather_put_nc_field_int()."); + log_err("Memory allocation error"); } } // Gather the results from the nodes, result for the local node is in the @@ -1928,13 +1948,12 @@ gather_put_nc_field_int(char *nc_name, status = MPI_Gatherv(var, local_domain.ncells_active, MPI_INT, ivar_gathered, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_INT, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { - fprintf(stderr, "MPI error in main(): %d\n", status); - exit(EXIT_FAILURE); + log_err("MPI error"); } - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // remap the array map(sizeof(int), global_domain.ncells_active, NULL, mpi_map_mapping_array, @@ -1943,8 +1962,9 @@ gather_put_nc_field_int(char *nc_name, map(sizeof(int), global_domain.ncells_active, NULL, filter_active_cells, ivar_remapped, ivar); // write to file - put_nc_field_int(nc_name, open, nc_id, fillval, dimids, ndims, - var_name, start, count, ivar); + status = nc_put_vara_int(nc_id, var_id, start, count, ivar); + check_nc_status(status, "Error writing values"); + // cleanup free(ivar); free(ivar_gathered); @@ -1952,6 +1972,164 @@ gather_put_nc_field_int(char *nc_name, } } +/****************************************************************************** + * @brief Gather and write short integer NetCDF field + * @details Values are gathered to the master node and then written from the + * master node + *****************************************************************************/ +void +gather_put_nc_field_short(int nc_id, + int var_id, + short int fillval, + size_t *start, + size_t *count, + short int *var) +{ + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + short int *svar = NULL; + short int *svar_gathered = NULL; + short int *svar_remapped = NULL; + size_t grid_size; + size_t i; + + if (mpi_rank == VIC_MPI_ROOT) { + grid_size = global_domain.n_nx * global_domain.n_ny; + svar = malloc(grid_size * sizeof(*svar)); + if (svar == NULL) { + log_err("Memory allocation error"); + } + for (i = 0; i < grid_size; i++) { + svar[i] = fillval; + } + + svar_gathered = + malloc(global_domain.ncells_active * sizeof(*svar_gathered)); + if (svar_gathered == NULL) { + log_err("Memory allocation error"); + } + + svar_remapped = + malloc(global_domain.ncells_active * sizeof(*svar_remapped)); + if (svar_remapped == NULL) { + log_err("Memory allocation error"); + } + } + // Gather the results from the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Gatherv(var, local_domain.ncells_active, MPI_SHORT, + svar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_SHORT, + VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error"); + } + + if (mpi_rank == VIC_MPI_ROOT) { + // remap the array + map(sizeof(short int), global_domain.ncells_active, NULL, + mpi_map_mapping_array, + svar_gathered, svar_remapped); + // expand to full grid size + map(sizeof(short int), global_domain.ncells_active, NULL, + filter_active_cells, svar_remapped, svar); + // write to file + status = nc_put_vara_short(nc_id, var_id, start, count, svar); + check_nc_status(status, "Error writing values"); + + // cleanup + free(svar); + free(svar_gathered); + free(svar_remapped); + } +} + +/****************************************************************************** + * @brief Gather and write signed character NetCDF field + * @details Values are gathered to the master node and then written from the + * master node + *****************************************************************************/ +void +gather_put_nc_field_schar(int nc_id, + int var_id, + char fillval, + size_t *start, + size_t *count, + char *var) +{ + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + signed char *cvar = NULL; + signed char *cvar_gathered = NULL; + signed char *cvar_remapped = NULL; + size_t grid_size; + size_t i; + + if (mpi_rank == VIC_MPI_ROOT) { + grid_size = global_domain.n_nx * global_domain.n_ny; + cvar = malloc(grid_size * sizeof(*cvar)); + if (cvar == NULL) { + log_err("Memory allocation error"); + } + for (i = 0; i < grid_size; i++) { + cvar[i] = fillval; + } + + cvar_gathered = + malloc(global_domain.ncells_active * sizeof(*cvar_gathered)); + if (cvar_gathered == NULL) { + log_err("Memory allocation error"); + } + + cvar_remapped = + malloc(global_domain.ncells_active * sizeof(*cvar_remapped)); + if (cvar_remapped == NULL) { + log_err("Memory allocation error"); + } + } + // Gather the results from the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Gatherv(var, local_domain.ncells_active, MPI_CHAR, + cvar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_CHAR, + VIC_MPI_ROOT, MPI_COMM_VIC); + if (status != MPI_SUCCESS) { + log_err("MPI error"); + } + + if (mpi_rank == VIC_MPI_ROOT) { + // remap the array + map(sizeof(char), global_domain.ncells_active, NULL, + mpi_map_mapping_array, + cvar_gathered, cvar_remapped); + // expand to full grid size + map(sizeof(char), global_domain.ncells_active, NULL, + filter_active_cells, cvar_remapped, cvar); + // write to file + status = nc_put_vara_schar(nc_id, var_id, start, count, cvar); + check_nc_status(status, "Error writing values"); + + // cleanup + free(cvar); + free(cvar_gathered); + free(cvar_remapped); + } +} + /****************************************************************************** * @brief Read double precision NetCDF field from file and scatter * @details Read happens on the master node and is then scattered to the local @@ -1977,30 +2155,28 @@ get_scatter_nc_field_double(char *nc_name, double *dvar_filtered = NULL; double *dvar_mapped = NULL; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { dvar = malloc(global_domain.ncells_total * sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in get_scatter_nc_field_double()."); + log_err("Memory allocation error"); } dvar_filtered = malloc(global_domain.ncells_active * sizeof(*dvar_filtered)); if (dvar_filtered == NULL) { - log_err("Memory allocation error in get_scatter_nc_field_double()."); + log_err("Memory allocation error"); } dvar_mapped = malloc(global_domain.ncells_active * sizeof(*dvar_mapped)); if (dvar_mapped == NULL) { - log_err("Memory allocation error in get_scatter_nc_field_double()."); + log_err("Memory allocation error"); } get_nc_field_double(nc_name, var_name, start, count, dvar); // filter the active cells only map(sizeof(double), global_domain.ncells_active, filter_active_cells, - NULL, - dvar, dvar_filtered); + NULL, dvar, dvar_filtered); // map to prepare for MPI_Scatterv map(sizeof(double), global_domain.ncells_active, mpi_map_mapping_array, - NULL, - dvar_filtered, dvar_mapped); + NULL, dvar_filtered, dvar_mapped); free(dvar); free(dvar_filtered); } @@ -2010,13 +2186,12 @@ get_scatter_nc_field_double(char *nc_name, status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, var, local_domain.ncells_active, MPI_DOUBLE, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { - fprintf(stderr, "MPI error in main(): %d\n", status); - exit(EXIT_FAILURE); + log_err("MPI error"); } - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { free(dvar_mapped); } } @@ -2046,7 +2221,7 @@ get_scatter_nc_field_float(char *nc_name, float *fvar_filtered = NULL; float *fvar_mapped = NULL; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { fvar = malloc(global_domain.ncells_total * sizeof(*fvar)); if (fvar == NULL) { log_err("Memory allocation error in get_scatter_nc_field_float()."); @@ -2079,13 +2254,12 @@ get_scatter_nc_field_float(char *nc_name, status = MPI_Scatterv(fvar_mapped, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_FLOAT, var, local_domain.ncells_active, MPI_FLOAT, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { - fprintf(stderr, "MPI error in main(): %d\n", status); - exit(EXIT_FAILURE); + log_err("MPI error"); } - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { free(fvar_mapped); } } @@ -2115,7 +2289,7 @@ get_scatter_nc_field_int(char *nc_name, int *ivar_filtered = NULL; int *ivar_mapped = NULL; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { ivar = malloc(global_domain.ncells_total * sizeof(*ivar)); if (ivar == NULL) { log_err("Memory allocation error in get_scatter_nc_field_int()."); @@ -2147,13 +2321,12 @@ get_scatter_nc_field_int(char *nc_name, status = MPI_Scatterv(ivar_mapped, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_INT, var, local_domain.ncells_active, MPI_INT, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { - fprintf(stderr, "MPI error in main(): %d\n", status); - exit(EXIT_FAILURE); + log_err("MPI error"); } - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { free(ivar_mapped); } } @@ -2178,7 +2351,6 @@ domain_struct local_domain; // lake_con_struct lake_con; MPI_Datatype mpi_global_struct_type; MPI_Datatype mpi_location_struct_type; -MPI_Datatype mpi_nc_file_struct_type; MPI_Datatype mpi_option_struct_type; MPI_Datatype mpi_param_struct_type; int *mpi_map_local_array_sizes = NULL; @@ -2239,11 +2411,10 @@ main(int argc, create_MPI_global_struct_type(&mpi_global_struct_type); create_MPI_location_struct_type(&mpi_location_struct_type); - create_MPI_nc_file_struct_type(&mpi_nc_file_struct_type); create_MPI_option_struct_type(&mpi_option_struct_type); create_MPI_param_struct_type(&mpi_param_struct_type); - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // populate the test structure on the master // make sure to test the last element of the structure, because any // problem with alignment would show there @@ -2280,31 +2451,25 @@ main(int argc, // broadcast to the slaves status = MPI_Bcast(&global, 1, mpi_global_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in main(): %d\n", status); } status = MPI_Bcast(&location, 1, mpi_location_struct_type, - 0, MPI_COMM_VIC); - if (status != MPI_SUCCESS) { - log_err("MPI error in main(): %d\n", status); - } - - status = MPI_Bcast(&ncfile, 1, mpi_nc_file_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in main(): %d\n", status); } status = MPI_Bcast(&option, 1, mpi_option_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in main(): %d\n", status); } status = MPI_Bcast(¶m, 1, mpi_param_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in main(): %d\n", status); } diff --git a/vic/drivers/shared_image/src/vic_nc_info.c b/vic/drivers/shared_image/src/vic_nc_info.c index 94422368e..f5e855a3d 100644 --- a/vic/drivers/shared_image/src/vic_nc_info.c +++ b/vic/drivers/shared_image/src/vic_nc_info.c @@ -30,367 +30,216 @@ * @brief Setup netCDF output variables. *****************************************************************************/ void -vic_nc_info(nc_file_struct *nc_hist_file, - out_data_struct **out_data, - nc_var_struct *nc_vars) +set_nc_var_info(unsigned int varid, + unsigned short int dtype, + nc_file_struct *nc_hist_file, + nc_var_struct *nc_var) { - extern option_struct options; + size_t i; - size_t i; - size_t j; + // set datatype + nc_var->nc_type = get_nc_dtype(dtype); - // default is a variable of type NC_DOUBLE with only a single field per - // timestep - for (i = 0; i < N_OUTVAR_TYPES; i++) { - strncpy(nc_vars[i].nc_var_name, - out_data[0][i].varname, MAXSTRING); - nc_vars[i].nc_write = out_data[0][i].write; - nc_vars[i].nc_aggtype = out_data[0][i].aggtype; - nc_vars[i].nc_type = NC_DOUBLE; - for (j = 0; j < MAXDIMS; j++) { - nc_vars[i].nc_dimids[j] = -1; - nc_vars[i].nc_counts[j] = -1; - } - nc_vars[i].nc_dims = 3; - nc_vars[i].nc_dimids[0] = nc_hist_file->time_dimid; - nc_vars[i].nc_dimids[1] = nc_hist_file->nj_dimid; - nc_vars[i].nc_counts[1] = nc_hist_file->nj_size; - nc_vars[i].nc_dimids[2] = nc_hist_file->ni_dimid; - nc_vars[i].nc_counts[2] = nc_hist_file->ni_size; + for (i = 0; i < MAXDIMS; i++) { + nc_var->nc_dimids[i] = -1; + nc_var->nc_counts[i] = 0; + } + + // Set the number of dimensions and the count sizes + switch (varid) { + case OUT_FDEPTH: + case OUT_TDEPTH: + nc_var->nc_dims = 4; + nc_var->nc_counts[1] = nc_hist_file->front_size; + nc_var->nc_counts[2] = nc_hist_file->nj_size; + nc_var->nc_counts[3] = nc_hist_file->ni_size; + break; + case OUT_SMLIQFRAC: + case OUT_SMFROZFRAC: + case OUT_SOIL_ICE: + case OUT_SOIL_LIQ: + case OUT_SOIL_MOIST: + case OUT_SOIL_TEMP: + nc_var->nc_dims = 4; + nc_var->nc_counts[1] = nc_hist_file->layer_size; + nc_var->nc_counts[2] = nc_hist_file->nj_size; + nc_var->nc_counts[3] = nc_hist_file->ni_size; + break; + case OUT_SOIL_TNODE: + case OUT_SOIL_TNODE_WL: + case OUT_SOILT_FBFLAG: + nc_var->nc_dims = 4; + nc_var->nc_counts[1] = nc_hist_file->node_size; + nc_var->nc_counts[2] = nc_hist_file->nj_size; + nc_var->nc_counts[3] = nc_hist_file->ni_size; + break; + case OUT_ADV_SENS_BAND: + case OUT_ADVECTION_BAND: + case OUT_ALBEDO_BAND: + case OUT_DELTACC_BAND: + case OUT_GRND_FLUX_BAND: + case OUT_IN_LONG_BAND: + case OUT_LATENT_BAND: + case OUT_LATENT_SUB_BAND: + case OUT_MELT_ENERGY_BAND: + case OUT_LWNET_BAND: + case OUT_SWNET_BAND: + case OUT_RFRZ_ENERGY_BAND: + case OUT_SENSIBLE_BAND: + case OUT_SNOW_CANOPY_BAND: + case OUT_SNOW_COVER_BAND: + case OUT_SNOW_DEPTH_BAND: + case OUT_SNOW_FLUX_BAND: + case OUT_SNOW_MELT_BAND: + case OUT_SNOW_PACKT_BAND: + case OUT_SNOW_SURFT_BAND: + case OUT_SWE_BAND: + nc_var->nc_dims = 4; + nc_var->nc_counts[1] = nc_hist_file->band_size; + nc_var->nc_counts[2] = nc_hist_file->nj_size; + nc_var->nc_counts[3] = nc_hist_file->ni_size; + break; + default: + nc_var->nc_dims = 3; + nc_var->nc_counts[1] = nc_hist_file->nj_size; + nc_var->nc_counts[2] = nc_hist_file->ni_size; + } +} + +/****************************************************************************** + * @brief Set netcdf dim ids. + *****************************************************************************/ +void +set_nc_var_dimids(unsigned int varid, + nc_file_struct *nc_hist_file, + nc_var_struct *nc_var) +{ + size_t i; + + for (i = 0; i < MAXDIMS; i++) { + nc_var->nc_dimids[i] = -1; } // Set the non-default ones + switch (varid) { + case OUT_FDEPTH: + case OUT_TDEPTH: + nc_var->nc_dimids[0] = nc_hist_file->time_dimid; + nc_var->nc_dimids[1] = nc_hist_file->front_dimid; + nc_var->nc_dimids[2] = nc_hist_file->nj_dimid; + nc_var->nc_dimids[3] = nc_hist_file->ni_dimid; + break; + case OUT_SMLIQFRAC: + case OUT_SMFROZFRAC: + case OUT_SOIL_ICE: + case OUT_SOIL_LIQ: + case OUT_SOIL_MOIST: + case OUT_SOIL_TEMP: + nc_var->nc_dimids[0] = nc_hist_file->time_dimid; + nc_var->nc_dimids[1] = nc_hist_file->layer_dimid; + nc_var->nc_dimids[2] = nc_hist_file->nj_dimid; + nc_var->nc_dimids[3] = nc_hist_file->ni_dimid; + break; + case OUT_SOIL_TNODE: + case OUT_SOIL_TNODE_WL: + case OUT_SOILT_FBFLAG: + nc_var->nc_dimids[0] = nc_hist_file->time_dimid; + nc_var->nc_dimids[1] = nc_hist_file->node_dimid; + nc_var->nc_dimids[2] = nc_hist_file->nj_dimid; + nc_var->nc_dimids[3] = nc_hist_file->ni_dimid; + break; + case OUT_ADV_SENS_BAND: + case OUT_ADVECTION_BAND: + case OUT_ALBEDO_BAND: + case OUT_DELTACC_BAND: + case OUT_GRND_FLUX_BAND: + case OUT_IN_LONG_BAND: + case OUT_LATENT_BAND: + case OUT_LATENT_SUB_BAND: + case OUT_MELT_ENERGY_BAND: + case OUT_LWNET_BAND: + case OUT_SWNET_BAND: + case OUT_RFRZ_ENERGY_BAND: + case OUT_SENSIBLE_BAND: + case OUT_SNOW_CANOPY_BAND: + case OUT_SNOW_COVER_BAND: + case OUT_SNOW_DEPTH_BAND: + case OUT_SNOW_FLUX_BAND: + case OUT_SNOW_MELT_BAND: + case OUT_SNOW_PACKT_BAND: + case OUT_SNOW_SURFT_BAND: + case OUT_SWE_BAND: + nc_var->nc_dimids[0] = nc_hist_file->time_dimid; + nc_var->nc_dimids[1] = nc_hist_file->band_dimid; + nc_var->nc_dimids[2] = nc_hist_file->nj_dimid; + nc_var->nc_dimids[3] = nc_hist_file->ni_dimid; + break; + default: + nc_var->nc_dimids[0] = nc_hist_file->time_dimid; + nc_var->nc_dimids[1] = nc_hist_file->nj_dimid; + nc_var->nc_dimids[2] = nc_hist_file->ni_dimid; + } +} + +/****************************************************************************** + * @brief Determine the netCDF file format + *****************************************************************************/ +int +get_nc_mode(unsigned short int format) +{ + int nc_format; - for (i = 0; i < N_OUTVAR_TYPES; i++) { - switch (i) { - case OUT_FDEPTH: - case OUT_TDEPTH: - nc_vars[i].nc_dims = 4; - nc_vars[i].nc_dimids[0] = nc_hist_file->time_dimid; - nc_vars[i].nc_dimids[1] = nc_hist_file->front_dimid; - nc_vars[i].nc_counts[1] = nc_hist_file->front_size; - nc_vars[i].nc_dimids[2] = nc_hist_file->nj_dimid; - nc_vars[i].nc_counts[2] = nc_hist_file->nj_size; - nc_vars[i].nc_dimids[3] = nc_hist_file->ni_dimid; - nc_vars[i].nc_counts[3] = nc_hist_file->ni_size; - break; - case OUT_SMLIQFRAC: - case OUT_SMFROZFRAC: - case OUT_SOIL_ICE: - case OUT_SOIL_LIQ: - case OUT_SOIL_MOIST: - case OUT_SOIL_TEMP: - nc_vars[i].nc_dims = 4; - nc_vars[i].nc_dimids[0] = nc_hist_file->time_dimid; - nc_vars[i].nc_dimids[1] = nc_hist_file->layer_dimid; - nc_vars[i].nc_counts[1] = nc_hist_file->layer_size; - nc_vars[i].nc_dimids[2] = nc_hist_file->nj_dimid; - nc_vars[i].nc_counts[2] = nc_hist_file->nj_size; - nc_vars[i].nc_dimids[3] = nc_hist_file->ni_dimid; - nc_vars[i].nc_counts[3] = nc_hist_file->ni_size; - break; - case OUT_SOIL_TNODE: - case OUT_SOIL_TNODE_WL: - case OUT_SOILT_FBFLAG: - nc_vars[i].nc_dims = 4; - nc_vars[i].nc_dimids[0] = nc_hist_file->time_dimid; - nc_vars[i].nc_dimids[1] = nc_hist_file->node_dimid; - nc_vars[i].nc_counts[1] = nc_hist_file->node_size; - nc_vars[i].nc_dimids[2] = nc_hist_file->nj_dimid; - nc_vars[i].nc_counts[2] = nc_hist_file->nj_size; - nc_vars[i].nc_dimids[3] = nc_hist_file->ni_dimid; - nc_vars[i].nc_counts[3] = nc_hist_file->ni_size; - break; - case OUT_ADV_SENS_BAND: - case OUT_ADVECTION_BAND: - case OUT_ALBEDO_BAND: - case OUT_DELTACC_BAND: - case OUT_GRND_FLUX_BAND: - case OUT_IN_LONG_BAND: - case OUT_LATENT_BAND: - case OUT_LATENT_SUB_BAND: - case OUT_MELT_ENERGY_BAND: - case OUT_LWNET_BAND: - case OUT_RFRZ_ENERGY_BAND: - case OUT_SENSIBLE_BAND: - case OUT_SNOW_CANOPY_BAND: - case OUT_SNOW_COVER_BAND: - case OUT_SNOW_DEPTH_BAND: - case OUT_SNOW_FLUX_BAND: - case OUT_SNOW_MELT_BAND: - case OUT_SNOW_PACKT_BAND: - case OUT_SNOW_SURFT_BAND: - case OUT_SWE_BAND: - nc_vars[i].nc_dims = 4; - nc_vars[i].nc_dimids[0] = nc_hist_file->time_dimid; - nc_vars[i].nc_dimids[1] = nc_hist_file->band_dimid; - nc_vars[i].nc_counts[1] = nc_hist_file->band_size; - nc_vars[i].nc_dimids[2] = nc_hist_file->nj_dimid; - nc_vars[i].nc_counts[2] = nc_hist_file->nj_size; - nc_vars[i].nc_dimids[3] = nc_hist_file->ni_dimid; - nc_vars[i].nc_counts[3] = nc_hist_file->ni_size; - break; - } + switch (format) { + case NETCDF3_CLASSIC: + nc_format = NC_CLASSIC_MODEL; + break; + case NETCDF3_64BIT_OFFSET: + nc_format = NC_64BIT_OFFSET; + break; + case NETCDF4_CLASSIC: + nc_format = (NC_NETCDF4 | NC_CLASSIC_MODEL); + break; + case NETCDF4: + nc_format = NC_NETCDF4; + break; + default: + log_err("Unrecognized netCDF file format"); } + return nc_format; +} +/****************************************************************************** + * @brief Determine the netCDF data type + *****************************************************************************/ +int +get_nc_dtype(unsigned short int dtype) +{ + int type; - // set the units - for (i = 0; i < N_OUTVAR_TYPES; i++) { - switch (i) { - // fraction or unitless - case OUT_ASAT: - case OUT_LAKE_AREA_FRAC: - case OUT_LAKE_ICE_FRACT: - case OUT_SMFROZFRAC: - case OUT_SMLIQFRAC: - case OUT_SNOW_COVER: - case OUT_SOIL_WET: - case OUT_SURF_FROST_FRAC: - case OUT_ALBEDO: - case OUT_SALBEDO: - case OUT_SNOWT_FBFLAG: - case OUT_SOILT_FBFLAG: - case OUT_SURFT_FBFLAG: - case OUT_TCAN_FBFLAG: - case OUT_TFOL_FBFLAG: - case OUT_FDIR: - case OUT_REL_HUMID: - case OUT_ALBEDO_BAND: - case OUT_SNOW_COVER_BAND: - strncpy(nc_vars[i].nc_units, "-", MAXSTRING); - break; - // depth in meters - case OUT_LAKE_DEPTH: - case OUT_LAKE_SWE: - strncpy(nc_vars[i].nc_units, "m", MAXSTRING); - break; - // depth in cm - case OUT_LAKE_ICE_HEIGHT: - case OUT_SNOW_DEPTH: - case OUT_ZWT: - case OUT_ZWT_LUMPED: - case OUT_SNOW_DEPTH_BAND: - strncpy(nc_vars[i].nc_units, "cm", MAXSTRING); - break; - // depth in cm, changed to m for ALMA_OUTPUT - case OUT_FDEPTH: - case OUT_TDEPTH: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "m", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "cm", MAXSTRING); - } - break; - // depth in mm - case OUT_LAKE_ICE: - case OUT_LAKE_MOIST: - case OUT_ROOTMOIST: - case OUT_SNOW_CANOPY: - case OUT_SOIL_ICE: - case OUT_SOIL_LIQ: - case OUT_SOIL_MOIST: - case OUT_SURFSTOR: - case OUT_SWE: - case OUT_WDEW: - case OUT_DELINTERCEPT: - case OUT_DELSOILMOIST: - case OUT_DELSURFSTOR: - case OUT_DELSWE: - case OUT_WATER_ERROR: - case OUT_SNOW_CANOPY_BAND: - case OUT_SWE_BAND: - strncpy(nc_vars[i].nc_units, "mm", MAXSTRING); - break; - // rate in mm per timestep, changed to mm/s for ALMA_OUTPUT - case OUT_BASEFLOW: - case OUT_EVAP: - case OUT_EVAP_BARE: - case OUT_EVAP_CANOP: - case OUT_INFLOW: - case OUT_LAKE_BF_IN: - case OUT_LAKE_BF_OUT: - case OUT_LAKE_CHAN_IN: - case OUT_LAKE_CHAN_OUT: - case OUT_LAKE_DSTOR: - case OUT_LAKE_DSWE: - case OUT_LAKE_EVAP: - case OUT_LAKE_RCHRG: - case OUT_LAKE_RO_IN: - case OUT_LAKE_VAPFLX: - case OUT_PET: - case OUT_PREC: - case OUT_RAINF: - case OUT_REFREEZE: - case OUT_RUNOFF: - case OUT_SNOW_MELT: - case OUT_SNOWF: - case OUT_SUB_BLOWING: - case OUT_SUB_CANOP: - case OUT_SUB_SNOW: - case OUT_SUB_SURFACE: - case OUT_TRANSP_VEG: - case OUT_SNOW_MELT_BAND: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "mm s-1", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "mm", MAXSTRING); - } - break; - // area in m2 - case OUT_LAKE_SURF_AREA: - strncpy(nc_vars[i].nc_units, "m2", MAXSTRING); - break; - // volume in m3 - case OUT_LAKE_SWE_V: - case OUT_LAKE_VOLUME: - strncpy(nc_vars[i].nc_units, "m3", MAXSTRING); - break; - // rate in m3 per timestep, changed to m3/s for ALMA_OUTPUT - case OUT_DISCHARGE: - case OUT_LAKE_BF_IN_V: - case OUT_LAKE_BF_OUT_V: - case OUT_LAKE_CHAN_IN_V: - case OUT_LAKE_CHAN_OUT_V: - case OUT_LAKE_DSTOR_V: - case OUT_LAKE_DSWE_V: - case OUT_LAKE_EVAP_V: - case OUT_LAKE_PREC_V: - case OUT_LAKE_RCHRG_V: - case OUT_LAKE_RO_IN_V: - case OUT_LAKE_VAPFLX_V: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "m3 s-1", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "m3", MAXSTRING); - } - break; - // rate in m/s - case OUT_AERO_COND: - case OUT_AERO_COND1: - case OUT_AERO_COND2: - case OUT_SURF_COND: - case OUT_WIND: - strncpy(nc_vars[i].nc_units, "m s-1", MAXSTRING); - break; - // resistance in s/m - case OUT_AERO_RESIST: - case OUT_AERO_RESIST1: - case OUT_AERO_RESIST2: - strncpy(nc_vars[i].nc_units, "s m-1", MAXSTRING); - break; - // temperature in K - case OUT_RAD_TEMP: - strncpy(nc_vars[i].nc_units, "K", MAXSTRING); - break; - // temperature in C, changed to K for ALMA_OUTPUT - case OUT_BARESOILT: - case OUT_LAKE_ICE_TEMP: - case OUT_LAKE_SURF_TEMP: - case OUT_SNOW_PACK_TEMP: - case OUT_SNOW_SURF_TEMP: - case OUT_SOIL_TEMP: - case OUT_SOIL_TNODE: - case OUT_SOIL_TNODE_WL: - case OUT_SURF_TEMP: - case OUT_VEGT: - case OUT_AIR_TEMP: - case OUT_SNOW_PACKT_BAND: - case OUT_SNOW_SURFT_BAND: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "K", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "C", MAXSTRING); - } - break; - // energy flux in W/m2 - case OUT_ADV_SENS: - case OUT_ADVECTION: - case OUT_ENERGY_ERROR: - case OUT_FUSION: - case OUT_GRND_FLUX: - case OUT_IN_LONG: - case OUT_LATENT: - case OUT_LATENT_SUB: - case OUT_MELT_ENERGY: - case OUT_LWNET: - case OUT_SWNET: - case OUT_R_NET: - case OUT_RFRZ_ENERGY: - case OUT_SENSIBLE: - case OUT_SNOW_FLUX: - case OUT_LWDOWN: - case OUT_PAR: - case OUT_SWDOWN: - case OUT_ADV_SENS_BAND: - case OUT_ADVECTION_BAND: - case OUT_DELTACC_BAND: - case OUT_GRND_FLUX_BAND: - case OUT_IN_LONG_BAND: - case OUT_LATENT_BAND: - case OUT_LATENT_SUB_BAND: - case OUT_MELT_ENERGY_BAND: - case OUT_SWNET_BAND: - case OUT_RFRZ_ENERGY_BAND: - case OUT_SENSIBLE_BAND: - case OUT_SNOW_FLUX_BAND: - case OUT_APAR: - strncpy(nc_vars[i].nc_units, "W m-2", MAXSTRING); - break; - // energy flux in W/m2, changed to J/m2 for ALMA_OUTPUT - case OUT_DELTACC: - case OUT_DELTAH: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "J m-2", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "W m-2", MAXSTRING); - } - break; - // density in kg m-3 - case OUT_DENSITY: - strncpy(nc_vars[i].nc_units, "kg m-3", MAXSTRING); - break; - // concentration in ppm - case OUT_CATM: - strncpy(nc_vars[i].nc_units, "ppm", MAXSTRING); - break; - // pressure in kPa, changed to Pa for ALMA_OUTPUT - case OUT_PRESSURE: - case OUT_VP: - case OUT_VPD: - if (options.ALMA_OUTPUT) { - strncpy(nc_vars[i].nc_units, "Pa", MAXSTRING); - } - else { - strncpy(nc_vars[i].nc_units, "kPa", MAXSTRING); - } - break; - // mixing ratio - case OUT_QAIR: - strncpy(nc_vars[i].nc_units, "kg kg-1", MAXSTRING); - break; - // carbon fluxes - case OUT_GPP: - case OUT_RAUT: - case OUT_NPP: - case OUT_LITTERFALL: - case OUT_RHET: - case OUT_NEE: - strncpy(nc_vars[i].nc_units, "g C m-2 d-1", MAXSTRING); - break; - // carbon pools - case OUT_CLITTER: - case OUT_CINTER: - case OUT_CSLOW: - strncpy(nc_vars[i].nc_units, "g C m-2", MAXSTRING); - break; - default: - log_warn("%zd - not defined\n", i); - break; - } + switch (dtype) { + case OUT_TYPE_DEFAULT: + type = OUT_TYPE_DOUBLE; + break; + case OUT_TYPE_CHAR: + type = NC_CHAR; + break; + case OUT_TYPE_SINT: + type = NC_SHORT; + break; + case OUT_TYPE_USINT: + type = NC_UINT; + break; + case OUT_TYPE_INT: + type = NC_INT; + break; + case OUT_TYPE_FLOAT: + type = NC_FLOAT; + break; + case OUT_TYPE_DOUBLE: + type = NC_DOUBLE; + break; + default: + log_err("Unrecognized netCDF variable datatype %hu", dtype); } + return type; } diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index b33c08a0d..0818a56a1 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -38,6 +38,7 @@ vic_restore(void) extern option_struct options; extern veg_con_map_struct *veg_con_map; extern filenames_struct filenames; + extern metadata_struct state_metadata[N_STATE_VARS]; int v; size_t i; @@ -45,10 +46,8 @@ vic_restore(void) size_t k; size_t m; size_t p; - char *cvar = NULL; int *ivar = NULL; double *dvar = NULL; - float *fvar = NULL; size_t d2count[2]; size_t d2start[2]; size_t d3count[3]; @@ -66,11 +65,6 @@ vic_restore(void) // read state variables // allocate memory for variables to be stored - cvar = malloc(local_domain.ncells_active * sizeof(*cvar)); - if (cvar == NULL) { - log_err("Memory allocation error in vic_restore()."); - } - ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); if (ivar == NULL) { log_err("Memory allocation error in vic_restore()."); @@ -81,11 +75,6 @@ vic_restore(void) log_err("Memory allocation error in vic_restore()."); } - fvar = malloc(local_domain.ncells_active * sizeof(*fvar)); - if (fvar == NULL) { - log_err("Memory allocation error in vic_restore()."); - } - // initialize starts and counts d2start[0] = 0; d2start[1] = 0; @@ -140,7 +129,7 @@ vic_restore(void) for (j = 0; j < options.Nlayer; j++) { d5start[2] = j; get_scatter_nc_field_double(filenames.init_state, - "Soil_moisture", + state_metadata[STATE_SOIL_MOISTURE].varname, d5start, d5count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -162,7 +151,7 @@ vic_restore(void) for (p = 0; p < options.Nfrost; p++) { d6start[3] = p; get_scatter_nc_field_double(filenames.init_state, - "Soil_ice", + state_metadata[STATE_SOIL_ICE].varname, d6start, d6count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -181,7 +170,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Canopy_water", + state_metadata[STATE_CANOPY_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -199,7 +188,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "AnnualNPP", + state_metadata[STATE_ANNUALNPP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -216,7 +205,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "AnnualNPPPrev", + state_metadata[STATE_ANNUALNPPPREV].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -233,7 +222,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "CLitter", + state_metadata[STATE_CLITTER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -250,7 +239,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "CInter", + state_metadata[STATE_CINTER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -267,7 +256,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "CSlow", + state_metadata[STATE_CSLOW].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -285,7 +274,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_int(filenames.init_state, - "Snow_age", + state_metadata[STATE_SNOW_AGE].varname, d4start, d4count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -302,7 +291,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_int(filenames.init_state, - "Snow_melt_state", + state_metadata[STATE_SNOW_MELT_STATE].varname, d4start, d4count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -319,7 +308,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_coverage", + state_metadata[STATE_SNOW_COVERAGE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -336,7 +325,8 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_water_equivalent", + state_metadata[ + STATE_SNOW_WATER_EQUIVALENT].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -353,7 +343,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_surf_temp", + state_metadata[STATE_SNOW_SURF_TEMP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -370,7 +360,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_surf_water", + state_metadata[STATE_SNOW_SURF_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -387,7 +377,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_pack_temp", + state_metadata[STATE_SNOW_PACK_TEMP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -404,7 +394,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_pack_water", + state_metadata[STATE_SNOW_PACK_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -421,7 +411,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_density", + state_metadata[STATE_SNOW_DENSITY].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -438,7 +428,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_cold_content", + state_metadata[STATE_SNOW_COLD_CONTENT].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -455,7 +445,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Snow_canopy", + state_metadata[STATE_SNOW_CANOPY].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -474,7 +464,7 @@ vic_restore(void) for (j = 0; j < options.Nnode; j++) { d5start[2] = j; get_scatter_nc_field_double(filenames.init_state, - "Soil_node_temp", + state_metadata[STATE_SOIL_NODE_TEMP].varname, d5start, d5count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -492,7 +482,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Foliage_temperature", + state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -510,7 +500,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Energy_LongUnderOut", + state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -528,7 +518,7 @@ vic_restore(void) for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; get_scatter_nc_field_double(filenames.init_state, - "Energy_snow_flux", + state_metadata[STATE_ENERGY_SNOW_FLUX].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; @@ -544,7 +534,7 @@ vic_restore(void) for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; get_scatter_nc_field_double(filenames.init_state, - "Lake_soil_moisture", + state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; @@ -557,7 +547,7 @@ vic_restore(void) for (p = 0; p < options.Nfrost; p++) { d4start[1] = p; get_scatter_nc_field_double(filenames.init_state, - "Lake_soil_ice", + state_metadata[STATE_LAKE_SOIL_ICE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.layer[j].ice[p] = dvar[i]; @@ -568,7 +558,7 @@ vic_restore(void) if (options.CARBON) { // litter carbon: tmpval = lake_var.soil.CLitter; get_scatter_nc_field_double(filenames.init_state, - "Lake_CLitter", + state_metadata[STATE_LAKE_CLITTER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.CLitter = dvar[i]; @@ -576,7 +566,7 @@ vic_restore(void) // intermediate carbon: tmpval = lake_var.soil.CInter; get_scatter_nc_field_double(filenames.init_state, - "Lake_CInter", + state_metadata[STATE_LAKE_CINTER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.CInter = dvar[i]; @@ -584,7 +574,7 @@ vic_restore(void) // slow carbon: tmpval = lake_var.soil.CSlow; get_scatter_nc_field_double(filenames.init_state, - "Lake_CSlow", + state_metadata[STATE_LAKE_CSLOW].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.CSlow = dvar[i]; @@ -593,7 +583,7 @@ vic_restore(void) // snow age: lake_var.snow.last_snow get_scatter_nc_field_int(filenames.init_state, - "Lake_snow_age", + state_metadata[STATE_LAKE_SNOW_AGE].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.last_snow = ivar[i]; @@ -601,7 +591,7 @@ vic_restore(void) // melting state: (int)lake_var.snow.MELTING get_scatter_nc_field_int(filenames.init_state, - "Lake_snow_melt_state", + state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.MELTING = ivar[i]; @@ -609,7 +599,7 @@ vic_restore(void) // snow covered fraction: lake_var.snow.coverage get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_coverage", + state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.coverage = dvar[i]; @@ -617,7 +607,8 @@ vic_restore(void) // snow water equivalent: lake_var.snow.swq get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_water_equivalent", + state_metadata[ + STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.swq = dvar[i]; @@ -625,7 +616,7 @@ vic_restore(void) // snow surface temperature: lake_var.snow.surf_temp get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_surf_temp", + state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.surf_temp = dvar[i]; @@ -633,7 +624,7 @@ vic_restore(void) // snow surface water: lake_var.snow.surf_water get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_surf_water", + state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.surf_water = dvar[i]; @@ -641,7 +632,7 @@ vic_restore(void) // snow pack temperature: lake_var.snow.pack_temp get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_pack_temp", + state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.pack_temp = dvar[i]; @@ -649,7 +640,7 @@ vic_restore(void) // snow pack water: lake_var.snow.pack_water get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_pack_water", + state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.pack_water = dvar[i]; @@ -657,7 +648,7 @@ vic_restore(void) // snow density: lake_var.snow.density get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_density", + state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.density = dvar[i]; @@ -665,7 +656,7 @@ vic_restore(void) // snow cold content: lake_var.snow.coldcontent get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_cold_content", + state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.coldcontent = dvar[i]; @@ -673,7 +664,7 @@ vic_restore(void) // snow canopy storage: lake_var.snow.snow_canopy get_scatter_nc_field_double(filenames.init_state, - "Lake_snow_canopy", + state_metadata[STATE_LAKE_SNOW_CANOPY].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.snow.snow_canopy = dvar[i]; @@ -683,7 +674,7 @@ vic_restore(void) for (j = 0; j < options.Nnode; j++) { d3start[0] = j; get_scatter_nc_field_double(filenames.init_state, - "Lake_soil_node_temp", + state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; @@ -692,7 +683,7 @@ vic_restore(void) // lake active layers: lake_var.activenod get_scatter_nc_field_int(filenames.init_state, - "Lake_active_layers", + state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.activenod = ivar[i]; @@ -700,7 +691,7 @@ vic_restore(void) // lake layer thickness: lake_var.dz get_scatter_nc_field_double(filenames.init_state, - "Lake_layer_dz", + state_metadata[STATE_LAKE_LAYER_DZ].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.dz = dvar[i]; @@ -708,7 +699,7 @@ vic_restore(void) // lake surface layer thickness: lake_var.surfdz get_scatter_nc_field_double(filenames.init_state, - "Lake_surf_layer_dz", + state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.surfdz = dvar[i]; @@ -716,7 +707,7 @@ vic_restore(void) // lake depth: lake_var.ldepth get_scatter_nc_field_double(filenames.init_state, - "Lake_depth", + state_metadata[STATE_LAKE_DEPTH].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.ldepth = dvar[i]; @@ -726,7 +717,8 @@ vic_restore(void) for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; get_scatter_nc_field_double(filenames.init_state, - "Lake_layer_surf_area", + state_metadata[ + STATE_LAKE_LAYER_SURF_AREA].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.surface[j] = dvar[i]; @@ -735,7 +727,7 @@ vic_restore(void) // lake surface area: lake_var.sarea get_scatter_nc_field_double(filenames.init_state, - "Lake_surf_area", + state_metadata[STATE_LAKE_SURF_AREA].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.sarea = dvar[i]; @@ -743,7 +735,7 @@ vic_restore(void) // lake volume: lake_var.volume get_scatter_nc_field_double(filenames.init_state, - "Lake_volume", + state_metadata[STATE_LAKE_VOLUME].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.volume = dvar[i]; @@ -753,7 +745,7 @@ vic_restore(void) for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; get_scatter_nc_field_double(filenames.init_state, - "Lake_layer_temp", + state_metadata[STATE_LAKE_LAYER_TEMP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.temp[j] = dvar[i]; @@ -762,7 +754,7 @@ vic_restore(void) // vertical average lake temperature: lake_var.tempavg get_scatter_nc_field_double(filenames.init_state, - "Lake_average_temp", + state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.tempavg = dvar[i]; @@ -770,7 +762,7 @@ vic_restore(void) // lake ice area fraction: lake_var.areai get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_area_frac", + state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.areai = dvar[i]; @@ -778,7 +770,7 @@ vic_restore(void) // new lake ice area fraction: lake_var.new_ice_area get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_area_frac_new", + state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.new_ice_area = dvar[i]; @@ -786,7 +778,8 @@ vic_restore(void) // lake ice water equivalent: lake_var.ice_water_eq get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_water_equivalent", + state_metadata[ + STATE_LAKE_ICE_WATER_EQUIVALENT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.ice_water_eq = dvar[i]; @@ -794,7 +787,7 @@ vic_restore(void) // lake ice height: lake_var.hice get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_height", + state_metadata[STATE_LAKE_ICE_HEIGHT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.hice = dvar[i]; @@ -802,7 +795,7 @@ vic_restore(void) // lake ice temperature: lake_var.tempi get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_temp", + state_metadata[STATE_LAKE_ICE_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.tempi = dvar[i]; @@ -810,7 +803,7 @@ vic_restore(void) // lake ice snow water equivalent: lake_var.swe get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_water_equivalent", + state_metadata[STATE_LAKE_ICE_SWE].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.swe = dvar[i]; @@ -818,7 +811,7 @@ vic_restore(void) // lake ice snow surface temperature: lake_var.surf_temp get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_surf_temp", + state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.surf_temp = dvar[i]; @@ -826,7 +819,7 @@ vic_restore(void) // lake ice snow pack temperature: lake_var.pack_temp get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_pack_temp", + state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.pack_temp = dvar[i]; @@ -834,7 +827,8 @@ vic_restore(void) // lake ice snow coldcontent: lake_var.coldcontent get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_cold_content", + state_metadata[ + STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.coldcontent = dvar[i]; @@ -842,7 +836,8 @@ vic_restore(void) // lake ice snow surface water: lake_var.surf_water get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_surf_water", + state_metadata[ + STATE_LAKE_ICE_SNOW_SURF_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.surf_water = dvar[i]; @@ -850,7 +845,8 @@ vic_restore(void) // lake ice snow pack water: lake_var.pack_water get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_pack_water", + state_metadata[ + STATE_LAKE_ICE_SNOW_PACK_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.pack_water = dvar[i]; @@ -858,7 +854,7 @@ vic_restore(void) // lake ice snow albedo: lake_var.SAlbedo get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_albedo", + state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.SAlbedo = dvar[i]; @@ -866,19 +862,21 @@ vic_restore(void) // lake ice snow depth: lake_var.sdepth get_scatter_nc_field_double(filenames.init_state, - "Lake_ice_snow_depth", + state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { all_vars[i].lake_var.sdepth = dvar[i]; } } - free(cvar); free(ivar); free(dvar); - free(fvar); } +/****************************************************************************** + * @brief Check that the initial state file matches the global parameter + settings + *****************************************************************************/ void check_init_state_file(void) { @@ -904,9 +902,7 @@ check_init_state_file(void) // open the netcdf file status = nc_open(filenames.init_state, NC_SHARE, &(nc.nc_id)); - if (status != NC_NOERR) { - log_err("Error opening %s", filenames.init_state); - } + check_nc_status(status, "Error opening %s", filenames.init_state); // read and validate dimension lengths dimlen = get_nc_dimension(filenames.init_state, global_domain.info.x_dim); @@ -956,15 +952,11 @@ check_init_state_file(void) // lat/lon status = nc_inq_varid(nc.nc_id, global_domain.info.lon_var, &lon_var_id); - if (status != NC_NOERR) { - log_err("Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - } + check_nc_status(status, "Unable to find variable \"%s\" in %s", + global_domain.info.lon_var, filenames.init_state); status = nc_inq_varid(nc.nc_id, global_domain.info.lat_var, &lat_var_id); - if (status != NC_NOERR) { - log_err("Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); - } + check_nc_status(status, "Unable to find variable \"%s\" in %s", + global_domain.info.lat_var, filenames.init_state); if (global_domain.info.n_coord_dims == 1) { d1start[0] = 0; dvar = calloc(global_domain.n_nx, sizeof(*dvar)); @@ -974,10 +966,8 @@ check_init_state_file(void) d1count[0] = global_domain.n_nx; status = nc_get_vara_double(nc.nc_id, lon_var_id, d1start, d1count, dvar); - if (status != NC_NOERR) { - log_err("Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - } + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, filenames.init_state); // implicitly nested loop over ni and nj with j set to 0 for (i = 0; i < global_domain.n_nx; i++) { if (!assert_close_double(dvar[i], @@ -996,10 +986,8 @@ check_init_state_file(void) d1count[0] = global_domain.n_ny; status = nc_get_vara_double(nc.nc_id, lat_var_id, d1start, d1count, dvar); - if (status != NC_NOERR) { - log_err("Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); - } + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, filenames.init_state); // implicitly nested loop over ni and nj with i set to 0; // j stride = n_nx for (j = 0; j < global_domain.n_ny; j++) { @@ -1025,10 +1013,8 @@ check_init_state_file(void) d2count[1] = global_domain.n_nx; status = nc_get_vara_double(nc.nc_id, lon_var_id, d2start, d2count, dvar); - if (status != NC_NOERR) { - log_err("Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - } + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, filenames.init_state); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].longitude) { log_err("Longitudes in initial state file do not " @@ -1037,10 +1023,8 @@ check_init_state_file(void) } status = nc_get_vara_double(nc.nc_id, lat_var_id, d2start, d2count, dvar); - if (status != NC_NOERR) { - log_err("Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); - } + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, filenames.init_state); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].latitude) { log_err("Latitudes in initial state file do not " diff --git a/vic/drivers/shared_image/src/vic_start.c b/vic/drivers/shared_image/src/vic_start.c index e60537fbd..d4e8dd8af 100644 --- a/vic/drivers/shared_image/src/vic_start.c +++ b/vic/drivers/shared_image/src/vic_start.c @@ -59,7 +59,7 @@ vic_start(void) size_t j; status = MPI_Bcast(&filenames, 1, mpi_filenames_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } @@ -67,11 +67,12 @@ vic_start(void) // Set Log Destination setup_logging(mpi_rank); - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // set model constants if (strcasecmp(filenames.constants, "MISSING")) { filep.constants = open_file(filenames.constants, "r"); get_parameters(filep.constants); + fclose(filep.constants); } // read domain info @@ -121,30 +122,30 @@ vic_start(void) // broadcast global, option, param structures as well as global valies // such as NF and NR - status = MPI_Bcast(&NF, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_VIC); + status = MPI_Bcast(&NF, 1, MPI_UNSIGNED_LONG, VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } - status = MPI_Bcast(&NR, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_VIC); + status = MPI_Bcast(&NR, 1, MPI_UNSIGNED_LONG, VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } status = MPI_Bcast(&global_param, 1, mpi_global_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } status = MPI_Bcast(&options, 1, mpi_option_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } status = MPI_Bcast(¶m, 1, mpi_param_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } @@ -153,7 +154,8 @@ vic_start(void) // First scatter the array sizes status = MPI_Scatter(mpi_map_local_array_sizes, 1, MPI_INT, - &local_ncells_active, 1, MPI_INT, 0, MPI_COMM_VIC); + &local_ncells_active, 1, MPI_INT, VIC_MPI_ROOT, + MPI_COMM_VIC); local_domain.ncells_active = (size_t) local_ncells_active; if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); @@ -170,7 +172,7 @@ vic_start(void) } // map the location vector to a temporary array so they can be scattered - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { mapped_locations = malloc(global_domain.ncells_active * sizeof(*mapped_locations)); if (mapped_locations == NULL) { @@ -207,7 +209,7 @@ vic_start(void) mpi_location_struct_type, local_domain.locations, local_domain.ncells_active, mpi_location_struct_type, - 0, MPI_COMM_VIC); + VIC_MPI_ROOT, MPI_COMM_VIC); if (status != MPI_SUCCESS) { log_err("MPI error in vic_start(): %d\n", status); } @@ -217,7 +219,7 @@ vic_start(void) } // cleanup - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { free(mapped_locations); free(active_locations); } diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index d170191be..d76bf57c0 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -32,487 +32,74 @@ void vic_store(dmy_struct *dmy_current) { - extern size_t current; extern filenames_struct filenames; extern all_vars_struct *all_vars; - extern domain_struct global_domain; extern domain_struct local_domain; extern option_struct options; - extern soil_con_struct *soil_con; extern veg_con_map_struct *veg_con_map; extern int mpi_rank; + char filename[MAXSTRING]; int status; - int old_fill_mode; - size_t dcount[MAXDIMS]; - size_t dstart[MAXDIMS]; - int dimids[MAXDIMS]; int v; size_t i; size_t j; size_t k; size_t m; size_t p; - size_t ndims; - char *cvar = NULL; int *ivar = NULL; double *dvar = NULL; - float *fvar = NULL; - int lon_var_id; - int lat_var_id; - size_t d1count[1]; - size_t d1start[1]; - size_t d2count[2]; size_t d2start[2]; - size_t d3count[3]; size_t d3start[3]; - size_t d4count[4]; size_t d4start[4]; - size_t d5count[5]; size_t d5start[5]; - size_t d6count[6]; size_t d6start[6]; - nc_file_struct nc_state_file; + nc_var_struct *nc_var; - // create netcdf file for storing model state - sprintf(nc_state_file.fname, "%s.%04d%02d%02d_%05u.nc", - filenames.statefile, dmy_current->year, dmy_current->month, - dmy_current->day, dmy_current->dayseconds); - - nc_state_file.c_fillvalue = NC_FILL_CHAR; - nc_state_file.i_fillvalue = NC_FILL_INT; - nc_state_file.d_fillvalue = NC_FILL_DOUBLE; - nc_state_file.f_fillvalue = NC_FILL_FLOAT; - - nc_state_file.ni_size = global_domain.n_nx; - nc_state_file.nj_size = global_domain.n_ny; - nc_state_file.veg_size = options.NVEGTYPES; - nc_state_file.band_size = options.SNOW_BAND; - nc_state_file.layer_size = options.Nlayer; - nc_state_file.frost_size = options.Nfrost; - nc_state_file.node_size = options.Nnode; - if (options.LAKES) { - nc_state_file.lake_node_size = options.NLAKENODES; - } + set_nc_state_file_info(&nc_state_file); // only open and initialize the netcdf file on the first thread - if (mpi_rank == 0) { - // open the netcdf file - status = nc_create(nc_state_file.fname, get_nc_mode( - options.STATE_FORMAT), &(nc_state_file.nc_id)); - if (status != NC_NOERR) { - log_err("Error creating %s", nc_state_file.fname); - } - nc_state_file.open = true; - - // Set netcdf file global attributes - set_global_nc_attributes(nc_state_file.nc_id, NC_STATE_FILE); - - // set the NC_FILL attribute - status = nc_set_fill(nc_state_file.nc_id, NC_FILL, &old_fill_mode); - if (status != NC_NOERR) { - log_err("Error setting fill value in %s", nc_state_file.fname); - } - - // define netcdf dimensions - status = nc_def_dim(nc_state_file.nc_id, global_domain.info.x_dim, - nc_state_file.ni_size, &(nc_state_file.ni_dimid)); - if (status != NC_NOERR) { - log_err("Error defining \"%s\" in %s", global_domain.info.x_dim, - nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, global_domain.info.y_dim, - nc_state_file.nj_size, &(nc_state_file.nj_dimid)); - if (status != NC_NOERR) { - log_err("Error defining \"%s\" in %s", global_domain.info.y_dim, - nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, "veg_class", - nc_state_file.veg_size, &(nc_state_file.veg_dimid)); - if (status != NC_NOERR) { - log_err("Error defining veg_class in %s", nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, "snow_band", - nc_state_file.band_size, - &(nc_state_file.band_dimid)); - if (status != NC_NOERR) { - log_err("Error defining snow_band in %s", nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, "nlayer", - nc_state_file.layer_size, - &(nc_state_file.layer_dimid)); - if (status != NC_NOERR) { - log_err("Error defining nlayer in %s", nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, "frost_area", - nc_state_file.frost_size, - &(nc_state_file.frost_dimid)); - if (status != NC_NOERR) { - log_err("Error defining frost_area in %s", nc_state_file.fname); - } - - status = nc_def_dim(nc_state_file.nc_id, "soil_node", - nc_state_file.node_size, - &(nc_state_file.node_dimid)); - if (status != NC_NOERR) { - log_err("Error defining soil_node in %s", nc_state_file.fname); - } - - if (options.LAKES) { - status = nc_def_dim(nc_state_file.nc_id, "lake_node", - nc_state_file.lake_node_size, - &(nc_state_file.lake_node_dimid)); - if (status != NC_NOERR) { - log_err("Error defining lake_node in %s", nc_state_file.fname); - } - } - - // initialize dimids to invalid values - for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; - } - - // write dimension variables - - // Coordinate variables - ndims = global_domain.info.n_coord_dims; - dstart[0] = 0; - dstart[1] = 0; - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file.ni_dimid; - dcount[0] = nc_state_file.ni_size; - } - else if (global_domain.info.n_coord_dims == 2) { - dimids[0] = nc_state_file.nj_dimid; - dcount[0] = nc_state_file.nj_size; - - dimids[1] = nc_state_file.ni_dimid; - dcount[1] = nc_state_file.ni_size; - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); - } - - // define the netcdf variable longitude - status = nc_def_var(nc_state_file.nc_id, global_domain.info.lon_var, - NC_DOUBLE, ndims, dimids, &(lon_var_id)); - if (status != NC_NOERR) { - log_err("Error defining lon variable in %s", nc_state_file.fname); - } - - status = nc_put_att_text(nc_state_file.nc_id, lon_var_id, "long_name", strlen( - "longitude"), "longitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - status = nc_put_att_text(nc_state_file.nc_id, lon_var_id, "units", strlen( - "degrees_east"), "degrees_east"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - status = nc_put_att_text(nc_state_file.nc_id, lon_var_id, - "standard_name", strlen( - "longitude"), "longitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file.nj_dimid; - dcount[0] = nc_state_file.nj_size; - } - - // define the netcdf variable latitude - status = nc_def_var(nc_state_file.nc_id, global_domain.info.lat_var, - NC_DOUBLE, ndims, dimids, &(lat_var_id)); - if (status != NC_NOERR) { - log_err("Error defining lat variable in %s", nc_state_file.fname); - } - status = nc_put_att_text(nc_state_file.nc_id, lat_var_id, "long_name", strlen( - "latitude"), "latitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - status = nc_put_att_text(nc_state_file.nc_id, lat_var_id, "units", strlen( - "degrees_north"), "degrees_north"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - status = nc_put_att_text(nc_state_file.nc_id, lat_var_id, - "standard_name", strlen("latitude"), - "latitude"); - if (status != NC_NOERR) { - log_err("Error adding attribute in %s", nc_state_file.fname); - } - - // leave define mode - status = nc_enddef(nc_state_file.nc_id); - if (status != NC_NOERR) { - log_err("Error leaving define mode for %s", nc_state_file.fname); - } - - // populate lat/lon - if (global_domain.info.n_coord_dims == 1) { - dvar = calloc(nc_state_file.ni_size, sizeof(*dvar)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - - dcount[0] = nc_state_file.ni_size; - // implicitly nested loop over ni and nj with j set to 0 - for (i = 0; i < nc_state_file.ni_size; i++) { - dvar[i] = (double) global_domain.locations[i].longitude; - } - status = nc_put_vara_double(nc_state_file.nc_id, lon_var_id, dstart, - dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc_state_file.fname); - } - free(dvar); - - dvar = calloc(nc_state_file.nj_size, sizeof(*dvar)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - dcount[0] = nc_state_file.nj_size; - // implicitly nested loop over ni and nj with i set to 0; - // j stride = ni_size - for (j = 0; j < nc_state_file.nj_size; j++) { - dvar[j] = - (double) global_domain.locations[j * - nc_state_file.ni_size]. - latitude; - } - - status = nc_put_vara_double(nc_state_file.nc_id, lat_var_id, dstart, - dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc_state_file.fname); - } - free(dvar); - } - else if (global_domain.info.n_coord_dims == 2) { - dvar = - calloc(nc_state_file.nj_size * nc_state_file.ni_size, - sizeof(*dvar)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - - for (i = 0; i < nc_state_file.nj_size * nc_state_file.ni_size; - i++) { - dvar[i] = (double) global_domain.locations[i].longitude; - } - status = nc_put_vara_double(nc_state_file.nc_id, lon_var_id, dstart, - dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lon in %s", nc_state_file.fname); - } - - for (i = 0; i < nc_state_file.nj_size * nc_state_file.ni_size; - i++) { - dvar[i] = (double) global_domain.locations[i].latitude; - } - status = nc_put_vara_double(nc_state_file.nc_id, lat_var_id, dstart, - dcount, dvar); - if (status != NC_NOERR) { - log_err("Error adding data to lat in %s", nc_state_file.fname); - } - - free(dvar); - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); - } - - // Variables for other dimensions (all 1-dimensional) - ndims = 1; - d1start[0] = 0; - - // vegetation classes - dimids[0] = nc_state_file.veg_dimid; - d1count[0] = nc_state_file.veg_size; - ivar = malloc(nc_state_file.veg_size * sizeof(*ivar)); - if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - for (j = 0; j < nc_state_file.veg_size; j++) { - ivar[j] = (int) j + 1; - } - put_nc_field_int(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "veg_class", d1start, d1count, ivar); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - free(ivar); - - // snow bands - dimids[0] = nc_state_file.band_dimid; - d1count[0] = nc_state_file.band_size; - ivar = malloc(nc_state_file.band_size * sizeof(*ivar)); - if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - for (j = 0; j < nc_state_file.band_size; j++) { - ivar[j] = (int) j; - } - put_nc_field_int(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "snow_band", d1start, d1count, ivar); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - free(ivar); - - // soil layers - dimids[0] = nc_state_file.layer_dimid; - d1count[0] = nc_state_file.layer_size; - ivar = malloc(nc_state_file.layer_size * sizeof(*ivar)); - if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - for (j = 0; j < nc_state_file.layer_size; j++) { - ivar[j] = (int) j; - } - put_nc_field_int(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "layer", d1start, d1count, ivar); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - free(ivar); - - // frost areas - dimids[0] = nc_state_file.frost_dimid; - d1count[0] = nc_state_file.frost_size; - ivar = malloc(nc_state_file.frost_size * sizeof(*ivar)); - if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - for (j = 0; j < nc_state_file.frost_size; j++) { - ivar[j] = (int) j; - } - put_nc_field_int(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "frost_area", d1start, d1count, ivar); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - free(ivar); - - // soil thermal node deltas - dimids[0] = nc_state_file.node_dimid; - d1count[0] = nc_state_file.node_size; - put_nc_field_double(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "dz_node", d1start, d1count, soil_con[0].dz_node); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - - // soil thermal node depths - dimids[0] = nc_state_file.node_dimid; - d1count[0] = nc_state_file.node_size; - put_nc_field_double(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "node_depth", d1start, d1count, - soil_con[0].Zsum_node); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - - if (options.LAKES) { - // lake nodes - dimids[0] = nc_state_file.lake_node_dimid; - d1count[0] = nc_state_file.lake_node_size; - ivar = malloc(nc_state_file.lake_node_size * sizeof(*ivar)); - if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - for (j = 0; j < nc_state_file.lake_node_size; j++) { - ivar[j] = (int) j; - } - put_nc_field_int(nc_state_file.fname, &(nc_state_file.open), - &(nc_state_file.nc_id), nc_state_file.d_fillvalue, - dimids, ndims, - "lake_node", d1start, d1count, ivar); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } - free(ivar); - } - } // end if (mpi_rank == 0) + if (mpi_rank == (mpi_rank == VIC_MPI_ROOT)) { + // create netcdf file for storing model state + sprintf(filename, "%s.%04d%02d%02d_%05u.nc", + filenames.statefile, dmy_current->year, dmy_current->month, + dmy_current->day, dmy_current->dayseconds); + initialize_state_file(filename, &nc_state_file); + } // write state variables // allocate memory for variables to be stored - cvar = malloc(local_domain.ncells_active * sizeof(*cvar)); - if (cvar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); if (ivar == NULL) { - log_err("Memory allocation error in vic_store()."); + log_err("Memory allocation error"); } dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); if (dvar == NULL) { - log_err("Memory allocation error in vic_store()."); - } - - fvar = malloc(local_domain.ncells_active * sizeof(*fvar)); - if (fvar == NULL) { - log_err("Memory allocation error in vic_store()."); + log_err("Memory allocation error"); } // initialize starts and counts d2start[0] = 0; d2start[1] = 0; - d2count[0] = global_domain.n_ny; - d2count[1] = global_domain.n_nx; d3start[0] = 0; d3start[1] = 0; d3start[2] = 0; - d3count[0] = 1; - d3count[1] = global_domain.n_ny; - d3count[2] = global_domain.n_nx; d4start[0] = 0; d4start[1] = 0; d4start[2] = 0; d4start[3] = 0; - d4count[0] = 1; - d4count[1] = 1; - d4count[2] = global_domain.n_ny; - d4count[3] = global_domain.n_nx; d5start[0] = 0; d5start[1] = 0; d5start[2] = 0; d5start[3] = 0; d5start[4] = 0; - d5count[0] = 1; - d5count[1] = 1; - d5count[2] = 1; - d5count[3] = global_domain.n_ny; - d5count[4] = global_domain.n_nx; d6start[0] = 0; d6start[1] = 0; @@ -520,28 +107,15 @@ vic_store(dmy_struct *dmy_current) d6start[3] = 0; d6start[4] = 0; d6start[5] = 0; - d6count[0] = 1; - d6count[1] = 1; - d6count[2] = 1; - d6count[3] = 1; - d6count[4] = global_domain.n_ny; - d6count[5] = global_domain.n_nx; // set missing values for (i = 0; i < local_domain.ncells_active; i++) { - cvar[i] = nc_state_file.c_fillvalue; ivar[i] = nc_state_file.i_fillvalue; dvar[i] = nc_state_file.d_fillvalue; - fvar[i] = nc_state_file.f_fillvalue; } // total soil moisture - ndims = 5; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.layer_dimid; - dimids[3] = nc_state_file.nj_dimid; - dimids[4] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); for (m = 0; m < options.NVEGTYPES; m++) { d5start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -551,37 +125,26 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].cell[v][k].layer[j].moist; + dvar[i] = + (double) all_vars[i].cell[v][k].layer[j].moist; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Soil_moisture", - d5start, d5count, dvar); + d5start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // ice content - ndims = 6; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.layer_dimid; - dimids[3] = nc_state_file.frost_dimid; - dimids[4] = nc_state_file.nj_dimid; - dimids[5] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_ICE]); for (m = 0; m < options.NVEGTYPES; m++) { d6start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -593,19 +156,18 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].cell[v][k].layer[j].ice[p]; + dvar[i] = + (double) all_vars[i].cell[v][k].layer[j].ice[p]; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Soil_ice", - d6start, d6count, dvar); + d6start, nc_var->nc_counts, + dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } @@ -613,16 +175,10 @@ vic_store(dmy_struct *dmy_current) } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // dew storage: tmpval = veg_var[veg][band].Wdew; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_CANOPY_WATER]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -630,35 +186,26 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].veg_var[v][k].Wdew; + dvar[i] = (double) all_vars[i].veg_var[v][k].Wdew; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Canopy_water", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + if (options.CARBON) { // cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPP]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -666,34 +213,24 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].veg_var[v][k].AnnualNPP; + dvar[i] = (double) all_vars[i].veg_var[v][k].AnnualNPP; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "AnnualNPP", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPPPREV]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -701,34 +238,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].veg_var[v][k].AnnualNPPPrev; + dvar[i] = + (double) all_vars[i].veg_var[v][k].AnnualNPPPrev; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "AnnualNPPPrev", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // litter carbon: tmpval = cell[veg][band].CLitter; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_CLITTER]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -736,34 +264,24 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].cell[v][k].CLitter; + dvar[i] = (double) all_vars[i].cell[v][k].CLitter; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "CLitter", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // intermediate carbon: tmpval = tmpval = cell[veg][band].CInter; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_CINTER]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -771,34 +289,24 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].cell[v][k].CInter; + dvar[i] = (double) all_vars[i].cell[v][k].CInter; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "CInter", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // slow carbon: tmpval = cell[veg][band].CSlow; - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_CSLOW]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -806,35 +314,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].cell[v][k].CSlow; + dvar[i] = (double) all_vars[i].cell[v][k].CSlow; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "CSlow", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } } // snow age: snow[veg][band].last_snow - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_AGE]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -842,34 +340,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - ivar[i] = (int) - all_vars[i].snow[v][k].last_snow; + ivar[i] = (int) all_vars[i].snow[v][k].last_snow; } else { ivar[i] = nc_state_file.i_fillvalue; } } - gather_put_nc_field_int(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), - nc_state_file.i_fillvalue, - dimids, ndims, "Snow_age", - d4start, d4count, ivar); + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // melting state: (int)snow[veg][band].MELTING - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_MELT_STATE]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -877,34 +366,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - ivar[i] = (int) - all_vars[i].snow[v][k].MELTING; + ivar[i] = (int) all_vars[i].snow[v][k].MELTING; } else { ivar[i] = nc_state_file.i_fillvalue; } } - gather_put_nc_field_int(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), - nc_state_file.i_fillvalue, - dimids, ndims, "Snow_melt_state", - d4start, d4count, ivar); + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow covered fraction: snow[veg][band].coverage - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COVERAGE]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -912,34 +392,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].coverage; + dvar[i] = (double) all_vars[i].snow[v][k].coverage; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_coverage", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow water equivalent: snow[veg][band].swq - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_WATER_EQUIVALENT]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -947,34 +418,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].swq; + dvar[i] = (double) all_vars[i].snow[v][k].swq; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_water_equivalent", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow surface temperature: snow[veg][band].surf_temp - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_TEMP]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -982,34 +444,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].surf_temp; + dvar[i] = (double) all_vars[i].snow[v][k].surf_temp; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_surf_temp", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow surface water: snow[veg][band].surf_water - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_WATER]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1017,34 +470,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].surf_water; + dvar[i] = (double) all_vars[i].snow[v][k].surf_water; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_surf_water", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow pack temperature: snow[veg][band].pack_temp - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_TEMP]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1052,34 +496,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].pack_temp; + dvar[i] = (double) all_vars[i].snow[v][k].pack_temp; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_pack_temp", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow pack water: snow[veg][band].pack_water - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_WATER]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1087,34 +522,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].pack_water; + dvar[i] = (double) all_vars[i].snow[v][k].pack_water; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_pack_water", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow density: snow[veg][band].density - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_DENSITY]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1122,34 +548,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].density; + dvar[i] = (double) all_vars[i].snow[v][k].density; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_density", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow cold content: snow[veg][band].coldcontent - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COLD_CONTENT]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1157,34 +574,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].coldcontent; + dvar[i] = (double) all_vars[i].snow[v][k].coldcontent; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_cold_content", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // snow canopy storage: snow[veg][band].snow_canopy - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_CANOPY]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1192,35 +600,25 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].snow[v][k].snow_canopy; + dvar[i] = (double) all_vars[i].snow[v][k].snow_canopy; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Snow_canopy", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // soil node temperatures: energy[veg][band].T[nidx] - ndims = 5; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.node_dimid; - dimids[3] = nc_state_file.nj_dimid; - dimids[4] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_NODE_TEMP]); for (m = 0; m < options.NVEGTYPES; m++) { d5start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1230,35 +628,26 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].energy[v][k].T[j]; + dvar[i] = (double) all_vars[i].energy[v][k].T[j]; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Soil_node_temp", - d5start, d5count, dvar); + d5start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // Foliage temperature: energy[veg][band].Tfoliage - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_FOLIAGE_TEMPERATURE]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1266,35 +655,26 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].energy[v][k].Tfoliage; + dvar[i] = (double) all_vars[i].energy[v][k].Tfoliage; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Foliage_temperature", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // Outgoing longwave from understory: energy[veg][band].LongUnderOut // This is a flux, and saving it to state file is a temporary solution!! - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_LONGUNDEROUT]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1302,35 +682,26 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].energy[v][k].LongUnderOut; + dvar[i] = (double) all_vars[i].energy[v][k].LongUnderOut; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Energy_LongUnderOut", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + // Thermal flux through the snow pack: energy[veg][band].snow_flux // This is a flux, and saving it to state file is a temporary solution!! - ndims = 4; - dimids[0] = nc_state_file.veg_dimid; - dimids[1] = nc_state_file.band_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_SNOW_FLUX]); for (m = 0; m < options.NVEGTYPES; m++) { d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { @@ -1338,848 +709,1355 @@ vic_store(dmy_struct *dmy_current) for (i = 0; i < local_domain.ncells_active; i++) { v = veg_con_map[i].vidx[m]; if (v >= 0) { - dvar[i] = (double) - all_vars[i].energy[v][k].snow_flux; + dvar[i] = (double) all_vars[i].energy[v][k].snow_flux; } else { dvar[i] = nc_state_file.d_fillvalue; } } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Energy_snow_flux", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } + if (options.LAKES) { // total soil moisture - ndims = 3; - dimids[0] = nc_state_file.layer_dimid; - dimids[1] = nc_state_file.nj_dimid; - dimids[2] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_MOISTURE]); for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_soil_moisture", - d3start, d3count, dvar); + d3start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // ice content - ndims = 4; - dimids[0] = nc_state_file.layer_dimid; - dimids[1] = nc_state_file.frost_dimid; - dimids[2] = nc_state_file.nj_dimid; - dimids[3] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_ICE]); for (j = 0; j < options.Nlayer; j++) { d4start[0] = j; for (p = 0; p < options.Nfrost; p++) { d4start[1] = p; for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) - all_vars[i].lake_var.soil.layer[j].ice[p]; + dvar[i] = + (double) all_vars[i].lake_var.soil.layer[j].ice[p]; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_soil_ice", - d4start, d4count, dvar); + d4start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } if (options.CARBON) { // litter carbon: tmpval = lake_var.soil.CLitter; - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CLITTER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.soil.CLitter; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_CLitter", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // intermediate carbon: tmpval = lake_var.soil.CInter; - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CINTER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.soil.CInter; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_CInter", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // slow carbon: tmpval = lake_var.soil.CSlow; - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CSLOW]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.soil.CSlow; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_CSlow", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } } // snow age: lake_var.snow.last_snow - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_AGE]); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = (int) all_vars[i].lake_var.snow.last_snow; } - gather_put_nc_field_int(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), - nc_state_file.i_fillvalue, - dimids, ndims, "Lake_snow_age", - d2start, d2count, ivar); + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // melting state: (int)lake_var.snow.MELTING - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_MELT_STATE]); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = (int) all_vars[i].lake_var.snow.MELTING; } - gather_put_nc_field_int(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), - nc_state_file.i_fillvalue, - dimids, ndims, "Lake_snow_melt_state", - d2start, d2count, ivar); + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // snow covered fraction: lake_var.snow.coverage - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COVERAGE]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.coverage; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_coverage", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow water equivalent: lake_var.snow.swq - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_WATER_EQUIVALENT]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.swq; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_water_equivalent", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow surface temperature: lake_var.snow.surf_temp - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.surf_temp; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_surf_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow surface water: lake_var.snow.surf_water - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_WATER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.surf_water; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_surf_water", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow pack temperature: lake_var.snow.pack_temp - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.pack_temp; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_pack_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow pack water: lake_var.snow.pack_water - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_WATER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.pack_water; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_pack_water", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow density: lake_var.snow.density - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_DENSITY]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.density; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_density", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow cold content: lake_var.snow.coldcontent - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COLD_CONTENT]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.coldcontent; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_cold_content", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // snow canopy storage: lake_var.snow.snow_canopy - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_CANOPY]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.snow.snow_canopy; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_snow_canopy", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // soil node temperatures: lake_var.energy.T[nidx] - ndims = 3; - dimids[0] = nc_state_file.node_dimid; - dimids[1] = nc_state_file.nj_dimid; - dimids[2] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_NODE_TEMP]); for (j = 0; j < options.Nnode; j++) { d3start[0] = j; for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_soil_node_temp", - d3start, d3count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // lake active layers: lake_var.activenod - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ACTIVE_LAYERS]); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = (int) all_vars[i].lake_var.activenod; } - gather_put_nc_field_int(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), - nc_state_file.i_fillvalue, - dimids, ndims, "Lake_active_layers", - d2start, d2count, ivar); + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // lake layer thickness: lake_var.dz - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_DZ]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.dz; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_layer_dz", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake surface layer thickness: lake_var.surfdz - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_LAYER_DZ]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.surfdz; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_surf_layer_dz", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake depth: lake_var.ldepth - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_DEPTH]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.ldepth; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_depth", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake layer surface areas: lake_var.surface[ndix] - ndims = 3; - dimids[0] = nc_state_file.lake_node_dimid; - dimids[1] = nc_state_file.nj_dimid; - dimids[2] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_SURF_AREA]); for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.surface[j]; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_layer_surf_area", - d3start, d3count, dvar); + d3start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // lake surface area: lake_var.sarea - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_AREA]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.sarea; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_surf_area", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake volume: lake_var.volume - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_VOLUME]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.volume; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_volume", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake layer temperatures: lake_var.temp[nidx] - ndims = 3; - dimids[0] = nc_state_file.lake_node_dimid; - dimids[1] = nc_state_file.nj_dimid; - dimids[2] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_TEMP]); for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.temp[j]; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_layer_temp", - d3start, d3count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = nc_state_file.d_fillvalue; } } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - } // vertical average lake temperature: lake_var.tempavg - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_AVERAGE_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.tempavg; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_average_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice area fraction: lake_var.areai - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.areai; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_area_frac", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // new lake ice area fraction: lake_var.new_ice_area - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC_NEW]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.new_ice_area; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_area_frac_new", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice water equivalent: lake_var.ice_water_eq - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_WATER_EQUIVALENT]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.ice_water_eq; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_water_equivalent", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice height: lake_var.hice - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_HEIGHT]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.hice; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_height", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice temperature: lake_var.tempi - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.tempi; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow water equivalent: lake_var.swe - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SWE]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.swe; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, - "Lake_ice_snow_water_equivalen", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow surface temperature: lake_var.surf_temp - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.surf_temp; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_surf_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow pack temperature: lake_var.pack_temp - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_TEMP]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.pack_temp; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_pack_temp", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow coldcontent: lake_var.coldcontent - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_COLD_CONTENT]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.coldcontent; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_cold_content", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow surface water: lake_var.surf_water - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_WATER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.surf_water; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_surf_water", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow pack water: lake_var.pack_water - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_WATER]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.pack_water; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_pack_water", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow albedo: lake_var.SAlbedo - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_ALBEDO]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.SAlbedo; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_albedo", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } // lake ice snow depth: lake_var.sdepth - ndims = 2; - dimids[0] = nc_state_file.nj_dimid; - dimids[1] = nc_state_file.ni_dimid; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_DEPTH]); for (i = 0; i < local_domain.ncells_active; i++) { dvar[i] = (double) all_vars[i].lake_var.sdepth; } - gather_put_nc_field_double(nc_state_file.fname, - &(nc_state_file.open), - &(nc_state_file.nc_id), + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, nc_state_file.d_fillvalue, - dimids, ndims, "Lake_ice_snow_depth", - d2start, d2count, dvar); + d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.i_fillvalue; - } - for (i = 0; i < ndims; i++) { - dimids[i] = -1; + dvar[i] = nc_state_file.d_fillvalue; } } // close the netcdf file if it is still open - if (nc_state_file.open == true) { - status = nc_close(nc_state_file.nc_id); - if (status != NC_NOERR) { - log_err("Error closing %s", nc_state_file.fname); + if (mpi_rank == (mpi_rank == VIC_MPI_ROOT)) { + if (nc_state_file.open == true) { + status = nc_close(nc_state_file.nc_id); + if (status != NC_NOERR) { + log_err("Error closing %s", filename); + } } } - free(cvar); free(ivar); free(dvar); - free(fvar); +} + +/****************************************************************************** + * @brief Setup state file netcdf structure + *****************************************************************************/ +void +set_nc_state_file_info(nc_file_struct *nc_state_file) +{ + extern option_struct options; + extern domain_struct global_domain; + + // Set fill values + nc_state_file->c_fillvalue = NC_FILL_CHAR; + nc_state_file->s_fillvalue = NC_FILL_SHORT; + nc_state_file->i_fillvalue = NC_FILL_INT; + nc_state_file->d_fillvalue = NC_FILL_DOUBLE; + nc_state_file->f_fillvalue = NC_FILL_FLOAT; + + // set ids to MISSING + nc_state_file->nc_id = MISSING; + nc_state_file->band_dimid = MISSING; + nc_state_file->front_dimid = MISSING; + nc_state_file->frost_dimid = MISSING; + nc_state_file->lake_node_dimid = MISSING; + nc_state_file->layer_dimid = MISSING; + nc_state_file->ni_dimid = MISSING; + nc_state_file->nj_dimid = MISSING; + nc_state_file->node_dimid = MISSING; + nc_state_file->root_zone_dimid = MISSING; + nc_state_file->time_dimid = MISSING; + nc_state_file->veg_dimid = MISSING; + + // Set dimension sizes + nc_state_file->time_size = 1; + nc_state_file->band_size = options.SNOW_BAND; + nc_state_file->front_size = MAX_FRONTS; + nc_state_file->frost_size = options.Nfrost; + nc_state_file->layer_size = options.Nlayer; + nc_state_file->ni_size = global_domain.n_nx; + nc_state_file->nj_size = global_domain.n_ny; + nc_state_file->node_size = options.Nnode; + nc_state_file->root_zone_size = options.ROOT_ZONES; + nc_state_file->time_size = NC_UNLIMITED; + nc_state_file->veg_size = options.NVEGTYPES; + + // allocate memory for nc_vars + nc_state_file->nc_vars = + calloc(N_STATE_VARS, sizeof(*(nc_state_file->nc_vars))); + if (nc_state_file->nc_vars == NULL) { + log_err("Memory allocation error"); + } +} + +/****************************************************************************** + * @brief Setup state variable dimensions, types, etc. + *****************************************************************************/ +void +set_nc_state_var_info(nc_file_struct *nc) +{ + size_t i; + size_t j; + + for (i = 0; i < N_STATE_VARS; i++) { + nc->nc_vars[i].nc_varid = i; + for (j = 0; j < MAXDIMS; j++) { + nc->nc_vars[i].nc_dimids[j] = -1; + nc->nc_vars[i].nc_counts[j] = 0; + } + nc->nc_vars[i].nc_dims = 0; + + switch (i) { + case STATE_LAKE_ACTIVE_LAYERS: + nc->nc_vars[i].nc_type = NC_INT; + break; + default: + nc->nc_vars[i].nc_type = NC_DOUBLE; + } + + // Set the number of dimensions and dimids for each state variable + switch (i) { + case STATE_SOIL_MOISTURE: + // 5d vars [veg, band, layer, j, i] + nc->nc_vars[i].nc_dims = 5; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = nc->nj_size; + nc->nc_vars[i].nc_counts[4] = nc->ni_size; + break; + case STATE_SOIL_ICE: + // 6d vars [veg, band, layer, frost, j, i] + nc->nc_vars[i].nc_dims = 6; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->frost_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[5] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = 1; + nc->nc_vars[i].nc_counts[4] = nc->nj_size; + nc->nc_vars[i].nc_counts[5] = nc->ni_size; + break; + case STATE_CANOPY_WATER: + case STATE_ANNUALNPP: + case STATE_ANNUALNPPPREV: + case STATE_CLITTER: + case STATE_CINTER: + case STATE_CSLOW: + case STATE_SNOW_AGE: + case STATE_SNOW_MELT_STATE: + case STATE_SNOW_COVERAGE: + case STATE_SNOW_WATER_EQUIVALENT: + case STATE_SNOW_SURF_TEMP: + case STATE_SNOW_SURF_WATER: + case STATE_SNOW_PACK_TEMP: + case STATE_SNOW_PACK_WATER: + case STATE_SNOW_DENSITY: + case STATE_SNOW_COLD_CONTENT: + case STATE_SNOW_CANOPY: + case STATE_FOLIAGE_TEMPERATURE: + case STATE_ENERGY_LONGUNDEROUT: + case STATE_ENERGY_SNOW_FLUX: + // 4d vars [veg, band, j, i] + nc->nc_vars[i].nc_dims = 4; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = nc->nj_size; + nc->nc_vars[i].nc_counts[3] = nc->ni_size; + break; + case STATE_SOIL_NODE_TEMP: + // 5d vars [veg, band, node, j, i] + nc->nc_vars[i].nc_dims = 5; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->node_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = nc->nj_size; + nc->nc_vars[i].nc_counts[4] = nc->ni_size; + break; + case STATE_LAKE_SOIL_MOISTURE: + // 3d vars [layer, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + break; + case STATE_LAKE_SOIL_ICE: + // 4d vars [layer, frost, j, i] + nc->nc_vars[i].nc_dims = 4; + nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->frost_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = nc->nj_size; + nc->nc_vars[i].nc_counts[3] = nc->ni_size; + break; + case STATE_LAKE_CLITTER: + case STATE_LAKE_CINTER: + case STATE_LAKE_CSLOW: + case STATE_LAKE_SNOW_AGE: + case STATE_LAKE_SNOW_MELT_STATE: + case STATE_LAKE_SNOW_COVERAGE: + case STATE_LAKE_SNOW_WATER_EQUIVALENT: + case STATE_LAKE_SNOW_SURF_TEMP: + case STATE_LAKE_SNOW_SURF_WATER: + case STATE_LAKE_SNOW_PACK_TEMP: + case STATE_LAKE_SNOW_PACK_WATER: + case STATE_LAKE_SNOW_DENSITY: + case STATE_LAKE_SNOW_COLD_CONTENT: + case STATE_LAKE_SNOW_CANOPY: + case STATE_LAKE_ACTIVE_LAYERS: + case STATE_LAKE_LAYER_DZ: + case STATE_LAKE_SURF_LAYER_DZ: + case STATE_LAKE_DEPTH: + case STATE_LAKE_SURF_AREA: + case STATE_LAKE_VOLUME: + case STATE_LAKE_AVERAGE_TEMP: + case STATE_LAKE_ICE_AREA_FRAC: + case STATE_LAKE_ICE_AREA_FRAC_NEW: + case STATE_LAKE_ICE_WATER_EQUIVALENT: + case STATE_LAKE_ICE_HEIGHT: + case STATE_LAKE_ICE_TEMP: + case STATE_LAKE_ICE_SWE: + case STATE_LAKE_ICE_SNOW_SURF_TEMP: + case STATE_LAKE_ICE_SNOW_PACK_TEMP: + case STATE_LAKE_ICE_SNOW_COLD_CONTENT: + case STATE_LAKE_ICE_SNOW_SURF_WATER: + case STATE_LAKE_ICE_SNOW_PACK_WATER: + case STATE_LAKE_ICE_SNOW_ALBEDO: + case STATE_LAKE_ICE_SNOW_DEPTH: + // 2d vars [j, i] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = nc->nj_size; + nc->nc_vars[i].nc_counts[1] = nc->ni_size; + break; + case STATE_LAKE_SOIL_NODE_TEMP: + // 3d vars [node, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->node_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = nc->nj_size; + nc->nc_vars[i].nc_counts[2] = nc->ni_size; + break; + case STATE_LAKE_LAYER_SURF_AREA: + case STATE_LAKE_LAYER_TEMP: + // 3d vars [lake_node, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->lake_node_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = nc->nj_size; + nc->nc_vars[i].nc_counts[2] = nc->ni_size; + break; + default: + log_err("state variable %zu not found when setting dimensions", i); + } + + if (nc->nc_vars[i].nc_dims > MAXDIMS) { + log_err("Too many dimensions specified in variable %zu", i); + } + } +} + +/****************************************************************************** + * @brief Initialize state file by creating dimensions, variables, + and adding metadata. + *****************************************************************************/ +void +initialize_state_file(char *filename, + nc_file_struct *nc_state_file) +{ + extern option_struct options; + extern domain_struct global_domain; + extern global_param_struct global_param; + extern metadata_struct state_metadata[N_STATE_VARS]; + + int status; + int dimids[MAXDIMS]; + int old_fill_mode; + size_t i; + size_t j; + size_t dcount[MAXDIMS]; + size_t dstart[MAXDIMS]; + int time_var_id; + int lon_var_id; + int lat_var_id; + int veg_var_id; + int snow_band_var_id; + int layer_var_id; + int frost_area_var_id; + int dz_node_var_id; + int node_depth_var_id; + int lake_node_var_id; + char unit_str[MAXSTRING]; + char str[MAXSTRING]; + size_t ndims; + double *dvar = NULL; + int *ivar = NULL; + + // open the netcdf file + status = nc_create(filename, NC_WRITE | get_nc_mode(options.STATE_FORMAT), + &(nc_state_file->nc_id)); + check_nc_status(status, "Error creating %s", filename); + nc_state_file->open = true; + + // Set netcdf file global attributes + set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); + + // set the NC_FILL attribute + status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); + check_nc_status(status, "Error setting fill value in %s", filename); + + // define the time dimension + status = nc_def_dim(nc_state_file->nc_id, "time", nc_state_file->time_size, + &(nc_state_file->time_dimid)); + check_nc_status(status, "Error defining time dimenension in %s", filename); + + // define the variable time + status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, + &(nc_state_file->time_dimid), &(time_var_id)); + check_nc_status(status, "Error defining time variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, time_var_id, "standard_name", + strlen("time"), "time"); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding units attribute to time variable + str_from_time_units(global_param.time_units, unit_str); + + sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); + + status = nc_put_att_text(nc_state_file->nc_id, time_var_id, "units", + strlen(str), str); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding calendar attribute to time variable + str_from_calendar(global_param.calendar, str); + + status = nc_put_att_text(nc_state_file->nc_id, time_var_id, "calendar", + strlen(str), str); + check_nc_status(status, "Error adding calendar attribute in %s", filename); + + // define netcdf dimensions + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, + nc_state_file->ni_size, &(nc_state_file->ni_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.x_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, + nc_state_file->nj_size, &(nc_state_file->nj_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.y_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, "veg_class", + nc_state_file->veg_size, &(nc_state_file->veg_dimid)); + check_nc_status(status, "Error defining veg_class in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "snow_band", + nc_state_file->band_size, + &(nc_state_file->band_dimid)); + check_nc_status(status, "Error defining snow_band in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "nlayer", + nc_state_file->layer_size, + &(nc_state_file->layer_dimid)); + check_nc_status(status, "Error defining nlayer in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "frost_area", + nc_state_file->frost_size, + &(nc_state_file->frost_dimid)); + check_nc_status(status, "Error defining frost_area in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "soil_node", + nc_state_file->node_size, + &(nc_state_file->node_dimid)); + check_nc_status(status, "Error defining soil_node in %s", filename); + + if (options.LAKES) { + status = nc_def_dim(nc_state_file->nc_id, "lake_node", + nc_state_file->lake_node_size, + &(nc_state_file->lake_node_dimid)); + check_nc_status(status, "Error defining lake_node in %s", filename); + } + + set_nc_state_var_info(nc_state_file); + + // initialize dimids to invalid values + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // write dimension variables + + // Coordinate variables + ndims = global_domain.info.n_coord_dims; + dstart[0] = 0; + dstart[1] = 0; + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->ni_dimid; + dcount[0] = nc_state_file->ni_size; + } + else if (global_domain.info.n_coord_dims == 2) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + + dimids[1] = nc_state_file->ni_dimid; + dcount[1] = nc_state_file->ni_size; + } + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); + } + + // define the netcdf variable longitude + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, + NC_DOUBLE, ndims, dimids, &(lon_var_id)); + check_nc_status(status, "Error defining lon variable in %s", filename); + + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( + "degrees_east"), "degrees_east"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, + "standard_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + } + + // define the netcdf variable latitude + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, + NC_DOUBLE, ndims, dimids, &(lat_var_id)); + check_nc_status(status, "Error defining lat variable (%s) in %s", + global_domain.info.lat_var, filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( + "latitude"), "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( + "degrees_north"), "degrees_north"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, + "standard_name", strlen("latitude"), + "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // veg_class + dimids[0] = nc_state_file->veg_dimid; + status = nc_def_var(nc_state_file->nc_id, "veg_class", + NC_INT, ndims, dimids, &(veg_var_id)); + check_nc_status(status, "Error defining veg_class variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", + strlen("veg_class"), "veg_class"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, + "standard_name", strlen("vegetation_class_number"), + "vegetation_class_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // snow_band + dimids[0] = nc_state_file->band_dimid; + status = nc_def_var(nc_state_file->nc_id, "snow_band", + NC_INT, ndims, dimids, &(snow_band_var_id)); + check_nc_status(status, "Error defining snow_band variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, + "long_name", + strlen("snow_band"), "snow_band"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, + "standard_name", + strlen("snow_elevation_band_number"), + "snow_elevation_band_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // layer + dimids[0] = nc_state_file->layer_dimid; + status = + nc_def_var(nc_state_file->nc_id, "layer", NC_INT, ndims, dimids, + &(layer_var_id)); + check_nc_status(status, "Error defining layer variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", + strlen("layer"), "layer"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, + "standard_name", strlen("soil_layer_number"), + "soil_layer_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // frost_area + dimids[0] = nc_state_file->frost_dimid; + status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, ndims, + dimids, &(frost_area_var_id)); + check_nc_status(status, "Error defining frost_area variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "long_name", + strlen("frost_area"), "frost_area"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "standard_name", strlen("frost_area_number"), + "frost_area_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // dz_node + dimids[0] = nc_state_file->node_dimid; + status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, ndims, + dimids, &(dz_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", + strlen("dz_node"), "dz_node"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "standard_name", strlen( + "soil_thermal_node_spacing"), + "soil_thermal_node_spacing"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "units", + strlen("m"), "m"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // node_depth + dimids[0] = nc_state_file->node_dimid; + status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, ndims, + dimids, &(node_depth_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "long_name", + strlen("node_depth"), "node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "standard_name", strlen("soil_thermal_node_depth"), + "soil_thermal_node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, "units", + strlen("m"), "m"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + if (options.LAKES) { + // lake_node + dimids[0] = nc_state_file->lake_node_dimid; + status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, ndims, + dimids, &(lake_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, + "long_name", + strlen("lake_node"), "lake_node"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "standard_name", strlen("lake_node_number"), + "lake_node_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + } + + // Define state variables + for (i = 0; i < N_STATE_VARS; i++) { + if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { + // skip variables not set in set_state_meta_data_info + continue; + } + + // create the variable + status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, + nc_state_file->nc_vars[i].nc_type, + nc_state_file->nc_vars[i].nc_dims, + nc_state_file->nc_vars[i].nc_dimids, + &(nc_state_file->nc_vars[i].nc_varid)); + check_nc_status(status, "Error defining state variable %s in %s", + state_metadata[i].varname, filename); + + // set the fill value attribute + if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { + status = nc_put_att_double(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_DOUBLE, 1, + &(nc_state_file->d_fillvalue)); + } + else if (nc_state_file->nc_vars[i].nc_type == NC_INT) { + status = nc_put_att_int(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_INT, 1, + &(nc_state_file->i_fillvalue)); + } + else { + log_err("NC_TYPE %d not supported at this time", + nc_state_file->nc_vars[i].nc_type); + } + check_nc_status(status, + "Error putting _FillValue attribute to %s in %s", + state_metadata[i].varname, filename); + + // Set string attributes + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "long_name", state_metadata[i].long_name); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "standard_name", state_metadata[i].standard_name); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "units", state_metadata[i].units); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "description", state_metadata[i].description); + } + + // leave define mode + status = nc_enddef(nc_state_file->nc_id); + check_nc_status(status, "Error leaving define mode for %s", filename); + + // populate lat/lon + if (global_domain.info.n_coord_dims == 1) { + dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); + if (dvar == NULL) { + log_err("Memory allocation error"); + } + + dcount[0] = nc_state_file->ni_size; + // implicitly nested loop over ni and nj with j set to 0 + for (i = 0; i < nc_state_file->ni_size; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + + dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); + if (dvar == NULL) { + log_err("Memory allocation error"); + } + dcount[0] = nc_state_file->nj_size; + // implicitly nested loop over ni and nj with i set to 0; + // j stride = ni_size + for (j = 0; j < nc_state_file->nj_size; j++) { + dvar[j] = + (double) global_domain.locations[j * + nc_state_file->ni_size]. + latitude; + } + + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + } + else if (global_domain.info.n_coord_dims == 2) { + dvar = calloc(global_domain.ncells_total, sizeof(*dvar)); + if (dvar == NULL) { + log_err("Memory allocation error"); + } + + for (i = 0; i < global_domain.ncells_total; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + + for (i = 0; i < global_domain.ncells_total; + i++) { + dvar[i] = (double) global_domain.locations[i].latitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lat in %s", filename); + + free(dvar); + } + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); + } + + // Variables for other dimensions (all 1-dimensional) + ndims = 1; + + // vegetation classes + dimids[0] = nc_state_file->veg_dimid; + dcount[0] = nc_state_file->veg_size; + ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + for (j = 0; j < nc_state_file->veg_size; j++) { + ivar[j] = (int) j + 1; + } + status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, dcount, + ivar); + check_nc_status(status, "Error writing veg var id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // snow bands + dimids[0] = nc_state_file->band_dimid; + dcount[0] = nc_state_file->band_size; + ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + for (j = 0; j < nc_state_file->band_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, snow_band_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing snow band id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // soil layers + dimids[0] = nc_state_file->layer_dimid; + dcount[0] = nc_state_file->layer_size; + ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + for (j = 0; j < nc_state_file->layer_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, dcount, + ivar); + check_nc_status(status, "Error writing layer id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // frost areas + dimids[0] = nc_state_file->frost_dimid; + dcount[0] = nc_state_file->frost_size; + ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + for (j = 0; j < nc_state_file->frost_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing frost id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // soil thermal node deltas + dimids[0] = nc_state_file->node_dimid; + dcount[0] = nc_state_file->node_size; + status = nc_put_vara_double(nc_state_file->nc_id, dz_node_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error writing thermal node deltas"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // soil thermal node depths + dimids[0] = nc_state_file->node_dimid; + dcount[0] = nc_state_file->node_size; + status = nc_put_vara_double(nc_state_file->nc_id, node_depth_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error writing thermal node depths"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + if (options.LAKES) { + // lake nodes + dimids[0] = nc_state_file->lake_node_dimid; + dcount[0] = nc_state_file->lake_node_size; + ivar = malloc(nc_state_file->lake_node_size * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + for (j = 0; j < nc_state_file->lake_node_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, lake_node_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing lake nodes"); + + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + } } diff --git a/vic/drivers/shared_image/src/vic_write.c b/vic/drivers/shared_image/src/vic_write.c index 9e426fdc6..267d5778d 100644 --- a/vic/drivers/shared_image/src/vic_write.c +++ b/vic/drivers/shared_image/src/vic_write.c @@ -26,55 +26,119 @@ #include +/****************************************************************************** + * @brief Write output data and convert units if necessary. + *****************************************************************************/ +void +vic_write_output(dmy_struct *dmy) +{ + extern option_struct options; + extern stream_struct *output_streams; + extern nc_file_struct *nc_hist_files; + + size_t stream_idx; + + // Write data + for (stream_idx = 0; stream_idx < options.Noutstreams; stream_idx++) { + if (raise_alarm(&(output_streams[stream_idx].agg_alarm), dmy)) { + debug("raised alarm for stream %zu", stream_idx); + vic_write(&(output_streams[stream_idx]), + &(nc_hist_files[stream_idx]), dmy); + reset_stream(&(output_streams[stream_idx]), dmy); + } + } +} + /****************************************************************************** * @brief Write output to netcdf file. Currently everything is cast to * double *****************************************************************************/ void -vic_write(dmy_struct *dmy_current) +vic_write(stream_struct *stream, + nc_file_struct *nc_hist_file, + dmy_struct *dmy_current) { - extern out_data_struct **out_data; extern global_param_struct global_param; extern domain_struct local_domain; - extern nc_file_struct nc_hist_file; - extern nc_var_struct nc_vars[N_OUTVAR_TYPES]; - extern size_t current; extern int mpi_rank; - int dimids[MAXDIMS]; + extern metadata_struct out_metadata[N_OUTVAR_TYPES]; + size_t i; size_t j; size_t k; size_t ndims; + double dtime; double *dvar = NULL; + float *fvar = NULL; + int *ivar = NULL; + short int *svar = NULL; + char *cvar = NULL; size_t dcount[MAXDIMS]; size_t dstart[MAXDIMS]; + unsigned int varid; + int status; - // allocate memory for variables to be stored - dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_write()."); - } - - // set missing values - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_hist_file.d_fillvalue; - } - // initialize dimids to invalid values - helps debugging for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; dstart[i] = -1; - dcount[i] = -1; + dcount[i] = 0; } - for (k = 0; k < N_OUTVAR_TYPES; k++) { - if (!nc_vars[k].nc_write) { - continue; + for (k = 0; k < stream->nvars; k++) { + varid = stream->varid[k]; + + if (nc_hist_file->nc_vars[k].nc_type == NC_DOUBLE) { + if (dvar == NULL) { + // allocate memory for variables to be stored + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + if (dvar == NULL) { + log_err("Memory allocation error"); + } + } + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_FLOAT) { + if (fvar == NULL) { + // allocate memory for variables to be stored + fvar = malloc(local_domain.ncells_active * sizeof(*fvar)); + if (fvar == NULL) { + log_err("Memory allocation error"); + } + } + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_INT) { + if (ivar == NULL) { + // allocate memory for variables to be stored + ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); + if (ivar == NULL) { + log_err("Memory allocation error"); + } + } + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_SHORT) { + if (svar == NULL) { + // allocate memory for variables to be stored + svar = malloc(local_domain.ncells_active * sizeof(*svar)); + if (svar == NULL) { + log_err("Memory allocation error"); + } + } + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_CHAR) { + if (cvar == NULL) { + // allocate memory for variables to be stored + cvar = malloc(local_domain.ncells_active * sizeof(*cvar)); + if (cvar == NULL) { + log_err("Memory allocation error"); + } + } } - ndims = nc_vars[k].nc_dims; + else { + log_err("Unsupported nc_type encountered"); + } + + ndims = nc_hist_file->nc_vars[k].nc_dims; for (j = 0; j < ndims; j++) { - dimids[j] = nc_vars[k].nc_dimids[j]; dstart[j] = 0; dcount[j] = 1; } @@ -82,59 +146,102 @@ vic_write(dmy_struct *dmy_current) // written one slice at a time, so all counts are 1, except the last // two for (j = ndims - 2; j < ndims; j++) { - dcount[j] = nc_vars[k].nc_counts[j]; + dcount[j] = nc_hist_file->nc_vars[k].nc_counts[j]; } - dstart[0] = current; - for (j = 0; j < out_data[0][k].nelem; j++) { + dstart[0] = stream->write_alarm.count; // Position in the time dimensions + + for (j = 0; j < out_metadata[varid].nelem; j++) { // if there is more than one layer, then dstart needs to advance dstart[1] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) out_data[i][k].aggdata[j]; + if (nc_hist_file->nc_vars[k].nc_type == NC_DOUBLE) { + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) stream->aggdata[i][k][j][0]; + } + gather_put_nc_field_double(nc_hist_file->nc_id, + nc_hist_file->nc_vars[k].nc_varid, + nc_hist_file->d_fillvalue, + dstart, dcount, dvar); } - gather_put_nc_field_double(nc_hist_file.fname, &(nc_hist_file.open), - &(nc_hist_file.nc_id), - nc_hist_file.d_fillvalue, - dimids, ndims, nc_vars[k].nc_var_name, - dstart, dcount, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_hist_file.d_fillvalue; + else if (nc_hist_file->nc_vars[k].nc_type == NC_FLOAT) { + for (i = 0; i < local_domain.ncells_active; i++) { + fvar[i] = (float) stream->aggdata[i][k][j][0]; + } + gather_put_nc_field_float(nc_hist_file->nc_id, + nc_hist_file->nc_vars[k].nc_varid, + nc_hist_file->f_fillvalue, + dstart, dcount, fvar); + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_INT) { + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = (int) stream->aggdata[i][k][j][0]; + } + gather_put_nc_field_int(nc_hist_file->nc_id, + nc_hist_file->nc_vars[k].nc_varid, + nc_hist_file->i_fillvalue, + dstart, dcount, ivar); + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_SHORT) { + for (i = 0; i < local_domain.ncells_active; i++) { + svar[i] = (short int) stream->aggdata[i][k][j][0]; + } + gather_put_nc_field_short(nc_hist_file->nc_id, + nc_hist_file->nc_vars[k].nc_varid, + nc_hist_file->s_fillvalue, + dstart, dcount, svar); + } + else if (nc_hist_file->nc_vars[k].nc_type == NC_CHAR) { + for (i = 0; i < local_domain.ncells_active; i++) { + cvar[i] = (char) stream->aggdata[i][k][j][0]; + } + gather_put_nc_field_schar(nc_hist_file->nc_id, + nc_hist_file->nc_vars[k].nc_varid, + nc_hist_file->d_fillvalue, + dstart, dcount, cvar); + } + else { + log_err("Unsupported nc_type encountered"); } } // reset dimids to invalid values - helps debugging for (j = 0; j < MAXDIMS; j++) { - dimids[j] = -1; dstart[j] = -1; dcount[j] = -1; } } - // reset the agg data - for (k = 0; k < N_OUTVAR_TYPES; k++) { - for (j = 0; j < out_data[0][k].nelem; j++) { - for (i = 0; i < local_domain.ncells_active; i++) { - out_data[i][k].aggdata[j] = 0; - } - } - } - - // ADD Time variable - dimids[0] = nc_hist_file.time_dimid; - dstart[0] = current; - dcount[0] = 1; + // write to file + if (mpi_rank == VIC_MPI_ROOT) { + // ADD Time variable + dstart[0] = stream->write_alarm.count; - dvar[0] = date2num(global_param.time_origin_num, dmy_current, 0., - global_param.calendar, global_param.time_units); + dtime = date2num(global_param.time_origin_num, dmy_current, 0., + global_param.calendar, global_param.time_units); - // write to file - if (mpi_rank == 0) { - put_nc_field_double(nc_hist_file.fname, &(nc_hist_file.open), - &(nc_hist_file.nc_id), - nc_hist_file.d_fillvalue, - dimids, 1, "time", - dstart, dcount, dvar); + status = nc_put_var1_double(nc_hist_file->nc_id, + nc_hist_file->time_varid, + dstart, &dtime); + check_nc_status(status, "Error writing time variable"); } + // Advance the position in the history file + stream->write_alarm.count++; + // TODO: Decide if it is time to close this file and open a new one. + // free memory - free(dvar); + if (dvar != NULL) { + free(dvar); + } + if (fvar != NULL) { + free(fvar); + } + if (ivar != NULL) { + free(ivar); + } + if (svar != NULL) { + free(svar); + } + if (cvar != NULL) { + free(cvar); + } } diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index d3c33b9bd..c4abd94ea 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -35,8 +35,9 @@ rout_run(void) log_info("In Routing Lohmann Model"); extern rout_struct rout; - extern out_data_struct **out_data; - extern dmy_struct *dmy; +// extern out_data_struct **out_data; + extern double ***out_data; + size_t iSource, iOutlet, iTimestep, jTimestep; int offset; /*2d indicies*/ size_t iRing, iUH; /*1d indicies*/ @@ -71,16 +72,15 @@ rout_run(void) rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * (out_data[rout.rout_param.source_VIC_index[ iSource]][ - OUT_RUNOFF].data[0] + + OUT_RUNOFF][0] + out_data[rout.rout_param.source_VIC_index[ iSource]][ - OUT_BASEFLOW].data[0])); + OUT_BASEFLOW][0])); } } // Write to output struct... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE]. - aggdata[0] = rout.ring[iOutlet]; + out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = rout.ring[iOutlet]; } } diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 7b956c65e..92b9790e2 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -46,6 +46,7 @@ #define MAXSTRING 2048 #define MISSING -99999. /**< missing value */ #define MISSING_USI 99999. /**< missing value for unsigned ints */ +#define MISSING_S "MISSING" /**< missing value for strings */ #define NODATA_VH -1 /**< missing value for veg_hist inputs */ #define NODATA_VEG -1 /**< flag for veg types not in grid cell */ #define ERROR -999 /**< Error Flag returned by subroutines */ @@ -62,7 +63,7 @@ /***** Define minimum values for model parameters *****/ #define MINSOILDEPTH 0.001 /**< Minimum layer depth with which model can work (m) */ -#define MIN_FCANOPY 0.0001 /**< Minimum allowable canopy fraction */ +#define MIN_FCANOPY 1.0 /**< Minimum allowable canopy fraction */ #define MIN_SNOW_WETFRAC 0.01 /**< Minimum fraction of snow depth to be considered wet */ /***** Define minimum and maximum values for model timesteps *****/ @@ -155,44 +156,6 @@ enum /***** Data Structures *****/ -/****************************************************************************** - * @brief file structures - *****************************************************************************/ -typedef struct { - FILE *forcing[2]; /**< atmospheric forcing data files */ - FILE *globalparam; /**< global parameters file */ - FILE *constants; /**< model constants parameter file */ - FILE *domain; /**< domain file */ - FILE *init_state; /**< initial model state file */ - FILE *lakeparam; /**< lake parameter file */ - FILE *snowband; /**< snow elevation band data file */ - FILE *soilparam; /**< soil parameters for all grid cells */ - FILE *statefile; /**< output model state file */ - FILE *veglib; /**< vegetation parameters for all vege types */ - FILE *vegparam; /**< fractional coverage info for grid cell */ - FILE *logfile; /**< log file */ -} filep_struct; - -/****************************************************************************** - * @brief This structure stores input and output filenames. - *****************************************************************************/ -typedef struct { - char forcing[2][MAXSTRING]; /**< atmospheric forcing data file names */ - char f_path_pfx[2][MAXSTRING]; /**< path and prefix for atmospheric forcing data file names */ - char global[MAXSTRING]; /**< global control file name */ - char domain[MAXSTRING]; /**< domain file name */ - char constants[MAXSTRING]; /**< model constants file name */ - char init_state[MAXSTRING]; /**< initial model state file name */ - char lakeparam[MAXSTRING]; /**< lake model constants file */ - char result_dir[MAXSTRING]; /**< directory where results will be written */ - char snowband[MAXSTRING]; /**< snow band parameter file name */ - char soil[MAXSTRING]; /**< soil parameter file name */ - char statefile[MAXSTRING]; /**< name of file in which to store model state */ - char veg[MAXSTRING]; /**< vegetation grid coverage file */ - char veglib[MAXSTRING]; /**< vegetation parameter library file */ - char log_path[MAXSTRING]; /**< Location to write log file to*/ -} filenames_struct; - /****************************************************************************** * @brief This structure stores model options. *****************************************************************************/ @@ -320,16 +283,7 @@ typedef struct { bool SAVE_STATE; /**< TRUE = save state file */ // output options - bool ALMA_OUTPUT; /**< TRUE = output variables are in ALMA-compliant units; FALSE = standard VIC units */ - unsigned short int OUT_FORMAT; /**< TRUE = output files are in binary, not ASCII */ - bool COMPRESS; /**< TRUE = Compress all output files */ - bool MOISTFRACT; /**< TRUE = output soil moisture as fractional moisture content */ - size_t Noutfiles; /**< Number of output files (not including state files) */ - bool PRT_HEADER; /**< TRUE = insert header at beginning of output file; FALSE = no header */ - bool PRT_SNOW_BAND; /**< TRUE = print snow parameters for each snow band. This is only used when default - output files are used (for backwards-compatibility); if outfiles and - variables are explicitly mentioned in global parameter file, this option - is ignored. */ + size_t Noutstreams; /**< Number of output stream */ } option_struct; /****************************************************************************** @@ -342,12 +296,10 @@ typedef struct { double snow_dt; /**< Snow model time step in seconds */ double runoff_dt; /**< Runoff time step in seconds */ double atmos_dt; /**< Atmos time step in seconds */ - double out_dt; /**< Output time step in seconds */ size_t model_steps_per_day; /**< Number of model timesteps per day */ size_t snow_steps_per_day; /**< Number of snow timesteps per day */ size_t runoff_steps_per_day; /**< Number of runoff timesteps per day */ size_t atmos_steps_per_day; /**< Number of atmos timesteps per day */ - size_t output_steps_per_day; /**< Number of output timesteps per day */ unsigned short int endday; /**< Last day of model simulation */ unsigned short int endmonth; /**< Last month of model simulation */ unsigned short int endyear; /**< Last year of model simulation */ @@ -361,8 +313,6 @@ typedef struct { the start of the forcing file */ unsigned short int forceyear[2]; /**< year forcing files start */ size_t nrecs; /**< Number of time steps simulated */ - unsigned short int skipyear; /**< Number of years to skip before writing - output data */ unsigned short int startday; /**< Starting day of the simulation */ unsigned short int startmonth; /**< Starting month of the simulation */ unsigned int startsec; /**< Seconds since midnight when simulation @@ -378,6 +328,7 @@ typedef struct { unsigned short int calendar; /**< Date/time calendar */ unsigned short int time_units; /**< Units for numeric times */ double time_origin_num; /**< Numeric date origin */ + char time_origin_str[MAXSTRING]; /**< string date origin */ } global_param_struct; /****************************************************************************** diff --git a/vic/vic_run/include/vic_log.h b/vic/vic_run/include/vic_log.h index 0143f2b27..0735dbe1e 100644 --- a/vic/vic_run/include/vic_log.h +++ b/vic/vic_run/include/vic_log.h @@ -73,7 +73,7 @@ void setup_logging(int id); // Debug Level #if LOG_LVL < 10 #define debug(M, ...) fprintf(LOG_DEST, "[DEBUG] %s:%d: " M "\n", __FILE__, \ - __LINE__, ## __VA_ARGS__) + __LINE__, ## __VA_ARGS__); fflush(LOG_DEST); #else #define debug(M, ...) @@ -111,13 +111,13 @@ void setup_logging(int id); #define log_err(M, ...) print_trace(); fprintf(LOG_DEST, \ "[ERROR] errno: %s: " M "\n", \ clean_errno(), ## __VA_ARGS__); \ - exit(1); + exit(EXIT_FAILURE); #else #define log_err(M, ...) print_trace(); fprintf(LOG_DEST, \ "[ERROR] %s:%d: errno: %s: " M "\n", \ __FILE__, __LINE__, \ clean_errno(), ## __VA_ARGS__); \ - exit(1); + exit(EXIT_FAILURE); #endif // These depend on previously defined macros @@ -126,12 +126,13 @@ void setup_logging(int id); // here means that it just doesn't print a message, it still does the // check. MKAY? #define check_debug(A, M, ...) if (!(A)) {debug(M, ## __VA_ARGS__); errno = 0; \ - exit(1); } + exit(EXIT_FAILURE); } #define check(A, M, ...) if (!(A)) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ - 1); } + EXIT_FAILURE); } -#define sentinel(M, ...) {log_err(M, ## __VA_ARGS__); errno = 0; exit(1); } +#define sentinel(M, ...) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ + EXIT_FAILURE); } #define check_mem(A) check((A), "Out of memory.") @@ -143,5 +144,4 @@ void setup_logging(int id); #define error_unless(T, F, C, M, ...) if (!(T)) \ error_response(F, C, M, ## __VA_ARGS__) - #endif diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 046c3351e..1a0eb8a5e 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -145,8 +145,8 @@ double ErrorPrintIcePackEnergyBalance(double, va_list); int ErrorPrintSnowPackEnergyBalance(double, va_list); int ErrorSnowPackEnergyBalance(double Tsurf, ...); void estimate_frost_temperature_and_depth(double ***, double **, double *, - double *, double *, double *, - double, size_t, size_t); + double *, double *, double *, double, + size_t, size_t); int estimate_layer_ice_content(layer_data_struct *, double ***, double **, double *, double *, double *, double *, double *, size_t, size_t, char); diff --git a/vic/vic_run/src/soil_conduction.c b/vic/vic_run/src/soil_conduction.c index 6de5de003..c09dff904 100644 --- a/vic/vic_run/src/soil_conduction.c +++ b/vic/vic_run/src/soil_conduction.c @@ -571,7 +571,7 @@ estimate_layer_ice_content(layer_data_struct *layer, layer[lidx].ice[frost_area] += (tmpZ[lidx][nidx + 1] - tmpZ[lidx][nidx]) * (tmp_ice[nidx + 1][frost_area] + - tmp_ice[nidx][frost_area]) / 2.; + tmp_ice[nidx][frost_area]) / 2.; } } for (frost_area = 0; frost_area < options.Nfrost; frost_area++) { @@ -674,7 +674,7 @@ estimate_layer_ice_content_quick_flux(layer_data_struct *layer, else { tmp_fract += (frost_fract[frost_area - 1] / - 2. + frost_fract[frost_area] / 2.); + 2. + frost_fract[frost_area] / 2.); } tmpT = linear_interp(tmp_fract, 0, 1, min_temp, max_temp); tmp_ice = layer[lidx].moist - From 1a124492d150b7289da50d79d9fa97ed57fec535 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 23 Jun 2016 17:08:48 +0200 Subject: [PATCH 017/294] makefile --- vic/drivers/image/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 25b48f354..bfcf003e0 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -72,7 +72,7 @@ SHELL = /bin/bash ifeq (true, ${TRAVIS}) CC = ${MPIPATH}/bin/mpicc else ifeq ($(UNAME_S), Linux) -CC = /usr/lib64/mpich/bin/mpicc +CC = ${MPIPATH}/bin/mpicc else CC = mpicc endif From d6b42819f0a565bae99fce08a481afc403e37aee Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 23 Jun 2016 17:10:29 +0200 Subject: [PATCH 018/294] rout include --- vic/drivers/shared_image/src/vic_image_run.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index 79b553540..9961504b4 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Run VIC for one timestep and store output data From 7b8e7850f2a85b9c518f7bbbd4158a6055a59fdd Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 1 Jul 2016 10:57:29 +0200 Subject: [PATCH 019/294] Changed discharge units to [m3 s-1] --- vic/drivers/shared_all/src/history_metadata.c | 8 ++++---- vic/drivers/shared_all/src/vic_history.c | 2 +- vic/extensions/rout_rvic/src/rout_run.c | 19 +++++++++++-------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index 7e301f374..c55f9251f 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -124,11 +124,11 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_SWE].description, "liquid water equivalent of snow on top of lake ice"); - /* river discharge [m3] */ + /* river discharge [m3 s-1] */ strcpy(out_metadata[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); - strcpy(out_metadata[OUT_DISCHARGE].long_name, "river discharge"); - strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river discharge"); - strcpy(out_metadata[OUT_DISCHARGE].units, "m3"); + strcpy(out_metadata[OUT_DISCHARGE].long_name, "river_discharge"); + strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river_discharge"); + strcpy(out_metadata[OUT_DISCHARGE].units, "m3 s-1"); strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index aa20c9e7e..1c6212ee9 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -250,7 +250,6 @@ get_default_outvar_aggtype(unsigned int varid) switch (varid) { // AGG_TYPE_END - case OUT_DISCHARGE: case OUT_ASAT: case OUT_LAKE_AREA_FRAC: case OUT_LAKE_DEPTH: @@ -285,6 +284,7 @@ get_default_outvar_aggtype(unsigned int varid) agg_type = AGG_TYPE_END; break; // AGG_TYPE_SUM + case OUT_DISCHARGE: case OUT_BASEFLOW: case OUT_DELINTERCEPT: case OUT_DELSOILMOIST: diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index c4abd94ea..8812535bf 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -34,13 +34,12 @@ rout_run(void) { log_info("In Routing Lohmann Model"); - extern rout_struct rout; -// extern out_data_struct **out_data; - extern double ***out_data; - - size_t iSource, iOutlet, iTimestep, jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ + extern rout_struct rout; + extern double ***out_data; + extern domain_struct local_domain; + size_t iSource, iOutlet, iTimestep, jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. @@ -81,6 +80,10 @@ rout_run(void) // Write to output struct... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = rout.ring[iOutlet]; + out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = + rout.ring[iOutlet] * + local_domain + .locations[rout.rout_param.outlet_VIC_index[iOutlet]].area / + (SEC_PER_DAY * MM_PER_M); } } From ead840b771e39a9b2548d0275cf66b2396ae7844 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 6 Jul 2016 12:28:36 +0200 Subject: [PATCH 020/294] unit fix --- vic/drivers/shared_all/src/history_metadata.c | 4 ++-- vic/extensions/rout_rvic/src/rout_run.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index c55f9251f..1b10e37fe 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -124,11 +124,11 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_SWE].description, "liquid water equivalent of snow on top of lake ice"); - /* river discharge [m3 s-1] */ + /* river discharge [m3] */ strcpy(out_metadata[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); strcpy(out_metadata[OUT_DISCHARGE].long_name, "river_discharge"); strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river_discharge"); - strcpy(out_metadata[OUT_DISCHARGE].units, "m3 s-1"); + strcpy(out_metadata[OUT_DISCHARGE].units, "m3"); strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 8812535bf..fcc5ec84c 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -81,9 +81,7 @@ rout_run(void) // Write to output struct... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = - rout.ring[iOutlet] * - local_domain - .locations[rout.rout_param.outlet_VIC_index[iOutlet]].area / - (SEC_PER_DAY * MM_PER_M); + rout.ring[iOutlet] * local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]].area / + MM_PER_M;// / CONST_CDAY; } } From 535c619d6f827aecd4ccb8760bce54e1b4e0114a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 7 Jul 2016 15:28:07 +0200 Subject: [PATCH 021/294] changed units of OUT_DISCHARGE to [m3 s-1] --- .../include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/history_metadata.c | 8 ++++---- vic/drivers/shared_all/src/vic_history.c | 1 - vic/extensions/rout_rvic/src/rout_run.c | 20 +++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index f1f4bc0f9..8cca1ff00 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -146,7 +146,7 @@ enum OUT_DELSOILMOIST, /**< change in soil water content [mm] */ OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ OUT_DELSWE, /**< change in snow water equivalent [mm] */ - OUT_DISCHARGE, /**< river discharge [m3]) */ + OUT_DISCHARGE, /**< river discharge [m3 s-1]) */ OUT_EVAP, /**< total net evaporation [mm] */ OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index 1b10e37fe..1e393b120 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -124,13 +124,13 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_SWE].description, "liquid water equivalent of snow on top of lake ice"); - /* river discharge [m3] */ + /* river discharge [m3 s-1] */ strcpy(out_metadata[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); strcpy(out_metadata[OUT_DISCHARGE].long_name, "river_discharge"); strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river_discharge"); - strcpy(out_metadata[OUT_DISCHARGE].units, "m3"); - strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); - + strcpy(out_metadata[OUT_DISCHARGE].units, "m3 s-1"); + strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); + /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ strcpy(out_metadata[OUT_LAKE_SWE_V].varname, "OUT_LAKE_SWE_V"); strcpy(out_metadata[OUT_LAKE_SWE_V].long_name, "lake_swe_v"); diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index a5dd0aa4f..1696db343 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -268,7 +268,6 @@ get_default_outvar_aggtype(unsigned int varid) agg_type = AGG_TYPE_END; break; // AGG_TYPE_SUM - case OUT_DISCHARGE: case OUT_BASEFLOW: case OUT_DELINTERCEPT: case OUT_DELSOILMOIST: diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index fcc5ec84c..b6a2c5b90 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -34,12 +34,14 @@ rout_run(void) { log_info("In Routing Lohmann Model"); - extern rout_struct rout; - extern double ***out_data; - extern domain_struct local_domain; - size_t iSource, iOutlet, iTimestep, jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ + extern rout_struct rout; + extern double ***out_data; + extern domain_struct local_domain; + extern global_param_struct global_param; + + size_t iSource, iOutlet, iTimestep, jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. @@ -81,7 +83,9 @@ rout_run(void) // Write to output struct... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = - rout.ring[iOutlet] * local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]].area / - MM_PER_M;// / CONST_CDAY; + rout.ring[iOutlet] * + local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]]. + area / + MM_PER_M / global_param.dt; } } From cf79eb93ffb609f97911b16c37822bddbe3f703e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 8 Jul 2016 11:45:15 +0200 Subject: [PATCH 022/294] little fix --- vic/drivers/shared_image/src/vic_finalize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_finalize.c b/vic/drivers/shared_image/src/vic_finalize.c index b06cb272c..fe817b1f1 100644 --- a/vic/drivers/shared_image/src/vic_finalize.c +++ b/vic/drivers/shared_image/src/vic_finalize.c @@ -64,7 +64,7 @@ vic_finalize(void) int status; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // close the global parameter file fclose(filep.globalparam); From f569c09886a4748b74f12ed27278b17d419eb6ec Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 8 Jul 2016 11:48:26 +0200 Subject: [PATCH 023/294] little fix --- vic/extensions/rout_rvic/src/rout_start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 1972df5e0..16b1d4ab0 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -39,7 +39,7 @@ rout_start(void) extern filep_struct filep; extern int mpi_rank; - if (mpi_rank == 0) { + if (mpi_rank == VIC_MPI_ROOT) { // read global settings filep.globalparam = open_file(filenames.global, "r"); get_global_param_rout(filep.globalparam); From b78884ea3d0ccbc349507c65762bc1a9bd661e7e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 8 Jul 2016 12:35:22 +0200 Subject: [PATCH 024/294] placed everything on MPI_ROOT --- vic/extensions/rout_rvic/src/rout_alloc.c | 201 +++++++------- vic/extensions/rout_rvic/src/rout_init.c | 303 +++++++++++----------- vic/extensions/rout_rvic/src/rout_run.c | 95 +++---- 3 files changed, 303 insertions(+), 296 deletions(-) diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 778fc850f..bcb7db950 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -35,105 +35,116 @@ void rout_alloc(void) { - extern domain_struct local_domain; - extern rout_struct rout; - int ivar; - size_t d1count[1]; - size_t d1start[1]; + extern int mpi_rank; + if (mpi_rank == VIC_MPI_ROOT) { + extern domain_struct local_domain; + extern rout_struct rout; + int ivar; + size_t d1count[1]; + size_t d1start[1]; - d1count[0] = 0; - d1start[0] = 1; + d1count[0] = 0; + d1start[0] = 1; - // Get some values and dimensions - get_nc_field_int(rout.param_filename, - "full_time_length", - d1start, - d1count, - &ivar); - rout.rout_param.full_time_length = (int) ivar; + // Get some values and dimensions + get_nc_field_int(rout.param_filename, + "full_time_length", + d1start, + d1count, + &ivar); + rout.rout_param.full_time_length = (int) ivar; - rout.rout_param.nTimesteps = get_nc_dimension(rout.param_filename, - "timesteps"); - rout.rout_param.nOutlets = get_nc_dimension(rout.param_filename, "outlets"); - rout.rout_param.nSources = get_nc_dimension(rout.param_filename, "sources"); + rout.rout_param.nTimesteps = get_nc_dimension(rout.param_filename, + "timesteps"); + rout.rout_param.nOutlets = get_nc_dimension(rout.param_filename, + "outlets"); + rout.rout_param.nSources = get_nc_dimension(rout.param_filename, + "sources"); - // Allocate memory in rout param_struct - rout.rout_param.source2outlet_ind = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source2outlet_ind)); - if (rout.rout_param.source2outlet_ind == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source2outlet_ind()."); - } - rout.rout_param.source_time_offset = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_time_offset)); - if (rout.rout_param.source_time_offset == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source_time_offset()."); - } - rout.rout_param.source_x_ind = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_x_ind)); - if (rout.rout_param.source_x_ind == NULL) { - log_err("Memory allocation error in rout.rout_param.source_x_ind()."); - } - rout.rout_param.source_y_ind = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_y_ind)); - if (rout.rout_param.source_y_ind == NULL) { - log_err("Memory allocation error in rout.rout_param.source_y_ind()."); - } - rout.rout_param.source_lat = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_lat)); - if (rout.rout_param.source_lat == NULL) { - log_err("Memory allocation error in rout.rout_param.source_lat()."); - } - rout.rout_param.source_lon = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_lon)); - if (rout.rout_param.source_lon == NULL) { - log_err("Memory allocation error in rout.rout_param.source_lon()."); - } - rout.rout_param.source_VIC_index = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_VIC_index)); - if (rout.rout_param.source_VIC_index == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source_VIC_index()."); - } - rout.rout_param.outlet_lat = malloc( - rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lat)); - if (rout.rout_param.outlet_lat == NULL) { - log_err("Memory allocation error in rout.rout_param.outlet_lat()."); - } - rout.rout_param.outlet_lon = malloc( - rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lon)); - if (rout.rout_param.outlet_lon == NULL) { - log_err("Memory allocation error in rout.rout_param.outlet_lon()."); - } - rout.rout_param.outlet_VIC_index = malloc( - rout.rout_param.nOutlets * sizeof(rout.rout_param.outlet_VIC_index)); - if (rout.rout_param.outlet_VIC_index == NULL) { - log_err( - "Memory allocation error in rout.rout_param.outlet_VIC_index()."); - } - rout.rout_param.unit_hydrograph = malloc( - rout.rout_param.nSources * rout.rout_param.nTimesteps * - sizeof(*rout.rout_param.unit_hydrograph)); - if (rout.rout_param.unit_hydrograph == NULL) { - log_err("Memory allocation error in rout.rout_param.unit_hydrograph()."); - } - rout.rout_param.aggrunin = - malloc(local_domain.ncells_active * sizeof(*rout.rout_param.aggrunin)); - if (rout.rout_param.aggrunin == NULL) { - log_err("Memory allocation error in rout.rout_param.aggrunin()."); - } - rout.discharge = - malloc(local_domain.ncells_active * sizeof(*rout.discharge)); - if (rout.discharge == NULL) { - log_err("Memory allocation error in rout.rout_param.discharge()."); - } + // Allocate memory in rout param_struct + rout.rout_param.source2outlet_ind = malloc( + rout.rout_param.nSources * + sizeof(*rout.rout_param.source2outlet_ind)); + if (rout.rout_param.source2outlet_ind == NULL) { + log_err( + "Memory allocation error in rout.rout_param.source2outlet_ind()."); + } + rout.rout_param.source_time_offset = malloc( + rout.rout_param.nSources * + sizeof(*rout.rout_param.source_time_offset)); + if (rout.rout_param.source_time_offset == NULL) { + log_err( + "Memory allocation error in rout.rout_param.source_time_offset()."); + } + rout.rout_param.source_x_ind = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_x_ind)); + if (rout.rout_param.source_x_ind == NULL) { + log_err("Memory allocation error in rout.rout_param.source_x_ind()."); + } + rout.rout_param.source_y_ind = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_y_ind)); + if (rout.rout_param.source_y_ind == NULL) { + log_err("Memory allocation error in rout.rout_param.source_y_ind()."); + } + rout.rout_param.source_lat = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_lat)); + if (rout.rout_param.source_lat == NULL) { + log_err("Memory allocation error in rout.rout_param.source_lat()."); + } + rout.rout_param.source_lon = malloc( + rout.rout_param.nSources * sizeof(*rout.rout_param.source_lon)); + if (rout.rout_param.source_lon == NULL) { + log_err("Memory allocation error in rout.rout_param.source_lon()."); + } + rout.rout_param.source_VIC_index = malloc( + rout.rout_param.nSources * + sizeof(*rout.rout_param.source_VIC_index)); + if (rout.rout_param.source_VIC_index == NULL) { + log_err( + "Memory allocation error in rout.rout_param.source_VIC_index()."); + } + rout.rout_param.outlet_lat = malloc( + rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lat)); + if (rout.rout_param.outlet_lat == NULL) { + log_err("Memory allocation error in rout.rout_param.outlet_lat()."); + } + rout.rout_param.outlet_lon = malloc( + rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lon)); + if (rout.rout_param.outlet_lon == NULL) { + log_err("Memory allocation error in rout.rout_param.outlet_lon()."); + } + rout.rout_param.outlet_VIC_index = malloc( + rout.rout_param.nOutlets * + sizeof(rout.rout_param.outlet_VIC_index)); + if (rout.rout_param.outlet_VIC_index == NULL) { + log_err( + "Memory allocation error in rout.rout_param.outlet_VIC_index()."); + } + rout.rout_param.unit_hydrograph = malloc( + rout.rout_param.nSources * rout.rout_param.nTimesteps * + sizeof(*rout.rout_param.unit_hydrograph)); + if (rout.rout_param.unit_hydrograph == NULL) { + log_err( + "Memory allocation error in rout.rout_param.unit_hydrograph()."); + } + rout.rout_param.aggrunin = + malloc( + local_domain.ncells_active * sizeof(*rout.rout_param.aggrunin)); + if (rout.rout_param.aggrunin == NULL) { + log_err("Memory allocation error in rout.rout_param.aggrunin()."); + } + rout.discharge = + malloc(local_domain.ncells_active * sizeof(*rout.discharge)); + if (rout.discharge == NULL) { + log_err("Memory allocation error in rout.rout_param.discharge()."); + } - // Allocate memory for the ring - rout.ring = malloc( - rout.rout_param.full_time_length * rout.rout_param.nOutlets * - sizeof(*rout.ring)); - if (rout.ring == NULL) { - log_err("Memory allocation error in rout.ring()."); + // Allocate memory for the ring + rout.ring = malloc( + rout.rout_param.full_time_length * rout.rout_param.nOutlets * + sizeof(*rout.ring)); + if (rout.ring == NULL) { + log_err("Memory allocation error in rout.ring()."); + } } } diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 6a87b1a96..10ca3ad68 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -36,184 +36,175 @@ void rout_init(void) { - extern rout_struct rout; - extern domain_struct local_domain; - - int *ivar = NULL; - double *dvar = NULL; - - size_t i, j; - size_t i1start; - size_t d3count[3]; - size_t d3start[3]; - - i1start = 0; - - d3start[0] = 0; - d3start[1] = 0; - d3start[2] = 0; - d3count[0] = rout.rout_param.nTimesteps; - d3count[1] = rout.rout_param.nSources; - d3count[2] = 1; // tracers dimension - - - // allocate memory for variables to be read - ivar = (int *) malloc(sizeof(int) * rout.rout_param.nSources); - if (ivar == NULL) { - log_err("Memory allocation error in vic_init()."); - } + extern int mpi_rank; + if (mpi_rank == VIC_MPI_ROOT) { + extern rout_struct rout; + extern domain_struct local_domain; + + int *ivar = NULL; + double *dvar = NULL; + + size_t i, j; + size_t i1start; + size_t d3count[3]; + size_t d3start[3]; + + i1start = 0; + + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = rout.rout_param.nTimesteps; + d3count[1] = rout.rout_param.nSources; + d3count[2] = 1; // tracers dimension + + // allocate memory for variables to be read + ivar = (int *) malloc(sizeof(int) * rout.rout_param.nSources); + if (ivar == NULL) { + log_err("Memory allocation error in vic_init()."); + } - // allocate memory for variables to be read - dvar = (double *) malloc( - rout.rout_param.nTimesteps * rout.rout_param.nSources * - sizeof(double)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_init()."); - } + // allocate memory for variables to be read + dvar = (double *) malloc( + rout.rout_param.nTimesteps * rout.rout_param.nSources * + sizeof(double)); + if (dvar == NULL) { + log_err("Memory allocation error in vic_init()."); + } - // The Ring - for (j = 0; j < rout.rout_param.nOutlets; j++) { - for (i = 0; i < rout.rout_param.nTimesteps; i++) { - rout.ring[j * rout.rout_param.nTimesteps + i] = 0.0; + // The Ring + for (j = 0; j < rout.rout_param.nOutlets; j++) { + for (i = 0; i < rout.rout_param.nTimesteps; i++) { + rout.ring[j * rout.rout_param.nTimesteps + i] = 0.0; + } } - } - // discharge - for (j = 0; j < local_domain.ncells_active; j++) { - rout.discharge[j] = 0.0; - } + // discharge + for (j = 0; j < local_domain.ncells_active; j++) { + rout.discharge[j] = 0.0; + } - // source2outlet_ind: source to outlet index mapping - get_nc_field_int(rout.param_filename, - "source2outlet_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source2outlet_ind[i] = (int) ivar[i]; - } + // source2outlet_ind: source to outlet index mapping + get_nc_field_int(rout.param_filename, + "source2outlet_ind", + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source2outlet_ind[i] = (int) ivar[i]; + } - // source_time_offset: Number of leading timesteps ommited - get_nc_field_int(rout.param_filename, - "source_time_offset", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source_time_offset[i] = (int) ivar[i]; - } + // source_time_offset: Number of leading timesteps ommited + get_nc_field_int(rout.param_filename, + "source_time_offset", + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source_time_offset[i] = (int) ivar[i]; + } - // source_x_ind: x grid coordinate of source grid cell - get_nc_field_int(rout.param_filename, - "source_x_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source_x_ind[i] = (int) ivar[i]; - } + // source_x_ind: x grid coordinate of source grid cell + get_nc_field_int(rout.param_filename, + "source_x_ind", + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source_x_ind[i] = (int) ivar[i]; + } - // source_y_ind: y grid coordinate of source grid cell - get_nc_field_int(rout.param_filename, - "source_y_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source_y_ind[i] = (int) ivar[i]; - } + // source_y_ind: y grid coordinate of source grid cell + get_nc_field_int(rout.param_filename, + "source_y_ind", + &i1start, &rout.rout_param.nSources, ivar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source_y_ind[i] = (int) ivar[i]; + } - // source_lat: Latitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, - "source_lat", - &i1start, &rout.rout_param.nSources, dvar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source_lat[i] = (double) dvar[i]; - } + // source_lat: Latitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "source_lat", + &i1start, &rout.rout_param.nSources, dvar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source_lat[i] = (double) dvar[i]; + } - // source_lon: Longitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, - "source_lon", - &i1start, &rout.rout_param.nSources, dvar); - for (i = 0; i < rout.rout_param.nSources; i++) { - rout.rout_param.source_lon[i] = (double) dvar[i]; - } + // source_lon: Longitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "source_lon", + &i1start, &rout.rout_param.nSources, dvar); + for (i = 0; i < rout.rout_param.nSources; i++) { + rout.rout_param.source_lon[i] = (double) dvar[i]; + } - // outlet_lat: Latitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, - "outlet_lat", - &i1start, &rout.rout_param.nOutlets, dvar); - for (i = 0; i < rout.rout_param.nOutlets; i++) { - rout.rout_param.outlet_lat[i] = (double) dvar[i]; - } + // outlet_lat: Latitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "outlet_lat", + &i1start, &rout.rout_param.nOutlets, dvar); + for (i = 0; i < rout.rout_param.nOutlets; i++) { + rout.rout_param.outlet_lat[i] = (double) dvar[i]; + } - // outlet_lon: Longitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, - "outlet_lon", - &i1start, &rout.rout_param.nOutlets, dvar); - for (i = 0; i < rout.rout_param.nOutlets; i++) { - rout.rout_param.outlet_lon[i] = (double) dvar[i]; - } + // outlet_lon: Longitude coordinate of source grid cell + get_nc_field_double(rout.param_filename, + "outlet_lon", + &i1start, &rout.rout_param.nOutlets, dvar); + for (i = 0; i < rout.rout_param.nOutlets; i++) { + rout.rout_param.outlet_lon[i] = (double) dvar[i]; + } - // Unit Hydrograph: - get_nc_field_double(rout.param_filename, - "unit_hydrograph", - d3start, d3count, dvar); - for (i = 0; - i < (rout.rout_param.nTimesteps * rout.rout_param.nSources); - i++) { - rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; - } + // Unit Hydrograph: + get_nc_field_double(rout.param_filename, + "unit_hydrograph", + d3start, d3count, dvar); + for (i = 0; + i < (rout.rout_param.nTimesteps * rout.rout_param.nSources); + i++) { + rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; + } - // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! - // Mapping: Let the routing-source index numbers correspond to the VIC index numbers - size_t iSource; - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { - for (i = 0; i < local_domain.ncells_active; i++) { - if (rout.rout_param.source_lat[iSource] == - local_domain.locations[i].latitude && - rout.rout_param.source_lon[iSource] == - local_domain.locations[i].longitude) { - - rout.rout_param.source_VIC_index[iSource] = i; + // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! + // Mapping: Let the routing-source index numbers correspond to the VIC index numbers + size_t iSource; + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + for (i = 0; i < local_domain.ncells_active; i++) { + if (rout.rout_param.source_lat[iSource] == + local_domain.locations[i].latitude && + rout.rout_param.source_lon[iSource] == + local_domain.locations[i].longitude) { + rout.rout_param.source_VIC_index[iSource] = i; + } } } - } - printf("\nsource, index of VIC gridcell: \n "); - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { -// printf("iSource: iVIC: %3i, %7i, %5.2f, %5.2f %5.2f, %5.2f \n ", -// (int)(iSource), -// rout.rout_param.source_VIC_index[iSource], -// rout.rout_param.source_lon[iSource], -// local_domain.locations[rout.rout_param.source_VIC_index[iSource]].longitude, -// rout.rout_param.source_lat[iSource], -// local_domain.locations[rout.rout_param.source_VIC_index[iSource]].latitude -// ); - if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || - (size_t)rout.rout_param.source_VIC_index[iSource] > - local_domain.ncells_active) { - log_err("invalid source, index of VIC gridcell"); + printf("\nsource, index of VIC gridcell: \n "); + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || + (size_t)rout.rout_param.source_VIC_index[iSource] > + local_domain.ncells_active) { + log_err("invalid source, index of VIC gridcell"); + } } - } - // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers - size_t iOutlet; - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - for (i = 0; i < local_domain.ncells_active; i++) { - if (rout.rout_param.outlet_lat[iOutlet] == - local_domain.locations[i].latitude && - rout.rout_param.outlet_lon[iOutlet] == - local_domain.locations[i].longitude) { - rout.rout_param.outlet_VIC_index[iOutlet] = i; + // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers + size_t iOutlet; + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + for (i = 0; i < local_domain.ncells_active; i++) { + if (rout.rout_param.outlet_lat[iOutlet] == + local_domain.locations[i].latitude && + rout.rout_param.outlet_lon[iOutlet] == + local_domain.locations[i].longitude) { + rout.rout_param.outlet_VIC_index[iOutlet] = i; + } } } - } - printf("\noutlet, index of VIC gridcell: \n "); - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { -// printf("%3i, %7i \n ", (int)(iOutlet), -// rout.rout_param.outlet_VIC_index[iOutlet]); - if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || - (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > - local_domain.ncells_active) { - log_err("invalid outlet, index of VIC gridcell"); + printf("\noutlet, index of VIC gridcell: \n "); + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || + (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > + local_domain.ncells_active) { + log_err("invalid outlet, index of VIC gridcell"); + } } - } - // cleanup - free(ivar); - free(dvar); + // cleanup + free(ivar); + free(dvar); + } } diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index b6a2c5b90..86b69aba3 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -32,60 +32,65 @@ void rout_run(void) { - log_info("In Routing Lohmann Model"); + extern int mpi_rank; + if (mpi_rank == VIC_MPI_ROOT) { + log_info("In Routing Lohmann Model"); - extern rout_struct rout; - extern double ***out_data; - extern domain_struct local_domain; - extern global_param_struct global_param; + extern rout_struct rout; + extern double ***out_data; + extern domain_struct local_domain; + extern global_param_struct global_param; - size_t iSource, iOutlet, iTimestep, jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ + size_t iSource, iOutlet, iTimestep, jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ - // Zero out current ring - // in python: (from variables.py) self.ring[tracer][0, :] = 0. - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - rout.ring[iOutlet] = 0.0; - } + // Zero out current ring + // in python: (from variables.py) self.ring[tracer][0, :] = 0. + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + rout.ring[iOutlet] = 0.0; + } - // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.full_time_length, - rout.rout_param.nOutlets, 0, - 1); + // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) + cshift(rout.ring, rout.rout_param.full_time_length, + rout.rout_param.nOutlets, 0, + 1); - /*Loop through all sources*/ - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { - iOutlet = rout.rout_param.source2outlet_ind[iSource]; - offset = rout.rout_param.source_time_offset[iSource]; + /*Loop through all sources*/ + for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + iOutlet = rout.rout_param.source2outlet_ind[iSource]; + offset = rout.rout_param.source_time_offset[iSource]; - /* Do the convolution */ - // iTimestep is the position in the unit hydrograph - // jTimestep is the position in the ring - for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; - iTimestep++) { - jTimestep = iTimestep + offset; + /* Do the convolution */ + // iTimestep is the position in the unit hydrograph + // jTimestep is the position in the ring + for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; + iTimestep++) { + jTimestep = iTimestep + offset; - // index locations - iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; - iUH = (iTimestep * rout.rout_param.nSources) + iSource; + // index locations + iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; + iUH = (iTimestep * rout.rout_param.nSources) + iSource; - rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * - (out_data[rout.rout_param.source_VIC_index[ - iSource]][ - OUT_RUNOFF][0] + - out_data[rout.rout_param.source_VIC_index[ - iSource]][ - OUT_BASEFLOW][0])); + rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * + (out_data[rout.rout_param.source_VIC_index[ + iSource]][ + OUT_RUNOFF][0] + + out_data[rout.rout_param.source_VIC_index[ + iSource]][ + OUT_BASEFLOW][0])); + } } - } - // Write to output struct... - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0] = - rout.ring[iOutlet] * - local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]]. - area / - MM_PER_M / global_param.dt; + // Write to output struct... + for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0 + ] = + rout.ring[iOutlet] * + local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet] + ]. + area / + MM_PER_M / global_param.dt; + } } } From 9ab324da1159bcddf8d819adc3250ba7c77e34b6 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 8 Jul 2016 17:50:41 +0200 Subject: [PATCH 025/294] Made RVIC working with MPI --- vic/extensions/rout_rvic/include/rout.h | 6 ++ vic/extensions/rout_rvic/src/rout_alloc.c | 6 +- vic/extensions/rout_rvic/src/rout_init.c | 20 ++-- .../rout_rvic/src/rout_mpi_gather.c | 86 +++++++++++++++++ .../rout_rvic/src/rout_mpi_scatter.c | 80 ++++++++++++++++ vic/extensions/rout_rvic/src/rout_run.c | 94 +++++++++++++------ vic/extensions/rout_rvic/src/rout_write.c | 1 - 7 files changed, 252 insertions(+), 41 deletions(-) create mode 100644 vic/extensions/rout_rvic/src/rout_mpi_gather.c create mode 100644 vic/extensions/rout_rvic/src/rout_mpi_scatter.c diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 388bb573c..9525e36a0 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -72,6 +72,12 @@ void rout_run(void); // run routing over the domain void rout_write(void); // write routine for routing void rout_finalize(void); // clean up routine for routing +/****************************************************************************** + * @brief MPI Function prototypes for the rout_rvic extension + *****************************************************************************/ +void get_scatter_var_double(double *, double *); +void gather_put_var_double(double *, double *); + /****************************************************************************** * @brief Convolution function adapted from the RVIC scheme *****************************************************************************/ diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index bcb7db950..aaabbba7e 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -37,7 +37,7 @@ rout_alloc(void) { extern int mpi_rank; if (mpi_rank == VIC_MPI_ROOT) { - extern domain_struct local_domain; + extern domain_struct global_domain; extern rout_struct rout; int ivar; size_t d1count[1]; @@ -129,12 +129,12 @@ rout_alloc(void) } rout.rout_param.aggrunin = malloc( - local_domain.ncells_active * sizeof(*rout.rout_param.aggrunin)); + global_domain.ncells_total * sizeof(*rout.rout_param.aggrunin)); if (rout.rout_param.aggrunin == NULL) { log_err("Memory allocation error in rout.rout_param.aggrunin()."); } rout.discharge = - malloc(local_domain.ncells_active * sizeof(*rout.discharge)); + malloc(global_domain.ncells_total * sizeof(*rout.discharge)); if (rout.discharge == NULL) { log_err("Memory allocation error in rout.rout_param.discharge()."); } diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 10ca3ad68..e18fae70c 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -39,7 +39,7 @@ rout_init(void) extern int mpi_rank; if (mpi_rank == VIC_MPI_ROOT) { extern rout_struct rout; - extern domain_struct local_domain; + extern domain_struct global_domain; int *ivar = NULL; double *dvar = NULL; @@ -80,7 +80,7 @@ rout_init(void) } // discharge - for (j = 0; j < local_domain.ncells_active; j++) { + for (j = 0; j < global_domain.ncells_active; j++) { rout.discharge[j] = 0.0; } @@ -162,11 +162,11 @@ rout_init(void) // Mapping: Let the routing-source index numbers correspond to the VIC index numbers size_t iSource; for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { - for (i = 0; i < local_domain.ncells_active; i++) { + for (i = 0; i < global_domain.ncells_total; i++) { if (rout.rout_param.source_lat[iSource] == - local_domain.locations[i].latitude && + global_domain.locations[i].latitude && rout.rout_param.source_lon[iSource] == - local_domain.locations[i].longitude) { + global_domain.locations[i].longitude) { rout.rout_param.source_VIC_index[iSource] = i; } } @@ -176,7 +176,7 @@ rout_init(void) for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || (size_t)rout.rout_param.source_VIC_index[iSource] > - local_domain.ncells_active) { + global_domain.ncells_total) { log_err("invalid source, index of VIC gridcell"); } } @@ -184,11 +184,11 @@ rout_init(void) // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers size_t iOutlet; for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - for (i = 0; i < local_domain.ncells_active; i++) { + for (i = 0; i < global_domain.ncells_total; i++) { if (rout.rout_param.outlet_lat[iOutlet] == - local_domain.locations[i].latitude && + global_domain.locations[i].latitude && rout.rout_param.outlet_lon[iOutlet] == - local_domain.locations[i].longitude) { + global_domain.locations[i].longitude) { rout.rout_param.outlet_VIC_index[iOutlet] = i; } } @@ -198,7 +198,7 @@ rout_init(void) for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > - local_domain.ncells_active) { + global_domain.ncells_total) { log_err("invalid outlet, index of VIC gridcell"); } } diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c new file mode 100644 index 000000000..94f8c0112 --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_mpi_gather.c @@ -0,0 +1,86 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Allocate memory for Routing structures. + * + * @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 +#include +#include +#include + +/****************************************************************************** + * @brief Gather double precision variable + * @details Values are gathered to the master node + *****************************************************************************/ +void gather_put_var_double(double *dvar, double *var_local) { + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + double *dvar_gathered = NULL; + double *dvar_remapped = NULL; + size_t grid_size; + size_t i; + + if (mpi_rank == VIC_MPI_ROOT) { + grid_size = global_domain.n_nx * global_domain.n_ny; + + for (i = 0; i < grid_size; i++) { + dvar[i] = 0; + } + + dvar_gathered = + malloc(global_domain.ncells_active * sizeof (*dvar_gathered)); + check_alloc_status(dvar_gathered, "Memory allocation error."); + + dvar_remapped = + malloc(global_domain.ncells_active * sizeof (*dvar_remapped)); + check_alloc_status(dvar_remapped, "Memory allocation error."); + } + // Gather the results from the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Gatherv(var_local, local_domain.ncells_active, MPI_DOUBLE, + dvar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); + check_mpi_status(status, "MPI error."); + if (mpi_rank == VIC_MPI_ROOT) { + // remap the array + map(sizeof (double), global_domain.ncells_active, NULL, + mpi_map_mapping_array, dvar_gathered, dvar_remapped); + // expand to full grid size + map(sizeof (double), global_domain.ncells_active, NULL, + filter_active_cells, dvar_remapped, dvar); + + // cleanup + free(dvar_gathered); + free(dvar_remapped); + } +} + diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c new file mode 100644 index 000000000..04382fb2e --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c @@ -0,0 +1,80 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Allocate memory for Routing structures. + * + * @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 +#include +#include +#include + +/****************************************************************************** + * @brief Scatter double precision variable + * @details values from master node are scattered to the local nodes + *****************************************************************************/ +void get_scatter_var_double(double *dvar, double *var_local) { + + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + double *dvar_filtered = NULL; + double *dvar_mapped = NULL; + + if (mpi_rank == VIC_MPI_ROOT) { + dvar_filtered = + malloc(global_domain.ncells_active * sizeof (*dvar_filtered)); + check_alloc_status(dvar_filtered, "Memory allocation error."); + + dvar_mapped = + malloc(global_domain.ncells_active * sizeof (*dvar_mapped)); + check_alloc_status(dvar_mapped, "Memory allocation error."); + + // filter the active cells only + map(sizeof (double), global_domain.ncells_active, filter_active_cells, + NULL, dvar, dvar_filtered); + // map to prepare for MPI_Scatterv + map(sizeof (double), global_domain.ncells_active, mpi_map_mapping_array, + NULL, dvar_filtered, dvar_mapped); + free(dvar_filtered); + } + + // Scatter the results to the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_DOUBLE, + var_local, local_domain.ncells_active, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); + check_mpi_status(status, "MPI error."); + + if (mpi_rank == VIC_MPI_ROOT) { + free(dvar_mapped); + } +} + diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 86b69aba3..bab113591 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -30,20 +30,49 @@ #include void -rout_run(void) -{ +rout_run(void) { extern int mpi_rank; + extern double ***out_data; + extern global_param_struct global_param; + extern domain_struct local_domain; + extern domain_struct global_domain; + double *dvar_global = NULL; + double *dvar_local = NULL; + double *dvar_global_total_runoff = NULL; + double *dvar_local_total_runoff = NULL; + size_t i; + + ////////////////// + // Gather runoff and baseflow from local nodes to the masternode + // and add them together in total_runoff + dvar_global_total_runoff = malloc(global_domain.ncells_total * sizeof (*dvar_global_total_runoff)); + check_alloc_status(dvar_global_total_runoff, "Memory allocation error."); + dvar_local_total_runoff = malloc(local_domain.ncells_active * sizeof (*dvar_local_total_runoff)); + check_alloc_status(dvar_local_total_runoff, "Memory allocation error."); + + // Read from out_data... + for (i = 0; i < local_domain.ncells_active; i++) { + dvar_local_total_runoff[i] = out_data[i][OUT_RUNOFF][0] + out_data[i][OUT_BASEFLOW][0]; + } + + gather_put_var_double(dvar_global_total_runoff, dvar_local_total_runoff); + + free(dvar_local_total_runoff); + ////////////////////// + + // Do the routing on the master node if (mpi_rank == VIC_MPI_ROOT) { log_info("In Routing Lohmann Model"); - extern rout_struct rout; - extern double ***out_data; - extern domain_struct local_domain; - extern global_param_struct global_param; + extern rout_struct rout; + extern domain_struct global_domain; + + dvar_global = malloc(global_domain.ncells_total * sizeof (*dvar_global)); + check_alloc_status(dvar_global, "Memory allocation error."); - size_t iSource, iOutlet, iTimestep, jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ + size_t iSource, iOutlet, iTimestep, jTimestep; + int offset; /*2d indicies*/ + size_t iRing, iUH; /*1d indicies*/ // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. @@ -53,8 +82,8 @@ rout_run(void) // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) cshift(rout.ring, rout.rout_param.full_time_length, - rout.rout_param.nOutlets, 0, - 1); + rout.rout_param.nOutlets, 0, + 1); /*Loop through all sources*/ for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { @@ -65,32 +94,43 @@ rout_run(void) // iTimestep is the position in the unit hydrograph // jTimestep is the position in the ring for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; - iTimestep++) { + iTimestep++) { jTimestep = iTimestep + offset; // index locations iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; iUH = (iTimestep * rout.rout_param.nSources) + iSource; - rout.ring[iRing] += (rout.rout_param.unit_hydrograph[iUH] * - (out_data[rout.rout_param.source_VIC_index[ - iSource]][ - OUT_RUNOFF][0] + - out_data[rout.rout_param.source_VIC_index[ - iSource]][ - OUT_BASEFLOW][0])); + rout.ring[iRing] += rout.rout_param.unit_hydrograph[iUH] * + dvar_global_total_runoff[rout.rout_param.source_VIC_index[iSource]]; } } - // Write to output struct... + // Write to dvar_global prior to scattering over local domains... for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - out_data[rout.rout_param.outlet_VIC_index[iOutlet]][OUT_DISCHARGE][0 - ] = - rout.ring[iOutlet] * - local_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet] - ]. - area / - MM_PER_M / global_param.dt; + dvar_global[rout.rout_param.outlet_VIC_index[iOutlet]] = + rout.ring[iOutlet] * + global_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]].area + / (MM_PER_M * global_param.dt); } + + // cleanup + free(dvar_global); } + + // Scatter dvar_global to local domains (dvar_local)... + dvar_local = malloc(local_domain.ncells_active * sizeof (*dvar_local)); + check_alloc_status(dvar_local, "Memory allocation error."); + + get_scatter_var_double(dvar_global, dvar_local); + + // Write to output struct... + for (i = 0; i < local_domain.ncells_active; i++) { + out_data[i][OUT_DISCHARGE][0] = dvar_local[i]; + } + + // cleanup + free(dvar_local); + free(dvar_global_total_runoff); + } diff --git a/vic/extensions/rout_rvic/src/rout_write.c b/vic/extensions/rout_rvic/src/rout_write.c index 193a58578..c2f470341 100644 --- a/vic/extensions/rout_rvic/src/rout_write.c +++ b/vic/extensions/rout_rvic/src/rout_write.c @@ -30,5 +30,4 @@ void rout_write() { - log_info("In rout_write"); } From 7939c6d233bf2655981f1cb2549aac71fd59c85b Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 12 Jul 2016 16:19:40 +0200 Subject: [PATCH 026/294] little fix --- vic/drivers/shared_image/src/check_domain_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index 32d6aa61a..1095b05a9 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -58,7 +58,7 @@ compare_ncdomain_with_global_domain(char *ncfile) // loop over all grid cells and check that the two domains are identical for (i = 0; i < global_domain.ncells_total; i++) { // mask matches - if (ncfile_domain.locations[i].run > global_domain.locations[i].run) { + if (ncfile_domain.locations[i].run < global_domain.locations[i].run) { log_err("parameter file mask for gridcell %zu is zero and the " "domain file specifies that this cell should be run", i); } From a81ab414a0e9e414e1b64708a414a0c5f7f11d5a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 12 Jul 2016 16:30:39 +0200 Subject: [PATCH 027/294] smaller/greater than sign switched --- vic/drivers/shared_image/src/check_domain_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index 32d6aa61a..1095b05a9 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -58,7 +58,7 @@ compare_ncdomain_with_global_domain(char *ncfile) // loop over all grid cells and check that the two domains are identical for (i = 0; i < global_domain.ncells_total; i++) { // mask matches - if (ncfile_domain.locations[i].run > global_domain.locations[i].run) { + if (ncfile_domain.locations[i].run < global_domain.locations[i].run) { log_err("parameter file mask for gridcell %zu is zero and the " "domain file specifies that this cell should be run", i); } From 6be5e0266b468a53db053a5c80e27bc6f947847e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 12 Jul 2016 17:32:52 +0200 Subject: [PATCH 028/294] tiny update --- vic/drivers/image/Makefile | 2 +- vic/drivers/shared_image/src/vic_image_run.c | 5 +++-- vic/extensions/rout_rvic/src/rout_init.c | 4 ++-- vic/extensions/rout_rvic/src/rout_run.c | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index a88101ad3..e10e77fe8 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -94,7 +94,7 @@ include ${EXTPATH}/${ROUT}/rout.mk # | WARNING | < 30 | # | INFO | < 20 | # | DEBUG | < 10 | -LOG_LVL = 5 +LOG_LVL = 15 # set includes INCLUDES = -I ${DRIVERPATH}/include \ diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index f8d7d8c09..a41065443 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -53,8 +53,9 @@ vic_image_run(dmy_struct *dmy_current) timer_struct timer; // Print the current timestep info before running vic_run - sprint_dmy(dmy_str, dmy_current); - debug("Running timestep %zu: %s", current, dmy_str); + printf("Timestep %4zu, %u-%02hu-%02hu, sec: %5u\n", + current, dmy_current->year, dmy_current->month, + dmy_current->day, dmy_current->dayseconds); for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index e18fae70c..ea41ba4ef 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -172,7 +172,7 @@ rout_init(void) } } - printf("\nsource, index of VIC gridcell: \n "); + // Check source index of VIC gridcell for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || (size_t)rout.rout_param.source_VIC_index[iSource] > @@ -194,7 +194,7 @@ rout_init(void) } } - printf("\noutlet, index of VIC gridcell: \n "); + // Check outlet index of VIC gridcell for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index bab113591..1e78ca1ee 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -62,7 +62,7 @@ rout_run(void) { // Do the routing on the master node if (mpi_rank == VIC_MPI_ROOT) { - log_info("In Routing Lohmann Model"); + debug("In Routing Lohmann Model"); extern rout_struct rout; extern domain_struct global_domain; From a2d89a69a15a3c2d6ca8d7f440cc98cdb5281b99 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 14 Jul 2016 16:31:39 +0200 Subject: [PATCH 029/294] j and i index should be switched. Fixed now --- vic/drivers/shared_all/src/vic_history.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index ffd4314a5..1696db343 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -52,7 +52,7 @@ alloc_out_data(size_t ngridcells, check_alloc_status((*out_data)[i][j], "Memory allocation error."); // initialize data member - for (k = 0; k < out_metadata[i].nelem; k++) { + for (k = 0; k < out_metadata[j].nelem; k++) { (*out_data)[i][j][k] = 0; } } From 1bc04c6e09e782c44dfa77686151797ece0229c2 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Jul 2016 14:54:36 +0200 Subject: [PATCH 030/294] tiny update --- vic/drivers/image/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index e10e77fe8..8c7101a5d 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -102,7 +102,6 @@ INCLUDES = -I ${DRIVERPATH}/include \ -I ${SHAREDPATH}/include \ -I ${SHAREDIMAGEPATH}/include \ -I ${NETCDFPATH}/include \ - -I ${MPIPATH}/include \ -I ${EXTPATH}/${ROUT}/include # Uncomment to include debugging information From 2fcc01033b6ae0a65f877fffed1526cf0fd923dc Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Jul 2016 16:23:16 +0200 Subject: [PATCH 031/294] little update --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 65b0554a6..8c9c8e2c1 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,6 @@ image_test uncrust.sh *.exe +# WUR specific not4git +samples_wur \ No newline at end of file From 3c5d9c368349ff09dcd3e653c0d2760fc5a488bd Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 2 Sep 2016 11:08:58 +0200 Subject: [PATCH 032/294] VIC5.0 updates --- tests/run_profiling.py | 12 ++++----- tests/test_utils.py | 25 ++++++++++--------- vic/drivers/image/src/vic_image.c | 3 --- .../shared_all/src/set_output_defaults.c | 1 + vic/drivers/shared_all/src/vic_time.c | 22 ---------------- .../shared_image/src/parse_output_info.c | 1 + .../shared_image/src/vic_init_output.c | 1 - vic/drivers/shared_image/src/vic_store.c | 15 +++++------ vic/vic_run/include/vic_def.h | 2 +- 9 files changed, 30 insertions(+), 52 deletions(-) diff --git a/tests/run_profiling.py b/tests/run_profiling.py index 9fb29bacb..cf2a1c46c 100755 --- a/tests/run_profiling.py +++ b/tests/run_profiling.py @@ -94,13 +94,14 @@ def log2_range(m): template='''#!/bin/bash #!/bin/bash -#PBS -N VIC_scaling_test_$i +#PBS -N VIC_scaling_test_$np #PBS -q standard #PBS -A NPSCA07935242 #PBS -l application=VIC #PBS -l select=$select:ncpus=36:mpiprocs=$mpiprocs -#PBS -l walltime=06:00:00 +#PBS -l walltime=04:00:00 #PBS -j oe +#PBS -o $WORKDIR # Qsub template for ERDC TOPAZ # Scheduler: PBS @@ -109,9 +110,8 @@ def log2_range(m): START=$(date +%s) mpiexec_mpt -np ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global -END=$(date +%s) DIFF=$(echo "$END - $START" | bc) -printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} +printf "%5s | %f" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} OUT_WIDTH = 100 @@ -217,7 +217,7 @@ def run_scaling(args): run_string = template.safe_substitute( vic_exe=args.vic_exe, vic_global=args.global_param, - timing_table_file=args.timing, i=i, **kwargs) + timing_table_file=args.timing, **kwargs) run_file = 'vic_{host}_{i}.sh'.format(host=args.host, i=i) with open(run_file, 'w') as f: f.write(run_string) @@ -259,7 +259,7 @@ def get_header_info(vic_exe, vic_global): try: header_kwargs['vic_version'] = subprocess.check_output( [vic_exe, '-v']).decode() - except subprocess.CalledProcessError: + except: pass return header_kwargs diff --git a/tests/test_utils.py b/tests/test_utils.py index a260f0262..efdd1835b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -12,9 +12,8 @@ import pandas as pd import xarray as xr -# Plotting libs +# Plottling libs import matplotlib -matplotlib.use('Agg') import matplotlib.pyplot as plt import seaborn as sns @@ -23,6 +22,8 @@ default_vic_valgrind_error_code) from tonic.testing import check_completed, check_for_nans, VICTestError +matplotlib.use('Agg') + OUTPUT_WIDTH = 100 ERROR_TAIL = 20 # lines @@ -528,6 +529,7 @@ def read_snotel_swe_obs(filename, science_test_data_dir, items): '''Reads in Snotel SWE obs and returns DataFrame. ''' filename_fullpath = os.path.join(science_test_data_dir, + 'science', 'inputdata', items['archive'], 'observations', @@ -554,13 +556,12 @@ def read_vic_42_output(lat, lng, science_test_data_dir, items): if items['compare_to'] == 'ecflux': vic_42_file = 'en_bal_%s_%s' % (lat, lng) - vic_42_dir = os.path.join(science_test_data_dir, 'archive', + vic_42_dir = os.path.join(science_test_data_dir, 'science', 'archive', items['archive'], 'ecflux', 'results') elif items['compare_to'] == 'snotel': vic_42_file = 'outfile_%s_%s' % (lat, lng) - - vic_42_dir = os.path.join(science_test_data_dir, 'archive', + vic_42_dir = os.path.join(science_test_data_dir, 'science', 'archive', items['archive'], 'snotel', 'results') else: @@ -706,6 +707,7 @@ def plot_snotel_comparison(driver, science_test_data_dir, pool = mp.Pool(processes=nproc) for filename in os.listdir(os.path.join(science_test_data_dir, + 'science', 'inputdata', 'snotel', 'observations')): @@ -727,10 +729,8 @@ def plot_snotel_comparison_one_site( result_dir, plot_dir, plots_to_make, plot_variables, context, style, filename): - - print(plots_to_make) - - # get lat/lng from filename + + # get lat/lng from filename file_split = re.split('_', filename) lng = file_split[3].split('.txt')[0] lat = file_split[2] @@ -740,7 +740,7 @@ def plot_snotel_comparison_one_site( data = {} for key, items in compare_data_dict.items(): - # read in data + # read in data if key == "snotel": data[key] = read_snotel_swe_obs(filename, science_test_data_dir, @@ -787,7 +787,7 @@ def plot_snotel_comparison_one_site( plotname = '%s_%s.png' % (lat, lng) savepath = os.path.join(plot_dir, plot_variable, plotname) plt.savefig(savepath, bbox_inches='tight') - print(savepath) + plt.clf() plt.close() @@ -831,7 +831,7 @@ def read_fluxnet_obs(subdir, science_test_data_dir, items): filename = '%s.stdfmt.hourly.local.txt' % subdir # read in data with -9999.0000 as NaNs - obs_dir = os.path.join(science_test_data_dir, 'inputdata', + obs_dir = os.path.join(science_test_data_dir, 'science', 'inputdata', 'ec_flux_towers', 'obs') ecflux_df = pd.read_csv(os.path.join(obs_dir, subdir, filename), skiprows=0, @@ -874,6 +874,7 @@ def plot_fluxnet_comparison(driver, science_test_data_dir, # loop over Ameriflux sites obs_dir = os.path.join(science_test_data_dir, + 'science', 'inputdata', 'ec_flux_towers', 'obs') diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 0c8e92e64..c22dc80ab 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -149,9 +149,6 @@ main(int argc, // run vic over the domain vic_image_run(&(dmy[current])); - // run routing over the domain -// rout_run(); // Routing routine (extension) - // Write history files vic_write_output(&(dmy[current])); diff --git a/vic/drivers/shared_all/src/set_output_defaults.c b/vic/drivers/shared_all/src/set_output_defaults.c index 0b53d7a13..3f763f81d 100644 --- a/vic/drivers/shared_all/src/set_output_defaults.c +++ b/vic/drivers/shared_all/src/set_output_defaults.c @@ -99,6 +99,7 @@ set_output_defaults(stream_struct **streams, unsigned short default_file_format) { extern option_struct options; + extern global_param_struct global_param; size_t streamnum; size_t varnum; diff --git a/vic/drivers/shared_all/src/vic_time.c b/vic/drivers/shared_all/src/vic_time.c index 0e57407ae..d8b7d387b 100644 --- a/vic/drivers/shared_all/src/vic_time.c +++ b/vic/drivers/shared_all/src/vic_time.c @@ -820,8 +820,6 @@ time_delta(dmy_struct *dmy_current, double td, a, b; dmy_struct dmy_next; - unsigned short int lastday[MONTHS_PER_YEAR]; - int i; // uniform timedeltas if (freq == FREQ_NSECONDS) { @@ -853,29 +851,9 @@ time_delta(dmy_struct *dmy_current, } } else if (freq == FREQ_NYEARS) { - // advance year dmy_next.year += n; - // re-calculate day_in_year (NOTE: currently will have problem - // if dmy_next.year is not leap year but date is Feb 29 !) - make_lastday(global_param.calendar, dmy_next.year, lastday); - dmy_next.day_in_year = 0; - for ( i = 0; i < MONTHS_PER_YEAR; i++ ) { - if ( (i+1) == dmy_next.month ) { - dmy_next.day_in_year += dmy_next.day; - break; } else { - dmy_next.day_in_year += lastday[i]; - } - } - // check if the advanced date is a valid date - if (invalid_date(global_param.calendar, &dmy_next)) { - log_err("VIC does not support a simulation starting from " - "Feb 29 of a leap year with yearly AGGFREQ or " - "HISTFREQ."); - } - } - else { log_err("Unknown frequency found during time_delta computation"); } diff --git a/vic/drivers/shared_image/src/parse_output_info.c b/vic/drivers/shared_image/src/parse_output_info.c index a9f0749a0..b31128b26 100644 --- a/vic/drivers/shared_image/src/parse_output_info.c +++ b/vic/drivers/shared_image/src/parse_output_info.c @@ -36,6 +36,7 @@ parse_output_info(FILE *gp, dmy_struct *dmy_current) { extern option_struct options; + extern global_param_struct global_param; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index 097e5aa07..3fb730bb8 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -256,7 +256,6 @@ initialize_history_file(nc_file_struct *nc, status = nc_create(stream->filename, get_nc_mode(stream->file_format), &(nc->nc_id)); - check_nc_status(status, "Error creating %s", stream->filename); nc->open = true; diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 79c34db73..529307b43 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1554,6 +1554,7 @@ initialize_state_file(char *filename, int *ivar = NULL; double offset; double time_num; + dmy_struct dmy_offset; // open the netcdf file status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), @@ -1716,7 +1717,7 @@ initialize_state_file(char *filename, // veg_class dimids[0] = nc_state_file->veg_dimid; status = nc_def_var(nc_state_file->nc_id, "veg_class", - NC_INT, 1, dimids, &(veg_var_id)); + NC_INT, ndims, dimids, &(veg_var_id)); check_nc_status(status, "Error defining veg_class variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", @@ -1731,7 +1732,7 @@ initialize_state_file(char *filename, // snow_band dimids[0] = nc_state_file->band_dimid; status = nc_def_var(nc_state_file->nc_id, "snow_band", - NC_INT, 1, dimids, &(snow_band_var_id)); + NC_INT, ndims, dimids, &(snow_band_var_id)); check_nc_status(status, "Error defining snow_band variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, @@ -1748,7 +1749,7 @@ initialize_state_file(char *filename, // layer dimids[0] = nc_state_file->layer_dimid; status = - nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, + nc_def_var(nc_state_file->nc_id, "layer", NC_INT, ndims, dimids, &(layer_var_id)); check_nc_status(status, "Error defining layer variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", @@ -1762,7 +1763,7 @@ initialize_state_file(char *filename, // frost_area dimids[0] = nc_state_file->frost_dimid; - status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, + status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, ndims, dimids, &(frost_area_var_id)); check_nc_status(status, "Error defining frost_area variable in %s", filename); @@ -1778,7 +1779,7 @@ initialize_state_file(char *filename, // dz_node dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 1, + status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, ndims, dimids, &(dz_node_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", @@ -1796,7 +1797,7 @@ initialize_state_file(char *filename, // node_depth dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 1, + status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, ndims, dimids, &(node_depth_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, @@ -1815,7 +1816,7 @@ initialize_state_file(char *filename, if (options.LAKES) { // lake_node dimids[0] = nc_state_file->lake_node_dimid; - status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, + status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, ndims, dimids, &(lake_node_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 904ce994d..ddeffb3ce 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -70,7 +70,7 @@ /***** Define minimum values for model parameters *****/ #define MINSOILDEPTH 0.001 /**< Minimum layer depth with which model can work (m) */ -#define MIN_FCANOPY 1.0 /**< Minimum allowable canopy fraction */ +#define MIN_FCANOPY 0.0001 /**< Minimum allowable canopy fraction */ #define MIN_SNOW_WETFRAC 0.01 /**< Minimum fraction of snow depth to be considered wet */ /***** Define minimum and maximum values for model timesteps *****/ From d2e003b7f883c10fab5410ccf323843a42c588cc Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 21 Oct 2016 14:59:46 +0200 Subject: [PATCH 033/294] changes applied for VIC 5.1 --- tests/test_utils.py | 4 +- vic/drivers/image/Makefile | 9 +- .../image/src/display_current_settings.c | 3 +- vic/drivers/image/src/vic_image.c | 5 +- vic/drivers/shared_all/src/history_metadata.c | 27 ++-- .../shared_all/src/set_output_defaults.c | 11 +- vic/drivers/shared_all/src/vic_time.c | 22 +++ .../shared_image/src/parse_output_info.c | 41 +++-- vic/drivers/shared_image/src/vic_image_run.c | 5 +- vic/drivers/shared_image/src/vic_store.c | 25 +-- vic/extensions/rout_rvic/include/rout.h | 11 +- vic/extensions/rout_rvic/rout.mk | 26 ++++ vic/extensions/rout_rvic/src/cshift.c | 142 ++++-------------- vic/extensions/rout_rvic/src/rout_alloc.c | 125 +++++++-------- vic/extensions/rout_rvic/src/rout_finalize.c | 5 +- vic/extensions/rout_rvic/src/rout_init.c | 123 +++++++-------- .../rout_rvic/src/rout_mpi_gather.c | 49 +++--- .../rout_rvic/src/rout_mpi_scatter.c | 48 +++--- vic/extensions/rout_rvic/src/rout_run.c | 110 +++++++------- vic/extensions/rout_rvic/src/rout_start.c | 11 +- vic/extensions/rout_rvic/src/rout_write.c | 33 ---- vic/extensions/rout_stub/include/rout.h | 4 +- vic/extensions/rout_stub/src/rout.c | 28 ++-- 23 files changed, 400 insertions(+), 467 deletions(-) delete mode 100644 vic/extensions/rout_rvic/src/rout_write.c diff --git a/tests/test_utils.py b/tests/test_utils.py index efdd1835b..61ebee7d1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -12,7 +12,7 @@ import pandas as pd import xarray as xr -# Plottling libs +# Plotting libs import matplotlib import matplotlib.pyplot as plt import seaborn as sns @@ -740,7 +740,7 @@ def plot_snotel_comparison_one_site( data = {} for key, items in compare_data_dict.items(): - # read in data + # read in data if key == "snotel": data[key] = read_snotel_swe_obs(filename, science_test_data_dir, diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 669309136..02dbb86d3 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -41,8 +41,11 @@ VICPATH = ../../vic_run # VIC EXTENTIONS PATH EXTPATH = ../../extensions -# set routing extension here (rout_stub means: no routing) -#ROUT=rout_stub +# Set the routing model extension +# | Level | Value | +# |---------- |--------------------------------- | +# | rout_stub | Stub routing model (no routing) | +# | rout_rvic | Use RVIC routing scheme | ROUT=rout_rvic include ${EXTPATH}/${ROUT}/rout.mk @@ -74,7 +77,7 @@ HOSTNAME := $(shell uname -n) # | WARNING | < 30 | # | INFO | < 20 | # | DEBUG | < 10 | -LOG_LVL = 15 +LOG_LVL = 5 # set includes INCLUDES = -I ${DRIVERPATH}/include \ diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index b62a22204..a129eb17a 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -26,6 +26,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Display the current settings of options defined in the header @@ -79,7 +80,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "Extensions:\n"); fprintf(LOG_DEST, "-----------\n"); - //fprintf(LOG_DEST, "ROUTING\t\t\t%2s\n", ROUT_EXT); + fprintf(LOG_DEST, "ROUTING\t\t\t%2s\n", ROUT_EXT); fprintf(LOG_DEST, "\n"); if (mode == DISP_COMPILE_TIME) { diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index c22dc80ab..560569f42 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -65,6 +65,8 @@ save_data_struct *save_data; // [ncells] double ***out_data = NULL; // [ncells, nvars, nelem] stream_struct *output_streams = NULL; // [nstreams] nc_file_struct *nc_hist_files = NULL; // [nstreams] + +// Extensions rout_struct rout; // Routing routine (extension) /****************************************************************************** @@ -151,9 +153,6 @@ main(int argc, // Write history files vic_write_output(&(dmy[current])); - - // if output (routing) - rout_write(); // Routing routine (extension) // Write state file if (check_save_state_flag(current)) { diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index c824b7c2e..4a2f85116 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -126,10 +126,13 @@ set_output_met_data_info() /* river discharge [m3 s-1] */ strcpy(out_metadata[OUT_DISCHARGE].varname, "OUT_DISCHARGE"); - strcpy(out_metadata[OUT_DISCHARGE].long_name, "river_discharge"); + strcpy(out_metadata[OUT_DISCHARGE].long_name, + "water_volume_transport_in_river_channel"); strcpy(out_metadata[OUT_DISCHARGE].standard_name, "river_discharge"); strcpy(out_metadata[OUT_DISCHARGE].units, "m3 s-1"); - strcpy(out_metadata[OUT_DISCHARGE].description, "river discharge"); + strcpy( + out_metadata[OUT_DISCHARGE].description, + "The water flux or volume transport in rivers is the amount of water flowing in the river channel and flood plain. 'Water' means water in all phases"); /* volumetric liquid water equivalent of snow on top of lake ice [m3] */ strcpy(out_metadata[OUT_LAKE_SWE_V].varname, "OUT_LAKE_SWE_V"); @@ -161,8 +164,9 @@ set_output_met_data_info() strcpy(out_metadata[OUT_SMFROZFRAC].standard_name, "soil_moisture_ice_fraction"); strcpy(out_metadata[OUT_SMFROZFRAC].units, "1"); - strcpy(out_metadata[OUT_SMFROZFRAC].description, - "fraction of soil moisture (by mass) that is ice, for each soil layer"); + strcpy( + out_metadata[OUT_SMFROZFRAC].description, + "fraction of soil moisture (by mass) that is ice, for each soil layer"); /* fraction of soil moisture (by mass) that is liquid, for each soil layer */ strcpy(out_metadata[OUT_SMLIQFRAC].varname, "OUT_SMLIQFRAC"); @@ -170,8 +174,9 @@ set_output_met_data_info() strcpy(out_metadata[OUT_SMLIQFRAC].standard_name, "soil_moisture_liquid_fraction"); strcpy(out_metadata[OUT_SMLIQFRAC].units, "1"); - strcpy(out_metadata[OUT_SMLIQFRAC].description, - "fraction of soil moisture (by mass) that is liquid, for each soil layer"); + strcpy( + out_metadata[OUT_SMLIQFRAC].description, + "fraction of soil moisture (by mass) that is liquid, for each soil layer"); /* snow interception storage in canopy [mm] */ strcpy(out_metadata[OUT_SNOW_CANOPY].varname, "OUT_SNOW_CANOPY"); @@ -301,8 +306,9 @@ set_output_met_data_info() strcpy(out_metadata[OUT_ZWT_LUMPED].standard_name, "lumped_water_table_position"); strcpy(out_metadata[OUT_ZWT_LUMPED].units, "cm"); - strcpy(out_metadata[OUT_ZWT_LUMPED].description, - "lumped water table position (zwt of total moisture across all layers, lumped together)"); + strcpy( + out_metadata[OUT_ZWT_LUMPED].description, + "lumped water table position (zwt of total moisture across all layers, lumped together)"); // Water Balance Terms - fluxes /* baseflow out of the bottom layer [mm] */ @@ -1026,8 +1032,9 @@ set_output_met_data_info() strcpy(out_metadata[OUT_AERO_RESIST].standard_name, "aerodynamic_resistance"); strcpy(out_metadata[OUT_AERO_RESIST].units, "s m-1"); - strcpy(out_metadata[OUT_AERO_RESIST].description, - "scene aerodynamic resistance (tiles with overstory contribute overstory resistance; others contribue surface resistance)"); + strcpy( + out_metadata[OUT_AERO_RESIST].description, + "scene aerodynamic resistance (tiles with overstory contribute overstory resistance; others contribue surface resistance)"); /* surface aerodynamic resistance [m/s] */ strcpy(out_metadata[OUT_AERO_RESIST1].varname, "OUT_AERO_RESIST1"); diff --git a/vic/drivers/shared_all/src/set_output_defaults.c b/vic/drivers/shared_all/src/set_output_defaults.c index 3f763f81d..82c4769af 100644 --- a/vic/drivers/shared_all/src/set_output_defaults.c +++ b/vic/drivers/shared_all/src/set_output_defaults.c @@ -98,13 +98,12 @@ set_output_defaults(stream_struct **streams, dmy_struct *dmy_current, unsigned short default_file_format) { - extern option_struct options; - extern global_param_struct global_param; + extern option_struct options; - size_t streamnum; - size_t varnum; - alarm_struct default_alarm; - int default_freq_n = 1; + size_t streamnum; + size_t varnum; + alarm_struct default_alarm; + int default_freq_n = 1; set_alarm(dmy_current, FREQ_NDAYS, &default_freq_n, &default_alarm); diff --git a/vic/drivers/shared_all/src/vic_time.c b/vic/drivers/shared_all/src/vic_time.c index d8b7d387b..144fe742f 100644 --- a/vic/drivers/shared_all/src/vic_time.c +++ b/vic/drivers/shared_all/src/vic_time.c @@ -820,6 +820,8 @@ time_delta(dmy_struct *dmy_current, double td, a, b; dmy_struct dmy_next; + unsigned short int lastday[MONTHS_PER_YEAR]; + int i; // uniform timedeltas if (freq == FREQ_NSECONDS) { @@ -851,9 +853,29 @@ time_delta(dmy_struct *dmy_current, } } else if (freq == FREQ_NYEARS) { + // advance year dmy_next.year += n; + // re-calculate day_in_year (NOTE: currently will have problem + // if dmy_next.year is not leap year but date is Feb 29 !) + make_lastday(global_param.calendar, dmy_next.year, lastday); + dmy_next.day_in_year = 0; + for (i = 0; i < MONTHS_PER_YEAR; i++) { + if ((i + 1) == dmy_next.month) { + dmy_next.day_in_year += dmy_next.day; + break; } else { + dmy_next.day_in_year += lastday[i]; + } + } + // check if the advanced date is a valid date + if (invalid_date(global_param.calendar, &dmy_next)) { + log_err("VIC does not support a simulation starting from " + "Feb 29 of a leap year with yearly AGGFREQ or " + "HISTFREQ."); + } + } + else { log_err("Unknown frequency found during time_delta computation"); } diff --git a/vic/drivers/shared_image/src/parse_output_info.c b/vic/drivers/shared_image/src/parse_output_info.c index b31128b26..8977eb605 100644 --- a/vic/drivers/shared_image/src/parse_output_info.c +++ b/vic/drivers/shared_image/src/parse_output_info.c @@ -35,28 +35,27 @@ parse_output_info(FILE *gp, stream_struct **streams, dmy_struct *dmy_current) { - extern option_struct options; - extern global_param_struct global_param; + extern option_struct options; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - char flgstr[MAXSTRING]; - short int streamnum; - char varname[MAXSTRING]; - int outvarnum; - char freq_type_str[MAXSTRING]; - char freq_value_str[MAXSTRING]; - char format[MAXSTRING]; - char typestr[MAXSTRING]; - int type; - char multstr[MAXSTRING]; - char aggstr[MAXSTRING]; - double mult; - unsigned short int freq; - int freq_n; - dmy_struct freq_dmy; - unsigned short int agg_type; - int found; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + char flgstr[MAXSTRING]; + short int streamnum; + char varname[MAXSTRING]; + int outvarnum; + char freq_type_str[MAXSTRING]; + char freq_value_str[MAXSTRING]; + char format[MAXSTRING]; + char typestr[MAXSTRING]; + int type; + char multstr[MAXSTRING]; + char aggstr[MAXSTRING]; + double mult; + unsigned short int freq; + int freq_n; + dmy_struct freq_dmy; + unsigned short int agg_type; + int found; streamnum = -1; diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index a41065443..f8d7d8c09 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -53,9 +53,8 @@ vic_image_run(dmy_struct *dmy_current) timer_struct timer; // Print the current timestep info before running vic_run - printf("Timestep %4zu, %u-%02hu-%02hu, sec: %5u\n", - current, dmy_current->year, dmy_current->month, - dmy_current->day, dmy_current->dayseconds); + sprint_dmy(dmy_str, dmy_current); + debug("Running timestep %zu: %s", current, dmy_str); for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 529307b43..b14330e3a 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1554,7 +1554,6 @@ initialize_state_file(char *filename, int *ivar = NULL; double offset; double time_num; - dmy_struct dmy_offset; // open the netcdf file status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), @@ -1678,8 +1677,9 @@ initialize_state_file(char *filename, NC_DOUBLE, ndims, dimids, &(lon_var_id)); check_nc_status(status, "Error defining lon variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( - "longitude"), "longitude"); + status = + nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( + "longitude"), "longitude"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( "degrees_east"), "degrees_east"); @@ -1699,8 +1699,9 @@ initialize_state_file(char *filename, NC_DOUBLE, ndims, dimids, &(lat_var_id)); check_nc_status(status, "Error defining lat variable (%s) in %s", global_domain.info.lat_var, filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( - "latitude"), "latitude"); + status = + nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( + "latitude"), "latitude"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( "degrees_north"), "degrees_north"); @@ -1717,7 +1718,7 @@ initialize_state_file(char *filename, // veg_class dimids[0] = nc_state_file->veg_dimid; status = nc_def_var(nc_state_file->nc_id, "veg_class", - NC_INT, ndims, dimids, &(veg_var_id)); + NC_INT, 1, dimids, &(veg_var_id)); check_nc_status(status, "Error defining veg_class variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", @@ -1732,7 +1733,7 @@ initialize_state_file(char *filename, // snow_band dimids[0] = nc_state_file->band_dimid; status = nc_def_var(nc_state_file->nc_id, "snow_band", - NC_INT, ndims, dimids, &(snow_band_var_id)); + NC_INT, 1, dimids, &(snow_band_var_id)); check_nc_status(status, "Error defining snow_band variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, @@ -1749,7 +1750,7 @@ initialize_state_file(char *filename, // layer dimids[0] = nc_state_file->layer_dimid; status = - nc_def_var(nc_state_file->nc_id, "layer", NC_INT, ndims, dimids, + nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, &(layer_var_id)); check_nc_status(status, "Error defining layer variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", @@ -1763,7 +1764,7 @@ initialize_state_file(char *filename, // frost_area dimids[0] = nc_state_file->frost_dimid; - status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, ndims, + status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, dimids, &(frost_area_var_id)); check_nc_status(status, "Error defining frost_area variable in %s", filename); @@ -1779,7 +1780,7 @@ initialize_state_file(char *filename, // dz_node dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, ndims, + status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 1, dimids, &(dz_node_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", @@ -1797,7 +1798,7 @@ initialize_state_file(char *filename, // node_depth dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, ndims, + status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 1, dimids, &(node_depth_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, @@ -1816,7 +1817,7 @@ initialize_state_file(char *filename, if (options.LAKES) { // lake_node dimids[0] = nc_state_file->lake_node_dimid; - status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, ndims, + status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, dimids, &(lake_node_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 9525e36a0..dfa4547d5 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -29,15 +29,16 @@ #define ROUT_EXT "rout_rvic" #include +#include /****************************************************************************** * @brief Routing Structs *****************************************************************************/ typedef struct { size_t full_time_length; /*scalar - total number of timesteps*/ - size_t nTimesteps; /*scalar - number of timesteps*/ - size_t nSources; /*scalar - number of sources*/ - size_t nOutlets; /*scalar - length of subset*/ + size_t n_timesteps; /*scalar - number of timesteps*/ + size_t n_sources; /*scalar - number of sources*/ + size_t n_outlets; /*scalar - length of subset*/ size_t *source2outlet_ind; /*1d array - source to outlet mapping*/ int *source_y_ind; /*1d array - source y location*/ int *source_x_ind; /*1d array - source x location*/ @@ -69,7 +70,6 @@ void rout_start(void); // read global parameters for routing void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain -void rout_write(void); // write routine for routing void rout_finalize(void); // clean up routine for routing /****************************************************************************** @@ -83,6 +83,5 @@ void gather_put_var_double(double *, double *); *****************************************************************************/ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); -void print_array(double *, int, int, int); #endif diff --git a/vic/extensions/rout_rvic/rout.mk b/vic/extensions/rout_rvic/rout.mk index 0eb6ef6f5..519deb49e 100644 --- a/vic/extensions/rout_rvic/rout.mk +++ b/vic/extensions/rout_rvic/rout.mk @@ -1,3 +1,29 @@ + ############################################################################## + # @section DESCRIPTION + # + # VIC Routing Extension Makefile Include + # + # @section LICENSE + # + # The Variable Infiltration Capacity (VIC) macroscale hydrological model + # Copyright (C) 2016 The Computational 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. + ############################################################################## + # make a list of all *.h files in routing folder INCL_ROUT := $(wildcard ${EXTPATH}/${ROUT}/include/*.h) diff --git a/vic/extensions/rout_rvic/src/cshift.c b/vic/extensions/rout_rvic/src/cshift.c index db6633cc0..7ff2ba2bd 100644 --- a/vic/extensions/rout_rvic/src/cshift.c +++ b/vic/extensions/rout_rvic/src/cshift.c @@ -1,6 +1,34 @@ -#include -#include - +/****************************************************************************** + * @section DESCRIPTION + * + * Function to shift columns or rows one position (used in convolution) + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Function to shift columns or rows one position + *****************************************************************************/ void cshift(double *data, int nx, @@ -51,111 +79,3 @@ cshift(double *data, } } } - -void -print_array(double *data, - int nx, - int ny, - int nlines) -{ - int x, y; - - for (y = 0; y != nlines; y++) { - for (x = 0; x != nx; x++) { - printf("%3i:%9.6f, ", (int)(x * ny + y), data[x * ny + y]); - } - printf("\n"); - } -} - -#include /* for CHAR_BIT */ -#include -#include -#include - -#define BITMASK(b) (1 << ((b) % CHAR_BIT)) -#define BITSLOT(b) ((b) / CHAR_BIT) -#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b)) -#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b)) -#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) -#define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT) - -void -Print2DArray(double *A, - int nr, - int nc) -{ - int r, c; - for (r = 0; r < nr; r++) { - for (c = 0; c < nc; c++) { - printf("%7.1f", *(A + r * nc + c)); - } - - printf("\n"); - } - printf("\n\n"); -} - -// Non-square matrix transpose of matrix of size r x c and base address data - -void -MatrixInplaceTranspose(double *data, - int r, - int c) -{ - int size = r * c - 1; - double temp1, temp2; // holds element to be replaced, eventually becomes next element to move - int next; // location of 'temp1' to be moved - int cycleBegin; // holds start of cycle - int i; // iterator - - char bitarray[BITNSLOTS(size)]; - memset(bitarray, 0, BITNSLOTS(size)); - - BITSET(bitarray, 0); - BITSET(bitarray, size); - - i = 1; // Note that data[0] and data[size-1] won't move - while (i < size) { - cycleBegin = i; - temp1 = *(data + i); - do - { - next = (i * r) % size; - // swap - temp2 = *(data + next); - *(data + next) = temp1; - temp1 = temp2; - BITSET(bitarray, i); - i = next; - } - while (i != cycleBegin); - - // Get Next Move - for (i = 1; i < size && BITTEST(bitarray, i); i++) { - ; - } - } -} - -// Driver program to test above function - -int -test_matrix(void) -{ - int r = 5, c = 6; - int size = r * c; - double *A; - int i; - A = (double *) malloc(size * sizeof(double)); - - for (i = 0; i < size; i++) { - A[i] = i + 11.1; - } - - Print2DArray(A, r, c); - MatrixInplaceTranspose(A, r, c); - Print2DArray(A, c, r); - - return 0; -} diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index aaabbba7e..2723e6d92 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,9 +24,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include #include /****************************************************************************** @@ -54,97 +51,87 @@ rout_alloc(void) &ivar); rout.rout_param.full_time_length = (int) ivar; - rout.rout_param.nTimesteps = get_nc_dimension(rout.param_filename, - "timesteps"); - rout.rout_param.nOutlets = get_nc_dimension(rout.param_filename, - "outlets"); - rout.rout_param.nSources = get_nc_dimension(rout.param_filename, - "sources"); + rout.rout_param.n_timesteps = get_nc_dimension(rout.param_filename, + "timesteps"); + rout.rout_param.n_outlets = get_nc_dimension(rout.param_filename, + "outlets"); + rout.rout_param.n_sources = get_nc_dimension(rout.param_filename, + "sources"); // Allocate memory in rout param_struct rout.rout_param.source2outlet_ind = malloc( - rout.rout_param.nSources * + rout.rout_param.n_sources * sizeof(*rout.rout_param.source2outlet_ind)); - if (rout.rout_param.source2outlet_ind == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source2outlet_ind()."); - } + check_alloc_status(rout.rout_param.source2outlet_ind, + "Memory allocation error."); + rout.rout_param.source_time_offset = malloc( - rout.rout_param.nSources * + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_time_offset)); - if (rout.rout_param.source_time_offset == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source_time_offset()."); - } + check_alloc_status(rout.rout_param.source_time_offset, + "Memory allocation error."); + rout.rout_param.source_x_ind = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_x_ind)); - if (rout.rout_param.source_x_ind == NULL) { - log_err("Memory allocation error in rout.rout_param.source_x_ind()."); - } + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_x_ind)); + check_alloc_status(rout.rout_param.source_x_ind, + "Memory allocation error."); + rout.rout_param.source_y_ind = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_y_ind)); - if (rout.rout_param.source_y_ind == NULL) { - log_err("Memory allocation error in rout.rout_param.source_y_ind()."); - } + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_y_ind)); + check_alloc_status(rout.rout_param.source_y_ind, + "Memory allocation error."); + rout.rout_param.source_lat = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_lat)); - if (rout.rout_param.source_lat == NULL) { - log_err("Memory allocation error in rout.rout_param.source_lat()."); - } + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_lat)); + check_alloc_status(rout.rout_param.source_lat, + "Memory allocation error."); + rout.rout_param.source_lon = malloc( - rout.rout_param.nSources * sizeof(*rout.rout_param.source_lon)); - if (rout.rout_param.source_lon == NULL) { - log_err("Memory allocation error in rout.rout_param.source_lon()."); - } + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_lon)); + check_alloc_status(rout.rout_param.source_lon, + "Memory allocation error."); + rout.rout_param.source_VIC_index = malloc( - rout.rout_param.nSources * + rout.rout_param.n_sources * sizeof(*rout.rout_param.source_VIC_index)); - if (rout.rout_param.source_VIC_index == NULL) { - log_err( - "Memory allocation error in rout.rout_param.source_VIC_index()."); - } + check_alloc_status(rout.rout_param.source_VIC_index, + "Memory allocation error."); + rout.rout_param.outlet_lat = malloc( - rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lat)); - if (rout.rout_param.outlet_lat == NULL) { - log_err("Memory allocation error in rout.rout_param.outlet_lat()."); - } + rout.rout_param.n_outlets * sizeof(*rout.rout_param.outlet_lat)); + check_alloc_status(rout.rout_param.outlet_lat, + "Memory allocation error."); + rout.rout_param.outlet_lon = malloc( - rout.rout_param.nOutlets * sizeof(*rout.rout_param.outlet_lon)); - if (rout.rout_param.outlet_lon == NULL) { - log_err("Memory allocation error in rout.rout_param.outlet_lon()."); - } + rout.rout_param.n_outlets * sizeof(*rout.rout_param.outlet_lon)); + check_alloc_status(rout.rout_param.outlet_lon, + "Memory allocation error."); + rout.rout_param.outlet_VIC_index = malloc( - rout.rout_param.nOutlets * + rout.rout_param.n_outlets * sizeof(rout.rout_param.outlet_VIC_index)); - if (rout.rout_param.outlet_VIC_index == NULL) { - log_err( - "Memory allocation error in rout.rout_param.outlet_VIC_index()."); - } + check_alloc_status(rout.rout_param.outlet_VIC_index, + "Memory allocation error."); + rout.rout_param.unit_hydrograph = malloc( - rout.rout_param.nSources * rout.rout_param.nTimesteps * + rout.rout_param.n_sources * rout.rout_param.n_timesteps * sizeof(*rout.rout_param.unit_hydrograph)); - if (rout.rout_param.unit_hydrograph == NULL) { - log_err( - "Memory allocation error in rout.rout_param.unit_hydrograph()."); - } + check_alloc_status(rout.rout_param.unit_hydrograph, + "Memory allocation error."); + rout.rout_param.aggrunin = malloc( global_domain.ncells_total * sizeof(*rout.rout_param.aggrunin)); - if (rout.rout_param.aggrunin == NULL) { - log_err("Memory allocation error in rout.rout_param.aggrunin()."); - } + check_alloc_status(rout.rout_param.aggrunin, "Memory allocation error."); + rout.discharge = malloc(global_domain.ncells_total * sizeof(*rout.discharge)); - if (rout.discharge == NULL) { - log_err("Memory allocation error in rout.rout_param.discharge()."); - } + check_alloc_status(rout.discharge, "Memory allocation error."); // Allocate memory for the ring rout.ring = malloc( - rout.rout_param.full_time_length * rout.rout_param.nOutlets * + rout.rout_param.full_time_length * rout.rout_param.n_outlets * sizeof(*rout.ring)); - if (rout.ring == NULL) { - log_err("Memory allocation error in rout.ring()."); - } + check_alloc_status(rout.ring, "Memory allocation error."); } } diff --git a/vic/extensions/rout_rvic/src/rout_finalize.c b/vic/extensions/rout_rvic/src/rout_finalize.c index 0f46a2e18..9083eb430 100644 --- a/vic/extensions/rout_rvic/src/rout_finalize.c +++ b/vic/extensions/rout_rvic/src/rout_finalize.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -26,6 +26,9 @@ #include +/****************************************************************************** + * @brief Finalize RVIC by freeing memory. + *****************************************************************************/ void rout_finalize(void) { diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index ea41ba4ef..8c332d12d 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,10 +24,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include - #include /****************************************************************************** @@ -36,46 +32,43 @@ void rout_init(void) { - extern int mpi_rank; - if (mpi_rank == VIC_MPI_ROOT) { - extern rout_struct rout; - extern domain_struct global_domain; + extern int mpi_rank; + extern rout_struct rout; + extern domain_struct global_domain; - int *ivar = NULL; - double *dvar = NULL; + if (mpi_rank == VIC_MPI_ROOT) { + int *ivar = NULL; + double *dvar = NULL; - size_t i, j; - size_t i1start; - size_t d3count[3]; - size_t d3start[3]; + size_t i; + size_t j; + size_t i1start; + size_t d3count[3]; + size_t d3start[3]; i1start = 0; d3start[0] = 0; d3start[1] = 0; d3start[2] = 0; - d3count[0] = rout.rout_param.nTimesteps; - d3count[1] = rout.rout_param.nSources; + d3count[0] = rout.rout_param.n_timesteps; + d3count[1] = rout.rout_param.n_sources; d3count[2] = 1; // tracers dimension // allocate memory for variables to be read - ivar = (int *) malloc(sizeof(int) * rout.rout_param.nSources); - if (ivar == NULL) { - log_err("Memory allocation error in vic_init()."); - } + ivar = malloc(rout.rout_param.n_sources * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error."); // allocate memory for variables to be read - dvar = (double *) malloc( - rout.rout_param.nTimesteps * rout.rout_param.nSources * - sizeof(double)); - if (dvar == NULL) { - log_err("Memory allocation error in vic_init()."); - } + dvar = malloc( + rout.rout_param.n_timesteps * rout.rout_param.n_sources * + sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error."); // The Ring - for (j = 0; j < rout.rout_param.nOutlets; j++) { - for (i = 0; i < rout.rout_param.nTimesteps; i++) { - rout.ring[j * rout.rout_param.nTimesteps + i] = 0.0; + for (j = 0; j < rout.rout_param.n_outlets; j++) { + for (i = 0; i < rout.rout_param.n_timesteps; i++) { + rout.ring[j * rout.rout_param.n_timesteps + i] = 0.0; } } @@ -87,64 +80,64 @@ rout_init(void) // source2outlet_ind: source to outlet index mapping get_nc_field_int(rout.param_filename, "source2outlet_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, ivar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source2outlet_ind[i] = (int) ivar[i]; } // source_time_offset: Number of leading timesteps ommited get_nc_field_int(rout.param_filename, "source_time_offset", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, ivar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source_time_offset[i] = (int) ivar[i]; } // source_x_ind: x grid coordinate of source grid cell get_nc_field_int(rout.param_filename, "source_x_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, ivar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source_x_ind[i] = (int) ivar[i]; } // source_y_ind: y grid coordinate of source grid cell get_nc_field_int(rout.param_filename, "source_y_ind", - &i1start, &rout.rout_param.nSources, ivar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, ivar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source_y_ind[i] = (int) ivar[i]; } // source_lat: Latitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "source_lat", - &i1start, &rout.rout_param.nSources, dvar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, dvar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source_lat[i] = (double) dvar[i]; } // source_lon: Longitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "source_lon", - &i1start, &rout.rout_param.nSources, dvar); - for (i = 0; i < rout.rout_param.nSources; i++) { + &i1start, &rout.rout_param.n_sources, dvar); + for (i = 0; i < rout.rout_param.n_sources; i++) { rout.rout_param.source_lon[i] = (double) dvar[i]; } // outlet_lat: Latitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "outlet_lat", - &i1start, &rout.rout_param.nOutlets, dvar); - for (i = 0; i < rout.rout_param.nOutlets; i++) { + &i1start, &rout.rout_param.n_outlets, dvar); + for (i = 0; i < rout.rout_param.n_outlets; i++) { rout.rout_param.outlet_lat[i] = (double) dvar[i]; } // outlet_lon: Longitude coordinate of source grid cell get_nc_field_double(rout.param_filename, "outlet_lon", - &i1start, &rout.rout_param.nOutlets, dvar); - for (i = 0; i < rout.rout_param.nOutlets; i++) { + &i1start, &rout.rout_param.n_outlets, dvar); + for (i = 0; i < rout.rout_param.n_outlets; i++) { rout.rout_param.outlet_lon[i] = (double) dvar[i]; } @@ -153,51 +146,51 @@ rout_init(void) "unit_hydrograph", d3start, d3count, dvar); for (i = 0; - i < (rout.rout_param.nTimesteps * rout.rout_param.nSources); + i < (rout.rout_param.n_timesteps * rout.rout_param.n_sources); i++) { rout.rout_param.unit_hydrograph[i] = (double) dvar[i]; } - // TODO: Check inbouwen: wat als er geen VIC gridcell bestaat voor een Rout source?! + // TODO: add check: what to do in case no VIC gridcell exists for a rout source? // Mapping: Let the routing-source index numbers correspond to the VIC index numbers - size_t iSource; - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { + size_t i_source; + for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { for (i = 0; i < global_domain.ncells_total; i++) { - if (rout.rout_param.source_lat[iSource] == + if (rout.rout_param.source_lat[i_source] == global_domain.locations[i].latitude && - rout.rout_param.source_lon[iSource] == + rout.rout_param.source_lon[i_source] == global_domain.locations[i].longitude) { - rout.rout_param.source_VIC_index[iSource] = i; + rout.rout_param.source_VIC_index[i_source] = i; } } } // Check source index of VIC gridcell - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { - if ((size_t)rout.rout_param.source_VIC_index[iSource] < 0 || - (size_t)rout.rout_param.source_VIC_index[iSource] > + for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { + if ((size_t)rout.rout_param.source_VIC_index[i_source] < 0 || + (size_t)rout.rout_param.source_VIC_index[i_source] > global_domain.ncells_total) { log_err("invalid source, index of VIC gridcell"); } } - // Mapping: Let the routing-outlet index numbers correspond to the VIC index numbers - size_t iOutlet; - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { + // Mapping: Let i_outlet the routing-outlet index numbers correspond to the VIC index numbers + size_t i_outlet; + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { for (i = 0; i < global_domain.ncells_total; i++) { - if (rout.rout_param.outlet_lat[iOutlet] == + if (rout.rout_param.outlet_lat[i_outlet] == global_domain.locations[i].latitude && - rout.rout_param.outlet_lon[iOutlet] == + rout.rout_param.outlet_lon[i_outlet] == global_domain.locations[i].longitude) { - rout.rout_param.outlet_VIC_index[iOutlet] = i; + rout.rout_param.outlet_VIC_index[i_outlet] = i; } } } // Check outlet index of VIC gridcell - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - if ((size_t)rout.rout_param.outlet_VIC_index[iOutlet] < 0 || - (size_t)rout.rout_param.outlet_VIC_index[iOutlet] > + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { + if ((size_t)rout.rout_param.outlet_VIC_index[i_outlet] < 0 || + (size_t)rout.rout_param.outlet_VIC_index[i_outlet] > global_domain.ncells_total) { log_err("invalid outlet, index of VIC gridcell"); } diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c index 94f8c0112..605fce23f 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_gather.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_gather.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,30 +24,30 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include #include /****************************************************************************** * @brief Gather double precision variable * @details Values are gathered to the master node *****************************************************************************/ -void gather_put_var_double(double *dvar, double *var_local) { - extern MPI_Comm MPI_COMM_VIC; +void +gather_put_var_double(double *dvar, + double *var_local) +{ + extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; extern domain_struct local_domain; - extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - int status; - double *dvar_gathered = NULL; - double *dvar_remapped = NULL; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + double *dvar_gathered = NULL; + double *dvar_remapped = NULL; size_t grid_size; size_t i; - + if (mpi_rank == VIC_MPI_ROOT) { grid_size = global_domain.n_nx * global_domain.n_ny; @@ -56,31 +56,30 @@ void gather_put_var_double(double *dvar, double *var_local) { } dvar_gathered = - malloc(global_domain.ncells_active * sizeof (*dvar_gathered)); + malloc(global_domain.ncells_active * sizeof(*dvar_gathered)); check_alloc_status(dvar_gathered, "Memory allocation error."); dvar_remapped = - malloc(global_domain.ncells_active * sizeof (*dvar_remapped)); + malloc(global_domain.ncells_active * sizeof(*dvar_remapped)); check_alloc_status(dvar_remapped, "Memory allocation error."); } // Gather the results from the nodes, result for the local node is in the // array *var (which is a function argument) status = MPI_Gatherv(var_local, local_domain.ncells_active, MPI_DOUBLE, - dvar_gathered, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); + dvar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); check_mpi_status(status, "MPI error."); if (mpi_rank == VIC_MPI_ROOT) { // remap the array - map(sizeof (double), global_domain.ncells_active, NULL, - mpi_map_mapping_array, dvar_gathered, dvar_remapped); + map(sizeof(double), global_domain.ncells_active, NULL, + mpi_map_mapping_array, dvar_gathered, dvar_remapped); // expand to full grid size - map(sizeof (double), global_domain.ncells_active, NULL, - filter_active_cells, dvar_remapped, dvar); + map(sizeof(double), global_domain.ncells_active, NULL, + filter_active_cells, dvar_remapped, dvar); // cleanup free(dvar_gathered); free(dvar_remapped); } } - diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c index 04382fb2e..0afce0a08 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,57 +24,55 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include #include /****************************************************************************** * @brief Scatter double precision variable * @details values from master node are scattered to the local nodes *****************************************************************************/ -void get_scatter_var_double(double *dvar, double *var_local) { - - extern MPI_Comm MPI_COMM_VIC; +void +get_scatter_var_double(double *dvar, + double *var_local) +{ + extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; extern domain_struct local_domain; - extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - int status; - double *dvar_filtered = NULL; - double *dvar_mapped = NULL; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + double *dvar_filtered = NULL; + double *dvar_mapped = NULL; if (mpi_rank == VIC_MPI_ROOT) { dvar_filtered = - malloc(global_domain.ncells_active * sizeof (*dvar_filtered)); + malloc(global_domain.ncells_active * sizeof(*dvar_filtered)); check_alloc_status(dvar_filtered, "Memory allocation error."); dvar_mapped = - malloc(global_domain.ncells_active * sizeof (*dvar_mapped)); + malloc(global_domain.ncells_active * sizeof(*dvar_mapped)); check_alloc_status(dvar_mapped, "Memory allocation error."); // filter the active cells only - map(sizeof (double), global_domain.ncells_active, filter_active_cells, - NULL, dvar, dvar_filtered); + map(sizeof(double), global_domain.ncells_active, filter_active_cells, + NULL, dvar, dvar_filtered); // map to prepare for MPI_Scatterv - map(sizeof (double), global_domain.ncells_active, mpi_map_mapping_array, - NULL, dvar_filtered, dvar_mapped); + map(sizeof(double), global_domain.ncells_active, mpi_map_mapping_array, + NULL, dvar_filtered, dvar_mapped); free(dvar_filtered); } // Scatter the results to the nodes, result for the local node is in the // array *var (which is a function argument) status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - var_local, local_domain.ncells_active, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); + mpi_map_global_array_offsets, MPI_DOUBLE, + var_local, local_domain.ncells_active, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); check_mpi_status(status, "MPI error."); if (mpi_rank == VIC_MPI_ROOT) { free(dvar_mapped); } } - diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 1e78ca1ee..808c8c0cf 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,94 +24,101 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include #include -#include -#include +/****************************************************************************** +* @brief This subroutine controls the RVIC convolution. +******************************************************************************/ void -rout_run(void) { - extern int mpi_rank; - extern double ***out_data; +rout_run(void) +{ + extern int mpi_rank; + extern double ***out_data; extern global_param_struct global_param; - extern domain_struct local_domain; - extern domain_struct global_domain; - double *dvar_global = NULL; - double *dvar_local = NULL; - double *dvar_global_total_runoff = NULL; - double *dvar_local_total_runoff = NULL; - size_t i; - - ////////////////// + extern domain_struct local_domain; + extern domain_struct global_domain; + extern rout_struct rout; + double *dvar_global = NULL; + double *dvar_local = NULL; + double *dvar_global_total_runoff = NULL; + double *dvar_local_total_runoff = NULL; + size_t i; + size_t i_source; + size_t i_outlet; + size_t i_timestep; + size_t j_timestep; + int offset; /*2d indicies*/ + size_t i_ring; + size_t i_uh; /*1d indicies*/ + // Gather runoff and baseflow from local nodes to the masternode // and add them together in total_runoff - dvar_global_total_runoff = malloc(global_domain.ncells_total * sizeof (*dvar_global_total_runoff)); + dvar_global_total_runoff = + malloc(global_domain.ncells_total * sizeof(*dvar_global_total_runoff)); check_alloc_status(dvar_global_total_runoff, "Memory allocation error."); - dvar_local_total_runoff = malloc(local_domain.ncells_active * sizeof (*dvar_local_total_runoff)); + dvar_local_total_runoff = + malloc(local_domain.ncells_active * sizeof(*dvar_local_total_runoff)); check_alloc_status(dvar_local_total_runoff, "Memory allocation error."); - + // Read from out_data... for (i = 0; i < local_domain.ncells_active; i++) { - dvar_local_total_runoff[i] = out_data[i][OUT_RUNOFF][0] + out_data[i][OUT_BASEFLOW][0]; + dvar_local_total_runoff[i] = out_data[i][OUT_RUNOFF][0] + + out_data[i][OUT_BASEFLOW][0]; } gather_put_var_double(dvar_global_total_runoff, dvar_local_total_runoff); free(dvar_local_total_runoff); - ////////////////////// // Do the routing on the master node if (mpi_rank == VIC_MPI_ROOT) { - debug("In Routing Lohmann Model"); + debug("RVIC"); - extern rout_struct rout; - extern domain_struct global_domain; - - dvar_global = malloc(global_domain.ncells_total * sizeof (*dvar_global)); + dvar_global = malloc(global_domain.ncells_total * sizeof(*dvar_global)); check_alloc_status(dvar_global, "Memory allocation error."); - size_t iSource, iOutlet, iTimestep, jTimestep; - int offset; /*2d indicies*/ - size_t iRing, iUH; /*1d indicies*/ - // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - rout.ring[iOutlet] = 0.0; + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { + rout.ring[i_outlet] = 0.0; } - // Equivalent to Fortran 90 cshift function, in python: (from variables.py) self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) + // Equivalent to Fortran 90 cshift function, in python: (from variables.py) + // self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) cshift(rout.ring, rout.rout_param.full_time_length, - rout.rout_param.nOutlets, 0, - 1); + rout.rout_param.n_outlets, 0, + 1); /*Loop through all sources*/ - for (iSource = 0; iSource < rout.rout_param.nSources; iSource++) { - iOutlet = rout.rout_param.source2outlet_ind[iSource]; - offset = rout.rout_param.source_time_offset[iSource]; + for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { + i_outlet = rout.rout_param.source2outlet_ind[i_source]; + offset = rout.rout_param.source_time_offset[i_source]; /* Do the convolution */ // iTimestep is the position in the unit hydrograph // jTimestep is the position in the ring - for (iTimestep = 0; iTimestep < rout.rout_param.nTimesteps; - iTimestep++) { - jTimestep = iTimestep + offset; + for (i_timestep = 0; i_timestep < rout.rout_param.n_timesteps; + i_timestep++) { + j_timestep = i_timestep + offset; // index locations - iRing = (jTimestep * rout.rout_param.nOutlets) + iOutlet; - iUH = (iTimestep * rout.rout_param.nSources) + iSource; + i_ring = (j_timestep * rout.rout_param.n_outlets) + i_outlet; + i_uh = (i_timestep * rout.rout_param.n_sources) + i_source; - rout.ring[iRing] += rout.rout_param.unit_hydrograph[iUH] * - dvar_global_total_runoff[rout.rout_param.source_VIC_index[iSource]]; + rout.ring[i_ring] += rout.rout_param.unit_hydrograph[i_uh] * + dvar_global_total_runoff[rout.rout_param. + source_VIC_index[ + i_source]]; } } // Write to dvar_global prior to scattering over local domains... - for (iOutlet = 0; iOutlet < rout.rout_param.nOutlets; iOutlet++) { - dvar_global[rout.rout_param.outlet_VIC_index[iOutlet]] = - rout.ring[iOutlet] * - global_domain.locations[rout.rout_param.outlet_VIC_index[iOutlet]].area - / (MM_PER_M * global_param.dt); + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { + dvar_global[rout.rout_param.outlet_VIC_index[i_outlet]] = + rout.ring[i_outlet] * + global_domain.locations[rout.rout_param.outlet_VIC_index[ + i_outlet]].area / + (MM_PER_M * global_param.dt); } // cleanup @@ -119,7 +126,7 @@ rout_run(void) { } // Scatter dvar_global to local domains (dvar_local)... - dvar_local = malloc(local_domain.ncells_active * sizeof (*dvar_local)); + dvar_local = malloc(local_domain.ncells_active * sizeof(*dvar_local)); check_alloc_status(dvar_local, "Memory allocation error."); get_scatter_var_double(dvar_global, dvar_local); @@ -132,5 +139,4 @@ rout_run(void) { // cleanup free(dvar_local); free(dvar_global_total_runoff); - } diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 16b1d4ab0..3856f1c22 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,13 +24,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include #include /****************************************************************************** - * @brief + * @brief Wrapper function for RVIC startup. *****************************************************************************/ void rout_start(void) @@ -46,6 +43,10 @@ rout_start(void) } } +/****************************************************************************** + * @brief Read the VIC model global control file, getting values for + * global parameters specifically for RVIC. + *****************************************************************************/ void get_global_param_rout(FILE *gp) { diff --git a/vic/extensions/rout_rvic/src/rout_write.c b/vic/extensions/rout_rvic/src/rout_write.c deleted file mode 100644 index c2f470341..000000000 --- a/vic/extensions/rout_rvic/src/rout_write.c +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Write routines for routing. - * - * @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 -#include - -void -rout_write() -{ -} diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 2ed0a7a75..df1c656d8 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -23,6 +23,7 @@ * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ + #ifndef ROUT_STUB_H #define ROUT_STUB_H @@ -41,6 +42,5 @@ void rout_start(void); // read global parameters for routing void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain -void rout_write(void); // write routine for routing void rout_finalize(void); // clean up routine for routing #endif diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index e005ef446..993a9f2e4 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -6,7 +6,7 @@ * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2014 The Land Surface Hydrology Group, Department of Civil + * Copyright (C) 2016 The Computational Hydrology Group, Department of Civil * and Environmental Engineering, University of Washington. * * The VIC model is free software; you can redistribute it and/or @@ -24,37 +24,41 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ -// read global parameters for routing +/****************************************************************************** + * @brief Read global parameters for routing. + *****************************************************************************/ void rout_start(void) { } -// allocate memory +/****************************************************************************** + * @brief Allocate memory. + *****************************************************************************/ void rout_alloc(void) { } -// initialize model parameters from parameter files +/****************************************************************************** + * @brief Initialize model parameters from parameter files. + *****************************************************************************/ void rout_init(void) { } -// run routing over the domain +/****************************************************************************** + * @brief Run routing over the domain. + *****************************************************************************/ void rout_run(void) { } -// write routine for routing -void -rout_write(void) -{ -} - -// clean up routine for routing +/****************************************************************************** + * @brief Clean up routine for routing. + *****************************************************************************/ void rout_finalize(void) { From 561c94a34dd88735c4b78ec500c24fcbae5e958c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 22 Nov 2016 16:43:17 +0100 Subject: [PATCH 034/294] added documentation about RVIC --- docs/Documentation/Drivers/Image/Inputs.md | 1 + docs/Documentation/Drivers/Image/RunVIC.md | 2 ++ docs/Documentation/Drivers/Image/RvicParams.md | 7 +++++++ 3 files changed, 10 insertions(+) create mode 100644 docs/Documentation/Drivers/Image/RvicParams.md diff --git a/docs/Documentation/Drivers/Image/Inputs.md b/docs/Documentation/Drivers/Image/Inputs.md index dff766816..a72d2438b 100644 --- a/docs/Documentation/Drivers/Image/Inputs.md +++ b/docs/Documentation/Drivers/Image/Inputs.md @@ -13,3 +13,4 @@ And a few more are optional: * [Constants File](../../Constants.md): Model parameters that are constant in time and space. * [Initial State File](StateFile.md): Moisture storages (soil moisture, snow pack, etc), energy storages (soil temperatures, etc) and other information describing the current state of the system. A state file saved from a previous VIC simulation may be used as the initial state for another run. * [Lake/Wetland Parameter File](LakeParam.md): File containing lake model parameters. By default, VIC does not simulate lakes or other impoundment of surface water. +* [Routing Parameter File](RvicParam.md): File containing the parameters necessary to perform the Lohmann routing. diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 078e0527a..25fa04154 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -33,6 +33,8 @@ The flags and libraries required to compile VIC with netCDF are automatically de In some versions of the MPI library (e.g. OPEN-MPI with Intel), you may also need to set the environment variable `MX_RCACHE=2` prior to compiling. +To enable the Routing module you have to set ROUT=rout_rvic if not you have to set ROUT=rout_stub. + - Change directory, `cd`, to the "Image Driver" source code directory and type `make` cd vic/drivers/image diff --git a/docs/Documentation/Drivers/Image/RvicParams.md b/docs/Documentation/Drivers/Image/RvicParams.md new file mode 100644 index 000000000..208995964 --- /dev/null +++ b/docs/Documentation/Drivers/Image/RvicParams.md @@ -0,0 +1,7 @@ +# RvicParams + +The routing process is done in two steps: Generation unit hydrograph (ref) and the convolution (ref) +* The unit hydrograph is generated separately with the RVIC streamflow routing model. This RVIC is a stand alone python program see: http://rvic.readthedocs.io/en/latest/. +* Convolution is calculated in VIC itself (if routing is enabled in the makefile) and uses the parameter file generated in step 1 + +VIC needs the parameter file generated in step 1. In formation how to generate this file can be found at http://rvic.readthedocs.io/en/latest/user-guide/parameters/. From 53c3d76c39ee5da2073099f20b2809a82b812584 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 7 Dec 2016 14:04:36 +0100 Subject: [PATCH 035/294] updated some formatting and some documentation --- docs/Documentation/Drivers/Image/Inputs.md | 2 +- .../Image/{RvicParams.md => Routing.md} | 2 +- docs/Documentation/Drivers/Image/RunVIC.md | 2 +- tests/run_profiling.py | 12 +++--- tests/test_utils.py | 21 +++++----- .../shared_all/src/set_output_defaults.c | 10 ++--- vic/drivers/shared_all/src/vic_time.c | 4 +- .../shared_image/src/parse_output_info.c | 40 +++++++++---------- vic/drivers/shared_image/src/vic_store.c | 10 ++--- 9 files changed, 50 insertions(+), 53 deletions(-) rename docs/Documentation/Drivers/Image/{RvicParams.md => Routing.md} (97%) diff --git a/docs/Documentation/Drivers/Image/Inputs.md b/docs/Documentation/Drivers/Image/Inputs.md index a72d2438b..de0bf12b4 100644 --- a/docs/Documentation/Drivers/Image/Inputs.md +++ b/docs/Documentation/Drivers/Image/Inputs.md @@ -13,4 +13,4 @@ And a few more are optional: * [Constants File](../../Constants.md): Model parameters that are constant in time and space. * [Initial State File](StateFile.md): Moisture storages (soil moisture, snow pack, etc), energy storages (soil temperatures, etc) and other information describing the current state of the system. A state file saved from a previous VIC simulation may be used as the initial state for another run. * [Lake/Wetland Parameter File](LakeParam.md): File containing lake model parameters. By default, VIC does not simulate lakes or other impoundment of surface water. -* [Routing Parameter File](RvicParam.md): File containing the parameters necessary to perform the Lohmann routing. +* [Routing Parameter File](RvicParam.md): File containing the parameters necessary to perform the Lohmann routing. Note that by default, VIC does not perform any streamflow routing. diff --git a/docs/Documentation/Drivers/Image/RvicParams.md b/docs/Documentation/Drivers/Image/Routing.md similarity index 97% rename from docs/Documentation/Drivers/Image/RvicParams.md rename to docs/Documentation/Drivers/Image/Routing.md index 208995964..f6548d240 100644 --- a/docs/Documentation/Drivers/Image/RvicParams.md +++ b/docs/Documentation/Drivers/Image/Routing.md @@ -1,4 +1,4 @@ -# RvicParams +# Routing The routing process is done in two steps: Generation unit hydrograph (ref) and the convolution (ref) * The unit hydrograph is generated separately with the RVIC streamflow routing model. This RVIC is a stand alone python program see: http://rvic.readthedocs.io/en/latest/. diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 25fa04154..876bdd38b 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -33,7 +33,7 @@ The flags and libraries required to compile VIC with netCDF are automatically de In some versions of the MPI library (e.g. OPEN-MPI with Intel), you may also need to set the environment variable `MX_RCACHE=2` prior to compiling. -To enable the Routing module you have to set ROUT=rout_rvic if not you have to set ROUT=rout_stub. +To enable the routing extension, you must set the ROUT option. Valid options are rout_stub (default) and rout_rvic. For more information on what these options mean, see the [routing extension documentation](Routing.md). - Change directory, `cd`, to the "Image Driver" source code directory and type `make` diff --git a/tests/run_profiling.py b/tests/run_profiling.py index cf2a1c46c..9fb29bacb 100755 --- a/tests/run_profiling.py +++ b/tests/run_profiling.py @@ -94,14 +94,13 @@ def log2_range(m): template='''#!/bin/bash #!/bin/bash -#PBS -N VIC_scaling_test_$np +#PBS -N VIC_scaling_test_$i #PBS -q standard #PBS -A NPSCA07935242 #PBS -l application=VIC #PBS -l select=$select:ncpus=36:mpiprocs=$mpiprocs -#PBS -l walltime=04:00:00 +#PBS -l walltime=06:00:00 #PBS -j oe -#PBS -o $WORKDIR # Qsub template for ERDC TOPAZ # Scheduler: PBS @@ -110,8 +109,9 @@ def log2_range(m): START=$(date +%s) mpiexec_mpt -np ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global +END=$(date +%s) DIFF=$(echo "$END - $START" | bc) -printf "%5s | %f" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} +printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} OUT_WIDTH = 100 @@ -217,7 +217,7 @@ def run_scaling(args): run_string = template.safe_substitute( vic_exe=args.vic_exe, vic_global=args.global_param, - timing_table_file=args.timing, **kwargs) + timing_table_file=args.timing, i=i, **kwargs) run_file = 'vic_{host}_{i}.sh'.format(host=args.host, i=i) with open(run_file, 'w') as f: f.write(run_string) @@ -259,7 +259,7 @@ def get_header_info(vic_exe, vic_global): try: header_kwargs['vic_version'] = subprocess.check_output( [vic_exe, '-v']).decode() - except: + except subprocess.CalledProcessError: pass return header_kwargs diff --git a/tests/test_utils.py b/tests/test_utils.py index 61ebee7d1..a260f0262 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -14,6 +14,7 @@ # Plotting libs import matplotlib +matplotlib.use('Agg') import matplotlib.pyplot as plt import seaborn as sns @@ -22,8 +23,6 @@ default_vic_valgrind_error_code) from tonic.testing import check_completed, check_for_nans, VICTestError -matplotlib.use('Agg') - OUTPUT_WIDTH = 100 ERROR_TAIL = 20 # lines @@ -529,7 +528,6 @@ def read_snotel_swe_obs(filename, science_test_data_dir, items): '''Reads in Snotel SWE obs and returns DataFrame. ''' filename_fullpath = os.path.join(science_test_data_dir, - 'science', 'inputdata', items['archive'], 'observations', @@ -556,12 +554,13 @@ def read_vic_42_output(lat, lng, science_test_data_dir, items): if items['compare_to'] == 'ecflux': vic_42_file = 'en_bal_%s_%s' % (lat, lng) - vic_42_dir = os.path.join(science_test_data_dir, 'science', 'archive', + vic_42_dir = os.path.join(science_test_data_dir, 'archive', items['archive'], 'ecflux', 'results') elif items['compare_to'] == 'snotel': vic_42_file = 'outfile_%s_%s' % (lat, lng) - vic_42_dir = os.path.join(science_test_data_dir, 'science', 'archive', + + vic_42_dir = os.path.join(science_test_data_dir, 'archive', items['archive'], 'snotel', 'results') else: @@ -707,7 +706,6 @@ def plot_snotel_comparison(driver, science_test_data_dir, pool = mp.Pool(processes=nproc) for filename in os.listdir(os.path.join(science_test_data_dir, - 'science', 'inputdata', 'snotel', 'observations')): @@ -729,8 +727,10 @@ def plot_snotel_comparison_one_site( result_dir, plot_dir, plots_to_make, plot_variables, context, style, filename): - - # get lat/lng from filename + + print(plots_to_make) + + # get lat/lng from filename file_split = re.split('_', filename) lng = file_split[3].split('.txt')[0] lat = file_split[2] @@ -787,7 +787,7 @@ def plot_snotel_comparison_one_site( plotname = '%s_%s.png' % (lat, lng) savepath = os.path.join(plot_dir, plot_variable, plotname) plt.savefig(savepath, bbox_inches='tight') - + print(savepath) plt.clf() plt.close() @@ -831,7 +831,7 @@ def read_fluxnet_obs(subdir, science_test_data_dir, items): filename = '%s.stdfmt.hourly.local.txt' % subdir # read in data with -9999.0000 as NaNs - obs_dir = os.path.join(science_test_data_dir, 'science', 'inputdata', + obs_dir = os.path.join(science_test_data_dir, 'inputdata', 'ec_flux_towers', 'obs') ecflux_df = pd.read_csv(os.path.join(obs_dir, subdir, filename), skiprows=0, @@ -874,7 +874,6 @@ def plot_fluxnet_comparison(driver, science_test_data_dir, # loop over Ameriflux sites obs_dir = os.path.join(science_test_data_dir, - 'science', 'inputdata', 'ec_flux_towers', 'obs') diff --git a/vic/drivers/shared_all/src/set_output_defaults.c b/vic/drivers/shared_all/src/set_output_defaults.c index 82c4769af..0b53d7a13 100644 --- a/vic/drivers/shared_all/src/set_output_defaults.c +++ b/vic/drivers/shared_all/src/set_output_defaults.c @@ -98,12 +98,12 @@ set_output_defaults(stream_struct **streams, dmy_struct *dmy_current, unsigned short default_file_format) { - extern option_struct options; + extern option_struct options; - size_t streamnum; - size_t varnum; - alarm_struct default_alarm; - int default_freq_n = 1; + size_t streamnum; + size_t varnum; + alarm_struct default_alarm; + int default_freq_n = 1; set_alarm(dmy_current, FREQ_NDAYS, &default_freq_n, &default_alarm); diff --git a/vic/drivers/shared_all/src/vic_time.c b/vic/drivers/shared_all/src/vic_time.c index 144fe742f..0e57407ae 100644 --- a/vic/drivers/shared_all/src/vic_time.c +++ b/vic/drivers/shared_all/src/vic_time.c @@ -859,8 +859,8 @@ time_delta(dmy_struct *dmy_current, // if dmy_next.year is not leap year but date is Feb 29 !) make_lastday(global_param.calendar, dmy_next.year, lastday); dmy_next.day_in_year = 0; - for (i = 0; i < MONTHS_PER_YEAR; i++) { - if ((i + 1) == dmy_next.month) { + for ( i = 0; i < MONTHS_PER_YEAR; i++ ) { + if ( (i+1) == dmy_next.month ) { dmy_next.day_in_year += dmy_next.day; break; } diff --git a/vic/drivers/shared_image/src/parse_output_info.c b/vic/drivers/shared_image/src/parse_output_info.c index 8977eb605..a9f0749a0 100644 --- a/vic/drivers/shared_image/src/parse_output_info.c +++ b/vic/drivers/shared_image/src/parse_output_info.c @@ -35,27 +35,27 @@ parse_output_info(FILE *gp, stream_struct **streams, dmy_struct *dmy_current) { - extern option_struct options; + extern option_struct options; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - char flgstr[MAXSTRING]; - short int streamnum; - char varname[MAXSTRING]; - int outvarnum; - char freq_type_str[MAXSTRING]; - char freq_value_str[MAXSTRING]; - char format[MAXSTRING]; - char typestr[MAXSTRING]; - int type; - char multstr[MAXSTRING]; - char aggstr[MAXSTRING]; - double mult; - unsigned short int freq; - int freq_n; - dmy_struct freq_dmy; - unsigned short int agg_type; - int found; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + char flgstr[MAXSTRING]; + short int streamnum; + char varname[MAXSTRING]; + int outvarnum; + char freq_type_str[MAXSTRING]; + char freq_value_str[MAXSTRING]; + char format[MAXSTRING]; + char typestr[MAXSTRING]; + int type; + char multstr[MAXSTRING]; + char aggstr[MAXSTRING]; + double mult; + unsigned short int freq; + int freq_n; + dmy_struct freq_dmy; + unsigned short int agg_type; + int found; streamnum = -1; diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index b14330e3a..79c34db73 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1677,9 +1677,8 @@ initialize_state_file(char *filename, NC_DOUBLE, ndims, dimids, &(lon_var_id)); check_nc_status(status, "Error defining lon variable in %s", filename); - status = - nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( - "longitude"), "longitude"); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( + "longitude"), "longitude"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( "degrees_east"), "degrees_east"); @@ -1699,9 +1698,8 @@ initialize_state_file(char *filename, NC_DOUBLE, ndims, dimids, &(lat_var_id)); check_nc_status(status, "Error defining lat variable (%s) in %s", global_domain.info.lat_var, filename); - status = - nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( - "latitude"), "latitude"); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( + "latitude"), "latitude"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( "degrees_north"), "degrees_north"); From 2e98728288e436ccff1644aba00d1ff57ee4eea9 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 7 Dec 2016 14:08:10 +0100 Subject: [PATCH 036/294] restructured routing first attemps incl testing --- vic/extensions/rout_rvic/include/rout.h | 11 +- vic/extensions/rout_rvic/src/rout_alloc.c | 2 +- .../rout_rvic/src/rout_convolution.c | 78 ++++++++ .../rout_rvic/src/rout_mpi_gather.c | 2 +- .../rout_rvic/src/rout_mpi_scatter.c | 2 +- vic/extensions/rout_rvic/src/rout_run.c | 187 +++++++++--------- 6 files changed, 185 insertions(+), 97 deletions(-) create mode 100644 vic/extensions/rout_rvic/src/rout_convolution.c diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index dfa4547d5..dbbc2b4d7 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -66,11 +66,12 @@ typedef struct { /****************************************************************************** * @brief Function prototypes for the rout_rvic extension *****************************************************************************/ -void rout_start(void); // read global parameters for routing -void rout_alloc(void); // allocate memory -void rout_init(void); // initialize model parameters from parameter files -void rout_run(void); // run routing over the domain -void rout_finalize(void); // clean up routine for routing +void rout_start(void); // read global parameters for routing +void rout_alloc(void); // allocate memory +void rout_init(void); // initialize model parameters from parameter files +void rout_run(void); // run routing over the domain +void rout_finalize(void); // clean up routine for routing +void convolution(double *, double *); // convolution over the domain /****************************************************************************** * @brief MPI Function prototypes for the rout_rvic extension diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 2723e6d92..06c20d485 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -130,7 +130,7 @@ rout_alloc(void) // Allocate memory for the ring rout.ring = malloc( - rout.rout_param.full_time_length * rout.rout_param.n_outlets * + rout.rout_param.n_timesteps * rout.rout_param.n_outlets * sizeof(*rout.ring)); check_alloc_status(rout.ring, "Memory allocation error."); } diff --git a/vic/extensions/rout_rvic/src/rout_convolution.c b/vic/extensions/rout_rvic/src/rout_convolution.c new file mode 100644 index 000000000..d8dd1a631 --- /dev/null +++ b/vic/extensions/rout_rvic/src/rout_convolution.c @@ -0,0 +1,78 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Convolution part of the routing + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +void +convolution(double *runoff, double *discharge) { + extern rout_struct rout; + extern global_param_struct global_param; + extern domain_struct global_domain; + + size_t i_source; + size_t i_outlet; + size_t i_timestep; + size_t j_timestep; + int offset; /*2d indicies*/ + size_t i_ring; + size_t i_uh; /*1d indicies*/ + + // Zero out current ring + // in python: (from variables.py) self.ring[tracer][0, :] = 0. + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { + rout.ring[i_outlet] = 0.0; + } + + // Equivalent to Fortran 90 cshift function, in python: (from variables.py) + // self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) + cshift(rout.ring, rout.rout_param.n_timesteps, rout.rout_param.n_outlets, 0, 1); +// cshift(rout.ring, rout.rout_param.full_time_length, rout.rout_param.n_outlets, 0, 1); + + /*Loop through all sources*/ + for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { + i_outlet = rout.rout_param.source2outlet_ind[i_source]; + offset = rout.rout_param.source_time_offset[i_source]; + + /* Do the convolution */ + // iTimestep is the position in the unit hydrograph + // jTimestep is the position in the ring + for (i_timestep = 0; i_timestep < rout.rout_param.n_timesteps; + i_timestep++) { + j_timestep = i_timestep + offset; + + // index locations + i_ring = (j_timestep * rout.rout_param.n_outlets) + i_outlet; + i_uh = (i_timestep * rout.rout_param.n_sources) + i_source; + rout.ring[i_ring] += rout.rout_param.unit_hydrograph[i_uh] * + runoff[rout.rout_param.source_VIC_index[i_source]]; + } + } + // Write to discharge prior to scattering over local domains... + for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { + discharge[rout.rout_param.outlet_VIC_index[i_outlet]] = + rout.ring[i_outlet] * global_domain.locations[rout.rout_param.outlet_VIC_index[i_outlet]].area / (MM_PER_M * global_param.dt); + } +} \ No newline at end of file diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c index 605fce23f..d192bd437 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_gather.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_gather.c @@ -1,7 +1,7 @@ /****************************************************************************** * @section DESCRIPTION * - * Allocate memory for Routing structures. + * MPI support routines for Routing * * @section LICENSE * diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c index 0afce0a08..a2f9e49de 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c @@ -1,7 +1,7 @@ /****************************************************************************** * @section DESCRIPTION * - * Allocate memory for Routing structures. + * MPI support routines for Routing * * @section LICENSE * diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 808c8c0cf..1ca1ec779 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -27,116 +27,125 @@ #include /****************************************************************************** -* @brief This subroutine controls the RVIC convolution. -******************************************************************************/ + * @brief This subroutine controls the RVIC convolution. + ******************************************************************************/ void -rout_run(void) -{ - extern int mpi_rank; - extern double ***out_data; - extern global_param_struct global_param; - extern domain_struct local_domain; - extern domain_struct global_domain; - extern rout_struct rout; - double *dvar_global = NULL; - double *dvar_local = NULL; - double *dvar_global_total_runoff = NULL; - double *dvar_local_total_runoff = NULL; - size_t i; - size_t i_source; - size_t i_outlet; - size_t i_timestep; - size_t j_timestep; - int offset; /*2d indicies*/ - size_t i_ring; - size_t i_uh; /*1d indicies*/ - - // Gather runoff and baseflow from local nodes to the masternode - // and add them together in total_runoff - dvar_global_total_runoff = - malloc(global_domain.ncells_total * sizeof(*dvar_global_total_runoff)); - check_alloc_status(dvar_global_total_runoff, "Memory allocation error."); - dvar_local_total_runoff = - malloc(local_domain.ncells_active * sizeof(*dvar_local_total_runoff)); - check_alloc_status(dvar_local_total_runoff, "Memory allocation error."); +rout_run(void) { + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + extern MPI_Comm MPI_COMM_VIC; + + extern double ***out_data; + extern domain_struct local_domain; + extern domain_struct global_domain; + int status; + double *var_local_runoff = NULL; + double *var2 = NULL; + double *dvar = NULL; + double *dvar_runoff = NULL; + double *dvar_filtered = NULL; + double *dvar_mapped = NULL; + double *dvar_gathered = NULL; + double *dvar_remapped = NULL; + size_t i; + + // allocate memory for variables to be read + var_local_runoff = malloc(local_domain.ncells_active * sizeof (*var_local_runoff)); + check_alloc_status(var_local_runoff, "Memory allocation error."); // Read from out_data... for (i = 0; i < local_domain.ncells_active; i++) { - dvar_local_total_runoff[i] = out_data[i][OUT_RUNOFF][0] + - out_data[i][OUT_BASEFLOW][0]; + var_local_runoff[i] = out_data[i][OUT_RUNOFF][0] + + out_data[i][OUT_BASEFLOW][0]; } - gather_put_var_double(dvar_global_total_runoff, dvar_local_total_runoff); + if (mpi_rank == VIC_MPI_ROOT) { + dvar_runoff = malloc(global_domain.ncells_total * sizeof (*dvar_runoff)); + check_alloc_status(dvar_runoff, "Memory allocation error."); + for (i = 0; i < global_domain.ncells_total; i++) { + dvar_runoff[i] = 0.0; + } + dvar_gathered = + malloc(global_domain.ncells_active * sizeof (*dvar_gathered)); + check_alloc_status(dvar_gathered, "Memory allocation error."); + + dvar_remapped = + malloc(global_domain.ncells_active * sizeof (*dvar_remapped)); + check_alloc_status(dvar_remapped, "Memory allocation error."); + } - free(dvar_local_total_runoff); + // Gather the results from the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Gatherv(var_local_runoff, local_domain.ncells_active, MPI_DOUBLE, + dvar_gathered, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); + check_mpi_status(status, "MPI error."); + free(var_local_runoff); + + if (mpi_rank == VIC_MPI_ROOT) { + map(sizeof (double), global_domain.ncells_active, NULL, + mpi_map_mapping_array, dvar_gathered, dvar_remapped); + // expand to full grid size + map(sizeof (double), global_domain.ncells_active, NULL, + filter_active_cells, dvar_remapped, dvar_runoff); + + free(dvar_gathered); + free(dvar_remapped); + } // Do the routing on the master node if (mpi_rank == VIC_MPI_ROOT) { debug("RVIC"); - dvar_global = malloc(global_domain.ncells_total * sizeof(*dvar_global)); - check_alloc_status(dvar_global, "Memory allocation error."); - - // Zero out current ring - // in python: (from variables.py) self.ring[tracer][0, :] = 0. - for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { - rout.ring[i_outlet] = 0.0; + dvar = malloc(global_domain.ncells_total * sizeof (*dvar)); + check_alloc_status(dvar, "Memory allocation error."); + for (i = 0; i < global_domain.ncells_total; i++) { + dvar[i] = 0.0; } - // Equivalent to Fortran 90 cshift function, in python: (from variables.py) - // self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.full_time_length, - rout.rout_param.n_outlets, 0, - 1); - - /*Loop through all sources*/ - for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { - i_outlet = rout.rout_param.source2outlet_ind[i_source]; - offset = rout.rout_param.source_time_offset[i_source]; - - /* Do the convolution */ - // iTimestep is the position in the unit hydrograph - // jTimestep is the position in the ring - for (i_timestep = 0; i_timestep < rout.rout_param.n_timesteps; - i_timestep++) { - j_timestep = i_timestep + offset; - - // index locations - i_ring = (j_timestep * rout.rout_param.n_outlets) + i_outlet; - i_uh = (i_timestep * rout.rout_param.n_sources) + i_source; - - rout.ring[i_ring] += rout.rout_param.unit_hydrograph[i_uh] * - dvar_global_total_runoff[rout.rout_param. - source_VIC_index[ - i_source]]; - } - } + dvar_filtered = + malloc(global_domain.ncells_active * sizeof (*dvar_filtered)); + check_alloc_status(dvar_filtered, "Memory allocation error."); - // Write to dvar_global prior to scattering over local domains... - for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { - dvar_global[rout.rout_param.outlet_VIC_index[i_outlet]] = - rout.ring[i_outlet] * - global_domain.locations[rout.rout_param.outlet_VIC_index[ - i_outlet]].area / - (MM_PER_M * global_param.dt); - } + dvar_mapped = + malloc(global_domain.ncells_active * sizeof (*dvar_mapped)); + check_alloc_status(dvar_mapped, "Memory allocation error."); + + convolution(dvar_runoff, dvar); + + // filter the active cells only + map(sizeof (double), global_domain.ncells_active, filter_active_cells, + NULL, dvar, dvar_filtered); + // map to prepare for MPI_Scatterv + map(sizeof (double), global_domain.ncells_active, mpi_map_mapping_array, + NULL, dvar_filtered, dvar_mapped); - // cleanup - free(dvar_global); + free(dvar); + free(dvar_runoff); + free(dvar_filtered); } + var2 = malloc(local_domain.ncells_active * sizeof (*var2)); + check_alloc_status(var2, "Memory allocation error."); - // Scatter dvar_global to local domains (dvar_local)... - dvar_local = malloc(local_domain.ncells_active * sizeof(*dvar_local)); - check_alloc_status(dvar_local, "Memory allocation error."); + // Scatter the results to the nodes, result for the local node is in the + // array *var (which is a function argument) + status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, + mpi_map_global_array_offsets, MPI_DOUBLE, + var2, local_domain.ncells_active, MPI_DOUBLE, + VIC_MPI_ROOT, MPI_COMM_VIC); + check_mpi_status(status, "MPI error."); - get_scatter_var_double(dvar_global, dvar_local); + if (mpi_rank == VIC_MPI_ROOT) { + free(dvar_mapped); + } // Write to output struct... for (i = 0; i < local_domain.ncells_active; i++) { - out_data[i][OUT_DISCHARGE][0] = dvar_local[i]; + out_data[i][OUT_DISCHARGE][0] = var2[i]; } - - // cleanup - free(dvar_local); - free(dvar_global_total_runoff); + free(var2); } From 47cd411d282503e53ebeb0a6ddc463d7ad9920d0 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 7 Dec 2016 16:17:02 +0100 Subject: [PATCH 037/294] minor changes --- .gitignore | 12 -- vic/drivers/image/Makefile | 2 +- vic/drivers/shared_all/src/history_metadata.c | 20 +-- vic/extensions/rout_rvic/include/rout.h | 4 +- .../rout_rvic/src/rout_convolution.c | 41 +++-- .../rout_rvic/src/rout_mpi_gather.c | 9 +- .../rout_rvic/src/rout_mpi_scatter.c | 6 +- vic/extensions/rout_rvic/src/rout_run.c | 145 ++++++------------ 8 files changed, 89 insertions(+), 150 deletions(-) diff --git a/.gitignore b/.gitignore index 64723e942..5c0ef4d1f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,15 +44,3 @@ TAGS __pycache__ .ipynb_checkpoints .eggs - -# Netbeans stuff -nbproject - -# Test folders -image_test -uncrust.sh -*.exe - -# WUR specific -not4git -samples_wur \ No newline at end of file diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 02dbb86d3..a764a8d96 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -46,7 +46,7 @@ EXTPATH = ../../extensions # |---------- |--------------------------------- | # | rout_stub | Stub routing model (no routing) | # | rout_rvic | Use RVIC routing scheme | -ROUT=rout_rvic +ROUT=rout_stub include ${EXTPATH}/${ROUT}/rout.mk diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index 4a2f85116..e38a39c76 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -164,9 +164,8 @@ set_output_met_data_info() strcpy(out_metadata[OUT_SMFROZFRAC].standard_name, "soil_moisture_ice_fraction"); strcpy(out_metadata[OUT_SMFROZFRAC].units, "1"); - strcpy( - out_metadata[OUT_SMFROZFRAC].description, - "fraction of soil moisture (by mass) that is ice, for each soil layer"); + strcpy(out_metadata[OUT_SMFROZFRAC].description, + "fraction of soil moisture (by mass) that is ice, for each soil layer"); /* fraction of soil moisture (by mass) that is liquid, for each soil layer */ strcpy(out_metadata[OUT_SMLIQFRAC].varname, "OUT_SMLIQFRAC"); @@ -174,9 +173,8 @@ set_output_met_data_info() strcpy(out_metadata[OUT_SMLIQFRAC].standard_name, "soil_moisture_liquid_fraction"); strcpy(out_metadata[OUT_SMLIQFRAC].units, "1"); - strcpy( - out_metadata[OUT_SMLIQFRAC].description, - "fraction of soil moisture (by mass) that is liquid, for each soil layer"); + strcpy(out_metadata[OUT_SMLIQFRAC].description, + "fraction of soil moisture (by mass) that is liquid, for each soil layer"); /* snow interception storage in canopy [mm] */ strcpy(out_metadata[OUT_SNOW_CANOPY].varname, "OUT_SNOW_CANOPY"); @@ -306,9 +304,8 @@ set_output_met_data_info() strcpy(out_metadata[OUT_ZWT_LUMPED].standard_name, "lumped_water_table_position"); strcpy(out_metadata[OUT_ZWT_LUMPED].units, "cm"); - strcpy( - out_metadata[OUT_ZWT_LUMPED].description, - "lumped water table position (zwt of total moisture across all layers, lumped together)"); + strcpy(out_metadata[OUT_ZWT_LUMPED].description, + "lumped water table position (zwt of total moisture across all layers, lumped together)"); // Water Balance Terms - fluxes /* baseflow out of the bottom layer [mm] */ @@ -1032,9 +1029,8 @@ set_output_met_data_info() strcpy(out_metadata[OUT_AERO_RESIST].standard_name, "aerodynamic_resistance"); strcpy(out_metadata[OUT_AERO_RESIST].units, "s m-1"); - strcpy( - out_metadata[OUT_AERO_RESIST].description, - "scene aerodynamic resistance (tiles with overstory contribute overstory resistance; others contribue surface resistance)"); + strcpy(out_metadata[OUT_AERO_RESIST].description, + "scene aerodynamic resistance (tiles with overstory contribute overstory resistance; others contribue surface resistance)"); /* surface aerodynamic resistance [m/s] */ strcpy(out_metadata[OUT_AERO_RESIST1].varname, "OUT_AERO_RESIST1"); diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index dbbc2b4d7..45c0afdc1 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -76,8 +76,8 @@ void convolution(double *, double *); // convolution over the domain /****************************************************************************** * @brief MPI Function prototypes for the rout_rvic extension *****************************************************************************/ -void get_scatter_var_double(double *, double *); -void gather_put_var_double(double *, double *); +void scatter_var_double(double *, double *); +void gather_var_double(double *, double *); /****************************************************************************** * @brief Convolution function adapted from the RVIC scheme diff --git a/vic/extensions/rout_rvic/src/rout_convolution.c b/vic/extensions/rout_rvic/src/rout_convolution.c index d8dd1a631..904e4643f 100644 --- a/vic/extensions/rout_rvic/src/rout_convolution.c +++ b/vic/extensions/rout_rvic/src/rout_convolution.c @@ -2,7 +2,7 @@ * @section DESCRIPTION * * Convolution part of the routing - * + * * @section LICENSE * * The Variable Infiltration Capacity (VIC) macroscale hydrological model @@ -27,18 +27,20 @@ #include void -convolution(double *runoff, double *discharge) { - extern rout_struct rout; +convolution(double *runoff, + double *discharge) +{ + extern rout_struct rout; extern global_param_struct global_param; - extern domain_struct global_domain; + extern domain_struct global_domain; - size_t i_source; - size_t i_outlet; - size_t i_timestep; - size_t j_timestep; - int offset; /*2d indicies*/ - size_t i_ring; - size_t i_uh; /*1d indicies*/ + size_t i_source; + size_t i_outlet; + size_t i_timestep; + size_t j_timestep; + int offset; /*2d indicies*/ + size_t i_ring; + size_t i_uh; /*1d indicies*/ // Zero out current ring // in python: (from variables.py) self.ring[tracer][0, :] = 0. @@ -48,8 +50,9 @@ convolution(double *runoff, double *discharge) { // Equivalent to Fortran 90 cshift function, in python: (from variables.py) // self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) - cshift(rout.ring, rout.rout_param.n_timesteps, rout.rout_param.n_outlets, 0, 1); -// cshift(rout.ring, rout.rout_param.full_time_length, rout.rout_param.n_outlets, 0, 1); + cshift(rout.ring, rout.rout_param.n_timesteps, rout.rout_param.n_outlets, 0, + 1); +// cshift(rout.ring, rout.rout_param.full_time_length, rout.rout_param.n_outlets, 0, 1); /*Loop through all sources*/ for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { @@ -60,19 +63,23 @@ convolution(double *runoff, double *discharge) { // iTimestep is the position in the unit hydrograph // jTimestep is the position in the ring for (i_timestep = 0; i_timestep < rout.rout_param.n_timesteps; - i_timestep++) { + i_timestep++) { j_timestep = i_timestep + offset; // index locations i_ring = (j_timestep * rout.rout_param.n_outlets) + i_outlet; i_uh = (i_timestep * rout.rout_param.n_sources) + i_source; rout.ring[i_ring] += rout.rout_param.unit_hydrograph[i_uh] * - runoff[rout.rout_param.source_VIC_index[i_source]]; + runoff[rout.rout_param.source_VIC_index[ + i_source]]; } } // Write to discharge prior to scattering over local domains... for (i_outlet = 0; i_outlet < rout.rout_param.n_outlets; i_outlet++) { discharge[rout.rout_param.outlet_VIC_index[i_outlet]] = - rout.ring[i_outlet] * global_domain.locations[rout.rout_param.outlet_VIC_index[i_outlet]].area / (MM_PER_M * global_param.dt); + rout.ring[i_outlet] * + global_domain.locations[rout.rout_param.outlet_VIC_index[i_outlet]] + .area + / (MM_PER_M * global_param.dt); } -} \ No newline at end of file +} diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c index d192bd437..d6b0f1d16 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_gather.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_gather.c @@ -31,8 +31,8 @@ * @details Values are gathered to the master node *****************************************************************************/ void -gather_put_var_double(double *dvar, - double *var_local) +gather_var_double(double *dvar, + double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -50,7 +50,6 @@ gather_put_var_double(double *dvar, if (mpi_rank == VIC_MPI_ROOT) { grid_size = global_domain.n_nx * global_domain.n_ny; - for (i = 0; i < grid_size; i++) { dvar[i] = 0; } @@ -63,13 +62,15 @@ gather_put_var_double(double *dvar, malloc(global_domain.ncells_active * sizeof(*dvar_remapped)); check_alloc_status(dvar_remapped, "Memory allocation error."); } + // Gather the results from the nodes, result for the local node is in the // array *var (which is a function argument) - status = MPI_Gatherv(var_local, local_domain.ncells_active, MPI_DOUBLE, + status = MPI_Gatherv(var, local_domain.ncells_active, MPI_DOUBLE, dvar_gathered, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, VIC_MPI_ROOT, MPI_COMM_VIC); check_mpi_status(status, "MPI error."); + if (mpi_rank == VIC_MPI_ROOT) { // remap the array map(sizeof(double), global_domain.ncells_active, NULL, diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c index a2f9e49de..77fe04612 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c @@ -31,8 +31,8 @@ * @details values from master node are scattered to the local nodes *****************************************************************************/ void -get_scatter_var_double(double *dvar, - double *var_local) +scatter_var_double(double *dvar, + double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -68,7 +68,7 @@ get_scatter_var_double(double *dvar, // array *var (which is a function argument) status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, - var_local, local_domain.ncells_active, MPI_DOUBLE, + var, local_domain.ncells_active, MPI_DOUBLE, VIC_MPI_ROOT, MPI_COMM_VIC); check_mpi_status(status, "MPI error."); diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 1ca1ec779..1131a64aa 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -27,125 +27,72 @@ #include /****************************************************************************** - * @brief This subroutine controls the RVIC convolution. - ******************************************************************************/ +* @brief This subroutine controls the RVIC convolution. +******************************************************************************/ void -rout_run(void) { - extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - extern MPI_Comm MPI_COMM_VIC; - - extern double ***out_data; +rout_run(void) +{ + extern int mpi_rank; + extern double ***out_data; extern domain_struct local_domain; extern domain_struct global_domain; - int status; - double *var_local_runoff = NULL; - double *var2 = NULL; - double *dvar = NULL; - double *dvar_runoff = NULL; - double *dvar_filtered = NULL; - double *dvar_mapped = NULL; - double *dvar_gathered = NULL; - double *dvar_remapped = NULL; - size_t i; + double *var_local_runoff = NULL; + double *var_local_discharge = NULL; + double *dvar_runoff = NULL; + double *dvar_discharge = NULL; + size_t i; + + debug("RVIC"); - // allocate memory for variables to be read - var_local_runoff = malloc(local_domain.ncells_active * sizeof (*var_local_runoff)); + // Allocate memory for the local_domain variables + var_local_runoff = + malloc(local_domain.ncells_active * sizeof(*var_local_runoff)); check_alloc_status(var_local_runoff, "Memory allocation error."); - // Read from out_data... - for (i = 0; i < local_domain.ncells_active; i++) { - var_local_runoff[i] = out_data[i][OUT_RUNOFF][0] + - out_data[i][OUT_BASEFLOW][0]; - } + var_local_discharge = + malloc(local_domain.ncells_active * sizeof(*var_local_discharge)); + check_alloc_status(var_local_discharge, "Memory allocation error."); + + // Allocate memory for entire global_domain variables on the master node if (mpi_rank == VIC_MPI_ROOT) { - dvar_runoff = malloc(global_domain.ncells_total * sizeof (*dvar_runoff)); + dvar_runoff = malloc(global_domain.ncells_total * sizeof(*dvar_runoff)); check_alloc_status(dvar_runoff, "Memory allocation error."); - for (i = 0; i < global_domain.ncells_total; i++) { - dvar_runoff[i] = 0.0; - } - dvar_gathered = - malloc(global_domain.ncells_active * sizeof (*dvar_gathered)); - check_alloc_status(dvar_gathered, "Memory allocation error."); - dvar_remapped = - malloc(global_domain.ncells_active * sizeof (*dvar_remapped)); - check_alloc_status(dvar_remapped, "Memory allocation error."); + dvar_discharge = + malloc(global_domain.ncells_total * sizeof(*dvar_discharge)); + check_alloc_status(dvar_discharge, "Memory allocation error."); } - // Gather the results from the nodes, result for the local node is in the - // array *var (which is a function argument) - status = MPI_Gatherv(var_local_runoff, local_domain.ncells_active, MPI_DOUBLE, - dvar_gathered, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); - check_mpi_status(status, "MPI error."); - free(var_local_runoff); - - if (mpi_rank == VIC_MPI_ROOT) { - map(sizeof (double), global_domain.ncells_active, NULL, - mpi_map_mapping_array, dvar_gathered, dvar_remapped); - // expand to full grid size - map(sizeof (double), global_domain.ncells_active, NULL, - filter_active_cells, dvar_remapped, dvar_runoff); - - free(dvar_gathered); - free(dvar_remapped); + // Read from runoff and baseflow from out_data and sum to runoff + for (i = 0; i < local_domain.ncells_active; i++) { + var_local_runoff[i] = out_data[i][OUT_RUNOFF][0] + + out_data[i][OUT_BASEFLOW][0]; } - // Do the routing on the master node - if (mpi_rank == VIC_MPI_ROOT) { - debug("RVIC"); - - dvar = malloc(global_domain.ncells_total * sizeof (*dvar)); - check_alloc_status(dvar, "Memory allocation error."); - for (i = 0; i < global_domain.ncells_total; i++) { - dvar[i] = 0.0; - } + // Gather the runoff for the local nodes + gather_var_double(dvar_runoff, var_local_runoff); - dvar_filtered = - malloc(global_domain.ncells_active * sizeof (*dvar_filtered)); - check_alloc_status(dvar_filtered, "Memory allocation error."); - - dvar_mapped = - malloc(global_domain.ncells_active * sizeof (*dvar_mapped)); - check_alloc_status(dvar_mapped, "Memory allocation error."); - - convolution(dvar_runoff, dvar); + // Run the convolution on the master node + if (mpi_rank == VIC_MPI_ROOT) { + convolution(dvar_runoff, dvar_discharge); + } - // filter the active cells only - map(sizeof (double), global_domain.ncells_active, filter_active_cells, - NULL, dvar, dvar_filtered); - // map to prepare for MPI_Scatterv - map(sizeof (double), global_domain.ncells_active, mpi_map_mapping_array, - NULL, dvar_filtered, dvar_mapped); + // Scatter the discharge back to the local nodes + scatter_var_double(dvar_discharge, var_local_discharge); - free(dvar); - free(dvar_runoff); - free(dvar_filtered); + // Write to output struct... + for (i = 0; i < local_domain.ncells_active; i++) { + out_data[i][OUT_DISCHARGE][0] = var_local_discharge[i]; } - var2 = malloc(local_domain.ncells_active * sizeof (*var2)); - check_alloc_status(var2, "Memory allocation error."); - // Scatter the results to the nodes, result for the local node is in the - // array *var (which is a function argument) - status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - var2, local_domain.ncells_active, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); - check_mpi_status(status, "MPI error."); + // Free variables on the local nodes + free(var_local_runoff); + free(var_local_discharge); + // Free variables on the master node if (mpi_rank == VIC_MPI_ROOT) { - free(dvar_mapped); - } - - // Write to output struct... - for (i = 0; i < local_domain.ncells_active; i++) { - out_data[i][OUT_DISCHARGE][0] = var2[i]; + free(dvar_runoff); + free(dvar_discharge); } - free(var2); } From a48acee97a7fc38b29e010491ba8aaf0de7ae00c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 7 Dec 2016 16:40:44 +0100 Subject: [PATCH 038/294] Added rvic_stub to the makefile of the CESM driver to solve compilation errors --- docs/Development/ReleaseNotes.md | 5 +++++ vic/drivers/cesm/Makefile | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index a5d52aefb..3b4dd7e92 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -19,6 +19,11 @@ To check which release of VIC you are running: **Release date: (Unreleased)** +#### New Features: + +1. Added rvic river routing module in the image driver. + + Documentation for the routing module can be found [here](../Documentation/Drivers/Image/Routing.md). ------------------------------ diff --git a/vic/drivers/cesm/Makefile b/vic/drivers/cesm/Makefile index 41029ed94..1c5ecbf39 100644 --- a/vic/drivers/cesm/Makefile +++ b/vic/drivers/cesm/Makefile @@ -57,6 +57,12 @@ else MPIPATH = /opt/local endif +# VIC EXTENTIONS PATH +EXTPATH = ../../extensions + +# Set the routing model extension +include ${EXTPATH}/rout_stub/rout.mk + # Set SHELL = your shell here SHELL = /bin/bash @@ -82,6 +88,7 @@ INCLUDES = -I ${DRIVERPATH}/include \ -I ${SHAREDPATH}/include \ -I ${SHAREDIMAGEPATH}/include \ -I ${NETCDFPATH}/include \ + -I ${EXTPATH}/rout_stub/include # Set libraries LIBRARY = -lm -L${NETCDFPATH}/lib -lnetcdf @@ -118,13 +125,15 @@ HDRS = \ $(wildcard ${VICPATH}/include/*.h) \ $(wildcard ${DRIVERPATH}/include/*.h) \ $(wildcard ${SHAREDPATH}/include/*.h) \ - $(wildcard ${SHAREDIMAGEPATH}/include/*.h) + $(wildcard ${SHAREDIMAGEPATH}/include/*.h) \ + $(wildcard ${EXTPATH}/rout_stub/include/*.h) CSRCS = \ $(wildcard ${VICPATH}/src/*.c) \ $(wildcard ${DRIVERPATH}/src/*.c) \ $(wildcard ${SHAREDPATH}/src/*.c) \ - $(wildcard ${SHAREDIMAGEPATH}/src/*.c) + $(wildcard ${SHAREDIMAGEPATH}/src/*.c) \ + $(wildcard ${EXTPATH}/rout_stub/src/*.c) FSRCS = \ $(wildcard ${DRIVERPATH}/src/*.F90) From d3aef9fa4a37c3e71c28750ca9f0a4aca20ba58a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 7 Dec 2016 16:45:11 +0100 Subject: [PATCH 039/294] fixed redirection in Inputs.md --- docs/Documentation/Drivers/Image/Inputs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Documentation/Drivers/Image/Inputs.md b/docs/Documentation/Drivers/Image/Inputs.md index de0bf12b4..5971f1a70 100644 --- a/docs/Documentation/Drivers/Image/Inputs.md +++ b/docs/Documentation/Drivers/Image/Inputs.md @@ -13,4 +13,4 @@ And a few more are optional: * [Constants File](../../Constants.md): Model parameters that are constant in time and space. * [Initial State File](StateFile.md): Moisture storages (soil moisture, snow pack, etc), energy storages (soil temperatures, etc) and other information describing the current state of the system. A state file saved from a previous VIC simulation may be used as the initial state for another run. * [Lake/Wetland Parameter File](LakeParam.md): File containing lake model parameters. By default, VIC does not simulate lakes or other impoundment of surface water. -* [Routing Parameter File](RvicParam.md): File containing the parameters necessary to perform the Lohmann routing. Note that by default, VIC does not perform any streamflow routing. +* [Routing Parameter File](Routing.md): File containing the parameters necessary to perform the Lohmann routing. Note that by default, VIC does not perform any streamflow routing. From c7b0875c986f919fda159cea316a7b62ee945dd3 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 8 Dec 2016 10:38:12 +0100 Subject: [PATCH 040/294] added some info for the travis test system --- tests/system/global.image.STEHE.mpi.rvic.txt | 74 ++++++++++++++++++++ tests/system/system_tests.cfg | 9 +++ 2 files changed, 83 insertions(+) create mode 100644 tests/system/global.image.STEHE.mpi.rvic.txt diff --git a/tests/system/global.image.STEHE.mpi.rvic.txt b/tests/system/global.image.STEHE.mpi.rvic.txt new file mode 100644 index 000000000..a93a3f1ba --- /dev/null +++ b/tests/system/global.image.STEHE.mpi.rvic.txt @@ -0,0 +1,74 @@ +NODES 3 +MODEL_STEPS_PER_DAY 24 +SNOW_STEPS_PER_DAY 24 +RUNOFF_STEPS_PER_DAY 24 +STARTYEAR 1949 +STARTMONTH 1 +STARTDAY 1 +ENDYEAR 1949 +ENDMONTH 1 +ENDDAY 10 +CALENDAR PROLEPTIC_GREGORIAN +FULL_ENERGY FALSE +FROZEN_SOIL FALSE + +DOMAIN $test_data_dir/image/Stehekin/parameters/domain.stehekin.20151028.nc +DOMAIN_TYPE LAT lat +DOMAIN_TYPE LON lon +DOMAIN_TYPE MASK mask +DOMAIN_TYPE AREA area +DOMAIN_TYPE FRAC frac +DOMAIN_TYPE YDIM lat +DOMAIN_TYPE XDIM lon + +#INIT_STATE +STATENAME $state_dir/states +STATEYEAR 1949 +STATEMONTH 1 +STATEDAY 11 +STATESEC 0 + +FORCING1 $test_data_dir/image/Stehekin/forcings/Stehekin_image_test.forcings_10days. +FORCE_TYPE AIR_TEMP tas +FORCE_TYPE PREC prcp +FORCE_TYPE PRESSURE pres +FORCE_TYPE SWDOWN dswrf +FORCE_TYPE LWDOWN dlwrf +FORCE_TYPE VP vp +FORCE_TYPE WIND wind +WIND_H 10.0 + +PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc +BASEFLOW ARNO +JULY_TAVG_SUPPLIED FALSE +ORGANIC_FRACT FALSE +LAI_SRC FROM_VEGPARAM +SNOW_BAND TRUE + +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + +RESULT_DIR $result_dir + +OUTFILE fluxes +AGGFREQ NHOURS 1 +OUTVAR OUT_PREC +OUTVAR OUT_RAINF +OUTVAR OUT_SNOWF +OUTVAR OUT_AIR_TEMP +OUTVAR OUT_SWDOWN +OUTVAR OUT_LWDOWN +OUTVAR OUT_PRESSURE +OUTVAR OUT_WIND +OUTVAR OUT_DENSITY +OUTVAR OUT_REL_HUMID +OUTVAR OUT_QAIR +OUTVAR OUT_VP +OUTVAR OUT_VPD +OUTVAR OUT_RUNOFF +OUTVAR OUT_BASEFLOW +OUTVAR OUT_EVAP +OUTVAR OUT_SWE +OUTVAR OUT_SOIL_MOIST +OUTVAR OUT_ALBEDO +OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_DISCHARGE diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index a03d8a7c7..8f4ca5034 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -247,3 +247,12 @@ check = driver_match FULL_ENERGY=FALSE FROZEN_SOIL=FALSE +[System-mpi-rvic_image_check_identical_results] +test_description = check that multi-processor runs produce identical results - image driver with rvic routing enabled +driver = image +global_parameter_file = global.image.STEHE.mpi.rvic.txt +expected_retval = 0 +check = mpi +[[mpi]] +# A list of number of processors to run and compare (need at least a list of two numbers) +n_proc = 1,4 From fdb0b5bd13cb9e3525760a7f6241467a84b643bc Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 12 Dec 2016 09:31:27 +0100 Subject: [PATCH 041/294] changed naming of local and domain variables in rvic --- .../rout_rvic/src/rout_convolution.c | 1 - .../rout_rvic/src/rout_mpi_gather.c | 4 +-- .../rout_rvic/src/rout_mpi_scatter.c | 4 +-- vic/extensions/rout_rvic/src/rout_run.c | 26 +++++++++---------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/vic/extensions/rout_rvic/src/rout_convolution.c b/vic/extensions/rout_rvic/src/rout_convolution.c index 904e4643f..e10d30a3a 100644 --- a/vic/extensions/rout_rvic/src/rout_convolution.c +++ b/vic/extensions/rout_rvic/src/rout_convolution.c @@ -52,7 +52,6 @@ convolution(double *runoff, // self.ring[tracer] = np.roll(self.ring[tracer], -1, axis=0) cshift(rout.ring, rout.rout_param.n_timesteps, rout.rout_param.n_outlets, 0, 1); -// cshift(rout.ring, rout.rout_param.full_time_length, rout.rout_param.n_outlets, 0, 1); /*Loop through all sources*/ for (i_source = 0; i_source < rout.rout_param.n_sources; i_source++) { diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c index d6b0f1d16..943075880 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_gather.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_gather.c @@ -32,7 +32,7 @@ *****************************************************************************/ void gather_var_double(double *dvar, - double *var) + double *local_var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -65,7 +65,7 @@ gather_var_double(double *dvar, // Gather the results from the nodes, result for the local node is in the // array *var (which is a function argument) - status = MPI_Gatherv(var, local_domain.ncells_active, MPI_DOUBLE, + status = MPI_Gatherv(local_var, local_domain.ncells_active, MPI_DOUBLE, dvar_gathered, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, VIC_MPI_ROOT, MPI_COMM_VIC); diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c index 77fe04612..6788c5901 100644 --- a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c +++ b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c @@ -32,7 +32,7 @@ *****************************************************************************/ void scatter_var_double(double *dvar, - double *var) + double *local_var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -68,7 +68,7 @@ scatter_var_double(double *dvar, // array *var (which is a function argument) status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, mpi_map_global_array_offsets, MPI_DOUBLE, - var, local_domain.ncells_active, MPI_DOUBLE, + local_var, local_domain.ncells_active, MPI_DOUBLE, VIC_MPI_ROOT, MPI_COMM_VIC); check_mpi_status(status, "MPI error."); diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 1131a64aa..989aacc99 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -38,8 +38,8 @@ rout_run(void) extern domain_struct global_domain; double *var_local_runoff = NULL; double *var_local_discharge = NULL; - double *dvar_runoff = NULL; - double *dvar_discharge = NULL; + double *var_domain_runoff = NULL; + double *var_domain_discharge = NULL; size_t i; debug("RVIC"); @@ -56,12 +56,12 @@ rout_run(void) // Allocate memory for entire global_domain variables on the master node if (mpi_rank == VIC_MPI_ROOT) { - dvar_runoff = malloc(global_domain.ncells_total * sizeof(*dvar_runoff)); - check_alloc_status(dvar_runoff, "Memory allocation error."); + var_domain_runoff = malloc(global_domain.ncells_total * sizeof(*var_domain_runoff)); + check_alloc_status(var_domain_runoff, "Memory allocation error."); - dvar_discharge = - malloc(global_domain.ncells_total * sizeof(*dvar_discharge)); - check_alloc_status(dvar_discharge, "Memory allocation error."); + var_domain_discharge = + malloc(global_domain.ncells_total * sizeof(*var_domain_discharge)); + check_alloc_status(var_domain_discharge, "Memory allocation error."); } // Read from runoff and baseflow from out_data and sum to runoff @@ -71,17 +71,17 @@ rout_run(void) } // Gather the runoff for the local nodes - gather_var_double(dvar_runoff, var_local_runoff); + gather_var_double(var_domain_runoff, var_local_runoff); // Run the convolution on the master node if (mpi_rank == VIC_MPI_ROOT) { - convolution(dvar_runoff, dvar_discharge); + convolution(var_domain_runoff, var_domain_discharge); } // Scatter the discharge back to the local nodes - scatter_var_double(dvar_discharge, var_local_discharge); + scatter_var_double(var_domain_discharge, var_local_discharge); - // Write to output struct... + // Write to output struct for (i = 0; i < local_domain.ncells_active; i++) { out_data[i][OUT_DISCHARGE][0] = var_local_discharge[i]; } @@ -92,7 +92,7 @@ rout_run(void) // Free variables on the master node if (mpi_rank == VIC_MPI_ROOT) { - free(dvar_runoff); - free(dvar_discharge); + free(var_domain_runoff); + free(var_domain_discharge); } } From 72fe8e65ee6d9b9ce612bed23d4c0b74b980d347 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 12 Dec 2016 10:38:15 +0100 Subject: [PATCH 042/294] added rvic to travis (first try) --- .travis.yml | 14 +++++++++++++- ci/image.travis | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 59d8a85e8..e6cad1da8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,18 @@ matrix: - gfortran - valgrind # open-mpi is built from source in image.travis + # Image Driver with rvic-routing + - compiler: gcc + os: linux + env: TESTID='image' EXTENSIONS='ROUT=rout_rvic' + addons: + apt_packages: + - libnetcdf-dev + - netcdf-bin + - netcdf-doc + - gfortran + - valgrind + # open-mpi is built from source in image.travis # CESM Driver - compiler: gcc os: linux @@ -83,7 +95,7 @@ before_install: - install_miniconda - vic_before_install install: - - vic_install + - vic_install ${ROUT} before_script: - vic_before_script script: diff --git a/ci/image.travis b/ci/image.travis index c0d022fe2..cf97bffb8 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -61,7 +61,7 @@ function vic_install { echo vic_install cd ${TRAVIS_BUILD_DIR} echo $PWD - make full -C $DRIVER_PATH + make full $EXTENSIONS -C $DRIVER_PATH } function vic_before_script { From aad5031e1ef919b3e3d2436e169b3e921c385a8e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 12 Dec 2016 11:22:30 +0100 Subject: [PATCH 043/294] added routing doc --- docs/Documentation/Drivers/Image/Routing.md | 31 +++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/Documentation/Drivers/Image/Routing.md b/docs/Documentation/Drivers/Image/Routing.md index f6548d240..b50475f62 100644 --- a/docs/Documentation/Drivers/Image/Routing.md +++ b/docs/Documentation/Drivers/Image/Routing.md @@ -1,7 +1,28 @@ -# Routing +# Routing -The routing process is done in two steps: Generation unit hydrograph (ref) and the convolution (ref) -* The unit hydrograph is generated separately with the RVIC streamflow routing model. This RVIC is a stand alone python program see: http://rvic.readthedocs.io/en/latest/. -* Convolution is calculated in VIC itself (if routing is enabled in the makefile) and uses the parameter file generated in step 1 +There are two routing options available: rout_stub (default) and rout_rvic. -VIC needs the parameter file generated in step 1. In formation how to generate this file can be found at http://rvic.readthedocs.io/en/latest/user-guide/parameters/. +## Option: rout_stub + +Option rout_stub is the default option. During compilation the routing module is left empty: VIC can thus not be used for routing and consequently no discharge will be calculated. + +## Option: rout_rvic + +Option rout_rvic is optional. + +The routing process is done in two steps: Generation unit hydrograph and the convolution +* The unit hydrograph is generated separately with the RVIC streamflow routing model. This RVIC is a stand alone python program see: http://rvic.readthedocs.io/en/latest/. VIC is tested with RVIC version 1.1.0. +* Convolution is calculated in VIC itself (if routing is enabled in the makefile) and uses the RVIC-parameter file generated in the step mentioned above. + +### Running: rout_rvic + +This option can be enabled by adding the following commandline option to the `make`: +`make ROUT=rout_rvic` + +VIC needs the RVIC-parameter file. In formation how to generate this file can be found at http://rvic.readthedocs.io/en/latest/user-guide/parameters/. Note that the domain (lat-lon information and mask) of the RVIC-parameter file must match with the one of the VIC domain. + +The RIVC-parameter file must be set in the [Global Parameter File](GlobalParam.md) e.g.: +`ROUT_PARAM RVIC_params.nc # Routing parameter path/file` + +An extra output has to be set in the [Global Parameter File](GlobalParam.md): +`OUTVAR OUT_DISCHARGE` From c630944e8bfc6ea1011ec7dec889e0e4f2e99faf Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 14 Dec 2016 14:30:57 +0100 Subject: [PATCH 044/294] added statefile functionality for rvic --- .../include/vic_driver_shared_all.h | 1 + .../include/vic_driver_shared_image.h | 4 ++ vic/drivers/shared_image/src/state_metadata.c | 10 +++++ vic/drivers/shared_image/src/vic_restore.c | 27 +++++++++++++ vic/drivers/shared_image/src/vic_store.c | 39 +++++++++++++++++++ vic/extensions/rout_stub/include/rout.h | 13 +++++++ vic/extensions/rout_stub/src/rout.c | 12 ++++++ 7 files changed, 106 insertions(+) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index f5121457b..0ba13bb93 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -312,6 +312,7 @@ enum STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ + STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 8257b1249..1a172640f 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -120,6 +120,8 @@ typedef struct { int ni_dimid; int nj_dimid; int node_dimid; + int outlet_dimid; + int routing_timestep_dimid; int root_zone_dimid; int time_dimid; int time_bounds_dimid; @@ -134,6 +136,8 @@ typedef struct { size_t ni_size; size_t nj_size; size_t node_size; + size_t outlet_size; + size_t routing_timestep_size; size_t root_zone_size; size_t time_size; size_t veg_size; diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c index 5ed707d55..eaae28633 100644 --- a/vic/drivers/shared_image/src/state_metadata.c +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -232,6 +232,16 @@ set_state_meta_data_info() strcpy(state_metadata[STATE_SNOW_CANOPY].description, "snow interception storage in canopy"); + // STATE_ROUT_RING + strcpy(state_metadata[STATE_ROUT_RING].varname, + "STATE_ROUT_RING"); + strcpy(state_metadata[STATE_ROUT_RING].long_name, "routing_ring"); + strcpy(state_metadata[STATE_ROUT_RING].standard_name, + "routing_ring"); + strcpy(state_metadata[STATE_ROUT_RING].units, "-"); + strcpy(state_metadata[STATE_ROUT_RING].description, + "unit hydrographs in the routing ring"); + // STATE_SOIL_NODE_TEMP strcpy(state_metadata[STATE_SOIL_NODE_TEMP].varname, "STATE_SOIL_NODE_TEMP"); diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index c86fce08b..a413b8f96 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Read initial model state. @@ -39,6 +40,8 @@ vic_restore(void) extern veg_con_map_struct *veg_con_map; extern filenames_struct filenames; extern metadata_struct state_metadata[N_STATE_VARS]; + extern int mpi_rank; + extern rout_struct rout; int v; size_t i; @@ -48,6 +51,7 @@ vic_restore(void) size_t p; int *ivar = NULL; double *dvar = NULL; + size_t d2count_rout[2]; size_t d2count[2]; size_t d2start[2]; size_t d3count[3]; @@ -117,6 +121,18 @@ vic_restore(void) d6count[4] = global_domain.n_ny; d6count[5] = global_domain.n_nx; + // routing ring + if (mpi_rank == VIC_MPI_ROOT) { + d2start[0] = 0; + d2start[1] = 0; + d2count_rout[0] = rout.rout_param.n_timesteps; + d2count_rout[1] = rout.rout_param.n_outlets; + + get_nc_field_double(filenames.init_state, + state_metadata[STATE_ROUT_RING].varname, + d2start, d2count_rout, rout.ring); + } + // total soil moisture for (m = 0; m < options.NVEGTYPES; m++) { d5start[0] = m; @@ -880,6 +896,7 @@ check_init_state_file(void) extern domain_struct global_domain; extern option_struct options; extern soil_con_struct *soil_con; + extern rout_struct rout; int status; size_t dimlen; @@ -936,6 +953,16 @@ check_init_state_file(void) log_err("Number of soil nodes in state file does not " "match parameter file"); } + dimlen = get_nc_dimension(filenames.init_state, "outlet"); + if (dimlen != rout.rout_param.n_outlets) { + log_err("Number of outlets in state file does not " + "match routing parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, "routing_timestep"); + if (dimlen != rout.rout_param.n_timesteps) { + log_err("Number of routing timesteps in state file does not " + "match routing parameter file"); + } if (options.LAKES) { dimlen = get_nc_dimension(filenames.init_state, "lake_node"); if (dimlen != options.NLAKENODES) { diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 79c34db73..09e1e2c15 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Save model state. @@ -40,6 +41,7 @@ vic_store(dmy_struct *dmy_current, extern veg_con_map_struct *veg_con_map; extern int mpi_rank; extern global_param_struct global_param; + extern rout_struct rout; int status; int v; @@ -116,6 +118,19 @@ vic_store(dmy_struct *dmy_current, dvar[i] = nc_state_file.d_fillvalue; } + // routing ring + if (mpi_rank == VIC_MPI_ROOT) { + d2start[0] = 0; + d2start[1] = 0; + nc_var = &(nc_state_file.nc_vars[STATE_ROUT_RING]); + + status = + nc_put_vara_double(nc_state_file.nc_id, nc_var->nc_varid, d2start, + nc_var->nc_counts, + rout.ring); + check_nc_status(status, "Error writing values."); + } + // total soil moisture nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); for (m = 0; m < options.NVEGTYPES; m++) { @@ -1278,6 +1293,7 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) { extern option_struct options; extern domain_struct global_domain; + extern rout_struct rout; // Set fill values nc_state_file->c_fillvalue = NC_FILL_CHAR; @@ -1296,6 +1312,8 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->ni_dimid = MISSING; nc_state_file->nj_dimid = MISSING; nc_state_file->node_dimid = MISSING; + nc_state_file->outlet_dimid = MISSING; + nc_state_file->routing_timestep_dimid = MISSING; nc_state_file->root_zone_dimid = MISSING; nc_state_file->time_dimid = MISSING; nc_state_file->veg_dimid = MISSING; @@ -1308,6 +1326,8 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->ni_size = global_domain.n_nx; nc_state_file->nj_size = global_domain.n_ny; nc_state_file->node_size = options.Nnode; + nc_state_file->outlet_size = rout.rout_param.n_outlets; + nc_state_file->routing_timestep_size = rout.rout_param.n_timesteps; nc_state_file->root_zone_size = options.ROOT_ZONES; nc_state_file->time_size = NC_UNLIMITED; nc_state_file->veg_size = options.NVEGTYPES; @@ -1410,6 +1430,14 @@ set_nc_state_var_info(nc_file_struct *nc) nc->nc_vars[i].nc_counts[2] = nc->nj_size; nc->nc_vars[i].nc_counts[3] = nc->ni_size; break; + case STATE_ROUT_RING: + // 2d vars [routing_timestep, outlet] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->routing_timestep_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->outlet_dimid; + nc->nc_vars[i].nc_counts[0] = nc->routing_timestep_size; + nc->nc_vars[i].nc_counts[1] = nc->outlet_size; + break; case STATE_SOIL_NODE_TEMP: // 5d vars [veg, band, node, j, i] nc->nc_vars[i].nc_dims = 5; @@ -1635,6 +1663,17 @@ initialize_state_file(char *filename, &(nc_state_file->node_dimid)); check_nc_status(status, "Error defining soil_node in %s", filename); + // Add routing dimensions + status = nc_def_dim(nc_state_file->nc_id, "outlet", + nc_state_file->outlet_size, + &(nc_state_file->outlet_dimid)); + check_nc_status(status, "Error defining outlet in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", + nc_state_file->routing_timestep_size, + &(nc_state_file->routing_timestep_dimid)); + check_nc_status(status, "Error defining routing_timestep in %s", filename); + if (options.LAKES) { status = nc_def_dim(nc_state_file->nc_id, "lake_node", nc_state_file->lake_node_size, diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index df1c656d8..f4917d2e0 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -29,10 +29,23 @@ #define ROUT_EXT "rout_stub" +#include +#include + +/****************************************************************************** + * @brief Routing Structs + *****************************************************************************/ +typedef struct { + size_t n_timesteps; /*scalar - number of timesteps*/ + size_t n_outlets; /*scalar - length of subset*/ +} rout_param_struct; + /****************************************************************************** * @brief main routing Struct *****************************************************************************/ typedef struct { + rout_param_struct rout_param; + double ring[1]; } rout_struct; /****************************************************************************** diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 993a9f2e4..a1d76148f 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -35,9 +35,21 @@ rout_start(void) /****************************************************************************** * @brief Allocate memory. *****************************************************************************/ +#include + void rout_alloc(void) { + extern int mpi_rank; + if (mpi_rank == VIC_MPI_ROOT) { + extern rout_struct rout; + + // We need to write at least something to the VIC state file (if enabled). + // Therefore we make the dimension size 1*1. + rout.rout_param.n_outlets = 1; + rout.rout_param.n_timesteps = 1; + rout.ring[1] = 0; + } } /****************************************************************************** From 8652ef11dfadc8f251a823abf00b135a412e5ee4 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 15 Dec 2016 14:08:42 +0100 Subject: [PATCH 045/294] removed vic_driver_image.h include in rout_stub in order to avoid compilation errors in de cesm driver --- vic/extensions/rout_stub/include/rout.h | 1 - vic/extensions/rout_stub/src/rout.c | 19 ++++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index f4917d2e0..b9bfea199 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -30,7 +30,6 @@ #define ROUT_EXT "rout_stub" #include -#include /****************************************************************************** * @brief Routing Structs diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index a1d76148f..8b5cf9d8d 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -24,6 +24,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ +#include + /****************************************************************************** * @brief Read global parameters for routing. *****************************************************************************/ @@ -35,21 +37,16 @@ rout_start(void) /****************************************************************************** * @brief Allocate memory. *****************************************************************************/ -#include - void rout_alloc(void) { - extern int mpi_rank; - if (mpi_rank == VIC_MPI_ROOT) { - extern rout_struct rout; + extern rout_struct rout; - // We need to write at least something to the VIC state file (if enabled). - // Therefore we make the dimension size 1*1. - rout.rout_param.n_outlets = 1; - rout.rout_param.n_timesteps = 1; - rout.ring[1] = 0; - } + // We need to write at least something to the VIC state file (if enabled). + // Therefore we make the dimension size 1*1. + rout.rout_param.n_outlets = 1; + rout.rout_param.n_timesteps = 1; + rout.ring[1] = 0; } /****************************************************************************** From 95f5a7cb782bdb259d7cbe39d1055a9f24f9e82c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 15 Dec 2016 14:41:58 +0100 Subject: [PATCH 046/294] travis: rvic test --- tests/system/global.image.STEHE.mpi.rvic.txt | 74 -------------------- tests/system/global.image.STEHE.rvic.txt | 74 ++++++++++++++++++++ tests/system/system_tests.cfg | 13 ++-- 3 files changed, 80 insertions(+), 81 deletions(-) delete mode 100644 tests/system/global.image.STEHE.mpi.rvic.txt create mode 100644 tests/system/global.image.STEHE.rvic.txt diff --git a/tests/system/global.image.STEHE.mpi.rvic.txt b/tests/system/global.image.STEHE.mpi.rvic.txt deleted file mode 100644 index a93a3f1ba..000000000 --- a/tests/system/global.image.STEHE.mpi.rvic.txt +++ /dev/null @@ -1,74 +0,0 @@ -NODES 3 -MODEL_STEPS_PER_DAY 24 -SNOW_STEPS_PER_DAY 24 -RUNOFF_STEPS_PER_DAY 24 -STARTYEAR 1949 -STARTMONTH 1 -STARTDAY 1 -ENDYEAR 1949 -ENDMONTH 1 -ENDDAY 10 -CALENDAR PROLEPTIC_GREGORIAN -FULL_ENERGY FALSE -FROZEN_SOIL FALSE - -DOMAIN $test_data_dir/image/Stehekin/parameters/domain.stehekin.20151028.nc -DOMAIN_TYPE LAT lat -DOMAIN_TYPE LON lon -DOMAIN_TYPE MASK mask -DOMAIN_TYPE AREA area -DOMAIN_TYPE FRAC frac -DOMAIN_TYPE YDIM lat -DOMAIN_TYPE XDIM lon - -#INIT_STATE -STATENAME $state_dir/states -STATEYEAR 1949 -STATEMONTH 1 -STATEDAY 11 -STATESEC 0 - -FORCING1 $test_data_dir/image/Stehekin/forcings/Stehekin_image_test.forcings_10days. -FORCE_TYPE AIR_TEMP tas -FORCE_TYPE PREC prcp -FORCE_TYPE PRESSURE pres -FORCE_TYPE SWDOWN dswrf -FORCE_TYPE LWDOWN dlwrf -FORCE_TYPE VP vp -FORCE_TYPE WIND wind -WIND_H 10.0 - -PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -BASEFLOW ARNO -JULY_TAVG_SUPPLIED FALSE -ORGANIC_FRACT FALSE -LAI_SRC FROM_VEGPARAM -SNOW_BAND TRUE - -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc - -RESULT_DIR $result_dir - -OUTFILE fluxes -AGGFREQ NHOURS 1 -OUTVAR OUT_PREC -OUTVAR OUT_RAINF -OUTVAR OUT_SNOWF -OUTVAR OUT_AIR_TEMP -OUTVAR OUT_SWDOWN -OUTVAR OUT_LWDOWN -OUTVAR OUT_PRESSURE -OUTVAR OUT_WIND -OUTVAR OUT_DENSITY -OUTVAR OUT_REL_HUMID -OUTVAR OUT_QAIR -OUTVAR OUT_VP -OUTVAR OUT_VPD -OUTVAR OUT_RUNOFF -OUTVAR OUT_BASEFLOW -OUTVAR OUT_EVAP -OUTVAR OUT_SWE -OUTVAR OUT_SOIL_MOIST -OUTVAR OUT_ALBEDO -OUTVAR OUT_SOIL_TEMP -OUTVAR OUT_DISCHARGE diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt new file mode 100644 index 000000000..e2907b766 --- /dev/null +++ b/tests/system/global.image.STEHE.rvic.txt @@ -0,0 +1,74 @@ +MODEL_STEPS_PER_DAY 24 +SNOW_STEPS_PER_DAY 24 +RUNOFF_STEPS_PER_DAY 24 + +STARTYEAR 1949 +STARTMONTH 1 +STARTDAY 1 +ENDYEAR 1949 +ENDMONTH 1 +ENDDAY 10 +CALENDAR PROLEPTIC_GREGORIAN + +FULL_ENERGY TRUE +FROZEN_SOIL FALSE + +#INIT_STATE +STATENAME $state_dir/states +STATEYEAR 1949 +STATEMONTH 1 +STATEDAY 11 +STATESEC 0 + +DOMAIN $test_data_dir/image/Stehekin/parameters/domain.stehekin.20151028.nc +DOMAIN_TYPE LAT lat +DOMAIN_TYPE LON lon +DOMAIN_TYPE MASK mask +DOMAIN_TYPE AREA area +DOMAIN_TYPE FRAC frac +DOMAIN_TYPE YDIM lat +DOMAIN_TYPE XDIM lon + +FORCING1 $test_data_dir/image/Stehekin/forcings/Stehekin_image_test.forcings_10days. +FORCE_TYPE AIR_TEMP tas +FORCE_TYPE PREC prcp +FORCE_TYPE PRESSURE pres +FORCE_TYPE SWDOWN dswrf +FORCE_TYPE LWDOWN dlwrf +FORCE_TYPE VP vp +FORCE_TYPE WIND wind +WIND_H 10.0 + +PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc +SNOW_BAND TRUE +NODES 3 +BASEFLOW ARNO +JULY_TAVG_SUPPLIED FALSE +ORGANIC_FRACT FALSE + +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + +RESULT_DIR $result_dir/ + +OUTFILE fluxes +AGGFREQ NHOURS 1 +OUTVAR OUT_PREC +OUTVAR OUT_RAINF +OUTVAR OUT_SNOWF +OUTVAR OUT_AIR_TEMP +OUTVAR OUT_SWDOWN +OUTVAR OUT_LWDOWN +OUTVAR OUT_PRESSURE +OUTVAR OUT_WIND +OUTVAR OUT_DENSITY +OUTVAR OUT_REL_HUMID +OUTVAR OUT_QAIR +OUTVAR OUT_VP +OUTVAR OUT_VPD +OUTVAR OUT_RUNOFF +OUTVAR OUT_BASEFLOW +OUTVAR OUT_EVAP +OUTVAR OUT_SWE +OUTVAR OUT_SOIL_MOIST +OUTVAR OUT_ALBEDO +OUTVAR OUT_SOIL_TEMP diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 8f4ca5034..d457ec763 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -247,12 +247,11 @@ check = driver_match FULL_ENERGY=FALSE FROZEN_SOIL=FALSE -[System-mpi-rvic_image_check_identical_results] -test_description = check that multi-processor runs produce identical results - image driver with rvic routing enabled +[System-check-image-and-rvic] +test_description = image driver with rvic routing enabled driver = image -global_parameter_file = global.image.STEHE.mpi.rvic.txt +global_parameter_file = global.image.STEHE.rvic.txt +domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc +mpi_proc = 4 expected_retval = 0 -check = mpi -[[mpi]] -# A list of number of processors to run and compare (need at least a list of two numbers) -n_proc = 1,4 +check = output_file_nans From 7061c61665397d8f067ef7c6f719627211a6c14a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 15 Dec 2016 17:12:15 +0100 Subject: [PATCH 047/294] travis: rvic test2 --- tests/system/system_tests.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index d457ec763..2a1aa9059 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -254,4 +254,4 @@ global_parameter_file = global.image.STEHE.rvic.txt domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc mpi_proc = 4 expected_retval = 0 -check = output_file_nans +check = nonans From 64df89d464bdf64ba00d9a3f5981d602f00fb154 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 11:11:10 +0100 Subject: [PATCH 048/294] Update readme.md --- vic/extensions/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/extensions/readme.md b/vic/extensions/readme.md index 40e5ee85d..d8b242a97 100644 --- a/vic/extensions/readme.md +++ b/vic/extensions/readme.md @@ -1 +1 @@ -Future home of VIC extension modules +Future home of VIC extension modules. From 4ce67739a62c672d106997ef34afb8813028de71 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 11:38:25 +0100 Subject: [PATCH 049/294] test path --- .../{global.image.STEHE.rvic.txt => global.image.STEHE.rvicc.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/system/{global.image.STEHE.rvic.txt => global.image.STEHE.rvicc.txt} (100%) diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvicc.txt similarity index 100% rename from tests/system/global.image.STEHE.rvic.txt rename to tests/system/global.image.STEHE.rvicc.txt From 3b326c8101c71fa688ad644ad888c25987c363ce Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 11:56:08 +0100 Subject: [PATCH 050/294] test path2 --- ci/image.travis | 2 +- ...global.image.STEHE.rvicc.txt => global.image.STEHE.rvic.txt} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/system/{global.image.STEHE.rvicc.txt => global.image.STEHE.rvic.txt} (100%) diff --git a/ci/image.travis b/ci/image.travis index cf97bffb8..eb3521690 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -80,7 +80,7 @@ function vic_script { echo vic_script $DRIVER_EXE -v $DRIVER_EXE -o - + tree $TRAVIS_BUILD_DIR # Run test package ./tests/run_tests.py unit examples system \ --image=${DRIVER_EXE} \ diff --git a/tests/system/global.image.STEHE.rvicc.txt b/tests/system/global.image.STEHE.rvic.txt similarity index 100% rename from tests/system/global.image.STEHE.rvicc.txt rename to tests/system/global.image.STEHE.rvic.txt From 97ac60b5d1d780422176bf0c8ebda4486af1e372 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 12:14:36 +0100 Subject: [PATCH 051/294] test path3 --- ci/image.travis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/image.travis b/ci/image.travis index eb3521690..abb3fd0e9 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -80,7 +80,7 @@ function vic_script { echo vic_script $DRIVER_EXE -v $DRIVER_EXE -o - tree $TRAVIS_BUILD_DIR + ls -R $TRAVIS_BUILD_DIR # Run test package ./tests/run_tests.py unit examples system \ --image=${DRIVER_EXE} \ From ddac192b4fdbd55a486bd98f5ca54a9167a4ffd2 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 12:41:18 +0100 Subject: [PATCH 052/294] test path4 --- ci/image.travis | 4 +++- vic/extensions/rout_rvic/src/rout_alloc.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/image.travis b/ci/image.travis index abb3fd0e9..d275e26ab 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -80,7 +80,9 @@ function vic_script { echo vic_script $DRIVER_EXE -v $DRIVER_EXE -o - ls -R $TRAVIS_BUILD_DIR + ls -R $SAMPLES_PATH + echo "TESTT" + ls -ltr $SAMPLES_PATH"/data/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc" # Run test package ./tests/run_tests.py unit examples system \ --image=${DRIVER_EXE} \ diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 06c20d485..891f04fda 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -44,6 +44,7 @@ rout_alloc(void) d1start[0] = 1; // Get some values and dimensions + printf("FILENAME RVIC: %s\n", rout.param_filename); get_nc_field_int(rout.param_filename, "full_time_length", d1start, From b3d01a1ed41aabe93752366189e361a93d592396 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 12:59:34 +0100 Subject: [PATCH 053/294] test path5 --- ci/image.travis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/image.travis b/ci/image.travis index d275e26ab..8efbe95e3 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -80,7 +80,7 @@ function vic_script { echo vic_script $DRIVER_EXE -v $DRIVER_EXE -o - ls -R $SAMPLES_PATH + #ls -R $SAMPLES_PATH echo "TESTT" ls -ltr $SAMPLES_PATH"/data/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc" # Run test package From c0b04297283fa6d5bd3cb22ac54ef51ea391d918 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 13:15:31 +0100 Subject: [PATCH 054/294] test path6 --- vic/drivers/shared_image/src/get_nc_field.c | 1 + vic/extensions/rout_rvic/src/rout_alloc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index af3d48ea7..b42170084 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -109,6 +109,7 @@ get_nc_field_int(char *nc_name, int var_id; // open the netcdf file + log_info("FILENAME: %s\n", nc_name); status = nc_open(nc_name, NC_NOWRITE, &nc_id); check_nc_status(status, "Error opening %s", nc_name); diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 891f04fda..7f90f1820 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -44,7 +44,7 @@ rout_alloc(void) d1start[0] = 1; // Get some values and dimensions - printf("FILENAME RVIC: %s\n", rout.param_filename); + log_info("FILENAME RVIC: %s\n", rout.param_filename); get_nc_field_int(rout.param_filename, "full_time_length", d1start, From 92fed0a916ab4f7ac58187d0a9160e4d1419b211 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 13:32:02 +0100 Subject: [PATCH 055/294] Update global.image.STEHE.rvic.txt --- tests/system/global.image.STEHE.rvic.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt index e2907b766..2fb4f236c 100644 --- a/tests/system/global.image.STEHE.rvic.txt +++ b/tests/system/global.image.STEHE.rvic.txt @@ -46,7 +46,7 @@ BASEFLOW ARNO JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_20150727.nc RESULT_DIR $result_dir/ From 2bf90eed1d32546f1986b37ff7262108a50cd291 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 13:50:38 +0100 Subject: [PATCH 056/294] test path8 --- tests/system/global.image.STEHE.rvic.txt | 2 +- vic/extensions/rout_rvic/src/rout_start.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt index 2fb4f236c..e2907b766 100644 --- a/tests/system/global.image.STEHE.rvic.txt +++ b/tests/system/global.image.STEHE.rvic.txt @@ -46,7 +46,7 @@ BASEFLOW ARNO JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_20150727.nc +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc RESULT_DIR $result_dir/ diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 3856f1c22..b1580c583 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -73,6 +73,7 @@ get_global_param_rout(FILE *gp) *************************************/ if (strcasecmp("ROUT_PARAM", optstr) == 0) { sscanf(cmdstr, "%*s %s", rout.param_filename); + log_info("ROUT_PARAM: %s\n", rout.param_filename); break; } } From f744fd4a50219c5d775c03874da32e52ba4bb943 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 14:05:08 +0100 Subject: [PATCH 057/294] test path9 --- vic/extensions/rout_rvic/src/rout_start.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index b1580c583..16ed25603 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -36,9 +36,13 @@ rout_start(void) extern filep_struct filep; extern int mpi_rank; + log_info("CHECK-1...\n"); + if (mpi_rank == VIC_MPI_ROOT) { // read global settings filep.globalparam = open_file(filenames.global, "r"); + log_info("CHECK0...\n"); + get_global_param_rout(filep.globalparam); } } @@ -53,6 +57,8 @@ get_global_param_rout(FILE *gp) extern rout_struct rout; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; + + log_info("CHECK1...\n"); /** Read through global control file to find parameters **/ rewind(gp); @@ -61,6 +67,7 @@ get_global_param_rout(FILE *gp) while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); + log_info("CHECK2...\n"); /* Handle case of comment line in which '#' is indented */ if (optstr[0] == '#') { @@ -72,6 +79,8 @@ get_global_param_rout(FILE *gp) Get Model Global Parameters *************************************/ if (strcasecmp("ROUT_PARAM", optstr) == 0) { + log_info("CHECK3...\n"); + sscanf(cmdstr, "%*s %s", rout.param_filename); log_info("ROUT_PARAM: %s\n", rout.param_filename); break; From 61e5fb5d03061ce4fd9d403c9bc6e138fcae5c6a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 14:23:28 +0100 Subject: [PATCH 058/294] test path10 --- vic/extensions/rout_rvic/src/rout_start.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 16ed25603..748d3d1cb 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -36,13 +36,9 @@ rout_start(void) extern filep_struct filep; extern int mpi_rank; - log_info("CHECK-1...\n"); - if (mpi_rank == VIC_MPI_ROOT) { // read global settings filep.globalparam = open_file(filenames.global, "r"); - log_info("CHECK0...\n"); - get_global_param_rout(filep.globalparam); } } @@ -58,8 +54,6 @@ get_global_param_rout(FILE *gp) char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; - log_info("CHECK1...\n"); - /** Read through global control file to find parameters **/ rewind(gp); fgets(cmdstr, MAXSTRING, gp); @@ -67,7 +61,7 @@ get_global_param_rout(FILE *gp) while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); - log_info("CHECK2...\n"); + log_info("CHECK2...: %s\n", optstr); /* Handle case of comment line in which '#' is indented */ if (optstr[0] == '#') { From d055a4f5872bed15e7da3a3d226d051e620c7c5c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 14:41:38 +0100 Subject: [PATCH 059/294] test path11 --- vic/extensions/rout_rvic/src/rout_start.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 748d3d1cb..0b66e173f 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -55,7 +55,8 @@ get_global_param_rout(FILE *gp) char optstr[MAXSTRING]; /** Read through global control file to find parameters **/ - rewind(gp); +// rewind(gp); + fseek(gp, 0 , SEEK_SET); fgets(cmdstr, MAXSTRING, gp); while (!feof(gp)) { From ad9d6ebc11f4b4abe4235b5e7da86f5156efec20 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 14:53:35 +0100 Subject: [PATCH 060/294] test path12 --- vic/extensions/rout_rvic/src/rout_start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 0b66e173f..fa9cc0f42 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -62,7 +62,7 @@ get_global_param_rout(FILE *gp) while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); - log_info("CHECK2...: %s\n", optstr); + log_warn("CHECK2...: %s\n", optstr); /* Handle case of comment line in which '#' is indented */ if (optstr[0] == '#') { From 6edadf8085470395b41786788fd202b1ebba438d Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 15:08:07 +0100 Subject: [PATCH 061/294] test path13 --- vic/extensions/rout_rvic/src/rout_start.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index fa9cc0f42..61333d20e 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -65,10 +65,10 @@ get_global_param_rout(FILE *gp) log_warn("CHECK2...: %s\n", optstr); /* Handle case of comment line in which '#' is indented */ - if (optstr[0] == '#') { - fgets(cmdstr, MAXSTRING, gp); - continue; - } +// if (optstr[0] == '#') { +// fgets(cmdstr, MAXSTRING, gp); +// continue; +// } /************************************* Get Model Global Parameters From 5ffb336cdb1d94e4de6fc210d256d5c262697acd Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 15:32:35 +0100 Subject: [PATCH 062/294] test path14 --- vic/extensions/rout_rvic/src/rout_start.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 61333d20e..9c04905a3 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -62,13 +62,13 @@ get_global_param_rout(FILE *gp) while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); - log_warn("CHECK2...: %s\n", optstr); - +// log_warn("CHECK2...: %s", optstr); + printf("%s ** ", optstr); /* Handle case of comment line in which '#' is indented */ -// if (optstr[0] == '#') { -// fgets(cmdstr, MAXSTRING, gp); -// continue; -// } + if (optstr[0] == '#') { + fgets(cmdstr, MAXSTRING, gp); + continue; + } /************************************* Get Model Global Parameters From b1a5292ecfe1918a9cb99303461e358a1a78571f Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 16 Jan 2017 15:50:09 +0100 Subject: [PATCH 063/294] test path15 --- tests/system/global.image.STEHE.rvic.txt | 4 ++-- vic/extensions/rout_rvic/src/rout_start.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt index e2907b766..bc0168936 100644 --- a/tests/system/global.image.STEHE.rvic.txt +++ b/tests/system/global.image.STEHE.rvic.txt @@ -46,8 +46,6 @@ BASEFLOW ARNO JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc - RESULT_DIR $result_dir/ OUTFILE fluxes @@ -72,3 +70,5 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP + +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index 9c04905a3..fd271b60f 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -62,8 +62,8 @@ get_global_param_rout(FILE *gp) while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); -// log_warn("CHECK2...: %s", optstr); - printf("%s ** ", optstr); + log_warn("CHECK2...: %s", optstr); +// printf("%s ** ", optstr); /* Handle case of comment line in which '#' is indented */ if (optstr[0] == '#') { fgets(cmdstr, MAXSTRING, gp); From d66cd3eaa45e4ebbda766d58b4d21978c19fe34f Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 18 Jan 2017 13:13:08 +0100 Subject: [PATCH 064/294] test path revert temporal changes --- ci/image.travis | 4 +--- tests/system/global.image.STEHE.rvic.txt | 4 ++-- vic/drivers/shared_image/src/get_nc_field.c | 1 - vic/extensions/readme.md | 2 +- vic/extensions/rout_rvic/src/rout_alloc.c | 1 - vic/extensions/rout_rvic/src/rout_start.c | 11 +++-------- 6 files changed, 7 insertions(+), 16 deletions(-) diff --git a/ci/image.travis b/ci/image.travis index 8efbe95e3..cf97bffb8 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -80,9 +80,7 @@ function vic_script { echo vic_script $DRIVER_EXE -v $DRIVER_EXE -o - #ls -R $SAMPLES_PATH - echo "TESTT" - ls -ltr $SAMPLES_PATH"/data/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc" + # Run test package ./tests/run_tests.py unit examples system \ --image=${DRIVER_EXE} \ diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt index bc0168936..e2907b766 100644 --- a/tests/system/global.image.STEHE.rvic.txt +++ b/tests/system/global.image.STEHE.rvic.txt @@ -46,6 +46,8 @@ BASEFLOW ARNO JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir/ OUTFILE fluxes @@ -70,5 +72,3 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP - -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index b42170084..af3d48ea7 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -109,7 +109,6 @@ get_nc_field_int(char *nc_name, int var_id; // open the netcdf file - log_info("FILENAME: %s\n", nc_name); status = nc_open(nc_name, NC_NOWRITE, &nc_id); check_nc_status(status, "Error opening %s", nc_name); diff --git a/vic/extensions/readme.md b/vic/extensions/readme.md index d8b242a97..40e5ee85d 100644 --- a/vic/extensions/readme.md +++ b/vic/extensions/readme.md @@ -1 +1 @@ -Future home of VIC extension modules. +Future home of VIC extension modules diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 7f90f1820..06c20d485 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -44,7 +44,6 @@ rout_alloc(void) d1start[0] = 1; // Get some values and dimensions - log_info("FILENAME RVIC: %s\n", rout.param_filename); get_nc_field_int(rout.param_filename, "full_time_length", d1start, diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c index fd271b60f..3856f1c22 100644 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ b/vic/extensions/rout_rvic/src/rout_start.c @@ -53,17 +53,15 @@ get_global_param_rout(FILE *gp) extern rout_struct rout; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; - + /** Read through global control file to find parameters **/ -// rewind(gp); - fseek(gp, 0 , SEEK_SET); + rewind(gp); fgets(cmdstr, MAXSTRING, gp); while (!feof(gp)) { if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { sscanf(cmdstr, "%s", optstr); - log_warn("CHECK2...: %s", optstr); -// printf("%s ** ", optstr); + /* Handle case of comment line in which '#' is indented */ if (optstr[0] == '#') { fgets(cmdstr, MAXSTRING, gp); @@ -74,10 +72,7 @@ get_global_param_rout(FILE *gp) Get Model Global Parameters *************************************/ if (strcasecmp("ROUT_PARAM", optstr) == 0) { - log_info("CHECK3...\n"); - sscanf(cmdstr, "%*s %s", rout.param_filename); - log_info("ROUT_PARAM: %s\n", rout.param_filename); break; } } From 563489c0f8965ea8b493dc49970fb626d66078e4 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 10 Jun 2016 15:19:18 -0700 Subject: [PATCH 065/294] initial commit of openmp threading --- vic/drivers/image/Makefile | 1 + vic/drivers/shared_image/include/vic_mpi.h | 1 + vic/drivers/shared_image/src/vic_image_run.c | 1 + 3 files changed, 3 insertions(+) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index b80455cd4..e70b9223b 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -75,6 +75,7 @@ INCLUDES = -I ${DRIVERPATH}/include \ # Uncomment to include debugging information CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ + - fopenmp \ -DLOG_LVL=$(LOG_LVL) \ -DGIT_VERSION=\"$(GIT_VERSION)\" \ -DUSERNAME=\"$(USER)\" \ diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index c72d5131e..32096dd93 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -29,6 +29,7 @@ #include #include +#include #define VIC_MPI_ROOT 0 diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index 56bccf520..c419afa98 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -55,6 +55,7 @@ vic_image_run(dmy_struct *dmy_current) sprint_dmy(dmy_str, dmy_current); debug("Running timestep %zu: %s", current, dmy_str); + #pragma omp parallel for private(i,vic_run_ref_str) for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) sprintf(vic_run_ref_str, "Gridcell io_idx: %zu, timestep info: %s", From a65650de0ca8abd131d871d8aff40da2d3fb5ebd Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 26 Jan 2017 12:49:34 +0100 Subject: [PATCH 066/294] hoi --- tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/README.md b/tests/README.md index e6b1d6d4d..21224363a 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,5 +1,5 @@ VIC Test Suite -======= +======= This is the VIC Test Suite. There are six main test types: From dc24fa3a20f48392f044b32fb9849c7353ced001 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 26 Jan 2017 12:52:54 +0100 Subject: [PATCH 067/294] hoi --- .travis.yml | 59 --------- tests/system/system_tests.cfg | 240 ---------------------------------- 2 files changed, 299 deletions(-) diff --git a/.travis.yml b/.travis.yml index e6cad1da8..c5c0738de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,65 +30,6 @@ matrix: - gfortran - valgrind # open-mpi is built from source in image.travis - # CESM Driver - - compiler: gcc - os: linux - env: TESTID='cesm' - addons: - apt_packages: - - libnetcdf-dev - - netcdf-bin - - netcdf-doc - - gfortran - # open-mpi is built from source in cesm.travis - # Classic Driver - - compiler: clang - os: linux - env: TESTID='classic' - addons: - apt_packages: - - valgrind - sources: - - ubuntu-toolchain-r-test - - compiler: gcc - os: linux - env: TESTID='classic' - addons: - apt_packages: - - valgrind - sources: - - ubuntu-toolchain-r-test - - compiler: gcc - os: linux - env: TESTID=classic USE_CC=gcc-5 - addons: - apt: - packages: - - gcc-5 - - gcc-5-multilib - - linux-libc-dev:i386 - - valgrind - sources: - - ubuntu-toolchain-r-test - - compiler: clang - os: linux - env: TESTID=classic USE_CC=clang-3.6 - addons: - apt: - packages: - - clang-3.6 - - valgrind - sources: - - llvm-toolchain-precise-3.6 - - ubuntu-toolchain-r-test - - compiler: gcc - os: osx - env: TESTID=classic BREW_INSTALLS=valgrind - allow_failures: - # OSX build moved to allowed failures because throughput was so slow on travis - - compiler: gcc - os: osx - env: TESTID=classic BREW_INSTALLS=valgrind before_install: - source ci/vic_install_utils - source ci/${TESTID}.travis diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 2a1aa9059..be22e51df 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -7,246 +7,6 @@ mpi_proc = 4 expected_retval = 0 check = output_file_nans -[System-check_classic_nans] -driver = classic -test_description = Short simulation to ensure system tests configuration works - classic driver -global_parameter_file = global.classic.STEHE.txt -expected_retval = 0 -check = output_file_nans - -[System-restart_classic_noFullEnergy_noFrozenSoil] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -# If test_type == exact_restart -# Full period - start and end date -# Full period run will start with no initial state file, and the last time step state will be saved -start_date = 1949-01-01 -end_date = 1949-01-10 -# Dates to split the run -# E.g., if the full running period is 1949-01-01 to 1949-01-10, and split at 1949-01-05, then the first run would be 1949-01-01 to 1949-01-05, the second run would be 1949-01-06 to 1949-01-10 -# There can be multiple splitting dates -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - -[System-restart_classic_FullEnergy_noFrozenSoil] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE - -[System-restart_classic_noFullEnergy_FrozenSoil] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_classic_FullEnergy_FrozenSoil] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_classic_noFullEnergy_noFrozenSoil_BinState] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE -STATE_FORMAT=BINARY - -[System-restart_classic_FullEnergy_noFrozenSoil_BinState] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE -STATE_FORMAT=BINARY - -[System-restart_classic_noFullEnergy_FrozenSoil_BinState] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 -STATE_FORMAT=BINARY - -[System-restart_classic_FullEnergy_FrozenSoil_BinState] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 -STATE_FORMAT=BINARY - -[System-restart_image_noFullEnergy_noFrozenSoil] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - -[System-restart_image_FullEnergy_noFrozenSoil] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE - -[System-restart_image_noFullEnergy_FrozenSoil] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_image_FullEnergy_FrozenSoil] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 - -[System-streams_classic_compare_to_instantaneous] -test_description = Test that the stream averaging is working expected. -driver = classic -global_parameter_file = global.classic.STEHE.multistream.txt -expected_retval = 0 -check = multistream - -[System-streams_classic_all_output_vars] -test_description = Test that all output variables can be successfully written to a stream -driver = classic -global_parameter_file = global.classic.STEHE.allhistvars.txt -expected_retval = 0 -check = nonans - -[System-streams_image_compare_to_instantaneous] -test_description = Test that the stream averaging is working expected. -driver = image -global_parameter_file = global.image.STEHE.multistream.txt -expected_retval = 0 -check = multistream, nonans - -[System-streams_image_all_output_vars] -test_description = Test that all output variables can be successfully written to a stream -driver = image -global_parameter_file = global.image.STEHE.allhistvars.txt -expected_retval = 0 -check = nonans - -[System-mpi_image_check_identical_results] -test_description = check that multi-processor runs produce identical results - image driver -driver = image -global_parameter_file = global.image.STEHE.mpi.txt -expected_retval = 0 -check = mpi -[[mpi]] -# A list of number of processors to run and compare (need at least a list of two numbers) -n_proc = 1,4 - -[System-drivers_match] -test_description = Test whether classic driver and image driver produce similar results -driver = classic,image -# A list of global parameter template files; in the order corresponding to "driver" specified above -global_parameter_file = global.classic.STEHE.txt,global.image.STEHE.txt -expected_retval = 0 -check = driver_match -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - [System-check-image-and-rvic] test_description = image driver with rvic routing enabled driver = image From 01372d58cb88df0bc7ed84e8da139224c6504a61 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 26 Jan 2017 13:05:57 +0100 Subject: [PATCH 068/294] hoi --- .travis.yml | 59 +++++++++ tests/system/system_tests.cfg | 240 ++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) diff --git a/.travis.yml b/.travis.yml index c5c0738de..e6cad1da8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,65 @@ matrix: - gfortran - valgrind # open-mpi is built from source in image.travis + # CESM Driver + - compiler: gcc + os: linux + env: TESTID='cesm' + addons: + apt_packages: + - libnetcdf-dev + - netcdf-bin + - netcdf-doc + - gfortran + # open-mpi is built from source in cesm.travis + # Classic Driver + - compiler: clang + os: linux + env: TESTID='classic' + addons: + apt_packages: + - valgrind + sources: + - ubuntu-toolchain-r-test + - compiler: gcc + os: linux + env: TESTID='classic' + addons: + apt_packages: + - valgrind + sources: + - ubuntu-toolchain-r-test + - compiler: gcc + os: linux + env: TESTID=classic USE_CC=gcc-5 + addons: + apt: + packages: + - gcc-5 + - gcc-5-multilib + - linux-libc-dev:i386 + - valgrind + sources: + - ubuntu-toolchain-r-test + - compiler: clang + os: linux + env: TESTID=classic USE_CC=clang-3.6 + addons: + apt: + packages: + - clang-3.6 + - valgrind + sources: + - llvm-toolchain-precise-3.6 + - ubuntu-toolchain-r-test + - compiler: gcc + os: osx + env: TESTID=classic BREW_INSTALLS=valgrind + allow_failures: + # OSX build moved to allowed failures because throughput was so slow on travis + - compiler: gcc + os: osx + env: TESTID=classic BREW_INSTALLS=valgrind before_install: - source ci/vic_install_utils - source ci/${TESTID}.travis diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index be22e51df..2a1aa9059 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -7,6 +7,246 @@ mpi_proc = 4 expected_retval = 0 check = output_file_nans +[System-check_classic_nans] +driver = classic +test_description = Short simulation to ensure system tests configuration works - classic driver +global_parameter_file = global.classic.STEHE.txt +expected_retval = 0 +check = output_file_nans + +[System-restart_classic_noFullEnergy_noFrozenSoil] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +# If test_type == exact_restart +# Full period - start and end date +# Full period run will start with no initial state file, and the last time step state will be saved +start_date = 1949-01-01 +end_date = 1949-01-10 +# Dates to split the run +# E.g., if the full running period is 1949-01-01 to 1949-01-10, and split at 1949-01-05, then the first run would be 1949-01-01 to 1949-01-05, the second run would be 1949-01-06 to 1949-01-10 +# There can be multiple splitting dates +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + +[System-restart_classic_FullEnergy_noFrozenSoil] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE + +[System-restart_classic_noFullEnergy_FrozenSoil] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_classic_FullEnergy_FrozenSoil] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_classic_noFullEnergy_noFrozenSoil_BinState] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE +STATE_FORMAT=BINARY + +[System-restart_classic_FullEnergy_noFrozenSoil_BinState] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE +STATE_FORMAT=BINARY + +[System-restart_classic_noFullEnergy_FrozenSoil_BinState] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 +STATE_FORMAT=BINARY + +[System-restart_classic_FullEnergy_FrozenSoil_BinState] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 +STATE_FORMAT=BINARY + +[System-restart_image_noFullEnergy_noFrozenSoil] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + +[System-restart_image_FullEnergy_noFrozenSoil] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE + +[System-restart_image_noFullEnergy_FrozenSoil] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_image_FullEnergy_FrozenSoil] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 + +[System-streams_classic_compare_to_instantaneous] +test_description = Test that the stream averaging is working expected. +driver = classic +global_parameter_file = global.classic.STEHE.multistream.txt +expected_retval = 0 +check = multistream + +[System-streams_classic_all_output_vars] +test_description = Test that all output variables can be successfully written to a stream +driver = classic +global_parameter_file = global.classic.STEHE.allhistvars.txt +expected_retval = 0 +check = nonans + +[System-streams_image_compare_to_instantaneous] +test_description = Test that the stream averaging is working expected. +driver = image +global_parameter_file = global.image.STEHE.multistream.txt +expected_retval = 0 +check = multistream, nonans + +[System-streams_image_all_output_vars] +test_description = Test that all output variables can be successfully written to a stream +driver = image +global_parameter_file = global.image.STEHE.allhistvars.txt +expected_retval = 0 +check = nonans + +[System-mpi_image_check_identical_results] +test_description = check that multi-processor runs produce identical results - image driver +driver = image +global_parameter_file = global.image.STEHE.mpi.txt +expected_retval = 0 +check = mpi +[[mpi]] +# A list of number of processors to run and compare (need at least a list of two numbers) +n_proc = 1,4 + +[System-drivers_match] +test_description = Test whether classic driver and image driver produce similar results +driver = classic,image +# A list of global parameter template files; in the order corresponding to "driver" specified above +global_parameter_file = global.classic.STEHE.txt,global.image.STEHE.txt +expected_retval = 0 +check = driver_match +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + [System-check-image-and-rvic] test_description = image driver with rvic routing enabled driver = image From fe521399b7b947295b200c0a762d25a094406c18 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 12:12:05 +0100 Subject: [PATCH 069/294] little test --- ci/requirements.yml | 2 ++ mkdocs.yml | 1 + tests/system/system_tests.cfg | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/ci/requirements.yml b/ci/requirements.yml index a7caa8514..d13b1ce93 100644 --- a/ci/requirements.yml +++ b/ci/requirements.yml @@ -1,4 +1,6 @@ name: vic_test_env +channels: + - conda-forge dependencies: - python=3.5 - numpy diff --git a/mkdocs.yml b/mkdocs.yml index 1c9107ef7..c989432a5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -64,6 +64,7 @@ pages: - 'Inputs': 'Documentation/Drivers/Image/Inputs.md' - 'Outputs': 'Documentation/Drivers/Image/Outputs.md' - 'Params': 'Documentation/Drivers/Image/Params.md' + - 'Domain': 'Documentation/Drivers/Image/Domain.md' - 'RunVIC': 'Documentation/Drivers/Image/RunVIC.md' - 'Lake Param': 'Documentation/Drivers/Image/LakeParam.md' - 'StateFile': 'Documentation/Drivers/Image/StateFile.md' diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 2a1aa9059..6f126826b 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -144,6 +144,7 @@ STATE_FORMAT=BINARY test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - image driver driver = image global_parameter_file = global.image.STEHE.restart.txt +mpi_proc = 4 expected_retval = 0 check = exact_restart [[restart]] @@ -158,6 +159,7 @@ FROZEN_SOIL=FALSE test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - image driver driver = image global_parameter_file = global.image.STEHE.restart.txt +mpi_proc = 4 expected_retval = 0 check = exact_restart [[restart]] @@ -172,6 +174,7 @@ FROZEN_SOIL=FALSE test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - image driver driver = image global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +mpi_proc = 4 expected_retval = 0 check = exact_restart [[restart]] @@ -187,6 +190,7 @@ NODES=10 test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - image driver driver = image global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +mpi_proc = 4 expected_retval = 0 check = exact_restart [[restart]] From 765809c3fc2fe381a97d07d3e223860663214d77 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 14:03:21 +0100 Subject: [PATCH 070/294] updated to hotfix --- docs/Development/ReleaseNotes.md | 44 +- .../Drivers/Classic/ForcingData.md | 2 +- .../Drivers/Classic/GlobalParam.md | 4 +- docs/Documentation/Drivers/Classic/RunVIC.md | 4 +- .../Drivers/Image/ForcingData.md | 7 +- .../Drivers/Image/GlobalParam.md | 2 +- docs/Documentation/Drivers/Image/Inputs.md | 2 +- docs/Documentation/Drivers/Image/Params.md | 9 +- docs/Documentation/Drivers/Image/RunVIC.md | 10 +- docs/Documentation/Drivers/Image/StateFile.md | 4 +- docs/Documentation/References.md | 2 +- tests/README.md | 2 +- vic/drivers/classic/src/get_global_param.c | 14 +- vic/drivers/image/src/get_global_param.c | 4 +- vic/drivers/image/src/vic_force.c | 11 +- vic/drivers/python/setup.py | 4 +- vic/drivers/shared_all/include/vic_version.h | 4 +- vic/drivers/shared_all/src/make_dmy.c | 13 +- .../include/vic_driver_shared_image.h | 7 +- .../shared_image/src/check_domain_info.c | 21 +- .../shared_image/src/get_global_domain.c | 216 ++-- .../shared_image/src/get_nc_var_attr.c | 2 +- .../shared_image/src/vic_init_output.c | 40 +- vic/drivers/shared_image/src/vic_restore.c | 304 +++--- vic/drivers/shared_image/src/vic_start.c | 6 +- vic/drivers/shared_image/src/vic_store.c | 983 +++++++++--------- 26 files changed, 948 insertions(+), 773 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 3b4dd7e92..0981da430 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -14,20 +14,54 @@ To check which release of VIC you are running: - For VIC 5 and later, type `vic_{classic,image}.exe -v` ------------------------------ - ## VIC 5.0.1 **Release date: (Unreleased)** -#### New Features: +#### Bug Fixes: + +1. Fixed image driver history file name timestamp ([GH#635](https://github.com/UW-Hydro/VIC/pull/635)) + + After the fix, the timestamp appeared in the image driver output history filename is the beginning time of the time period in the file. + +2. Fixed forceskip rounding bug ([GH#639](https://github.com/UW-Hydro/VIC/pull/639)) + + After the fix, the `forceskip` variable in the global parameter structure (i.e., the number of timesteps to skip in the forcing data for the simulatin period) is rounded correctly (before the fix, rounding error might cause 1-timestep offset in the simulation results). + +3. Fixed a problem with image restarts when using multiple processors ([GH#638](https://github.com/UW-Hydro/VIC/pull/638)) + + After the fix, only the master node is assigned the task of validating state file dimensions and coordinate variables. Multiprocessing was also added to the VIC testing framework. + +4. Ensured that the mask variable in the input domain file must be integer type; otherwise an error is raised. ([GH#645](https://github.com/UW-Hydro/VIC/pull/645)) + +5. Fixed a bug related to `make_lastday` function ([GH#647](https://github.com/UW-Hydro/VIC/pull/647)) + + Before the fix, the input arguments to function `make_lastday` are sometimes in a wrong order. The bug caused error when trying to write state file on a leap day. + +6. Fixed a bug related to writing two-dimensional lat/lon variables to a state file ([GH#652](https://github.com/UW-Hydro/VIC/pull/652)) + + Before the bug fix, two-dimensional lat/lon variables were not populated correctly and were written as fill values to a state file. Now two-dimensional lat/lon variables are correctly populated and written. + +7. Fixed a bug related to `dz_node` and `node_depth` variables in image driver output state file ([GH#657](https://github.com/UW-Hydro/VIC/pull/657)) + + Before the fix, `dz_node` and `node_depth` in image driver output state file were not spatially distributed, which was wrong. Now these two variables are spatially distributed in the output state file. + +8. Fixed a bug related to `run_cell` and `mask` variables in image driver inputs ([GH#662](https://github.com/UW-Hydro/VIC/pull/662)) + + Before the fix, active cell was controlled by `mask` variable in the domain file in image driver, and `run_cell` variable in the parameter file was not actually used. Now `run_cell` variable in the parameter file controls active cells (`run_cell` must be within the mask defined by the domain file). + +9. Fixed a time precision bug for long simulations ([GH#668](https://github.com/UW-Hydro/VIC/pull/668)) + + Before the fix, the timestamps of long VIC runs were incorrect in some cases due to precision issue in timestamp generation. This resulted in incorrect output timestamps after running for a long period of time, or output termination. Please refer to [GH#668](https://github.com/UW-Hydro/VIC/pull/668) for details on this bug fix. -1. Added rvic river routing module in the image driver. +10. Fixed a bug related to forcing and simulation start time ([GH#671](https://github.com/UW-Hydro/VIC/pull/671)) - Documentation for the routing module can be found [here](../Documentation/Drivers/Image/Routing.md). + Before the fix, there would be an error if the simulation start time is later than the forcing start time that year AND the simulation spans multiple years. Fixed this bug. + ------------------------------ -## VIC 5.0.0 [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.61422.svg)](http://dx.doi.org/10.5281/zenodo.61422) +## VIC 5.0.0 [![DOI](https://zenodo.org/badge/7766/UW-Hydro/VIC.svg)](https://zenodo.org/badge/latestdoi/7766/UW-Hydro/VIC) **Release date: (September 2, 2016)** diff --git a/docs/Documentation/Drivers/Classic/ForcingData.md b/docs/Documentation/Drivers/Classic/ForcingData.md index 504b4a5a5..49106ee14 100644 --- a/docs/Documentation/Drivers/Classic/ForcingData.md +++ b/docs/Documentation/Drivers/Classic/ForcingData.md @@ -1,6 +1,6 @@ # VIC Forcings Files -The VIC Classic Driver requires subdaily forcings (meteorological or other). The required forcing variables vary depending options set in the global parameter file. +The VIC Classic Driver requires subdaily forcings (meteorological or other). Forcing timestep must be the same as snow model timestep, which is specified by the `SNOW_STEPS_PER_DAY` parameter in the [Global Parameter File](GlobalParam.md). The required forcing variables and units are listed below and must also be specified in the [Global Parameter File](GlobalParam.md) #### Meteorological Forcings, Required in all simulations: diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index c7c3c1340..0b434d84f 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -75,8 +75,6 @@ Generally these default values do not need to be overridden. | BLOWING_SPATIAL_WIND | string | TRUE or FALSE | If TRUE, multiple wind speed ranges, calculated according to a probability distribution, are used to determine the sublimation flux from blowing snow. If FALSE, then a single wind speed is used. See Lu and Pomeroy (1997) for details.

    Default: TRUE. | | COMPUTE_TREELINE | string or integer | FALSE or veg class id | Options for handling above-treeline vegetation:FALSE = Do not compute treeline or replace vegetation above the treeline.CLASS_ID = Compute the treeline elevation based on average July temperatures; for those elevation bands with elevations above the treeline (or the entire grid cell if SNOW_BAND == 1 and the grid cell elevation is above the tree line), if they contain vegetation tiles having overstory, replace that vegetation with the vegetation having id CLASS_ID in the vegetation library. NOTE 1: You MUST supply VIC with a July average air temperature, in the optional July_Tavg field, AND set theJULY_TAVG_SUPPLIED option to TRUE so that VIC can read the soil parameter file correctly. NOTE 2: If LAKES=TRUE, COMPUTE_TREELINE MUST be FALSE.Default = FALSE. | | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | -| MAX_SNOW_TEMP | float | deg C | Maximum temperature at which snow can fall. Default = 0.5 C. | -| MIN_RAIN_TEMP | float | deg C | Minimum temperature at which rain can fall. Default = -0.5 C. | | SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -152,7 +150,7 @@ All FORCING filenames are actually the pathname, and prefix for gridded data typ | FORCE_ENDIAN | string | BIG or LITTLE | Identifies the architecture of the machine on which the binary forcing files were created:BIG = big-endian (e.g. SUN).LITTLE = little-endian (e.g. PC/linux). Model will identify the endian of the current machine, and swap bytes if necessary. Required for binary forcing file, not used for ASCII forcing file. | | N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI_IN, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI_IN, and FCANOPY each count as only 1 variable despite covering multiple columns. | | FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI_IN, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI_IN, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | -| FORCE_STEPS_PER_DAY | integer | steps | Number of timesteps per day in forcing file (must be >= 1) | +| FORCE_STEPS_PER_DAY | integer | steps | Number of timesteps per day in forcing file (must be = SNOW_STPES_PER_DAY) | | FORCEYEAR | integer | year | Year meteorological forcing files start | | FORCEMONTH | integer | month | Month meteorological forcing files start | | FORCEDAY | integer | day | Day meteorological forcing files start | diff --git a/docs/Documentation/Drivers/Classic/RunVIC.md b/docs/Documentation/Drivers/Classic/RunVIC.md index da78dfb3c..1dd4ed4e0 100644 --- a/docs/Documentation/Drivers/Classic/RunVIC.md +++ b/docs/Documentation/Drivers/Classic/RunVIC.md @@ -9,7 +9,7 @@ - Clang (`clang` version 3+) VIC has also been compiled using these compilers: - + - Intel (`icc`) - PGI (`pgcc`) @@ -28,7 +28,7 @@ At the command prompt, type: - vic_classic.exe -g global_parameter_filename + ./vic_classic.exe -g global_parameter_filename where `global_parameter_filename` = name of the global parameter file corresponding to your project. diff --git a/docs/Documentation/Drivers/Image/ForcingData.md b/docs/Documentation/Drivers/Image/ForcingData.md index fa3ba1f76..4187dedb7 100644 --- a/docs/Documentation/Drivers/Image/ForcingData.md +++ b/docs/Documentation/Drivers/Image/ForcingData.md @@ -1,6 +1,6 @@ # VIC Forcing File -The VIC Image Driver requires a NetCDF file with gridded subdaily forcings. The required forcing variables and units are listed below and must also be specified in the [Global Parameter File](GlobalParam.md): +The VIC Image Driver requires a NetCDF file with gridded subdaily forcings. Forcing timestep must be the same as snow model timestep, which is specified by the `SNOW_STEPS_PER_DAY` parameter in the [Global Parameter File](GlobalParam.md). The required forcing variables and units are listed below and must also be specified in the [Global Parameter File](GlobalParam.md): #### Meteorological Forcings, Required in all simulations: @@ -38,11 +38,6 @@ variables: lat:long_name = "latitude of grid cell center" ; lat:units = "degrees_north" ; lat:axis = "Y" ; - double mask(lat, lon) ; - mask:_FillValue = 0. ; - mask:comment = "0 value indicates cell is not active" ; - mask:long_name = "fraction of grid cell that is activedomain mask" ; - mask:note = "unitlessunitless" ; float prcp(time, lat, lon) ; prcp:_FillValue = 9.96921e+36f ; prcp:long_name = "PREC" ; diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index 677d71263..de2fa16d7 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -157,7 +157,7 @@ See the [example file](#example-global-parameter-file) at the end of this page f # Define Domain file -The folloiwng options describe the input domain file information. +The folloiwng options describe the input domain file information. See [Domain File](Domain.md) for details about the domain file. | Name | Type | Units | Description | |-------------|---------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/docs/Documentation/Drivers/Image/Inputs.md b/docs/Documentation/Drivers/Image/Inputs.md index 5971f1a70..2c69779c8 100644 --- a/docs/Documentation/Drivers/Image/Inputs.md +++ b/docs/Documentation/Drivers/Image/Inputs.md @@ -7,10 +7,10 @@ To run VIC, several sets of input data are necessary: * [Global Parameter File](GlobalParam.md): This is the main input file for VIC. It points VIC to the locations of the other input/output files and sets parameters that govern the simulation (e.g., start/end dates, modes of operation). * [Meteorological Forcing Files](ForcingData.md): Gridded, sub-daily timeseries of meteorological variables as inputs. * [Parameters File](Params.md): Spatially distributed parameters describing the land surface. +* [Domain File](Domain.md): Domain information of VIC run. And a few more are optional: * [Constants File](../../Constants.md): Model parameters that are constant in time and space. * [Initial State File](StateFile.md): Moisture storages (soil moisture, snow pack, etc), energy storages (soil temperatures, etc) and other information describing the current state of the system. A state file saved from a previous VIC simulation may be used as the initial state for another run. * [Lake/Wetland Parameter File](LakeParam.md): File containing lake model parameters. By default, VIC does not simulate lakes or other impoundment of surface water. -* [Routing Parameter File](Routing.md): File containing the parameters necessary to perform the Lohmann routing. Note that by default, VIC does not perform any streamflow routing. diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index bb05c324c..243904ba2 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -16,7 +16,7 @@ Below is a list of soil parameters. | Variable Name | Dimension | Units | Type | Number of Values | Description | |--------------------------|--------------------|----------|--------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| run_cell | [lat, lon] | N/A | int | 1 | 1 = Run Grid Cell, 0 = Do Not Run | +| run_cell | [lat, lon] | N/A | int | 1 | 1 = Run Grid Cell, 0 = Do Not Run. Must be zero for all grid cells outside of the mask defined in the domain netCDF file. | | gridcel | [lat, lon] | N/A | int | 1 | Grid cell number | | lat | [lat, lon] | degrees | double | 1 | Latitude of grid cell | | lon | [lat, lon] | degrees | double | 1 | Longitude of grid cell | @@ -173,13 +173,6 @@ variables: double lon(lon) ; lon:units = "degrees_east" ; lon:long_name = "longitude of grid cell center" ; - int mask(lat, lon) ; - mask:long_name = "area of grid cell" ; - mask:comment = "0 value indicates cell is not active" ; - mask:note = "unitless" ; - mask:standard_name = "area" ; - mask:units = "m2" ; - mask:axis = "Y" ; int layer(nlayer) ; layer:long_name = "soil layer" ; int run_cell(lat, lon) ; diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 876bdd38b..a88e588e2 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -46,13 +46,13 @@ To enable the routing extension, you must set the ROUT option. Valid options are At the command prompt, type: -`vic_image.exe -g global_parameter_filename.txt` + ./vic_image.exe -g global_parameter_filename.txt where `global_parameter_filename` = name of the global parameter file corresponding to your project. To run VIC image driver using multiple processors, type the following instead: -`mpiexec -np n_proc vic_image.exe -g global_parameter_filename.txt` + mpiexec -np $n_proc ./vic_image.exe -g global_parameter_filename.txt where `n_proc` = number of processors to be used @@ -60,6 +60,6 @@ where `n_proc` = number of processors to be used VIC has a few other command line options: -- `vic_image.exe -v`: says which version of VIC this is -- `vic_image.exe -h`: prints a list of all the VIC command-line options -- `vic_image.exe -o`: prints a list of all of the current compile-time settings in this executable; to change these settings, you must edit the appropriate header files (e.g. `vic_def.h` or `vic_driver_shared.h`) and recompile using `make full`. +- `./vic_image.exe -v`: says which version of VIC this is +- `./vic_image.exe -h`: prints a list of all the VIC command-line options +- `./vic_image.exe -o`: prints a list of all of the current compile-time settings in this executable; to change these settings, you must edit the appropriate header files (e.g. `vic_def.h` or `vic_driver_shared.h`) and recompile using `make full`. diff --git a/docs/Documentation/Drivers/Image/StateFile.md b/docs/Documentation/Drivers/Image/StateFile.md index ba6d43179..17447e6bf 100644 --- a/docs/Documentation/Drivers/Image/StateFile.md +++ b/docs/Documentation/Drivers/Image/StateFile.md @@ -38,8 +38,8 @@ The following variables define the basic model information, including grid cell | snow_band | snow_band | int | Snow band indices | | layer | nlayer | int | Soil layer indices | | frost_area | frost_area | int | Frost area indices | -| dz_node | soil_node | double | Distances between soil thermal nodes [m] | -| node_depth | soil_node | double | Depth from surface of each soil thermal node (first node should have a depth of 0m indicating it is at the surface) [m] | +| dz_node | [soil_node, lat, lon] | double | Distances between soil thermal nodes [m] | +| node_depth | [soil_node, lat, lon] | double | Depth from surface of each soil thermal node (first node should have a depth of 0m indicating it is at the surface) [m] | * * * diff --git a/docs/Documentation/References.md b/docs/Documentation/References.md index 9352afb2a..d8f336c35 100644 --- a/docs/Documentation/References.md +++ b/docs/Documentation/References.md @@ -2,7 +2,7 @@ ## Primary Historical Reference -Liang, X., D. P. Lettenmaier, E. F. Wood, and S. J. Burges, 1994: A Simple hydrologically Based Model of Land Surface Water and Energy Fluxes for GSMs, _J. Geophys. Res._, **99**(D7), 14415-14428, [doi:10.1029/94JD00483](http://dx.doi.org/10.1029/94JD00483). +Liang, X., D. P. Lettenmaier, E. F. Wood, and S. J. Burges (1994), A simple hydrologically based model of land surface water and energy fluxes for general circulation models, _J. Geophys. Res._, **99**(D7), 14415–14428, [doi:10.1029/94JD00483](http://dx.doi.org/10.1029/94JD00483). ### Other Historical References diff --git a/tests/README.md b/tests/README.md index 21224363a..e6b1d6d4d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,5 +1,5 @@ VIC Test Suite -======= +======= This is the VIC Test Suite. There are six main test types: diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 587adbc04..4a6534ab9 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -671,6 +671,16 @@ get_global_param(FILE *gp) log_err("SKIPYEAR has been deprecated. To avoid writing output" "to history files, set AGGFREQ == FREQ_NEVER"); } + else if (strcasecmp("MAX_SNOW_TEMP", optstr) == 0) { + log_err("MAX_SNOW_TEMP has been deprecated. To" + "specify a maximum snow temperature, use the option" + "SNOW_MAX_SNOW_TEMP in the vic constants file.") + } + else if (strcasecmp("MIN_RAIN_TEMP", optstr) == 0) { + log_err("MIN_RAIN_TEMP has been deprecated. To" + "specify a minimum rain temperature, use the option" + "SNOW_MIN_RAIN_TEMP in the vic constants file.") + } /*********************************** Unrecognized Global Parameter Flag @@ -891,7 +901,7 @@ get_global_param(FILE *gp) // Validate simulation end date and/or number of timesteps - make_lastday(global_param.endyear, global_param.calendar, lastday); + make_lastday(global_param.calendar, global_param.endyear, lastday); if (global_param.nrecs == 0 && global_param.endyear == 0 && global_param.endmonth == 0 && global_param.endday == 0) { @@ -1204,7 +1214,7 @@ get_global_param(FILE *gp) global_param.statesec); } // Check for month, day in range - make_lastday(global_param.stateyear, global_param.calendar, + make_lastday(global_param.calendar, global_param.stateyear, lastday); if (global_param.stateday > lastday[global_param.statemonth - 1] || global_param.statemonth < 1 || diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index c1865f1d0..3e8dc38f0 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -727,7 +727,7 @@ get_global_param(FILE *gp) } // Validate simulation end date and/or number of timesteps - make_lastday(global_param.endyear, global_param.calendar, lastday); + make_lastday(global_param.calendar, global_param.endyear, lastday); if (global_param.nrecs == 0 && global_param.endyear == 0 && global_param.endmonth == 0 && global_param.endday == 0) { @@ -895,7 +895,7 @@ get_global_param(FILE *gp) global_param.statesec); } // Check for month, day in range - make_lastday(global_param.stateyear, global_param.calendar, + make_lastday(global_param.calendar, global_param.stateyear, lastday); if (global_param.stateday > lastday[global_param.statemonth - 1] || global_param.statemonth < 1 || diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 68a30f421..11caca455 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -72,8 +72,10 @@ vic_force(void) // global_param.forceoffset[0] resets every year since the met file restarts // every year + // global_param.forceskip[0] should also reset to 0 after the first year if (current > 1 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[0] = 0; + global_param.forceskip[0] = 0; } // only the time slice changes for the met file reads. The rest is constant @@ -517,10 +519,11 @@ get_forcing_file_info(param_set_struct *param_set, // check that this forcing file will work if (param_set->force_steps_per_day[file_num] != - global_param.model_steps_per_day) { - log_err("Forcing file timestep must match the model timestep. " - "Model timesteps per day is set to %zu and the forcing file " - "timestep is set to %zu", global_param.model_steps_per_day, + global_param.snow_steps_per_day) { + log_err("Forcing file timestep must match the snow model timestep. " + "Snow model timesteps per day is set to %zu and the forcing " + "file timestep is set to %zu", + global_param.snow_steps_per_day, param_set->force_steps_per_day[file_num]) } if (calendar != global_param.calendar) { diff --git a/vic/drivers/python/setup.py b/vic/drivers/python/setup.py index 45c9192ef..44a58530d 100644 --- a/vic/drivers/python/setup.py +++ b/vic/drivers/python/setup.py @@ -25,10 +25,10 @@ MAJOR = 5 MINOR = 0 -MICRO = 1 +MICRO = 0 ISRELEASED = True VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) -QUALIFIER = '(unreleased)' +QUALIFIER = '' FULLVERSION = VERSION write_version = False diff --git a/vic/drivers/shared_all/include/vic_version.h b/vic/drivers/shared_all/include/vic_version.h index ce82c150b..e9b76fabf 100644 --- a/vic/drivers/shared_all/include/vic_version.h +++ b/vic/drivers/shared_all/include/vic_version.h @@ -31,11 +31,11 @@ #define STR(x) STR_HELPER(x) #ifndef VERSION -#define VERSION "5.0.1 (Unreleased)" +#define VERSION "5.0.0 September 2, 2016" #endif #ifndef SHORT_VERSION -#define SHORT_VERSION "5.0.1" +#define SHORT_VERSION "5.0.0" #endif #ifndef GIT_VERSION diff --git a/vic/drivers/shared_all/src/make_dmy.c b/vic/drivers/shared_all/src/make_dmy.c index 9abbdcb02..1b48cbdf0 100644 --- a/vic/drivers/shared_all/src/make_dmy.c +++ b/vic/drivers/shared_all/src/make_dmy.c @@ -43,8 +43,6 @@ make_dmy(global_param_struct *global) double dt_time_units, start_num, end_num, force_num, numdate; - dt_seconds_to_time_units(global->time_units, global->dt, &dt_time_units); - start_dmy.dayseconds = global->startsec; start_dmy.year = global->startyear; start_dmy.day = global->startday; @@ -98,8 +96,8 @@ make_dmy(global_param_struct *global) global->calendar, global->time_units); global->forceskip[i] = - (unsigned int) ((start_num - force_num) * - (double) param_set.force_steps_per_day[i]); + (unsigned int) round((start_num - force_num) * + (double) param_set.force_steps_per_day[i]); } } @@ -107,9 +105,10 @@ make_dmy(global_param_struct *global) temp = calloc(global->nrecs, sizeof(*temp)); /** Create Date Structure for each Model Time Step **/ - for (i = 0, numdate = start_num; - i < global->nrecs; - i++, numdate += dt_time_units) { + for (i = 0; i < global->nrecs; i++) { + dt_seconds_to_time_units(global->time_units, i * global->dt, + &dt_time_units); + numdate = start_num + dt_time_units; num2date(global->time_origin_num, numdate, 0., global->calendar, global->time_units, &temp[i]); } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 1a172640f..240af1aed 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -200,11 +200,14 @@ void compare_ncdomain_with_global_domain(char *ncfile); void free_force(force_data_struct *force); void free_veg_hist(veg_hist_struct *veg_hist); void get_domain_type(char *cmdstr); -size_t get_global_domain(char *fname, domain_struct *global_domain, - bool coords_only); +size_t get_global_domain(char *domain_nc_name, char *param_nc_name, + domain_struct *global_domain); +void copy_domain_info(domain_struct *domain_from, domain_struct *domain_to); +void get_nc_latlon(char *nc_name, domain_struct *nc_domain); size_t get_nc_dimension(char *nc_name, char *dim_name); void get_nc_var_attr(char *nc_name, char *var_name, char *attr_name, char **attr); +int get_nc_var_type(char *nc_name, char *var_name); int get_nc_varndimensions(char *nc_name, char *var_name); int get_nc_field_double(char *nc_name, char *var_name, size_t *start, size_t *count, double *var); diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index 1095b05a9..d67e9bc90 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -28,8 +28,8 @@ #include /****************************************************************************** - * @brief Check that the cooridnates, dimensions, and mask variables in a - netcdf file matches the global domain. + * @brief Check that the cooridnates and dimensions in a netcdf file matches + the global domain. *****************************************************************************/ void compare_ncdomain_with_global_domain(char *ncfile) @@ -40,10 +40,14 @@ compare_ncdomain_with_global_domain(char *ncfile) size_t i; - ncfile_domain.info = global_domain.info; - - // read the domain info from ncfile (e.g. parameters file or state file) - get_global_domain(ncfile, &ncfile_domain, true); + // read the lat lon coordinates info from ncfile + // (e.g. parameters file or state file) + ncfile_domain.locations = + malloc(global_domain.ncells_total * + sizeof(*(ncfile_domain.locations))); + check_alloc_status(ncfile_domain.locations, "Memory allocation error."); + copy_domain_info(&global_domain, &ncfile_domain); + get_nc_latlon(ncfile, &ncfile_domain); // using the ncfile_domain, we can compare the values to the global domain. @@ -57,11 +61,6 @@ compare_ncdomain_with_global_domain(char *ncfile) // loop over all grid cells and check that the two domains are identical for (i = 0; i < global_domain.ncells_total; i++) { - // mask matches - if (ncfile_domain.locations[i].run < global_domain.locations[i].run) { - log_err("parameter file mask for gridcell %zu is zero and the " - "domain file specifies that this cell should be run", i); - } // latitude matches if (!assert_close_double(ncfile_domain.locations[i].latitude, global_domain.locations[i].latitude, diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 6dbdd0574..07e6a243c 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -30,23 +30,23 @@ * @brief Get global domain information. *****************************************************************************/ size_t -get_global_domain(char *nc_name, - domain_struct *global_domain, - bool coords_only) +get_global_domain(char *domain_nc_name, + char *param_nc_name, + domain_struct *global_domain) { int *run = NULL; + int *mask = NULL; + int typeid; double *var = NULL; - double *var_lon = NULL; - double *var_lat = NULL; size_t i; size_t j; size_t d2count[2]; size_t d2start[2]; - size_t d1count[1]; - size_t d1start[1]; - global_domain->n_nx = get_nc_dimension(nc_name, global_domain->info.x_dim); - global_domain->n_ny = get_nc_dimension(nc_name, global_domain->info.y_dim); + global_domain->n_nx = get_nc_dimension(domain_nc_name, + global_domain->info.x_dim); + global_domain->n_ny = get_nc_dimension(domain_nc_name, + global_domain->info.y_dim); d2start[0] = 0; d2start[1] = 0; @@ -56,19 +56,45 @@ get_global_domain(char *nc_name, // get total number of gridcells in domain global_domain->ncells_total = global_domain->n_ny * global_domain->n_nx; - // allocate memory for cells to be run + // allocate memory for mask and cells to be run + mask = malloc(global_domain->ncells_total * sizeof(*mask)); + check_alloc_status(mask, "Memory allocation error."); run = malloc(global_domain->ncells_total * sizeof(*run)); check_alloc_status(run, "Memory allocation error."); - get_nc_field_int(nc_name, global_domain->info.mask_var, d2start, d2count, + // Get mask variable from the domain file + // (check whether mask variable is int type) + typeid = get_nc_var_type(domain_nc_name, global_domain->info.mask_var); + if (typeid != NC_INT) { + log_err("Mask variable in the domain file must be integer type."); + } + get_nc_field_int(domain_nc_name, global_domain->info.mask_var, d2start, d2count, + mask); + + // Get run_cell variable from the parameter file + // (check whether run_cell variable is int type) + typeid = get_nc_var_type(param_nc_name, "run_cell"); + if (typeid != NC_INT) { + log_err("Run_cell variable in the parameter file must be integer type."); + } + get_nc_field_int(param_nc_name, "run_cell", d2start, d2count, run); + // Check whether cells with run_cell == 1 are all within the mask domain + for (i = 0; i < global_domain->ncells_total; i++) { + if (run[i] == 1 && mask[i] != 1) { + log_err("Run_cell = 1 should only appear within the mask of the " + "domain file."); + } + } + + // Store active cell information into variables for (i = 0; i < global_domain->ncells_total; i++) { if (run[i] == 1) { global_domain->ncells_active++; } } - debug("%zu active grid cells found in domain mask", + debug("%zu active grid cells found in run_cell in the parameter file.", global_domain->ncells_active); global_domain->locations = @@ -78,10 +104,6 @@ get_global_domain(char *nc_name, initialize_location(&(global_domain->locations[i])); } - // allocate memory for variables - var = malloc(global_domain->ncells_total * sizeof(*var)); - check_alloc_status(var, "Memory allocation error."); - for (i = 0; i < global_domain->ncells_total; i++) { if (run[i] == 1) { global_domain->locations[i].run = true; @@ -96,109 +118,173 @@ get_global_domain(char *nc_name, } } + // allocate memory for variables + var = malloc(global_domain->ncells_total * sizeof(*var)); + check_alloc_status(var, "Memory allocation error."); + + // get area + // TBD: read var id from file + get_nc_field_double(domain_nc_name, global_domain->info.area_var, + d2start, d2count, var); + for (i = 0; i < global_domain->ncells_total; i++) { + global_domain->locations[i].area = var[i]; + } + + // get fraction + // TBD: read var id from file + get_nc_field_double(domain_nc_name, global_domain->info.frac_var, + d2start, d2count, var); + for (i = 0; i < global_domain->ncells_total; i++) { + global_domain->locations[i].frac = var[i]; + } + + // get lat and lon coordinates + get_nc_latlon(domain_nc_name, global_domain); + + // check whether lat and lon coordinates in the parameter file match those + // in the domain file + compare_ncdomain_with_global_domain(param_nc_name); + + // free memory + free(var); + free(run); + + return global_domain->ncells_active; +} + + +/****************************************************************************** + * @brief Get lat and lon coordinates information from a netCDF file and + store in nc_domain structure + *****************************************************************************/ +void +get_nc_latlon(char *nc_name, + domain_struct *nc_domain) +{ + double *var = NULL; + double *var_lon = NULL; + double *var_lat = NULL; + size_t i; + size_t j; + size_t d2count[2]; + size_t d2start[2]; + size_t d1count[1]; + size_t d1start[1]; + + + nc_domain->n_nx = get_nc_dimension(nc_name, + nc_domain->info.x_dim); + nc_domain->n_ny = get_nc_dimension(nc_name, + nc_domain->info.y_dim); + // Get number of lat/lon dimensions. - global_domain->info.n_coord_dims = get_nc_varndimensions(nc_name, - global_domain->info.lon_var); - if (global_domain->info.n_coord_dims != - (size_t) get_nc_varndimensions(nc_name, global_domain->info.lat_var)) { + nc_domain->info.n_coord_dims = get_nc_varndimensions(nc_name, + nc_domain->info.lon_var); + if (nc_domain->info.n_coord_dims != + (size_t) get_nc_varndimensions(nc_name, nc_domain->info.lat_var)) { log_err("Un even number of dimensions for %s and %s in: %s", - global_domain->info.lon_var, global_domain->info.lat_var, + nc_domain->info.lon_var, nc_domain->info.lat_var, nc_name); } - if (global_domain->info.n_coord_dims == 1) { + if (nc_domain->info.n_coord_dims == 1) { // allocate memory for variables - var_lon = malloc(global_domain->n_nx * sizeof(*var_lon)); + var_lon = malloc(nc_domain->n_nx * sizeof(*var_lon)); check_alloc_status(var_lon, "Memory allocation error."); - var_lat = malloc(global_domain->n_ny * sizeof(*var_lat)); + var_lat = malloc(nc_domain->n_ny * sizeof(*var_lat)); check_alloc_status(var_lat, "Memory allocation error."); d1start[0] = 0; - d1count[0] = global_domain->n_nx; + d1count[0] = nc_domain->n_nx; // get longitude for unmasked grid - get_nc_field_double(nc_name, global_domain->info.lon_var, + get_nc_field_double(nc_name, nc_domain->info.lon_var, d1start, d1count, var_lon); - for (j = 0; j < global_domain->n_ny; j++) { - for (i = 0; i < global_domain->n_nx; i++) { + for (j = 0; j < nc_domain->n_ny; j++) { + for (i = 0; i < nc_domain->n_nx; i++) { // rescale to [-180., 180]. Note that the if statement is not strictly // needed, but it prevents -180 from turning into 180 and vice versa if (var_lon[i] < -180.f || var_lon[i] > 180.f) { var_lon[i] -= round(var_lon[i] / 360.f) * 360.f; } - global_domain->locations[j * global_domain->n_nx + - i].longitude = (double) var_lon[i]; + nc_domain->locations[j * nc_domain->n_nx + i].longitude = + (double) var_lon[i]; } } d1start[0] = 0; - d1count[0] = global_domain->n_ny; + d1count[0] = nc_domain->n_ny; // get latitude for unmasked grid - get_nc_field_double(nc_name, global_domain->info.lat_var, + get_nc_field_double(nc_name, nc_domain->info.lat_var, d1start, d1count, var_lat); - for (i = 0; i < global_domain->n_ny; i++) { - for (j = 0; j < global_domain->n_nx; j++) { - global_domain->locations[i * - global_domain->n_nx + j].latitude = + for (i = 0; i < nc_domain->n_ny; i++) { + for (j = 0; j < nc_domain->n_nx; j++) { + nc_domain->locations[i * nc_domain->n_nx + j].latitude = (double) var_lat[i]; } } + // free memory free(var_lon); free(var_lat); } - else if (global_domain->info.n_coord_dims == 2) { + else if (nc_domain->info.n_coord_dims == 2) { + // allocate memory for variables + var = malloc(nc_domain->ncells_total * sizeof(*var)); + check_alloc_status(var, "Memory allocation error."); + + + d2start[0] = 0; + d2start[1] = 0; + d2count[0] = nc_domain->n_ny; + d2count[1] = nc_domain->n_nx; + // get longitude for unmasked grid - get_nc_field_double(nc_name, global_domain->info.lon_var, + get_nc_field_double(nc_name, nc_domain->info.lon_var, d2start, d2count, var); - for (i = 0; i < global_domain->ncells_total; i++) { + for (i = 0; i < nc_domain->ncells_total; i++) { // rescale to [-180., 180]. Note that the if statement is not strictly // needed, but it prevents -180 from turning into 180 and vice versa if (var[i] < -180.f || var[i] > 180.f) { var[i] -= round(var[i] / 360.f) * 360.f; } - global_domain->locations[i].longitude = var[i]; + nc_domain->locations[i].longitude = var[i]; } // get latitude for unmasked grid - get_nc_field_double(nc_name, global_domain->info.lat_var, + get_nc_field_double(nc_name, nc_domain->info.lat_var, d2start, d2count, var); - for (i = 0; i < global_domain->ncells_total; i++) { - global_domain->locations[i].latitude = var[i]; + for (i = 0; i < nc_domain->ncells_total; i++) { + nc_domain->locations[i].latitude = var[i]; } + // free memory + free(var); } else { log_err("Number of dimensions for %s and %s should be 1 or 2 in: %s", - global_domain->info.lon_var, global_domain->info.lat_var, + nc_domain->info.lon_var, nc_domain->info.lat_var, nc_name); } +} - if (!coords_only) { - // get area - // TBD: read var id from file - get_nc_field_double(nc_name, global_domain->info.area_var, - d2start, d2count, var); - for (i = 0; i < global_domain->ncells_total; i++) { - global_domain->locations[i].area = var[i]; - } - - // get fraction - // TBD: read var id from file - get_nc_field_double(nc_name, global_domain->info.frac_var, - d2start, d2count, var); - for (i = 0; i < global_domain->ncells_total; i++) { - global_domain->locations[i].frac = var[i]; - } - } +/****************************************************************************** + * @brief Copy domain info from one domain structure to another + *****************************************************************************/ +void +copy_domain_info(domain_struct *domain_from, domain_struct *domain_to) +{ + strcpy(domain_to->info.x_dim, domain_from->info.x_dim); + strcpy(domain_to->info.y_dim, domain_from->info.y_dim); + strcpy(domain_to->info.lon_var, domain_from->info.lon_var); + strcpy(domain_to->info.lat_var, domain_from->info.lat_var); - // free memory - free(var); - free(run); + domain_to->n_nx = domain_from->n_nx; + domain_to->n_ny = domain_from->n_ny; - return global_domain->ncells_active; + domain_to->ncells_total = domain_from->ncells_total; } /****************************************************************************** diff --git a/vic/drivers/shared_image/src/get_nc_var_attr.c b/vic/drivers/shared_image/src/get_nc_var_attr.c index 418f56277..6a91c8ebc 100644 --- a/vic/drivers/shared_image/src/get_nc_var_attr.c +++ b/vic/drivers/shared_image/src/get_nc_var_attr.c @@ -27,7 +27,7 @@ #include /****************************************************************************** - * @brief Get netCDF dimension. + * @brief Get netCDF variable attributes. *****************************************************************************/ void get_nc_var_attr(char *nc_name, diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index 3fb730bb8..e051cbc45 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -224,32 +224,36 @@ initialize_history_file(nc_file_struct *nc, double *dvar; - // This could be further refined but for now, I've choosen a file naming + // This could be further refined but for now, I've chosen a file naming // Convention that goes like this: switch (stream->agg_alarm.freq) { // If FREQ_NDAYS -- filename = result_dir/prefix.YYYY-MM-DD.nc case FREQ_NDAYS: sprintf(stream->filename, "%s/%s.%04d-%02d-%02d.nc", filenames.result_dir, - stream->prefix, ref_dmy->year, ref_dmy->month, - ref_dmy->day); + stream->prefix, stream->time_bounds[0].year, + stream->time_bounds[0].month, + stream->time_bounds[0].day); break; case FREQ_NMONTHS: // If FREQ_NMONTHS -- filename = result_dir/prefix.YYYY-MM.nc sprintf(stream->filename, "%s/%s.%04d-%02d.nc", filenames.result_dir, - stream->prefix, ref_dmy->year, ref_dmy->month); + stream->prefix, stream->time_bounds[0].year, + stream->time_bounds[0].month); break; case FREQ_NYEARS: // If FREQ_NYEARS -- filename = result_dir/prefix.YYYY.nc sprintf(stream->filename, "%s/%s.%04d.nc", filenames.result_dir, - stream->prefix, ref_dmy->year); + stream->prefix, stream->time_bounds[0].year); break; default: // For all other cases -- filename = result_dir/prefix.YYYY-MM-DD-SSSSS.nc sprintf(stream->filename, "%s/%s.%04d-%02d-%02d-%05u.nc", filenames.result_dir, - stream->prefix, ref_dmy->year, ref_dmy->month, - ref_dmy->day, ref_dmy->dayseconds); + stream->prefix, stream->time_bounds[0].year, + stream->time_bounds[0].month, + stream->time_bounds[0].day, + stream->time_bounds[0].dayseconds); } // open the netcdf file @@ -269,56 +273,56 @@ initialize_history_file(nc_file_struct *nc, // define netcdf dimensions status = nc_def_dim(nc->nc_id, "snow_band", nc->band_size, &(nc->band_dimid)); - check_nc_status(status, "Error defining snow_band dimenension in %s", + check_nc_status(status, "Error defining snow_band dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "front", nc->front_size, &(nc->front_dimid)); - check_nc_status(status, "Error defining front dimenension in %s", + check_nc_status(status, "Error defining front dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "frost_area", nc->frost_size, &(nc->frost_dimid)); - check_nc_status(status, "Error defining frost_area dimenension in %s", + check_nc_status(status, "Error defining frost_area dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "nlayer", nc->layer_size, &(nc->layer_dimid)); - check_nc_status(status, "Error defining nlayer dimenension in %s", + check_nc_status(status, "Error defining nlayer dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, global_domain.info.x_dim, nc->ni_size, &(nc->ni_dimid)); - check_nc_status(status, "Error defining x dimenension in %s", + check_nc_status(status, "Error defining x dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, global_domain.info.y_dim, nc->nj_size, &(nc->nj_dimid)); - check_nc_status(status, "Error defining y dimenension in %s", + check_nc_status(status, "Error defining y dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "node", nc->node_size, &(nc->node_dimid)); - check_nc_status(status, "Error defining node dimenension in %s", + check_nc_status(status, "Error defining node dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "root_zone", nc->root_zone_size, &(nc->root_zone_dimid)); - check_nc_status(status, "Error defining root_zone dimenension in %s", + check_nc_status(status, "Error defining root_zone dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "veg_class", nc->veg_size, &(nc->veg_dimid)); - check_nc_status(status, "Error defining veg_class dimenension in %s", + check_nc_status(status, "Error defining veg_class dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "time", nc->time_size, &(nc->time_dimid)); - check_nc_status(status, "Error defining time dimenension in %s", + check_nc_status(status, "Error defining time dimension in %s", stream->filename); status = nc_def_dim(nc->nc_id, "nv", 2, &(nc->time_bounds_dimid)); - check_nc_status(status, "Error defining time bounds dimenension in %s", + check_nc_status(status, "Error defining time bounds dimension in %s", stream->filename); // define the netcdf variable time diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index a413b8f96..7d26ac3bf 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -65,7 +65,6 @@ vic_restore(void) // validate state file dimensions and coordinate variables check_init_state_file(); - // read state variables // allocate memory for variables to be stored @@ -894,8 +893,10 @@ check_init_state_file(void) { extern filenames_struct filenames; extern domain_struct global_domain; + extern domain_struct local_domain; extern option_struct options; extern soil_con_struct *soil_con; + extern int mpi_rank; extern rout_struct rout; int status; @@ -906,6 +907,8 @@ check_init_state_file(void) size_t d1start[1]; size_t d2count[2]; size_t d2start[2]; + size_t d3count[3]; + size_t d3start[3]; int lon_var_id; int lat_var_id; double *dvar; @@ -918,173 +921,180 @@ check_init_state_file(void) check_nc_status(status, "Error opening %s", filenames.init_state); // read and validate dimension lengths - dimlen = get_nc_dimension(filenames.init_state, global_domain.info.x_dim); - if (dimlen != global_domain.n_nx) { - log_err("Number of grid columns in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, global_domain.info.y_dim); - if (dimlen != global_domain.n_ny) { - log_err("Number of grid rows in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "veg_class"); - if (dimlen != options.NVEGTYPES) { - log_err("Number of veg classes in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "snow_band"); - if (dimlen != options.SNOW_BAND) { - log_err("Number of snow bands in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "nlayer"); - if (dimlen != options.Nlayer) { - log_err("Number of soil layers in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "frost_area"); - if (dimlen != options.Nfrost) { - log_err("Number of frost areas in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "soil_node"); - if (dimlen != options.Nnode) { - log_err("Number of soil nodes in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "outlet"); - if (dimlen != rout.rout_param.n_outlets) { - log_err("Number of outlets in state file does not " - "match routing parameter file"); - } - dimlen = get_nc_dimension(filenames.init_state, "routing_timestep"); - if (dimlen != rout.rout_param.n_timesteps) { - log_err("Number of routing timesteps in state file does not " - "match routing parameter file"); - } - if (options.LAKES) { - dimlen = get_nc_dimension(filenames.init_state, "lake_node"); - if (dimlen != options.NLAKENODES) { - log_err("Number of lake nodes in state file does not " + if (mpi_rank == VIC_MPI_ROOT) { + dimlen = get_nc_dimension(filenames.init_state, global_domain.info.x_dim); + if (dimlen != global_domain.n_nx) { + log_err("Number of grid columns in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, global_domain.info.y_dim); + if (dimlen != global_domain.n_ny) { + log_err("Number of grid rows in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, "veg_class"); + if (dimlen != options.NVEGTYPES) { + log_err("Number of veg classes in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, "snow_band"); + if (dimlen != options.SNOW_BAND) { + log_err("Number of snow bands in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, "nlayer"); + if (dimlen != options.Nlayer) { + log_err("Number of soil layers in state file does not " "match parameter file"); } + dimlen = get_nc_dimension(filenames.init_state, "frost_area"); + if (dimlen != options.Nfrost) { + log_err("Number of frost areas in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(filenames.init_state, "soil_node"); + if (dimlen != options.Nnode) { + log_err("Number of soil nodes in state file does not " + "match parameter file"); + } + if (options.LAKES) { + dimlen = get_nc_dimension(filenames.init_state, "lake_node"); + if (dimlen != options.NLAKENODES) { + log_err("Number of lake nodes in state file does not " + "match parameter file"); + } + } } // read dimension variables // lat/lon - status = nc_inq_varid(nc.nc_id, global_domain.info.lon_var, &lon_var_id); - check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - status = nc_inq_varid(nc.nc_id, global_domain.info.lat_var, &lat_var_id); - check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); - if (global_domain.info.n_coord_dims == 1) { - d1start[0] = 0; - dvar = calloc(global_domain.n_nx, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d1count[0] = global_domain.n_nx; - status = nc_get_vara_double(nc.nc_id, lon_var_id, - d1start, d1count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_inq_varid(nc.nc_id, global_domain.info.lon_var, &lon_var_id); + check_nc_status(status, "Unable to find variable \"%s\" in %s", global_domain.info.lon_var, filenames.init_state); - // implicitly nested loop over ni and nj with j set to 0 - for (i = 0; i < global_domain.n_nx; i++) { - if (!assert_close_double(dvar[i], - global_domain.locations[i].longitude, rtol, - abs_tol)) { - log_err("Longitudes in initial state file do not " - "match parameter file"); - } - } - free(dvar); - - dvar = calloc(global_domain.n_ny, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d1count[0] = global_domain.n_ny; - status = nc_get_vara_double(nc.nc_id, lat_var_id, - d1start, d1count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", + status = nc_inq_varid(nc.nc_id, global_domain.info.lat_var, &lat_var_id); + check_nc_status(status, "Unable to find variable \"%s\" in %s", global_domain.info.lat_var, filenames.init_state); - // implicitly nested loop over ni and nj with i set to 0; - // j stride = n_nx - for (j = 0; j < global_domain.n_ny; j++) { - if (!assert_close_double(dvar[j], - global_domain.locations[j * - global_domain.n_nx] - .latitude, rtol, - abs_tol)) { - log_err("Latitudes in initial state file do not " - "match parameter file"); + if (global_domain.info.n_coord_dims == 1) { + d1start[0] = 0; + dvar = calloc(global_domain.n_nx, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d1count[0] = global_domain.n_nx; + status = nc_get_vara_double(nc.nc_id, lon_var_id, + d1start, d1count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, filenames.init_state); + // implicitly nested loop over ni and nj with j set to 0 + for (i = 0; i < global_domain.n_nx; i++) { + if (!assert_close_double(dvar[i], + global_domain.locations[i].longitude, rtol, + abs_tol)) { + log_err("Longitudes in initial state file do not " + "match parameter file"); + } } - } - free(dvar); - } - else if (global_domain.info.n_coord_dims == 2) { - d2start[0] = 0; - d2start[1] = 0; - dvar = calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d2count[0] = global_domain.n_ny; - d2count[1] = global_domain.n_nx; - status = nc_get_vara_double(nc.nc_id, lon_var_id, - d2start, d2count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { - if (dvar[i] != (double) global_domain.locations[i].longitude) { - log_err("Longitudes in initial state file do not " - "match parameter file"); + free(dvar); + + dvar = calloc(global_domain.n_ny, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d1count[0] = global_domain.n_ny; + status = nc_get_vara_double(nc.nc_id, lat_var_id, + d1start, d1count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, filenames.init_state); + // implicitly nested loop over ni and nj with i set to 0; + // j stride = n_nx + for (j = 0; j < global_domain.n_ny; j++) { + if (!assert_close_double(dvar[j], + global_domain.locations[j * + global_domain.n_nx] + .latitude, rtol, + abs_tol)) { + log_err("Latitudes in initial state file do not " + "match parameter file"); + } } - } - status = nc_get_vara_double(nc.nc_id, lat_var_id, - d2start, d2count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); - for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { - if (dvar[i] != (double) global_domain.locations[i].latitude) { - log_err("Latitudes in initial state file do not " - "match parameter file"); + free(dvar); + } + else if (global_domain.info.n_coord_dims == 2) { + d2start[0] = 0; + d2start[1] = 0; + dvar = calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d2count[0] = global_domain.n_ny; + d2count[1] = global_domain.n_nx; + status = nc_get_vara_double(nc.nc_id, lon_var_id, + d2start, d2count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, filenames.init_state); + for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { + if (dvar[i] != (double) global_domain.locations[i].longitude) { + log_err("Longitudes in initial state file do not " + "match parameter file"); + } } + status = nc_get_vara_double(nc.nc_id, lat_var_id, + d2start, d2count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, filenames.init_state); + for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { + if (dvar[i] != (double) global_domain.locations[i].latitude) { + log_err("Latitudes in initial state file do not " + "match parameter file"); + } + } + free(dvar); + } + else { + log_err("global_domain.info.n_coord_dims should be 1 or 2"); } - free(dvar); - } - else { - log_err("global_domain.info.n_coord_dims should be 1 or 2"); } - // Variables for other dimensions - d1start[0] = 0; - d1count[0] = options.Nnode; - - // soil thermal node deltas - dvar = calloc(options.Nnode, sizeof(*dvar)); + // initialize dvar for soil thermal node deltas and depths + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); - get_nc_field_double(filenames.init_state, "dz_node", - d1start, d1count, dvar); - for (i = 0; i < options.Nnode; i++) { - if (dvar[i] != soil_con[0].dz_node[i]) { - log_err("Soil node intervals in state file do not match " - "those computed by VIC"); + // soil thermal node deltas (dimension: node, lat, lon) + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = 1; + d3count[1] = global_domain.n_ny; + d3count[2] = global_domain.n_nx; + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + get_scatter_nc_field_double(filenames.init_state, + "dz_node", + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + if (dvar[i] != soil_con[i].dz_node[j]) { + log_err("Soil node intervals in state file do not match " + "those computed by VIC"); + } } } - free(dvar); // soil thermal node depths - dvar = calloc(options.Nnode, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - get_nc_field_double(filenames.init_state, "node_depth", - d1start, d1count, dvar); - for (i = 0; i < options.Nnode; i++) { - if (dvar[i] != soil_con[0].Zsum_node[i]) { - log_err("Soil node depths in state file do not match " - "those computed by VIC"); + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = 1; + d3count[1] = global_domain.n_ny; + d3count[2] = global_domain.n_nx; + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + get_scatter_nc_field_double(filenames.init_state, + "node_depth", + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + if (dvar[i] != soil_con[i].Zsum_node[j]) { + log_err("Soil node depths in state file do not match " + "those computed by VIC"); + } } } free(dvar); diff --git a/vic/drivers/shared_image/src/vic_start.c b/vic/drivers/shared_image/src/vic_start.c index ca94d0bc4..147647e90 100644 --- a/vic/drivers/shared_image/src/vic_start.c +++ b/vic/drivers/shared_image/src/vic_start.c @@ -74,7 +74,8 @@ vic_start(void) } // read domain info - get_global_domain(filenames.domain, &global_domain, false); + get_global_domain(filenames.domain, filenames.params, + &global_domain); // add the number of vegetation type to the location info in the // global domain struct. This just makes life easier @@ -110,9 +111,6 @@ vic_start(void) "lake_node"); } - // Validate the parameters file - compare_ncdomain_with_global_domain(filenames.params); - // Check that model parameters are valid validate_parameters(); } diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 09e1e2c15..da77839df 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -63,15 +63,13 @@ vic_store(dmy_struct *dmy_current, set_nc_state_file_info(&nc_state_file); // only open and initialize the netcdf file on the first thread + // create netcdf file for storing model state + sprintf(filename, "%s.%04i%02i%02i_%05u.nc", + filenames.statefile, global_param.stateyear, + global_param.statemonth, global_param.stateday, + global_param.statesec); + initialize_state_file(filename, &nc_state_file, dmy_current); if (mpi_rank == VIC_MPI_ROOT) { - // create netcdf file for storing model state - sprintf(filename, "%s.%04i%02i%02i_%05u.nc", - filenames.statefile, global_param.stateyear, - global_param.statemonth, global_param.stateday, - global_param.statesec); - - initialize_state_file(filename, &nc_state_file, dmy_current); - debug("writing state file: %s", filename); } @@ -1554,9 +1552,11 @@ initialize_state_file(char *filename, { extern option_struct options; extern domain_struct global_domain; + extern domain_struct local_domain; extern global_param_struct global_param; extern metadata_struct state_metadata[N_STATE_VARS]; extern soil_con_struct *soil_con; + extern int mpi_rank; int status; int dimids[MAXDIMS]; @@ -1584,104 +1584,97 @@ initialize_state_file(char *filename, double time_num; // open the netcdf file - status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), - &(nc_state_file->nc_id)); - check_nc_status(status, "Error creating %s", filename); - nc_state_file->open = true; - - // Set netcdf file global attributes - set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); - - // set the NC_FILL attribute - status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); - check_nc_status(status, "Error setting fill value in %s", filename); - - // define the time dimension - status = nc_def_dim(nc_state_file->nc_id, "time", nc_state_file->time_size, - &(nc_state_file->time_dimid)); - check_nc_status(status, "Error defining time dimenension in %s", filename); - - // define the variable time - status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, - &(nc_state_file->time_dimid), - &(nc_state_file->time_varid)); - check_nc_status(status, "Error defining time variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, - "standard_name", strlen("time"), "time"); - check_nc_status(status, "Error adding attribute in %s", filename); - - // adding units attribute to time variable - str_from_time_units(global_param.time_units, unit_str); - - sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); - - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, - "units", strlen(str), str); - check_nc_status(status, "Error adding attribute in %s", filename); - - // adding calendar attribute to time variable - str_from_calendar(global_param.calendar, str); - - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, - "calendar", strlen(str), str); - check_nc_status(status, "Error adding calendar attribute in %s", filename); - - // define netcdf dimensions - status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, - nc_state_file->ni_size, &(nc_state_file->ni_dimid)); - check_nc_status(status, "Error defining \"%s\" in %s", - global_domain.info.x_dim, - filename); - - status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, - nc_state_file->nj_size, &(nc_state_file->nj_dimid)); - check_nc_status(status, "Error defining \"%s\" in %s", - global_domain.info.y_dim, - filename); - - status = nc_def_dim(nc_state_file->nc_id, "veg_class", - nc_state_file->veg_size, &(nc_state_file->veg_dimid)); - check_nc_status(status, "Error defining veg_class in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "snow_band", - nc_state_file->band_size, - &(nc_state_file->band_dimid)); - check_nc_status(status, "Error defining snow_band in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "nlayer", - nc_state_file->layer_size, - &(nc_state_file->layer_dimid)); - check_nc_status(status, "Error defining nlayer in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "frost_area", - nc_state_file->frost_size, - &(nc_state_file->frost_dimid)); - check_nc_status(status, "Error defining frost_area in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "soil_node", - nc_state_file->node_size, - &(nc_state_file->node_dimid)); - check_nc_status(status, "Error defining soil_node in %s", filename); - - // Add routing dimensions - status = nc_def_dim(nc_state_file->nc_id, "outlet", - nc_state_file->outlet_size, - &(nc_state_file->outlet_dimid)); - check_nc_status(status, "Error defining outlet in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", - nc_state_file->routing_timestep_size, - &(nc_state_file->routing_timestep_dimid)); - check_nc_status(status, "Error defining routing_timestep in %s", filename); - - if (options.LAKES) { - status = nc_def_dim(nc_state_file->nc_id, "lake_node", - nc_state_file->lake_node_size, - &(nc_state_file->lake_node_dimid)); - check_nc_status(status, "Error defining lake_node in %s", filename); + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), + &(nc_state_file->nc_id)); + check_nc_status(status, "Error creating %s", filename); + nc_state_file->open = true; } - set_nc_state_var_info(nc_state_file); + if (mpi_rank == VIC_MPI_ROOT) { + // Set netcdf file global attributes + set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); + + // set the NC_FILL attribute + status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); + check_nc_status(status, "Error setting fill value in %s", filename); + + // define the time dimension + status = nc_def_dim(nc_state_file->nc_id, "time", nc_state_file->time_size, + &(nc_state_file->time_dimid)); + check_nc_status(status, "Error defining time dimenension in %s", filename); + + // define the variable time + status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, + &(nc_state_file->time_dimid), + &(nc_state_file->time_varid)); + check_nc_status(status, "Error defining time variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + "standard_name", strlen("time"), "time"); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding units attribute to time variable + str_from_time_units(global_param.time_units, unit_str); + + sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); + + status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + "units", strlen(str), str); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding calendar attribute to time variable + str_from_calendar(global_param.calendar, str); + + status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + "calendar", strlen(str), str); + check_nc_status(status, "Error adding calendar attribute in %s", filename); + + // define netcdf dimensions + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, + nc_state_file->ni_size, &(nc_state_file->ni_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.x_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, + nc_state_file->nj_size, &(nc_state_file->nj_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.y_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, "veg_class", + nc_state_file->veg_size, &(nc_state_file->veg_dimid)); + check_nc_status(status, "Error defining veg_class in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "snow_band", + nc_state_file->band_size, + &(nc_state_file->band_dimid)); + check_nc_status(status, "Error defining snow_band in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "nlayer", + nc_state_file->layer_size, + &(nc_state_file->layer_dimid)); + check_nc_status(status, "Error defining nlayer in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "frost_area", + nc_state_file->frost_size, + &(nc_state_file->frost_dimid)); + check_nc_status(status, "Error defining frost_area in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "soil_node", + nc_state_file->node_size, + &(nc_state_file->node_dimid)); + check_nc_status(status, "Error defining soil_node in %s", filename); + + if (options.LAKES) { + status = nc_def_dim(nc_state_file->nc_id, "lake_node", + nc_state_file->lake_node_size, + &(nc_state_file->lake_node_dimid)); + check_nc_status(status, "Error defining lake_node in %s", filename); + } + + set_nc_state_var_info(nc_state_file); + } // initialize dimids to invalid values for (i = 0; i < MAXDIMS; i++) { @@ -1692,402 +1685,452 @@ initialize_state_file(char *filename, // write dimension variables // Coordinate variables - ndims = global_domain.info.n_coord_dims; - dstart[0] = 0; - dstart[1] = 0; - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file->ni_dimid; - dcount[0] = nc_state_file->ni_size; - } - else if (global_domain.info.n_coord_dims == 2) { - dimids[0] = nc_state_file->nj_dimid; - dcount[0] = nc_state_file->nj_size; - - dimids[1] = nc_state_file->ni_dimid; - dcount[1] = nc_state_file->ni_size; - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); + if (mpi_rank == VIC_MPI_ROOT) { + ndims = global_domain.info.n_coord_dims; + dstart[0] = 0; + dstart[1] = 0; + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->ni_dimid; + dcount[0] = nc_state_file->ni_size; + } + else if (global_domain.info.n_coord_dims == 2) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + + dimids[1] = nc_state_file->ni_dimid; + dcount[1] = nc_state_file->ni_size; + } + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); + } } // define the netcdf variable longitude - status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, - NC_DOUBLE, ndims, dimids, &(lon_var_id)); - check_nc_status(status, "Error defining lon variable in %s", filename); - - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( - "longitude"), "longitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( - "degrees_east"), "degrees_east"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, - "standard_name", strlen( - "longitude"), "longitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file->nj_dimid; - dcount[0] = nc_state_file->nj_size; - } - - // define the netcdf variable latitude - status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, - NC_DOUBLE, ndims, dimids, &(lat_var_id)); - check_nc_status(status, "Error defining lat variable (%s) in %s", - global_domain.info.lat_var, filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( - "latitude"), "latitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( - "degrees_north"), "degrees_north"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, - "standard_name", strlen("latitude"), - "latitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - - // veg_class - dimids[0] = nc_state_file->veg_dimid; - status = nc_def_var(nc_state_file->nc_id, "veg_class", - NC_INT, 1, dimids, &(veg_var_id)); - check_nc_status(status, "Error defining veg_class variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", - strlen("veg_class"), "veg_class"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, - "standard_name", strlen("vegetation_class_number"), - "vegetation_class_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // snow_band - dimids[0] = nc_state_file->band_dimid; - status = nc_def_var(nc_state_file->nc_id, "snow_band", - NC_INT, 1, dimids, &(snow_band_var_id)); - check_nc_status(status, "Error defining snow_band variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, - "long_name", - strlen("snow_band"), "snow_band"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, - "standard_name", - strlen("snow_elevation_band_number"), - "snow_elevation_band_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // layer - dimids[0] = nc_state_file->layer_dimid; - status = - nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, - &(layer_var_id)); - check_nc_status(status, "Error defining layer variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", - strlen("layer"), "layer"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, - "standard_name", strlen("soil_layer_number"), - "soil_layer_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // frost_area - dimids[0] = nc_state_file->frost_dimid; - status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, - dimids, &(frost_area_var_id)); - check_nc_status(status, "Error defining frost_area variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, - "long_name", - strlen("frost_area"), "frost_area"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, - "standard_name", strlen("frost_area_number"), - "frost_area_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // dz_node - dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 1, - dimids, &(dz_node_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", - strlen("dz_node"), "dz_node"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "standard_name", strlen( - "soil_thermal_node_spacing"), - "soil_thermal_node_spacing"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "units", - strlen("m"), "m"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // node_depth - dimids[0] = nc_state_file->node_dimid; - status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 1, - dimids, &(node_depth_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "long_name", - strlen("node_depth"), "node_depth"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "standard_name", strlen("soil_thermal_node_depth"), - "soil_thermal_node_depth"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, "units", - strlen("m"), "m"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - if (options.LAKES) { - // lake_node - dimids[0] = nc_state_file->lake_node_dimid; - status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, - dimids, &(lake_node_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, + NC_DOUBLE, ndims, dimids, &(lon_var_id)); + check_nc_status(status, "Error defining lon variable in %s", filename); + + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( + "degrees_east"), "degrees_east"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, + "standard_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + } + + // define the netcdf variable latitude + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, + NC_DOUBLE, ndims, dimids, &(lat_var_id)); + check_nc_status(status, "Error defining lat variable (%s) in %s", + global_domain.info.lat_var, filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( + "latitude"), "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( + "degrees_north"), "degrees_north"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, + "standard_name", strlen("latitude"), + "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // veg_class + dimids[0] = nc_state_file->veg_dimid; + status = nc_def_var(nc_state_file->nc_id, "veg_class", + NC_INT, 1, dimids, &(veg_var_id)); + check_nc_status(status, "Error defining veg_class variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", + strlen("veg_class"), "veg_class"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, + "standard_name", strlen("vegetation_class_number"), + "vegetation_class_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // snow_band + dimids[0] = nc_state_file->band_dimid; + status = nc_def_var(nc_state_file->nc_id, "snow_band", + NC_INT, 1, dimids, &(snow_band_var_id)); + check_nc_status(status, "Error defining snow_band variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, "long_name", - strlen("lake_node"), "lake_node"); + strlen("snow_band"), "snow_band"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, + "standard_name", + strlen("snow_elevation_band_number"), + "snow_elevation_band_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // layer + dimids[0] = nc_state_file->layer_dimid; + status = + nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, + &(layer_var_id)); + check_nc_status(status, "Error defining layer variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", + strlen("layer"), "layer"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, + "standard_name", strlen("soil_layer_number"), + "soil_layer_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // frost_area + dimids[0] = nc_state_file->frost_dimid; + status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, + dimids, &(frost_area_var_id)); + check_nc_status(status, "Error defining frost_area variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "long_name", + strlen("frost_area"), "frost_area"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "standard_name", strlen("frost_area_number"), + "frost_area_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // dz_node (dimension: node, lat, lon) + dimids[0] = nc_state_file->node_dimid; + dimids[1] = nc_state_file->nj_dimid; + dimids[2] = nc_state_file->ni_dimid; + status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 3, + dimids, &(dz_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", + strlen("dz_node"), "dz_node"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "standard_name", strlen("lake_node_number"), - "lake_node_number"); + "standard_name", strlen( + "soil_thermal_node_spacing"), + "soil_thermal_node_spacing"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "units", + strlen("m"), "m"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + dimids[1] = -1; + dimids[2] = -1; + + // node_depth (dimension: node, lat, lon) + dimids[0] = nc_state_file->node_dimid; + dimids[1] = nc_state_file->nj_dimid; + dimids[2] = nc_state_file->ni_dimid; + status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 3, + dimids, &(node_depth_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "long_name", + strlen("node_depth"), "node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "standard_name", strlen("soil_thermal_node_depth"), + "soil_thermal_node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, "units", + strlen("m"), "m"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; + dimids[1] = -1; + dimids[2] = -1; + + if (options.LAKES) { + // lake_node + dimids[0] = nc_state_file->lake_node_dimid; + status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, + dimids, &(lake_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, + "long_name", + strlen("lake_node"), "lake_node"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "standard_name", strlen("lake_node_number"), + "lake_node_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + } } // Define state variables - for (i = 0; i < N_STATE_VARS; i++) { - if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { - // skip variables not set in set_state_meta_data_info - continue; - } - - // create the variable - status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, - nc_state_file->nc_vars[i].nc_type, - nc_state_file->nc_vars[i].nc_dims, - nc_state_file->nc_vars[i].nc_dimids, - &(nc_state_file->nc_vars[i].nc_varid)); - check_nc_status(status, "Error defining state variable %s in %s", - state_metadata[i].varname, filename); - - // set the fill value attribute - if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { - status = nc_put_att_double(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "_FillValue", NC_DOUBLE, 1, - &(nc_state_file->d_fillvalue)); - } - else if (nc_state_file->nc_vars[i].nc_type == NC_INT) { - status = nc_put_att_int(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "_FillValue", NC_INT, 1, - &(nc_state_file->i_fillvalue)); - } - else { - log_err("NC_TYPE %d not supported at this time", - nc_state_file->nc_vars[i].nc_type); - } - check_nc_status(status, - "Error putting _FillValue attribute to %s in %s", - state_metadata[i].varname, filename); - - // Set string attributes - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, - "long_name", state_metadata[i].long_name); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, - "standard_name", state_metadata[i].standard_name); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, - "units", state_metadata[i].units); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, - "description", state_metadata[i].description); + if (mpi_rank == VIC_MPI_ROOT) { + for (i = 0; i < N_STATE_VARS; i++) { + if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { + // skip variables not set in set_state_meta_data_info + continue; + } + + // create the variable + status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, + nc_state_file->nc_vars[i].nc_type, + nc_state_file->nc_vars[i].nc_dims, + nc_state_file->nc_vars[i].nc_dimids, + &(nc_state_file->nc_vars[i].nc_varid)); + check_nc_status(status, "Error defining state variable %s in %s", + state_metadata[i].varname, filename); + + // set the fill value attribute + if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { + status = nc_put_att_double(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_DOUBLE, 1, + &(nc_state_file->d_fillvalue)); + } + else if (nc_state_file->nc_vars[i].nc_type == NC_INT) { + status = nc_put_att_int(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_INT, 1, + &(nc_state_file->i_fillvalue)); + } + else { + log_err("NC_TYPE %d not supported at this time", + nc_state_file->nc_vars[i].nc_type); + } + check_nc_status(status, + "Error putting _FillValue attribute to %s in %s", + state_metadata[i].varname, filename); + + // Set string attributes + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "long_name", state_metadata[i].long_name); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "standard_name", state_metadata[i].standard_name); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "units", state_metadata[i].units); + put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + "description", state_metadata[i].description); + } + + // leave define mode + status = nc_enddef(nc_state_file->nc_id); + check_nc_status(status, "Error leaving define mode for %s", filename); } - // leave define mode - status = nc_enddef(nc_state_file->nc_id); - check_nc_status(status, "Error leaving define mode for %s", filename); - // time variable // advance dmy_current by one timestep because dmy_current is the // "timestep-beginning" timestamp, but we want the time variable to be // the end of the current time step - dt_seconds_to_time_units(global_param.time_units, global_param.dt, - &offset); - time_num = date2num(global_param.time_origin_num, dmy_current, 0, - global_param.calendar, global_param.time_units); - dtime = time_num + offset; - // put in netCDF file - dstart[0] = 0; - status = nc_put_var1_double(nc_state_file->nc_id, - nc_state_file->time_varid, - dstart, &dtime); - check_nc_status(status, "Error writing time variable"); - - // populate lat/lon - if (global_domain.info.n_coord_dims == 1) { - dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - dcount[0] = nc_state_file->ni_size; - // implicitly nested loop over ni and nj with j set to 0 - for (i = 0; i < nc_state_file->ni_size; i++) { - dvar[i] = (double) global_domain.locations[i].longitude; - } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - free(dvar); - - dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - dcount[0] = nc_state_file->nj_size; - // implicitly nested loop over ni and nj with i set to 0; - // j stride = ni_size - for (j = 0; j < nc_state_file->nj_size; j++) { - dvar[j] = - (double) global_domain.locations[j * - nc_state_file->ni_size]. - latitude; - } - - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - free(dvar); + if (mpi_rank == VIC_MPI_ROOT) { + dt_seconds_to_time_units(global_param.time_units, global_param.dt, + &offset); + time_num = date2num(global_param.time_origin_num, dmy_current, 0, + global_param.calendar, global_param.time_units); + dtime = time_num + offset; + // put in netCDF file + dstart[0] = 0; + status = nc_put_var1_double(nc_state_file->nc_id, + nc_state_file->time_varid, + dstart, &dtime); + check_nc_status(status, "Error writing time variable"); } - else if (global_domain.info.n_coord_dims == 2) { - dvar = calloc(global_domain.ncells_total, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - for (i = 0; i < global_domain.ncells_total; i++) { - dvar[i] = (double) global_domain.locations[i].longitude; + // populate lat/lon + if (mpi_rank == VIC_MPI_ROOT) { + if (global_domain.info.n_coord_dims == 1) { + dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + dcount[0] = nc_state_file->ni_size; + // implicitly nested loop over ni and nj with j set to 0 + for (i = 0; i < nc_state_file->ni_size; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + + dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + dcount[0] = nc_state_file->nj_size; + // implicitly nested loop over ni and nj with i set to 0; + // j stride = ni_size + for (j = 0; j < nc_state_file->nj_size; j++) { + dvar[j] = + (double) global_domain.locations[j * + nc_state_file->ni_size]. + latitude; + } + + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + } + else if (global_domain.info.n_coord_dims == 2) { + dvar = calloc(global_domain.ncells_total, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + dcount[0] = nc_state_file->nj_size; + dcount[1] = nc_state_file->ni_size; + + for (i = 0; i < global_domain.ncells_total; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + + for (i = 0; i < global_domain.ncells_total; + i++) { + dvar[i] = (double) global_domain.locations[i].latitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lat in %s", filename); + + free(dvar); } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - - for (i = 0; i < global_domain.ncells_total; - i++) { - dvar[i] = (double) global_domain.locations[i].latitude; + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); } - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lat in %s", filename); - - free(dvar); - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); } // Variables for other dimensions (all 1-dimensional) - ndims = 1; - - // vegetation classes - dimids[0] = nc_state_file->veg_dimid; - dcount[0] = nc_state_file->veg_size; - ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->veg_size; j++) { - ivar[j] = (int) j + 1; - } - status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, dcount, - ivar); - check_nc_status(status, "Error writing veg var id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - - // snow bands - dimids[0] = nc_state_file->band_dimid; - dcount[0] = nc_state_file->band_size; - ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->band_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, snow_band_var_id, dstart, - dcount, ivar); - check_nc_status(status, "Error writing snow band id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - - // soil layers - dimids[0] = nc_state_file->layer_dimid; - dcount[0] = nc_state_file->layer_size; - ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->layer_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, dcount, - ivar); - check_nc_status(status, "Error writing layer id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; + if (mpi_rank == VIC_MPI_ROOT) { + ndims = 1; + + // vegetation classes + dimids[0] = nc_state_file->veg_dimid; + dcount[0] = nc_state_file->veg_size; + ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->veg_size; j++) { + ivar[j] = (int) j + 1; + } + status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, dcount, + ivar); + check_nc_status(status, "Error writing veg var id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // snow bands + dimids[0] = nc_state_file->band_dimid; + dcount[0] = nc_state_file->band_size; + ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->band_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, snow_band_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing snow band id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // soil layers + dimids[0] = nc_state_file->layer_dimid; + dcount[0] = nc_state_file->layer_size; + ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->layer_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, dcount, + ivar); + check_nc_status(status, "Error writing layer id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // frost areas + dimids[0] = nc_state_file->frost_dimid; + dcount[0] = nc_state_file->frost_size; + ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->frost_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing frost id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); } - free(ivar); - - // frost areas - dimids[0] = nc_state_file->frost_dimid; - dcount[0] = nc_state_file->frost_size; - ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - for (j = 0; j < nc_state_file->frost_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, dstart, - dcount, ivar); - check_nc_status(status, "Error writing frost id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; + // initialize dvar for soil thermal node deltas and depths + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + // set missing values + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; } - free(ivar); - // soil thermal node deltas - dimids[0] = nc_state_file->node_dimid; - dcount[0] = nc_state_file->node_size; - status = nc_put_vara_double(nc_state_file->nc_id, dz_node_var_id, dstart, - dcount, soil_con[0].dz_node); - check_nc_status(status, "Error writing thermal node deltas"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; + // soil thermal node deltas (dimension: node, lat, lon) + dstart[0] = 0; + dstart[1] = 0; + dstart[2] = 0; + dcount[0] = 1; + dcount[1] = nc_state_file->nj_size; + dcount[2] = nc_state_file->ni_size; + for (j = 0; j < nc_state_file->node_size; j++) { + dstart[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = soil_con[i].dz_node[j]; + } + gather_put_nc_field_double(nc_state_file->nc_id, + dz_node_var_id, + nc_state_file->d_fillvalue, + dstart, dcount, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; + } } - // soil thermal node depths - dimids[0] = nc_state_file->node_dimid; - dcount[0] = nc_state_file->node_size; - status = nc_put_vara_double(nc_state_file->nc_id, node_depth_var_id, dstart, - dcount, soil_con[0].Zsum_node); - check_nc_status(status, "Error writing thermal node depths"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; + // soil thermal node depths (dimension: node, lat, lon) + dstart[0] = 0; + dstart[1] = 0; + dstart[2] = 0; + dcount[0] = 1; + dcount[1] = nc_state_file->nj_size; + dcount[2] = nc_state_file->ni_size; + for (j = 0; j < nc_state_file->node_size; j++) { + dstart[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = soil_con[i].Zsum_node[j]; + } + gather_put_nc_field_double(nc_state_file->nc_id, + node_depth_var_id, + nc_state_file->d_fillvalue, + dstart, dcount, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; + } } if (options.LAKES) { From c37df1ee3b8a7136322b90b87cc87596e9aab6cf Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 14:44:41 +0100 Subject: [PATCH 071/294] added get_nc_var_type.c --- .../shared_image/src/get_nc_var_type.c | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 vic/drivers/shared_image/src/get_nc_var_type.c diff --git a/vic/drivers/shared_image/src/get_nc_var_type.c b/vic/drivers/shared_image/src/get_nc_var_type.c new file mode 100644 index 000000000..80a674de6 --- /dev/null +++ b/vic/drivers/shared_image/src/get_nc_var_type.c @@ -0,0 +1,60 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Get netCDF variable type. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Get netCDF variable type. + *****************************************************************************/ +int +get_nc_var_type(char *nc_name, + char *var_name) +{ + int nc_id; + int var_id; + int status; + int xtypep; + + // open the netcdf file + status = nc_open(nc_name, NC_NOWRITE, &nc_id); + check_nc_status(status, "Error opening %s", nc_name); + + // get variable id + status = nc_inq_varid(nc_id, var_name, &var_id); + check_nc_status(status, "Error getting variable id %s in %s", var_name, + nc_name); + + // get type ID + status = nc_inq_var(nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); + check_nc_status(status, "Error getting variable type %s in %s", var_name, + nc_name); + + // close the netcdf file + status = nc_close(nc_id); + check_nc_status(status, "Error closing %s", nc_name); + + return(xtypep); +} From b772dccbcc135ad08031d43a9f12aa3e069a7d0e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 15:25:29 +0100 Subject: [PATCH 072/294] little update --- {.github.com => .github}/CONTRIBUTING.md | 0 {.github.com => .github}/ISSUE_TEMPLATE.md | 0 .../PULL_REQUEST_TEMPLATE.md | 0 tests/system/system_tests.cfg | 244 ------------------ vic/drivers/shared_image/src/vic_store.c | 11 + 5 files changed, 11 insertions(+), 244 deletions(-) rename {.github.com => .github}/CONTRIBUTING.md (100%) rename {.github.com => .github}/ISSUE_TEMPLATE.md (100%) rename {.github.com => .github}/PULL_REQUEST_TEMPLATE.md (100%) diff --git a/.github.com/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from .github.com/CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/.github.com/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 100% rename from .github.com/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md diff --git a/.github.com/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github.com/PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 6f126826b..be22e51df 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -7,250 +7,6 @@ mpi_proc = 4 expected_retval = 0 check = output_file_nans -[System-check_classic_nans] -driver = classic -test_description = Short simulation to ensure system tests configuration works - classic driver -global_parameter_file = global.classic.STEHE.txt -expected_retval = 0 -check = output_file_nans - -[System-restart_classic_noFullEnergy_noFrozenSoil] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -# If test_type == exact_restart -# Full period - start and end date -# Full period run will start with no initial state file, and the last time step state will be saved -start_date = 1949-01-01 -end_date = 1949-01-10 -# Dates to split the run -# E.g., if the full running period is 1949-01-01 to 1949-01-10, and split at 1949-01-05, then the first run would be 1949-01-01 to 1949-01-05, the second run would be 1949-01-06 to 1949-01-10 -# There can be multiple splitting dates -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - -[System-restart_classic_FullEnergy_noFrozenSoil] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE - -[System-restart_classic_noFullEnergy_FrozenSoil] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_classic_FullEnergy_FrozenSoil] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_classic_noFullEnergy_noFrozenSoil_BinState] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE -STATE_FORMAT=BINARY - -[System-restart_classic_FullEnergy_noFrozenSoil_BinState] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE -STATE_FORMAT=BINARY - -[System-restart_classic_noFullEnergy_FrozenSoil_BinState] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 -STATE_FORMAT=BINARY - -[System-restart_classic_FullEnergy_FrozenSoil_BinState] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file -driver = classic -global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 -STATE_FORMAT=BINARY - -[System-restart_image_noFullEnergy_noFrozenSoil] -test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.txt -mpi_proc = 4 -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - -[System-restart_image_FullEnergy_noFrozenSoil] -test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.txt -mpi_proc = 4 -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=FALSE - -[System-restart_image_noFullEnergy_FrozenSoil] -test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt -mpi_proc = 4 -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=TRUE -NODES=10 - -[System-restart_image_FullEnergy_FrozenSoil] -test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - image driver -driver = image -global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt -mpi_proc = 4 -expected_retval = 0 -check = exact_restart -[[restart]] -start_date = 1949-01-01 -end_date = 1949-01-10 -split_dates = 1949-01-05 -[[options]] -FULL_ENERGY=TRUE -FROZEN_SOIL=TRUE -NODES=10 - -[System-streams_classic_compare_to_instantaneous] -test_description = Test that the stream averaging is working expected. -driver = classic -global_parameter_file = global.classic.STEHE.multistream.txt -expected_retval = 0 -check = multistream - -[System-streams_classic_all_output_vars] -test_description = Test that all output variables can be successfully written to a stream -driver = classic -global_parameter_file = global.classic.STEHE.allhistvars.txt -expected_retval = 0 -check = nonans - -[System-streams_image_compare_to_instantaneous] -test_description = Test that the stream averaging is working expected. -driver = image -global_parameter_file = global.image.STEHE.multistream.txt -expected_retval = 0 -check = multistream, nonans - -[System-streams_image_all_output_vars] -test_description = Test that all output variables can be successfully written to a stream -driver = image -global_parameter_file = global.image.STEHE.allhistvars.txt -expected_retval = 0 -check = nonans - -[System-mpi_image_check_identical_results] -test_description = check that multi-processor runs produce identical results - image driver -driver = image -global_parameter_file = global.image.STEHE.mpi.txt -expected_retval = 0 -check = mpi -[[mpi]] -# A list of number of processors to run and compare (need at least a list of two numbers) -n_proc = 1,4 - -[System-drivers_match] -test_description = Test whether classic driver and image driver produce similar results -driver = classic,image -# A list of global parameter template files; in the order corresponding to "driver" specified above -global_parameter_file = global.classic.STEHE.txt,global.image.STEHE.txt -expected_retval = 0 -check = driver_match -[[options]] -FULL_ENERGY=FALSE -FROZEN_SOIL=FALSE - [System-check-image-and-rvic] test_description = image driver with rvic routing enabled driver = image diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index da77839df..9235915ce 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1666,6 +1666,17 @@ initialize_state_file(char *filename, &(nc_state_file->node_dimid)); check_nc_status(status, "Error defining soil_node in %s", filename); + // Add routing dimensions + status = nc_def_dim(nc_state_file->nc_id, "outlet", + nc_state_file->outlet_size, + &(nc_state_file->outlet_dimid)); + check_nc_status(status, "Error defining outlet in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", + nc_state_file->routing_timestep_size, + &(nc_state_file->routing_timestep_dimid)); + check_nc_status(status, "Error defining routing_timestep in %s", filename); + if (options.LAKES) { status = nc_def_dim(nc_state_file->nc_id, "lake_node", nc_state_file->lake_node_size, From 972fbaba5c679a6aeb3402822b62486cc4181e9a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 15:52:57 +0100 Subject: [PATCH 073/294] little update --- .travis.yml | 2 +- tests/system/system_tests.cfg | 246 +++++++++++++++++++++++++++++++++- 2 files changed, 246 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e6cad1da8..b8e7293b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='image' EXTENSIONS='ROUT=rout_rvic' + env: TESTID='image-rvic' EXTENSIONS='ROUT=rout_rvic' addons: apt_packages: - libnetcdf-dev diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index be22e51df..78ce3252e 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -7,9 +7,253 @@ mpi_proc = 4 expected_retval = 0 check = output_file_nans +[System-check_classic_nans] +driver = classic +test_description = Short simulation to ensure system tests configuration works - classic driver +global_parameter_file = global.classic.STEHE.txt +expected_retval = 0 +check = output_file_nans + +[System-restart_classic_noFullEnergy_noFrozenSoil] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +# If test_type == exact_restart +# Full period - start and end date +# Full period run will start with no initial state file, and the last time step state will be saved +start_date = 1949-01-01 +end_date = 1949-01-10 +# Dates to split the run +# E.g., if the full running period is 1949-01-01 to 1949-01-10, and split at 1949-01-05, then the first run would be 1949-01-01 to 1949-01-05, the second run would be 1949-01-06 to 1949-01-10 +# There can be multiple splitting dates +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + +[System-restart_classic_FullEnergy_noFrozenSoil] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE + +[System-restart_classic_noFullEnergy_FrozenSoil] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_classic_FullEnergy_FrozenSoil] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_classic_noFullEnergy_noFrozenSoil_BinState] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE +STATE_FORMAT=BINARY + +[System-restart_classic_FullEnergy_noFrozenSoil_BinState] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE +STATE_FORMAT=BINARY + +[System-restart_classic_noFullEnergy_FrozenSoil_BinState] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 +STATE_FORMAT=BINARY + +[System-restart_classic_FullEnergy_FrozenSoil_BinState] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - classic driver, binary state file +driver = classic +global_parameter_file = global.classic.STEHE.restart.FROZEN_SOIL.txt +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 +STATE_FORMAT=BINARY + +[System-restart_image_noFullEnergy_noFrozenSoil] +test_description = Exact restart (falseFULL_ENERGY flaseFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.txt +mpi_proc = 4 +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + +[System-restart_image_FullEnergy_noFrozenSoil] +test_description = Exact restart (trueFULL_ENERGY flaseFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.txt +mpi_proc = 4 +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=FALSE + +[System-restart_image_noFullEnergy_FrozenSoil] +test_description = Exact restart (falseFULL_ENERGY trueFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +mpi_proc = 4 +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=TRUE +NODES=10 + +[System-restart_image_FullEnergy_FrozenSoil] +test_description = Exact restart (trueFULL_ENERGY trueFROZEN_SOIL) - image driver +driver = image +global_parameter_file = global.image.STEHE.restart.FROZEN_SOIL.txt +mpi_proc = 4 +expected_retval = 0 +check = exact_restart +[[restart]] +start_date = 1949-01-01 +end_date = 1949-01-10 +split_dates = 1949-01-05 +[[options]] +FULL_ENERGY=TRUE +FROZEN_SOIL=TRUE +NODES=10 + +[System-streams_classic_compare_to_instantaneous] +test_description = Test that the stream averaging is working expected. +driver = classic +global_parameter_file = global.classic.STEHE.multistream.txt +expected_retval = 0 +check = multistream + +[System-streams_classic_all_output_vars] +test_description = Test that all output variables can be successfully written to a stream +driver = classic +global_parameter_file = global.classic.STEHE.allhistvars.txt +expected_retval = 0 +check = nonans + +[System-streams_image_compare_to_instantaneous] +test_description = Test that the stream averaging is working expected. +driver = image +global_parameter_file = global.image.STEHE.multistream.txt +expected_retval = 0 +check = multistream, nonans + +[System-streams_image_all_output_vars] +test_description = Test that all output variables can be successfully written to a stream +driver = image +global_parameter_file = global.image.STEHE.allhistvars.txt +expected_retval = 0 +check = nonans + +[System-mpi_image_check_identical_results] +test_description = check that multi-processor runs produce identical results - image driver +driver = image +global_parameter_file = global.image.STEHE.mpi.txt +expected_retval = 0 +check = mpi +[[mpi]] +# A list of number of processors to run and compare (need at least a list of two numbers) +n_proc = 1,4 + +[System-drivers_match] +test_description = Test whether classic driver and image driver produce similar results +driver = classic,image +# A list of global parameter template files; in the order corresponding to "driver" specified above +global_parameter_file = global.classic.STEHE.txt,global.image.STEHE.txt +expected_retval = 0 +check = driver_match +[[options]] +FULL_ENERGY=FALSE +FROZEN_SOIL=FALSE + [System-check-image-and-rvic] test_description = image driver with rvic routing enabled -driver = image +driver = image-rvic global_parameter_file = global.image.STEHE.rvic.txt domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc mpi_proc = 4 From 2736f407477c3318b82ecaa8c8a30a006b78c446 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 16:21:14 +0100 Subject: [PATCH 074/294] little update --- .travis.yml | 2 +- ci/image-rvic.travis | 98 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 ci/image-rvic.travis diff --git a/.travis.yml b/.travis.yml index b8e7293b0..d9ae597a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='image-rvic' EXTENSIONS='ROUT=rout_rvic' + env: TESTID='image-rvic' addons: apt_packages: - libnetcdf-dev diff --git a/ci/image-rvic.travis b/ci/image-rvic.travis new file mode 100644 index 000000000..9678bedfc --- /dev/null +++ b/ci/image-rvic.travis @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +DRIVER_PATH="${TRAVIS_BUILD_DIR}/vic/drivers/image/" +DRIVER_EXE="${DRIVER_PATH}vic_image.exe" +SAMPLES_PATH="${TRAVIS_BUILD_DIR}/samples/" + +function vic_before_install { + echo vic_before_install + echo $PATH + if [ ! -z "$USE_CC" ]; then + echo "export CC=$USE_CC" + export CC=$USE_CC; + $CC --version + fi + if [ "$TRAVIS_OS_NAME" = "osx" ]; then + echo "Testing on osx" + if [ ! -z "$BREW_TAPS" ]; then + for tap in $BREW_TAPS + do + brew tap $tap + done + fi + if [ ! -z "$BREW_INSTALLS" ]; then + brew update + for pkg in $BREW_INSTALLS + do + brew outdated $pkg || brew upgrade $pkg || brew install $pkg + brew link $pkg + done + # building openmpi from source - not sure why the homebrew install + # isn't working right. + brew install homebrew/versions/gcc49 + brew reinstall open-mpi --build-from-source + fi + export TRAVIS_MPIPATH=/usr/local + export NC_LIBS=$(/usr/local/bin/nc-config --libs) + export NC_CFLAGS=$(/usr/local/bin/nc-config --cflags) + else + export TRAVIS_MPIPATH="${HOME}/mpich" + export NC_LIBS=$(/usr/bin/nc-config --libs) + export NC_CFLAGS=$(/usr/bin/nc-config --cflags) + + # Install MPICH + if [ ! -d ${TRAVIS_MPIPATH} ]; then + install_mpich + else + echo "MPICH installed..." + fi + fi + export PATH=${TRAVIS_MPIPATH}/bin:${PATH} + find ${TRAVIS_MPIPATH} -name mpiexec + mpiexec --version + find ${TRAVIS_MPIPATH} -name mpicc + export MPICC="${TRAVIS_MPIPATH}/bin/mpicc" + $MPICC --version + echo "NETCDF LIB FLAGS ------> ${NC_LIBS}" + echo "NETCDF C FLAGS --------> ${NC_CFLAGS}" +} + +function vic_install { + echo vic_install + cd ${TRAVIS_BUILD_DIR} + echo $PWD + make full ROUT=rout_rvic -C $DRIVER_PATH +} + +function vic_before_script { + echo vic_before_script + if [ ! -f $DRIVER_EXE ]; then + echo "Executable (${DRIVER_EXE}) not found!" + exit 1 + fi + + echo "Getting sample data" + bash ${SAMPLES_PATH}/get_sample_data.bash + +} + +function vic_script { + echo vic_script + $DRIVER_EXE -v + $DRIVER_EXE -o + + # Run test package + ./tests/run_tests.py unit examples system \ + --image=${DRIVER_EXE} \ + --data_dir=${SAMPLES_PATH}/data +} + +function vic_after_success { + echo vic_after_success + echo "Success!" +} + +function vic_after_failure { + echo vic_after_failure + echo "Test failed -- please review the log" +} From 160b165a4a66876bdb81ba8a57eda0c2001f5771 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 16:47:19 +0100 Subject: [PATCH 075/294] little update --- .travis.yml | 4 ++-- ci/{image-rvic.travis => imagervic.travis} | 0 tests/system/system_tests.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename ci/{image-rvic.travis => imagervic.travis} (100%) diff --git a/.travis.yml b/.travis.yml index d9ae597a8..b7cc01151 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='image-rvic' + env: TESTID='imagervic' addons: apt_packages: - libnetcdf-dev @@ -29,7 +29,7 @@ matrix: - netcdf-doc - gfortran - valgrind - # open-mpi is built from source in image.travis + # open-mpi is built from source in imagervic.travis # CESM Driver - compiler: gcc os: linux diff --git a/ci/image-rvic.travis b/ci/imagervic.travis similarity index 100% rename from ci/image-rvic.travis rename to ci/imagervic.travis diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 78ce3252e..8860404a0 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -253,7 +253,7 @@ FROZEN_SOIL=FALSE [System-check-image-and-rvic] test_description = image driver with rvic routing enabled -driver = image-rvic +driver = imagervic global_parameter_file = global.image.STEHE.rvic.txt domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc mpi_proc = 4 From bf78ddeb2effd47ecee2bc2a4e0563948e6ef7dc Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Jan 2017 17:25:16 +0100 Subject: [PATCH 076/294] little update --- .travis.yml | 4 ++-- ci/{imagervic.travis => rvic.travis} | 0 tests/system/system_tests.cfg | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename ci/{imagervic.travis => rvic.travis} (100%) diff --git a/.travis.yml b/.travis.yml index b7cc01151..1af4343ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='imagervic' + env: TESTID='rvic' addons: apt_packages: - libnetcdf-dev @@ -95,7 +95,7 @@ before_install: - install_miniconda - vic_before_install install: - - vic_install ${ROUT} + - vic_install before_script: - vic_before_script script: diff --git a/ci/imagervic.travis b/ci/rvic.travis similarity index 100% rename from ci/imagervic.travis rename to ci/rvic.travis diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index 8860404a0..f6b66c405 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -251,11 +251,11 @@ check = driver_match FULL_ENERGY=FALSE FROZEN_SOIL=FALSE -[System-check-image-and-rvic] +[System-check-rvic] test_description = image driver with rvic routing enabled -driver = imagervic +driver = rvic global_parameter_file = global.image.STEHE.rvic.txt -domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc +#domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc mpi_proc = 4 expected_retval = 0 check = nonans From 690b5365f8dbe6dbc7124ea237ddda082843b48e Mon Sep 17 00:00:00 2001 From: ymao Date: Tue, 7 Feb 2017 11:04:14 -0800 Subject: [PATCH 077/294] Cleaned up vic_store.c the part related to advancing dmy_current for state file timestamp - done only for image driver; CESM driver still needs to be updated --- vic/drivers/image/include/vic_driver_image.h | 2 +- vic/drivers/image/src/check_save_state_flag.c | 13 +++---- vic/drivers/image/src/vic_image.c | 5 ++- .../include/vic_driver_shared_image.h | 4 +- vic/drivers/shared_image/src/vic_store.c | 37 ++++--------------- 5 files changed, 20 insertions(+), 41 deletions(-) diff --git a/vic/drivers/image/include/vic_driver_image.h b/vic/drivers/image/include/vic_driver_image.h index b11f95817..0c64a2d39 100644 --- a/vic/drivers/image/include/vic_driver_image.h +++ b/vic/drivers/image/include/vic_driver_image.h @@ -31,7 +31,7 @@ #define VIC_DRIVER "Image" -bool check_save_state_flag(size_t); +bool check_save_state_flag(size_t, dmy_struct *dmy_offset); void display_current_settings(int); void get_forcing_file_info(param_set_struct *param_set, size_t file_num); void get_global_param(FILE *); diff --git a/vic/drivers/image/src/check_save_state_flag.c b/vic/drivers/image/src/check_save_state_flag.c index 39e7ef3a3..d71099719 100644 --- a/vic/drivers/image/src/check_save_state_flag.c +++ b/vic/drivers/image/src/check_save_state_flag.c @@ -32,14 +32,13 @@ * current time step *****************************************************************************/ bool -check_save_state_flag(size_t current) +check_save_state_flag(size_t current, dmy_struct *dmy_offset) { extern global_param_struct global_param; extern dmy_struct *dmy; double offset; double time_num; - dmy_struct dmy_offset; // Advance dmy by one timestep because dmy is the "timestep-beginning" // timestamp, but we want to check whether the end of the current @@ -50,14 +49,14 @@ check_save_state_flag(size_t current) time_num += offset; num2date(global_param.time_origin_num, time_num, 0, global_param.calendar, TIME_UNITS_DAYS, - &dmy_offset); + dmy_offset); // Check if the end of the current time step is equal to the state output // timestep specified by user - if (dmy_offset.year == global_param.stateyear && - dmy_offset.month == global_param.statemonth && - dmy_offset.day == global_param.stateday && - dmy_offset.dayseconds == global_param.statesec) { + if (dmy_offset->year == global_param.stateyear && + dmy_offset->month == global_param.statemonth && + dmy_offset->day == global_param.stateday && + dmy_offset->dayseconds == global_param.statesec) { return true; } else { diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 9ad7c04ba..20a4000d7 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -33,6 +33,7 @@ size_t *mpi_map_mapping_array = NULL; all_vars_struct *all_vars = NULL; force_data_struct *force = NULL; dmy_struct *dmy = NULL; +dmy_struct dmy_state; filenames_struct filenames; filep_struct filep; domain_struct global_domain; @@ -142,9 +143,9 @@ main(int argc, vic_write_output(&(dmy[current])); // Write state file - if (check_save_state_flag(current)) { + if (check_save_state_flag(current, &dmy_state)) { debug("writing state file for timestep %zu", current); - vic_store(&(dmy[current]), state_filename); + vic_store(&dmy_state, state_filename); debug("finished storing state file: %s", state_filename) } } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 98542935a..1e7513a12 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -221,7 +221,7 @@ void initialize_global_structures(void); void initialize_history_file(nc_file_struct *nc, stream_struct *stream, dmy_struct *dmy_current); void initialize_state_file(char *filename, nc_file_struct *nc_state_file, - dmy_struct *dmy_current); + dmy_struct *dmy_state); void initialize_location(location_struct *location); int initialize_model_state(all_vars_struct *all_vars, size_t Nveg, size_t Nnodes, double surf_temp, @@ -256,7 +256,7 @@ void vic_init(void); void vic_init_output(dmy_struct *dmy_current); void vic_restore(void); void vic_start(void); -void vic_store(dmy_struct *dmy_current, char *state_filename); +void vic_store(dmy_struct *dmy_state, char *state_filename); void vic_write(stream_struct *stream, nc_file_struct *nc_hist_file, dmy_struct *dmy_current); void vic_write_output(dmy_struct *dmy); diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 942724c6a..194ad1229 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -30,7 +30,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store(dmy_struct *dmy_current, +vic_store(dmy_struct *dmy_state, char *filename) { extern filenames_struct filenames; @@ -64,27 +64,13 @@ vic_store(dmy_struct *dmy_current, set_nc_state_file_info(&nc_state_file); - // advance dmy_current by one timestep since dmy_current is the - // timestep-beginning timestamp, and state file date should be - // the end of the current time step - dt_seconds_to_time_units(global_param.time_units, global_param.dt, - &offset); - time_num = date2num(global_param.time_origin_num, dmy_current, 0, - global_param.calendar, global_param.time_units); - end_time_num = time_num + offset; - - // allocate dmy struct for end of current time step - num2date(global_param.time_origin_num, end_time_num, 0., - global_param.calendar, global_param.time_units, - &end_time_date); - // create netcdf file for storing model state sprintf(filename, "%s.%04i%02i%02i_%05u.nc", - filenames.statefile, end_time_date.year, - end_time_date.month, end_time_date.day, - end_time_date.dayseconds); + filenames.statefile, dmy_state->year, + dmy_state->month, dmy_state->day, + dmy_state->dayseconds); - initialize_state_file(filename, &nc_state_file, dmy_current); + initialize_state_file(filename, &nc_state_file, dmy_state); if (mpi_rank == VIC_MPI_ROOT) { debug("writing state file: %s", filename); @@ -1539,7 +1525,7 @@ set_nc_state_var_info(nc_file_struct *nc) void initialize_state_file(char *filename, nc_file_struct *nc_state_file, - dmy_struct *dmy_current) + dmy_struct *dmy_state) { extern option_struct options; extern domain_struct global_domain; @@ -1572,7 +1558,6 @@ initialize_state_file(char *filename, double *dvar = NULL; int *ivar = NULL; double offset; - double time_num; // open the netcdf file if (mpi_rank == VIC_MPI_ROOT) { @@ -1919,15 +1904,9 @@ initialize_state_file(char *filename, } // time variable - // advance dmy_current by one timestep because dmy_current is the - // "timestep-beginning" timestamp, but we want the time variable to be - // the end of the current time step if (mpi_rank == VIC_MPI_ROOT) { - dt_seconds_to_time_units(global_param.time_units, global_param.dt, - &offset); - time_num = date2num(global_param.time_origin_num, dmy_current, 0, - global_param.calendar, global_param.time_units); - dtime = time_num + offset; + dtime = date2num(global_param.time_origin_num, dmy_state, 0, + global_param.calendar, global_param.time_units); // put in netCDF file dstart[0] = 0; status = nc_put_var1_double(nc_state_file->nc_id, From 9419e39baafc636bacb03d74b7b2616fbc02e715 Mon Sep 17 00:00:00 2001 From: dgergel Date: Sun, 12 Feb 2017 14:26:17 -0500 Subject: [PATCH 078/294] restructure cesm interface script to handle state file timestep in accordance with image driver --- vic/drivers/cesm/src/cesm_interface_c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 11e874e77..e08935ddd 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -138,6 +138,10 @@ vic_cesm_run(vic_clock *vclock) // Write history files vic_write_output(&dmy_current); + // advance the clock + advance_time(); + assert_time_insync(vlock, &dmy_current); + // if save: if (vclock->state_flag) { // write state file @@ -148,10 +152,6 @@ vic_cesm_run(vic_clock *vclock) // reset x2l fields initialize_x2l_data(); - // advance the clock - advance_time(); - assert_time_insync(vclock, &dmy_current); - // stop vic run timer timer_stop(&(global_timers[TIMER_VIC_RUN])); // stop vic all timer From 79d828905593a4ca2511a59f4a1b3ef03364042d Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 12 Feb 2017 15:11:28 -0500 Subject: [PATCH 079/294] fixed typo --- vic/drivers/cesm/src/cesm_interface_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index e08935ddd..e5d1e500a 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -140,7 +140,7 @@ vic_cesm_run(vic_clock *vclock) // advance the clock advance_time(); - assert_time_insync(vlock, &dmy_current); + assert_time_insync(vclock, &dmy_current); // if save: if (vclock->state_flag) { From 338239aca6724a061b1ceff6cafa102a4fd0b70c Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 12:48:26 +0100 Subject: [PATCH 080/294] Moved RVIC part of global_param section to VIC itself --- vic/drivers/image/src/get_global_param.c | 3 + vic/drivers/image/src/vic_image.c | 3 - .../include/vic_driver_shared_image.h | 1 + vic/extensions/rout_rvic/include/rout.h | 2 - vic/extensions/rout_rvic/src/rout_alloc.c | 9 ++- vic/extensions/rout_rvic/src/rout_init.c | 21 ++--- vic/extensions/rout_rvic/src/rout_start.c | 81 ------------------- vic/extensions/rout_stub/include/rout.h | 1 - vic/extensions/rout_stub/src/rout.c | 8 -- 9 files changed, 20 insertions(+), 109 deletions(-) delete mode 100644 vic/extensions/rout_rvic/src/rout_start.c diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index c1865f1d0..47438f8a9 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -382,6 +382,9 @@ get_global_param(FILE *gp) else if (strcasecmp("PARAMETERS", optstr) == 0) { sscanf(cmdstr, "%*s %s", filenames.params); } + else if (strcasecmp("ROUT_PARAM", optstr) == 0) { + sscanf(cmdstr, "%*s %s", filenames.rout_params); + } else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("TRUE", flgstr) == 0) { diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 560569f42..3ab8d00fb 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -111,9 +111,6 @@ main(int argc, // read global parameters vic_image_start(); - // read global parameters for routing - rout_start(); // Routing routine (extension) - // allocate memory vic_alloc(); diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 1a172640f..c3131b171 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -184,6 +184,7 @@ typedef struct { char domain[MAXSTRING]; /**< domain file name */ char constants[MAXSTRING]; /**< model constants file name */ char params[MAXSTRING]; /**< model parameters file name */ + char rout_params[MAXSTRING]; /**< routing parameters file name */ char init_state[MAXSTRING]; /**< initial model state file name */ char result_dir[MAXSTRING]; /**< directory where results will be written */ char statefile[MAXSTRING]; /**< name of file in which to store model state */ diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 45c0afdc1..ccfbbbdbc 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -57,7 +57,6 @@ typedef struct { * @brief main routing Struct *****************************************************************************/ typedef struct { - char param_filename[MAXSTRING]; rout_param_struct rout_param; double *ring; double *discharge; @@ -66,7 +65,6 @@ typedef struct { /****************************************************************************** * @brief Function prototypes for the rout_rvic extension *****************************************************************************/ -void rout_start(void); // read global parameters for routing void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 06c20d485..6e0236892 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -39,23 +39,24 @@ rout_alloc(void) int ivar; size_t d1count[1]; size_t d1start[1]; + extern filenames_struct filenames; d1count[0] = 0; d1start[0] = 1; // Get some values and dimensions - get_nc_field_int(rout.param_filename, + get_nc_field_int(filenames.rout_params, "full_time_length", d1start, d1count, &ivar); rout.rout_param.full_time_length = (int) ivar; - rout.rout_param.n_timesteps = get_nc_dimension(rout.param_filename, + rout.rout_param.n_timesteps = get_nc_dimension(filenames.rout_params, "timesteps"); - rout.rout_param.n_outlets = get_nc_dimension(rout.param_filename, + rout.rout_param.n_outlets = get_nc_dimension(filenames.rout_params, "outlets"); - rout.rout_param.n_sources = get_nc_dimension(rout.param_filename, + rout.rout_param.n_sources = get_nc_dimension(filenames.rout_params, "sources"); // Allocate memory in rout param_struct diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 8c332d12d..8ac6ba629 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -35,7 +35,8 @@ rout_init(void) extern int mpi_rank; extern rout_struct rout; extern domain_struct global_domain; - + extern filenames_struct filenames; + if (mpi_rank == VIC_MPI_ROOT) { int *ivar = NULL; double *dvar = NULL; @@ -78,7 +79,7 @@ rout_init(void) } // source2outlet_ind: source to outlet index mapping - get_nc_field_int(rout.param_filename, + get_nc_field_int(filenames.rout_params, "source2outlet_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -86,7 +87,7 @@ rout_init(void) } // source_time_offset: Number of leading timesteps ommited - get_nc_field_int(rout.param_filename, + get_nc_field_int(filenames.rout_params, "source_time_offset", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -94,7 +95,7 @@ rout_init(void) } // source_x_ind: x grid coordinate of source grid cell - get_nc_field_int(rout.param_filename, + get_nc_field_int(filenames.rout_params, "source_x_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -102,7 +103,7 @@ rout_init(void) } // source_y_ind: y grid coordinate of source grid cell - get_nc_field_int(rout.param_filename, + get_nc_field_int(filenames.rout_params, "source_y_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -110,7 +111,7 @@ rout_init(void) } // source_lat: Latitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, + get_nc_field_double(filenames.rout_params, "source_lat", &i1start, &rout.rout_param.n_sources, dvar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -118,7 +119,7 @@ rout_init(void) } // source_lon: Longitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, + get_nc_field_double(filenames.rout_params, "source_lon", &i1start, &rout.rout_param.n_sources, dvar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -126,7 +127,7 @@ rout_init(void) } // outlet_lat: Latitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, + get_nc_field_double(filenames.rout_params, "outlet_lat", &i1start, &rout.rout_param.n_outlets, dvar); for (i = 0; i < rout.rout_param.n_outlets; i++) { @@ -134,7 +135,7 @@ rout_init(void) } // outlet_lon: Longitude coordinate of source grid cell - get_nc_field_double(rout.param_filename, + get_nc_field_double(filenames.rout_params, "outlet_lon", &i1start, &rout.rout_param.n_outlets, dvar); for (i = 0; i < rout.rout_param.n_outlets; i++) { @@ -142,7 +143,7 @@ rout_init(void) } // Unit Hydrograph: - get_nc_field_double(rout.param_filename, + get_nc_field_double(filenames.rout_params, "unit_hydrograph", d3start, d3count, dvar); for (i = 0; diff --git a/vic/extensions/rout_rvic/src/rout_start.c b/vic/extensions/rout_rvic/src/rout_start.c deleted file mode 100644 index 3856f1c22..000000000 --- a/vic/extensions/rout_rvic/src/rout_start.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Read global parameters for routing. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Wrapper function for RVIC startup. - *****************************************************************************/ -void -rout_start(void) -{ - extern filenames_struct filenames; - extern filep_struct filep; - extern int mpi_rank; - - if (mpi_rank == VIC_MPI_ROOT) { - // read global settings - filep.globalparam = open_file(filenames.global, "r"); - get_global_param_rout(filep.globalparam); - } -} - -/****************************************************************************** - * @brief Read the VIC model global control file, getting values for - * global parameters specifically for RVIC. - *****************************************************************************/ -void -get_global_param_rout(FILE *gp) -{ - extern rout_struct rout; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - - /** Read through global control file to find parameters **/ - rewind(gp); - fgets(cmdstr, MAXSTRING, gp); - - while (!feof(gp)) { - if (cmdstr[0] != '#' && cmdstr[0] != '\n' && cmdstr[0] != '\0') { - sscanf(cmdstr, "%s", optstr); - - /* Handle case of comment line in which '#' is indented */ - if (optstr[0] == '#') { - fgets(cmdstr, MAXSTRING, gp); - continue; - } - - /************************************* - Get Model Global Parameters - *************************************/ - if (strcasecmp("ROUT_PARAM", optstr) == 0) { - sscanf(cmdstr, "%*s %s", rout.param_filename); - break; - } - } - fgets(cmdstr, MAXSTRING, gp); - } -} diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index b9bfea199..7c20d8e06 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -50,7 +50,6 @@ typedef struct { /****************************************************************************** * @brief prototypes for dummy functions of the rout_stub extension *****************************************************************************/ -void rout_start(void); // read global parameters for routing void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 8b5cf9d8d..917bea43d 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -26,14 +26,6 @@ #include -/****************************************************************************** - * @brief Read global parameters for routing. - *****************************************************************************/ -void -rout_start(void) -{ -} - /****************************************************************************** * @brief Allocate memory. *****************************************************************************/ From 94f35ba878f610e0672e09aa26fc675f20c84b43 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 13:29:10 +0100 Subject: [PATCH 081/294] streamlined with Master --- docs/Development/ReleaseNotes.md | 2 +- docs/Documentation/Drivers/Image/Domain.md | 51 ++++++++++++++++++++ vic/drivers/python/setup.py | 2 +- vic/drivers/shared_all/include/vic_version.h | 4 +- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 docs/Documentation/Drivers/Image/Domain.md diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 0981da430..e96ef1c2e 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -16,7 +16,7 @@ To check which release of VIC you are running: ------------------------------ ## VIC 5.0.1 -**Release date: (Unreleased)** +**Release date: (February 1, 2017)** #### Bug Fixes: diff --git a/docs/Documentation/Drivers/Image/Domain.md b/docs/Documentation/Drivers/Image/Domain.md new file mode 100644 index 000000000..cdfedb738 --- /dev/null +++ b/docs/Documentation/Drivers/Image/Domain.md @@ -0,0 +1,51 @@ +# VIC Domain file + +The Image Driver uses the [NetCDF](http://www.unidata.ucar.edu/software/netcdf/) file format to define model running domain. + +Below is a list of variables in the domain netCDF file. The dimensions of the netCDF file are `lat` and `lon`. Note that here only the type of variables (i.e., MASK, AREA, FRAC, LAT and LON) is listed; corresponding variable names in the input netCDF file are specified by user in the [Global Parameter File](GlobalParam.md). All the listed variables are required. + +| Variable | Dimension | Units | Type | Description | +|------------|-------------|----------|--------|-------------| +| LAT | [lat] | degree | double | Latitudes | +| LON | [lon] | degree | double | Longitues | +| MASK | [lat, lon] | N/A | integer | Mask of domain. 1 for grid cells inside considered domain; 0 for grid cells outside of domain. Cells outside of domain will not be run. Use run_cell variable in the parameter file to turn on/off active cells inside domain. | +| AREA | [lat, lon] | m2 | double | Area of grid cells. | +| FRAC | [lat, lon] | N/A | double | Fraction of grid cells that is land. | + +# Example netCDF format VIC 5 image driver domain file + +```shell +ncdump -h /ArkRed.domain.nc +netcdf ArkRed.domain { +dimensions: + lat = 66 ; + lon = 125 ; +variables: + int mask(lat, lon) ; + mask:comment = "0 indicates grid cell outside of domain" ; + mask:long_name = "domain mask" ; + double lon(lon) ; + lon:long_name = "longitude coordinate" ; + lon:units = "degrees_east" ; + double lat(lat) ; + lat:long_name = "latitude coordinate" ; + lat:units = "degrees_north" ; + double frac(lat, lon) ; + frac:long_name = "fraction of grid cell that is active" ; + frac:units = "1" ; + double area(lat, lon) ; + area:standard_name = "area" ; + area:long_name = "area of grid cell" ; + area:units = "m2" ; + +// global attributes: + :title = "VIC domain data" ; + :Conventions = "CF-1.6" ; + :history = "Wed Oct 12 15:48:42 2016: ncap2 -s mask=int(mask) ArkRed.domain.nc.float_mask ArkRed.domain.nc\n", + "created by ymao, 2016-09-23 18:17:58.761256" ; + :user_comment = "VIC domain data" ; + :source = "generated from VIC CONUS 1.8 deg model parameters, see Maurer et al. (2002) for more information" ; + :nco_openmp_thread_number = 1 ; +} +``` + diff --git a/vic/drivers/python/setup.py b/vic/drivers/python/setup.py index 44a58530d..68e00de93 100644 --- a/vic/drivers/python/setup.py +++ b/vic/drivers/python/setup.py @@ -25,7 +25,7 @@ MAJOR = 5 MINOR = 0 -MICRO = 0 +MICRO = 1 ISRELEASED = True VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) QUALIFIER = '' diff --git a/vic/drivers/shared_all/include/vic_version.h b/vic/drivers/shared_all/include/vic_version.h index e9b76fabf..f3062b87c 100644 --- a/vic/drivers/shared_all/include/vic_version.h +++ b/vic/drivers/shared_all/include/vic_version.h @@ -31,11 +31,11 @@ #define STR(x) STR_HELPER(x) #ifndef VERSION -#define VERSION "5.0.0 September 2, 2016" +#define VERSION "5.0.1 February 1, 2017" #endif #ifndef SHORT_VERSION -#define SHORT_VERSION "5.0.0" +#define SHORT_VERSION "5.0.1" #endif #ifndef GIT_VERSION From fb05fc8af071fed8d5fb51dd4ef7b8ab18d452a6 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 13:38:52 +0100 Subject: [PATCH 082/294] travis test1 --- ci/image.travis | 2 +- .../system/global.image.STEHE.allhistvars.txt | 2 + tests/system/global.image.STEHE.mpi.txt | 2 + .../system/global.image.STEHE.multistream.txt | 2 + ...global.image.STEHE.restart.FROZEN_SOIL.txt | 2 + tests/system/global.image.STEHE.restart.txt | 2 + tests/system/global.image.STEHE.rvic.txt | 74 ------------------- tests/system/global.image.STEHE.txt | 2 + tests/system/system_tests.cfg | 20 ++--- 9 files changed, 23 insertions(+), 85 deletions(-) delete mode 100644 tests/system/global.image.STEHE.rvic.txt diff --git a/ci/image.travis b/ci/image.travis index cf97bffb8..c0d022fe2 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -61,7 +61,7 @@ function vic_install { echo vic_install cd ${TRAVIS_BUILD_DIR} echo $PWD - make full $EXTENSIONS -C $DRIVER_PATH + make full -C $DRIVER_PATH } function vic_before_script { diff --git a/tests/system/global.image.STEHE.allhistvars.txt b/tests/system/global.image.STEHE.allhistvars.txt index 02ceb1bf0..7eb5fec49 100644 --- a/tests/system/global.image.STEHE.allhistvars.txt +++ b/tests/system/global.image.STEHE.allhistvars.txt @@ -38,6 +38,8 @@ PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20 NODES 3 SNOW_BAND TRUE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir/ OUTFILE allvars diff --git a/tests/system/global.image.STEHE.mpi.txt b/tests/system/global.image.STEHE.mpi.txt index d82c4e6c5..803186bd3 100644 --- a/tests/system/global.image.STEHE.mpi.txt +++ b/tests/system/global.image.STEHE.mpi.txt @@ -45,6 +45,8 @@ ORGANIC_FRACT FALSE LAI_SRC FROM_VEGPARAM SNOW_BAND TRUE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir OUTFILE fluxes diff --git a/tests/system/global.image.STEHE.multistream.txt b/tests/system/global.image.STEHE.multistream.txt index dca2f33f6..ed65fedae 100644 --- a/tests/system/global.image.STEHE.multistream.txt +++ b/tests/system/global.image.STEHE.multistream.txt @@ -37,6 +37,8 @@ WIND_H 10.0 PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc NODES 3 +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir/ # Instantaneous output diff --git a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt index 45e47ac44..ed4a1040b 100644 --- a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt +++ b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt @@ -44,6 +44,8 @@ JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE LAI_SRC FROM_VEGPARAM +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir OUTFILE fluxes diff --git a/tests/system/global.image.STEHE.restart.txt b/tests/system/global.image.STEHE.restart.txt index 1db3723f3..49d6b9212 100644 --- a/tests/system/global.image.STEHE.restart.txt +++ b/tests/system/global.image.STEHE.restart.txt @@ -45,6 +45,8 @@ ORGANIC_FRACT FALSE LAI_SRC FROM_VEGPARAM SNOW_BAND TRUE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir OUTFILE fluxes diff --git a/tests/system/global.image.STEHE.rvic.txt b/tests/system/global.image.STEHE.rvic.txt deleted file mode 100644 index e2907b766..000000000 --- a/tests/system/global.image.STEHE.rvic.txt +++ /dev/null @@ -1,74 +0,0 @@ -MODEL_STEPS_PER_DAY 24 -SNOW_STEPS_PER_DAY 24 -RUNOFF_STEPS_PER_DAY 24 - -STARTYEAR 1949 -STARTMONTH 1 -STARTDAY 1 -ENDYEAR 1949 -ENDMONTH 1 -ENDDAY 10 -CALENDAR PROLEPTIC_GREGORIAN - -FULL_ENERGY TRUE -FROZEN_SOIL FALSE - -#INIT_STATE -STATENAME $state_dir/states -STATEYEAR 1949 -STATEMONTH 1 -STATEDAY 11 -STATESEC 0 - -DOMAIN $test_data_dir/image/Stehekin/parameters/domain.stehekin.20151028.nc -DOMAIN_TYPE LAT lat -DOMAIN_TYPE LON lon -DOMAIN_TYPE MASK mask -DOMAIN_TYPE AREA area -DOMAIN_TYPE FRAC frac -DOMAIN_TYPE YDIM lat -DOMAIN_TYPE XDIM lon - -FORCING1 $test_data_dir/image/Stehekin/forcings/Stehekin_image_test.forcings_10days. -FORCE_TYPE AIR_TEMP tas -FORCE_TYPE PREC prcp -FORCE_TYPE PRESSURE pres -FORCE_TYPE SWDOWN dswrf -FORCE_TYPE LWDOWN dlwrf -FORCE_TYPE VP vp -FORCE_TYPE WIND wind -WIND_H 10.0 - -PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20160327.nc -SNOW_BAND TRUE -NODES 3 -BASEFLOW ARNO -JULY_TAVG_SUPPLIED FALSE -ORGANIC_FRACT FALSE - -ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc - -RESULT_DIR $result_dir/ - -OUTFILE fluxes -AGGFREQ NHOURS 1 -OUTVAR OUT_PREC -OUTVAR OUT_RAINF -OUTVAR OUT_SNOWF -OUTVAR OUT_AIR_TEMP -OUTVAR OUT_SWDOWN -OUTVAR OUT_LWDOWN -OUTVAR OUT_PRESSURE -OUTVAR OUT_WIND -OUTVAR OUT_DENSITY -OUTVAR OUT_REL_HUMID -OUTVAR OUT_QAIR -OUTVAR OUT_VP -OUTVAR OUT_VPD -OUTVAR OUT_RUNOFF -OUTVAR OUT_BASEFLOW -OUTVAR OUT_EVAP -OUTVAR OUT_SWE -OUTVAR OUT_SOIL_MOIST -OUTVAR OUT_ALBEDO -OUTVAR OUT_SOIL_TEMP diff --git a/tests/system/global.image.STEHE.txt b/tests/system/global.image.STEHE.txt index d7df3242f..e2907b766 100644 --- a/tests/system/global.image.STEHE.txt +++ b/tests/system/global.image.STEHE.txt @@ -46,6 +46,8 @@ BASEFLOW ARNO JULY_TAVG_SUPPLIED FALSE ORGANIC_FRACT FALSE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir/ OUTFILE fluxes diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index f6b66c405..bfeebc16c 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -232,8 +232,8 @@ check = nonans [System-mpi_image_check_identical_results] test_description = check that multi-processor runs produce identical results - image driver -driver = image -global_parameter_file = global.image.STEHE.mpi.txt +driver = image,rvic +global_parameter_file = global.image.STEHE.mpi.txt,global.image.STEHE.mpi.txt expected_retval = 0 check = mpi [[mpi]] @@ -251,11 +251,11 @@ check = driver_match FULL_ENERGY=FALSE FROZEN_SOIL=FALSE -[System-check-rvic] -test_description = image driver with rvic routing enabled -driver = rvic -global_parameter_file = global.image.STEHE.rvic.txt -#domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc -mpi_proc = 4 -expected_retval = 0 -check = nonans +#[System-check-rvic] +#test_description = image driver with rvic routing enabled +#driver = rvic +#global_parameter_file = global.image.STEHE.rvic.txt +##domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc +#mpi_proc = 4 +#expected_retval = 0 +#check = nonans From 3a400130063a5ff92c5a8e3a18902f729828d410 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 13:53:57 +0100 Subject: [PATCH 083/294] travis test2 --- tests/examples/global_param.image.STEHE.feb.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/examples/global_param.image.STEHE.feb.txt b/tests/examples/global_param.image.STEHE.feb.txt index f6b099845..a43cd3cde 100644 --- a/tests/examples/global_param.image.STEHE.feb.txt +++ b/tests/examples/global_param.image.STEHE.feb.txt @@ -38,6 +38,8 @@ PARAMETERS $test_data_dir/image/Stehekin/parameters/Stehekin_test_params_20 NODES 3 SNOW_BAND TRUE +ROUT_PARAM $test_data_dir/image/Stehekin/parameters/stehekin_parameters_01.rvic.prm.Stehekin.20150727.nc + RESULT_DIR $result_dir OUTFILE fluxes From 511a6107c91a623bfcfef069fb358b0e8c47169b Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 14:06:17 +0100 Subject: [PATCH 084/294] travis test3 --- .travis.yml | 2 +- ci/image.travis | 2 +- ci/rvic.travis | 98 ----------------------------------- tests/system/system_tests.cfg | 12 +---- 4 files changed, 4 insertions(+), 110 deletions(-) delete mode 100644 ci/rvic.travis diff --git a/.travis.yml b/.travis.yml index 1af4343ec..2229a52d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='rvic' + env: TESTID='image' EXTENSION='ROUT=rout_rvicerr' addons: apt_packages: - libnetcdf-dev diff --git a/ci/image.travis b/ci/image.travis index c0d022fe2..cc035be03 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -61,7 +61,7 @@ function vic_install { echo vic_install cd ${TRAVIS_BUILD_DIR} echo $PWD - make full -C $DRIVER_PATH + make full $EXTENSION -C $DRIVER_PATH } function vic_before_script { diff --git a/ci/rvic.travis b/ci/rvic.travis deleted file mode 100644 index 9678bedfc..000000000 --- a/ci/rvic.travis +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -DRIVER_PATH="${TRAVIS_BUILD_DIR}/vic/drivers/image/" -DRIVER_EXE="${DRIVER_PATH}vic_image.exe" -SAMPLES_PATH="${TRAVIS_BUILD_DIR}/samples/" - -function vic_before_install { - echo vic_before_install - echo $PATH - if [ ! -z "$USE_CC" ]; then - echo "export CC=$USE_CC" - export CC=$USE_CC; - $CC --version - fi - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - echo "Testing on osx" - if [ ! -z "$BREW_TAPS" ]; then - for tap in $BREW_TAPS - do - brew tap $tap - done - fi - if [ ! -z "$BREW_INSTALLS" ]; then - brew update - for pkg in $BREW_INSTALLS - do - brew outdated $pkg || brew upgrade $pkg || brew install $pkg - brew link $pkg - done - # building openmpi from source - not sure why the homebrew install - # isn't working right. - brew install homebrew/versions/gcc49 - brew reinstall open-mpi --build-from-source - fi - export TRAVIS_MPIPATH=/usr/local - export NC_LIBS=$(/usr/local/bin/nc-config --libs) - export NC_CFLAGS=$(/usr/local/bin/nc-config --cflags) - else - export TRAVIS_MPIPATH="${HOME}/mpich" - export NC_LIBS=$(/usr/bin/nc-config --libs) - export NC_CFLAGS=$(/usr/bin/nc-config --cflags) - - # Install MPICH - if [ ! -d ${TRAVIS_MPIPATH} ]; then - install_mpich - else - echo "MPICH installed..." - fi - fi - export PATH=${TRAVIS_MPIPATH}/bin:${PATH} - find ${TRAVIS_MPIPATH} -name mpiexec - mpiexec --version - find ${TRAVIS_MPIPATH} -name mpicc - export MPICC="${TRAVIS_MPIPATH}/bin/mpicc" - $MPICC --version - echo "NETCDF LIB FLAGS ------> ${NC_LIBS}" - echo "NETCDF C FLAGS --------> ${NC_CFLAGS}" -} - -function vic_install { - echo vic_install - cd ${TRAVIS_BUILD_DIR} - echo $PWD - make full ROUT=rout_rvic -C $DRIVER_PATH -} - -function vic_before_script { - echo vic_before_script - if [ ! -f $DRIVER_EXE ]; then - echo "Executable (${DRIVER_EXE}) not found!" - exit 1 - fi - - echo "Getting sample data" - bash ${SAMPLES_PATH}/get_sample_data.bash - -} - -function vic_script { - echo vic_script - $DRIVER_EXE -v - $DRIVER_EXE -o - - # Run test package - ./tests/run_tests.py unit examples system \ - --image=${DRIVER_EXE} \ - --data_dir=${SAMPLES_PATH}/data -} - -function vic_after_success { - echo vic_after_success - echo "Success!" -} - -function vic_after_failure { - echo vic_after_failure - echo "Test failed -- please review the log" -} diff --git a/tests/system/system_tests.cfg b/tests/system/system_tests.cfg index bfeebc16c..0d2f5c7fb 100644 --- a/tests/system/system_tests.cfg +++ b/tests/system/system_tests.cfg @@ -232,8 +232,8 @@ check = nonans [System-mpi_image_check_identical_results] test_description = check that multi-processor runs produce identical results - image driver -driver = image,rvic -global_parameter_file = global.image.STEHE.mpi.txt,global.image.STEHE.mpi.txt +driver = image +global_parameter_file = global.image.STEHE.mpi.txt expected_retval = 0 check = mpi [[mpi]] @@ -251,11 +251,3 @@ check = driver_match FULL_ENERGY=FALSE FROZEN_SOIL=FALSE -#[System-check-rvic] -#test_description = image driver with rvic routing enabled -#driver = rvic -#global_parameter_file = global.image.STEHE.rvic.txt -##domain_file = image/Stehekin/parameters/domain.stehekin.20151028.nc -#mpi_proc = 4 -#expected_retval = 0 -#check = nonans From 6dce6fa7b28a66e16719416e1eb38fc8e9192319 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 15 Feb 2017 14:15:42 +0100 Subject: [PATCH 085/294] travis test4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2229a52d8..fa2dbf58f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: # Image Driver with rvic-routing - compiler: gcc os: linux - env: TESTID='image' EXTENSION='ROUT=rout_rvicerr' + env: TESTID='image' EXTENSION='ROUT=rout_rvic' addons: apt_packages: - libnetcdf-dev From d7f0cffee93adc6147a157b1b5bf8d980e6fd762 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 13 Feb 2017 17:36:46 -0800 Subject: [PATCH 086/294] Deleted unused file handles (for text files) for nc input files --- vic/drivers/shared_image/include/vic_driver_shared_image.h | 5 ----- vic/drivers/shared_image/src/initialize_files.c | 6 ------ 2 files changed, 11 deletions(-) diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 1e7513a12..ace7c7054 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -160,13 +160,8 @@ typedef struct { * @brief file structures *****************************************************************************/ typedef struct { - FILE *forcing[MAX_FORCE_FILES]; /**< forcing data files */ FILE *globalparam; /**< global parameters file */ FILE *constants; /**< model constants parameter file */ - FILE *domain; /**< domain file */ - FILE *init_state; /**< initial model state file */ - FILE *paramfile; /**< parameter file */ - FILE *statefile; /**< output model state file */ FILE *logfile; /**< log file */ } filep_struct; diff --git a/vic/drivers/shared_image/src/initialize_files.c b/vic/drivers/shared_image/src/initialize_files.c index 22b97f651..a4191b140 100644 --- a/vic/drivers/shared_image/src/initialize_files.c +++ b/vic/drivers/shared_image/src/initialize_files.c @@ -61,11 +61,5 @@ initialize_fileps() filep.globalparam = NULL; filep.constants = NULL; - filep.init_state = NULL; - filep.paramfile = NULL; - filep.statefile = NULL; filep.logfile = NULL; - for (i = 0; i < 2; i++) { - filep.forcing[i] = NULL; - } } From 8a9a4cf22ab9fe9d880859988ab8a059201ff073 Mon Sep 17 00:00:00 2001 From: ymao Date: Thu, 16 Feb 2017 12:28:02 -0800 Subject: [PATCH 087/294] Fixed some remaining bugs related to reseting forceskip to zero that were missing in PR 671 --- vic/drivers/image/src/vic_force.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 11caca455..70fc35995 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -73,7 +73,7 @@ vic_force(void) // global_param.forceoffset[0] resets every year since the met file restarts // every year // global_param.forceskip[0] should also reset to 0 after the first year - if (current > 1 && (dmy[current].year != dmy[current - 1].year)) { + if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[0] = 0; global_param.forceskip[0] = 0; } @@ -264,8 +264,10 @@ vic_force(void) // global_param.forceoffset[1] resets every year since the met file restarts // every year - if (current > 1 && (dmy[current].year != dmy[current - 1].year)) { + // global_param.forceskip[1] should also reset to 0 after the first year + if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[1] = 0; + global_param.forceskip[0] = 0; } // only the time slice changes for the met file reads. The rest is constant From fbbf0765a5918ddf60986536f8eebc9edfe05569 Mon Sep 17 00:00:00 2001 From: ymao Date: Thu, 16 Feb 2017 12:46:40 -0800 Subject: [PATCH 088/294] Fixed a typo --- vic/drivers/image/src/vic_force.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 70fc35995..ce88a3e37 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -267,7 +267,7 @@ vic_force(void) // global_param.forceskip[1] should also reset to 0 after the first year if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[1] = 0; - global_param.forceskip[0] = 0; + global_param.forceskip[1] = 0; } // only the time slice changes for the met file reads. The rest is constant From 0c3609fe796eb8afd89347ec7f77ba05651a9f1f Mon Sep 17 00:00:00 2001 From: ymao Date: Thu, 16 Feb 2017 15:00:50 -0800 Subject: [PATCH 089/294] First commit for speeding up image driver initialization - by not opening and closing files again and again - Runs successfully without MPI specified - Error with MPI --- vic/drivers/image/src/get_global_param.c | 21 ++++--- vic/drivers/image/src/vic_force.c | 33 ++++++++--- vic/drivers/image/src/vic_image_init.c | 4 ++ vic/drivers/image/src/vic_image_start.c | 13 ++++- .../include/vic_driver_shared_image.h | 34 ++++++----- vic/drivers/shared_image/include/vic_mpi.h | 14 ++++- .../shared_image/src/check_domain_info.c | 4 +- .../shared_image/src/get_global_domain.c | 50 ++++++++-------- .../shared_image/src/get_nc_dimension.c | 21 ++----- vic/drivers/shared_image/src/get_nc_field.c | 57 +++++------------- .../shared_image/src/get_nc_var_attr.c | 22 +++---- .../shared_image/src/get_nc_var_type.c | 21 ++----- .../shared_image/src/get_nc_varndimensions.c | 19 ++---- .../shared_image/src/initialize_files.c | 6 +- vic/drivers/shared_image/src/nc_utils.c | 58 +++++++++++++++++++ .../shared_image/src/vic_image_timing.c | 2 +- .../shared_image/src/vic_mpi_support.c | 12 ++-- vic/drivers/shared_image/src/vic_restore.c | 35 +++++------ 18 files changed, 233 insertions(+), 193 deletions(-) create mode 100644 vic/drivers/shared_image/src/nc_utils.c diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 3e8dc38f0..ec396542d 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -296,7 +296,7 @@ get_global_param(FILE *gp) } else { options.INIT_STATE = true; - strcpy(filenames.init_state, flgstr); + strcpy(filenames.init_state.nc_file, flgstr); } } else if (strcasecmp("STATENAME", optstr) == 0) { @@ -374,13 +374,13 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", filenames.constants); } else if (strcasecmp("DOMAIN", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.domain); + sscanf(cmdstr, "%*s %s", filenames.domain.nc_file); } else if (strcasecmp("DOMAIN_TYPE", optstr) == 0) { get_domain_type(cmdstr); } else if (strcasecmp("PARAMETERS", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.params); + sscanf(cmdstr, "%*s %s", filenames.params.nc_file); } else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -787,12 +787,15 @@ get_global_param(FILE *gp) } // Get information from the forcing file(s) - sprintf(filenames.forcing[0], "%s%4d.nc", filenames.f_path_pfx[0], + // Open first-year forcing files and get info + sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], global_param.startyear); + filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); get_forcing_file_info(¶m_set, 0); if (param_set.N_TYPES[1] != MISSING) { - sprintf(filenames.forcing[1], "%s%4d.nc", filenames.f_path_pfx[1], + sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], global_param.startyear); + filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); get_forcing_file_info(¶m_set, 1); } @@ -829,7 +832,7 @@ get_global_param(FILE *gp) } // Validate parameter file information - if (strcmp(filenames.params, "MISSING") == 0) { + if (strcmp(filenames.params.nc_file, "MISSING") == 0) { log_err("A parameters file has not been defined. Make sure that the " "global file defines the parameters parameter file on the line " "that begins with \"PARAMETERS\"."); @@ -868,7 +871,7 @@ get_global_param(FILE *gp) // Validate the input state file information if (options.INIT_STATE) { - if (strcmp(filenames.init_state, "MISSING") == 0) { + if (strcmp(filenames.init_state.nc_file, "MISSING") == 0) { log_err("\"INIT_STATE\" was specified, but no input state file " "has been defined. Make sure that the global file " "defines the inputstate file on the line that begins " @@ -919,11 +922,11 @@ get_global_param(FILE *gp) global_param.statesec); } if (options.INIT_STATE && options.SAVE_STATE && - (strcmp(filenames.init_state, flgstr2) == 0)) { + (strcmp(filenames.init_state.nc_file, flgstr2) == 0)) { log_err("The save state file (%s) has the same name as the " "initialize state file (%s). The initialize state file " "will be destroyed when the save state file is opened.", - filenames.statefile, filenames.init_state); + filenames.statefile, filenames.init_state.nc_file); } // Validate soil parameter/simulation mode combinations diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index ce88a3e37..d8129a19c 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -66,16 +66,20 @@ vic_force(void) dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error."); - // for now forcing file is determined by the year - sprintf(filenames.forcing[0], "%s%4d.nc", filenames.f_path_pfx[0], - dmy[current].year); - // global_param.forceoffset[0] resets every year since the met file restarts // every year // global_param.forceskip[0] should also reset to 0 after the first year if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[0] = 0; global_param.forceskip[0] = 0; + // close the forcing file for the previous year and open the forcing + // file for the current new year + // (forcing file for the first year should already be open in + // get_global_param) + close_nc(filenames.forcing[0]); + sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], + dmy[current].year); + filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); } // only the time slice changes for the met file reads. The rest is constant @@ -228,6 +232,11 @@ vic_force(void) } } + // Close forcing file if it is the last time step + if (current == global_param.nrecs) { + close_nc(filenames.forcing[0]); + } + // Update the offset counter global_param.forceoffset[0] += NF; @@ -258,9 +267,6 @@ vic_force(void) if (options.LAI_SRC == FROM_VEGHIST || options.FCAN_SRC == FROM_VEGHIST || options.ALB_SRC == FROM_VEGHIST) { - // for now forcing file is determined by the year - sprintf(filenames.forcing[1], "%s%4d.nc", filenames.f_path_pfx[1], - dmy[current].year); // global_param.forceoffset[1] resets every year since the met file restarts // every year @@ -268,6 +274,14 @@ vic_force(void) if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[1] = 0; global_param.forceskip[1] = 0; + // close the forcing file for the previous year and open the forcing + // file for the current new year + // (forcing file for the first year should already be open in + // get_global_param) + close_nc(filenames.forcing[1]); + sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], + dmy[current].year); + filenames.forcing[1].nc_id = open_nc(filenames.forcing[1].nc_file); } // only the time slice changes for the met file reads. The rest is constant @@ -335,6 +349,11 @@ vic_force(void) } } + // Close forcing file if it is the last time step + if (current == global_param.nrecs) { + close_nc(filenames.forcing[1]); + } + // Update the offset counter global_param.forceoffset[1] += NF; } diff --git a/vic/drivers/image/src/vic_image_init.c b/vic/drivers/image/src/vic_image_init.c index cbb29eb93..1e47d9603 100644 --- a/vic/drivers/image/src/vic_image_init.c +++ b/vic/drivers/image/src/vic_image_init.c @@ -34,10 +34,14 @@ vic_image_init(void) { extern dmy_struct *dmy; extern global_param_struct global_param; + extern filenames_struct filenames; // make_dmy() initialize_time(); dmy = make_dmy(&global_param); vic_init(); + + // close parameter netCDF file + close_nc(filenames.params); } diff --git a/vic/drivers/image/src/vic_image_start.c b/vic/drivers/image/src/vic_image_start.c index 5a2ee4f12..17fee6123 100644 --- a/vic/drivers/image/src/vic_image_start.c +++ b/vic/drivers/image/src/vic_image_start.c @@ -32,9 +32,9 @@ void vic_image_start(void) { - extern filep_struct filep; - extern filenames_struct filenames; - extern int mpi_rank; + extern filep_struct filep; + extern filenames_struct filenames; + extern int mpi_rank; // Initialize structures initialize_global_structures(); @@ -45,6 +45,13 @@ vic_image_start(void) get_global_param(filep.globalparam); } + // Open domain and parameter netCDF files + filenames.domain.nc_id = open_nc(filenames.domain.nc_file); + filenames.params.nc_id = open_nc(filenames.params.nc_file); + // initialize image mode structures and settings vic_start(); + + // Close domain file + close_nc(filenames.domain); } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index ace7c7054..dfae537f3 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -169,42 +169,46 @@ typedef struct { * @brief This structure stores input and output filenames. *****************************************************************************/ typedef struct { - char forcing[MAX_FORCE_FILES][MAXSTRING]; /**< atmospheric forcing data file names */ + nameid_struct forcing[MAX_FORCE_FILES]; /**< atmospheric forcing data file names */ char f_path_pfx[MAX_FORCE_FILES][MAXSTRING]; /**< path and prefix for atmospheric forcing data file names */ char global[MAXSTRING]; /**< global control file name */ - char domain[MAXSTRING]; /**< domain file name */ + nameid_struct domain; /**< domain file name and nc_id*/ char constants[MAXSTRING]; /**< model constants file name */ - char params[MAXSTRING]; /**< model parameters file name */ - char init_state[MAXSTRING]; /**< initial model state file name */ + nameid_struct params; /**< model parameters file name and nc_id */ + nameid_struct init_state; /**< initial model state file name and nc_id */ char result_dir[MAXSTRING]; /**< directory where results will be written */ char statefile[MAXSTRING]; /**< name of file in which to store model state */ char log_path[MAXSTRING]; /**< Location to write log file to */ } filenames_struct; -void add_nveg_to_global_domain(char *nc_name, domain_struct *global_domain); +void add_nveg_to_global_domain(nameid_struct nc_nameid, + domain_struct *global_domain); void alloc_force(force_data_struct *force); void alloc_veg_hist(veg_hist_struct *veg_hist); double air_density(double t, double p); double average(double *ar, size_t n); void check_init_state_file(void); -void compare_ncdomain_with_global_domain(char *ncfile); +void compare_ncdomain_with_global_domain(nameid_struct nc_nameid); void free_force(force_data_struct *force); void free_veg_hist(veg_hist_struct *veg_hist); void get_domain_type(char *cmdstr); -size_t get_global_domain(char *domain_nc_name, char *param_nc_name, +size_t get_global_domain(nameid_struct domain_nc_nameid, + nameid_struct param_nc_nameid, domain_struct *global_domain); void copy_domain_info(domain_struct *domain_from, domain_struct *domain_to); -void get_nc_latlon(char *nc_name, domain_struct *nc_domain); -size_t get_nc_dimension(char *nc_name, char *dim_name); -void get_nc_var_attr(char *nc_name, char *var_name, char *attr_name, +int open_nc(char *nc_name); +int close_nc(nameid_struct nc_nameid); +void get_nc_latlon(nameid_struct nc_nameid, domain_struct *nc_domain); +size_t get_nc_dimension(nameid_struct nc_nameid, char *dim_name); +void get_nc_var_attr(nameid_struct nc_nameid, char *var_name, char *attr_name, char **attr); -int get_nc_var_type(char *nc_name, char *var_name); -int get_nc_varndimensions(char *nc_name, char *var_name); -int get_nc_field_double(char *nc_name, char *var_name, size_t *start, +int get_nc_var_type(nameid_struct nc_nameid, char *var_name); +int get_nc_varndimensions(nameid_struct nc_nameid, char *var_name); +int get_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, double *var); -int get_nc_field_float(char *nc_name, char *var_name, size_t *start, +int get_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, float *var); -int get_nc_field_int(char *nc_name, char *var_name, size_t *start, +int get_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, int *var); int get_nc_dtype(unsigned short int dtype); int get_nc_mode(unsigned short int format); diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index c72d5131e..13c25a3dc 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -32,6 +32,14 @@ #define VIC_MPI_ROOT 0 +/****************************************************************************** + * * @brief This structure stores netCDF file name and corresponding nc_id + * *****************************************************************************/ +typedef struct { + char nc_file[MAXSTRING]; + int nc_id; +} nameid_struct; + void create_MPI_filenames_struct_type(MPI_Datatype *mpi_type); void create_MPI_global_struct_type(MPI_Datatype *mpi_type); void create_MPI_location_struct_type(MPI_Datatype *mpi_type); @@ -48,11 +56,11 @@ void gather_put_nc_field_short(int nc_id, int var_id, short int fillval, size_t *start, size_t *count, short int *var); void gather_put_nc_field_schar(int nc_id, int var_id, char fillval, size_t *start, size_t *count, char *var); -void get_scatter_nc_field_double(char *nc_name, char *var_name, size_t *start, +void get_scatter_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, double *var); -void get_scatter_nc_field_float(char *nc_name, char *var_name, size_t *start, +void get_scatter_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, float *var); -void get_scatter_nc_field_int(char *nc_name, char *var_name, size_t *start, +void get_scatter_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, int *var); void initialize_mpi(void); void map(size_t size, size_t n, size_t *from_map, size_t *to_map, void *from, diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index d67e9bc90..e0efdf0be 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -32,7 +32,7 @@ the global domain. *****************************************************************************/ void -compare_ncdomain_with_global_domain(char *ncfile) +compare_ncdomain_with_global_domain(nameid_struct nc_nameid) { extern domain_struct global_domain; @@ -47,7 +47,7 @@ compare_ncdomain_with_global_domain(char *ncfile) sizeof(*(ncfile_domain.locations))); check_alloc_status(ncfile_domain.locations, "Memory allocation error."); copy_domain_info(&global_domain, &ncfile_domain); - get_nc_latlon(ncfile, &ncfile_domain); + get_nc_latlon(nc_nameid, &ncfile_domain); // using the ncfile_domain, we can compare the values to the global domain. diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 07e6a243c..cb9441b89 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -30,8 +30,8 @@ * @brief Get global domain information. *****************************************************************************/ size_t -get_global_domain(char *domain_nc_name, - char *param_nc_name, +get_global_domain(nameid_struct domain_nc_nameid, + nameid_struct param_nc_nameid, domain_struct *global_domain) { int *run = NULL; @@ -43,9 +43,9 @@ get_global_domain(char *domain_nc_name, size_t d2count[2]; size_t d2start[2]; - global_domain->n_nx = get_nc_dimension(domain_nc_name, + global_domain->n_nx = get_nc_dimension(domain_nc_nameid, global_domain->info.x_dim); - global_domain->n_ny = get_nc_dimension(domain_nc_name, + global_domain->n_ny = get_nc_dimension(domain_nc_nameid, global_domain->info.y_dim); d2start[0] = 0; @@ -64,20 +64,20 @@ get_global_domain(char *domain_nc_name, // Get mask variable from the domain file // (check whether mask variable is int type) - typeid = get_nc_var_type(domain_nc_name, global_domain->info.mask_var); + typeid = get_nc_var_type(domain_nc_nameid, global_domain->info.mask_var); if (typeid != NC_INT) { log_err("Mask variable in the domain file must be integer type."); } - get_nc_field_int(domain_nc_name, global_domain->info.mask_var, d2start, d2count, + get_nc_field_int(domain_nc_nameid, global_domain->info.mask_var, d2start, d2count, mask); // Get run_cell variable from the parameter file // (check whether run_cell variable is int type) - typeid = get_nc_var_type(param_nc_name, "run_cell"); + typeid = get_nc_var_type(param_nc_nameid, "run_cell"); if (typeid != NC_INT) { log_err("Run_cell variable in the parameter file must be integer type."); } - get_nc_field_int(param_nc_name, "run_cell", d2start, d2count, + get_nc_field_int(param_nc_nameid, "run_cell", d2start, d2count, run); // Check whether cells with run_cell == 1 are all within the mask domain @@ -124,7 +124,7 @@ get_global_domain(char *domain_nc_name, // get area // TBD: read var id from file - get_nc_field_double(domain_nc_name, global_domain->info.area_var, + get_nc_field_double(domain_nc_nameid, global_domain->info.area_var, d2start, d2count, var); for (i = 0; i < global_domain->ncells_total; i++) { global_domain->locations[i].area = var[i]; @@ -132,18 +132,18 @@ get_global_domain(char *domain_nc_name, // get fraction // TBD: read var id from file - get_nc_field_double(domain_nc_name, global_domain->info.frac_var, + get_nc_field_double(domain_nc_nameid, global_domain->info.frac_var, d2start, d2count, var); for (i = 0; i < global_domain->ncells_total; i++) { global_domain->locations[i].frac = var[i]; } // get lat and lon coordinates - get_nc_latlon(domain_nc_name, global_domain); + get_nc_latlon(domain_nc_nameid, global_domain); // check whether lat and lon coordinates in the parameter file match those // in the domain file - compare_ncdomain_with_global_domain(param_nc_name); + compare_ncdomain_with_global_domain(param_nc_nameid); // free memory free(var); @@ -158,7 +158,7 @@ get_global_domain(char *domain_nc_name, store in nc_domain structure *****************************************************************************/ void -get_nc_latlon(char *nc_name, +get_nc_latlon(nameid_struct nc_nameid, domain_struct *nc_domain) { double *var = NULL; @@ -172,19 +172,19 @@ get_nc_latlon(char *nc_name, size_t d1start[1]; - nc_domain->n_nx = get_nc_dimension(nc_name, + nc_domain->n_nx = get_nc_dimension(nc_nameid, nc_domain->info.x_dim); - nc_domain->n_ny = get_nc_dimension(nc_name, + nc_domain->n_ny = get_nc_dimension(nc_nameid, nc_domain->info.y_dim); // Get number of lat/lon dimensions. - nc_domain->info.n_coord_dims = get_nc_varndimensions(nc_name, + nc_domain->info.n_coord_dims = get_nc_varndimensions(nc_nameid, nc_domain->info.lon_var); if (nc_domain->info.n_coord_dims != - (size_t) get_nc_varndimensions(nc_name, nc_domain->info.lat_var)) { + (size_t) get_nc_varndimensions(nc_nameid, nc_domain->info.lat_var)) { log_err("Un even number of dimensions for %s and %s in: %s", nc_domain->info.lon_var, nc_domain->info.lat_var, - nc_name); + nc_nameid.nc_file); } if (nc_domain->info.n_coord_dims == 1) { @@ -199,7 +199,7 @@ get_nc_latlon(char *nc_name, d1count[0] = nc_domain->n_nx; // get longitude for unmasked grid - get_nc_field_double(nc_name, nc_domain->info.lon_var, + get_nc_field_double(nc_nameid, nc_domain->info.lon_var, d1start, d1count, var_lon); for (j = 0; j < nc_domain->n_ny; j++) { for (i = 0; i < nc_domain->n_nx; i++) { @@ -217,7 +217,7 @@ get_nc_latlon(char *nc_name, d1count[0] = nc_domain->n_ny; // get latitude for unmasked grid - get_nc_field_double(nc_name, nc_domain->info.lat_var, + get_nc_field_double(nc_nameid, nc_domain->info.lat_var, d1start, d1count, var_lat); for (i = 0; i < nc_domain->n_ny; i++) { for (j = 0; j < nc_domain->n_nx; j++) { @@ -242,7 +242,7 @@ get_nc_latlon(char *nc_name, d2count[1] = nc_domain->n_nx; // get longitude for unmasked grid - get_nc_field_double(nc_name, nc_domain->info.lon_var, + get_nc_field_double(nc_nameid, nc_domain->info.lon_var, d2start, d2count, var); for (i = 0; i < nc_domain->ncells_total; i++) { // rescale to [-180., 180]. Note that the if statement is not strictly @@ -254,7 +254,7 @@ get_nc_latlon(char *nc_name, } // get latitude for unmasked grid - get_nc_field_double(nc_name, nc_domain->info.lat_var, + get_nc_field_double(nc_nameid, nc_domain->info.lat_var, d2start, d2count, var); for (i = 0; i < nc_domain->ncells_total; i++) { nc_domain->locations[i].latitude = var[i]; @@ -265,7 +265,7 @@ get_nc_latlon(char *nc_name, else { log_err("Number of dimensions for %s and %s should be 1 or 2 in: %s", nc_domain->info.lon_var, nc_domain->info.lat_var, - nc_name); + nc_nameid.nc_file); } } @@ -331,7 +331,7 @@ initialize_location(location_struct *location) * @brief Read the number of vegetation type per grid cell from file *****************************************************************************/ void -add_nveg_to_global_domain(char *nc_name, +add_nveg_to_global_domain(nameid_struct nc_nameid, domain_struct *global_domain) { size_t d2count[2]; @@ -346,7 +346,7 @@ add_nveg_to_global_domain(char *nc_name, d2start[1] = 0; d2count[0] = global_domain->n_ny; d2count[1] = global_domain->n_nx; - get_nc_field_int(nc_name, "Nveg", d2start, d2count, ivar); + get_nc_field_int(nc_nameid, "Nveg", d2start, d2count, ivar); for (i = 0; i < global_domain->ncells_total; i++) { global_domain->locations[i].nveg = (size_t) ivar[i]; diff --git a/vic/drivers/shared_image/src/get_nc_dimension.c b/vic/drivers/shared_image/src/get_nc_dimension.c index cdbbb3943..96fb2527a 100644 --- a/vic/drivers/shared_image/src/get_nc_dimension.c +++ b/vic/drivers/shared_image/src/get_nc_dimension.c @@ -30,32 +30,23 @@ * @brief Get netCDF dimension. *****************************************************************************/ size_t -get_nc_dimension(char *nc_name, - char *dim_name) +get_nc_dimension(nameid_struct nc_nameid, + char *dim_name) { - int nc_id; int dim_id; size_t dim_size; int status; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - // get dimension id - status = nc_inq_dimid(nc_id, dim_name, &dim_id); + status = nc_inq_dimid(nc_nameid.nc_id, dim_name, &dim_id); check_nc_status(status, "Error getting dimension id %s in %s", dim_name, - nc_name); + nc_nameid.nc_file); // get dimension size - status = nc_inq_dimlen(nc_id, dim_id, &dim_size); + status = nc_inq_dimlen(nc_nameid.nc_id, dim_id, &dim_size); check_nc_status(status, "Error getting dimension size for dim %s in %s", dim_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return dim_size; } diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index af3d48ea7..d672106cd 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -30,32 +30,23 @@ * @brief Read double precision netCDF field from file. *****************************************************************************/ int -get_nc_field_double(char *nc_name, +get_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, double *var) { - int nc_id; int status; int var_id; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - /* get NetCDF variable */ - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_name); + nc_nameid.nc_file); - status = nc_get_vara_double(nc_id, var_id, start, count, var); + status = nc_get_vara_double(nc_nameid.nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return status; } @@ -64,32 +55,23 @@ get_nc_field_double(char *nc_name, * @brief Read single precision netCDF field from file. *****************************************************************************/ int -get_nc_field_float(char *nc_name, +get_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, float *var) { - int nc_id; int status; int var_id; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - /* get NetCDF variable */ - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_name); + nc_nameid.nc_file); - status = nc_get_vara_float(nc_id, var_id, start, count, var); + status = nc_get_vara_float(nc_nameid.nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return status; } @@ -98,32 +80,23 @@ get_nc_field_float(char *nc_name, * @brief Read integer netCDF field from file. *****************************************************************************/ int -get_nc_field_int(char *nc_name, +get_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, int *var) { - int nc_id; int status; int var_id; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - /* get NetCDF variable */ - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_name); + nc_nameid.nc_file); - status = nc_get_vara_int(nc_id, var_id, start, count, var); + status = nc_get_vara_int(nc_nameid.nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return status; } diff --git a/vic/drivers/shared_image/src/get_nc_var_attr.c b/vic/drivers/shared_image/src/get_nc_var_attr.c index 6a91c8ebc..ee8dc537f 100644 --- a/vic/drivers/shared_image/src/get_nc_var_attr.c +++ b/vic/drivers/shared_image/src/get_nc_var_attr.c @@ -30,7 +30,7 @@ * @brief Get netCDF variable attributes. *****************************************************************************/ void -get_nc_var_attr(char *nc_name, +get_nc_var_attr(nameid_struct nc_nameid, char *var_name, char *attr_name, char **attr) @@ -40,36 +40,28 @@ get_nc_var_attr(char *nc_name, int status; size_t attr_len; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - // get variable id - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_name); + nc_nameid.nc_file); // get size of the attribute - status = nc_inq_attlen(nc_id, var_id, attr_name, &attr_len); + status = nc_inq_attlen(nc_nameid.nc_id, var_id, attr_name, &attr_len); check_nc_status(status, "Error getting attribute length for %s:%s in %s", var_name, - attr_name, nc_name); + attr_name, nc_nameid.nc_file); // allocate memory for attribute *attr = malloc((attr_len + 1) * sizeof(**attr)); check_alloc_status(*attr, "Memory allocation error."); // read attribute text - status = nc_get_att_text(nc_id, var_id, attr_name, *attr); + status = nc_get_att_text(nc_nameid.nc_id, var_id, attr_name, *attr); check_nc_status(status, "Error getting netCDF attribute %s for var %s in %s", attr_name, - var_name, nc_name); + var_name, nc_nameid.nc_file); // we need to null terminate the string ourselves according to NetCDF docs (*attr)[attr_len] = '\0'; - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); } diff --git a/vic/drivers/shared_image/src/get_nc_var_type.c b/vic/drivers/shared_image/src/get_nc_var_type.c index 80a674de6..e3fdd0253 100644 --- a/vic/drivers/shared_image/src/get_nc_var_type.c +++ b/vic/drivers/shared_image/src/get_nc_var_type.c @@ -30,31 +30,22 @@ * @brief Get netCDF variable type. *****************************************************************************/ int -get_nc_var_type(char *nc_name, - char *var_name) +get_nc_var_type(nameid_struct nc_nameid, + char *var_name) { - int nc_id; int var_id; int status; int xtypep; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - // get variable id - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_name); + nc_nameid.nc_file); // get type ID - status = nc_inq_var(nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); + status = nc_inq_var(nc_nameid.nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); check_nc_status(status, "Error getting variable type %s in %s", var_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return(xtypep); } diff --git a/vic/drivers/shared_image/src/get_nc_varndimensions.c b/vic/drivers/shared_image/src/get_nc_varndimensions.c index 1f4131eae..c3a0ebe38 100644 --- a/vic/drivers/shared_image/src/get_nc_varndimensions.c +++ b/vic/drivers/shared_image/src/get_nc_varndimensions.c @@ -30,33 +30,24 @@ * @brief Get netCDF dimension. *****************************************************************************/ int -get_nc_varndimensions(char *nc_name, +get_nc_varndimensions(nameid_struct nc_nameid, char *var_name) { - int nc_id; int var_id; int ndims; int status; - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - // get variable id - status = nc_inq_varid(nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_name); + nc_nameid.nc_file); // get number of dimensions - status = nc_inq_varndims(nc_id, var_id, &ndims); + status = nc_inq_varndims(nc_nameid.nc_id, var_id, &ndims); check_nc_status(status, "Error getting number of dimensions for var %s in %s", var_name, - nc_name); - - // close the netcdf file - status = nc_close(nc_id); - check_nc_status(status, "Error closing %s", nc_name); + nc_nameid.nc_file); return ndims; } diff --git a/vic/drivers/shared_image/src/initialize_files.c b/vic/drivers/shared_image/src/initialize_files.c index a4191b140..3357cb44c 100644 --- a/vic/drivers/shared_image/src/initialize_files.c +++ b/vic/drivers/shared_image/src/initialize_files.c @@ -38,10 +38,10 @@ initialize_filenames() size_t i; - strcpy(filenames.init_state, "MISSING"); + strcpy(filenames.init_state.nc_file, "MISSING"); strcpy(filenames.statefile, "MISSING"); strcpy(filenames.constants, "MISSING"); - strcpy(filenames.params, "MISSING"); + strcpy(filenames.params.nc_file, "MISSING"); strcpy(filenames.result_dir, "MISSING"); strcpy(filenames.log_path, "MISSING"); for (i = 0; i < 2; i++) { @@ -57,8 +57,6 @@ initialize_fileps() { extern filep_struct filep; - size_t i; - filep.globalparam = NULL; filep.constants = NULL; filep.logfile = NULL; diff --git a/vic/drivers/shared_image/src/nc_utils.c b/vic/drivers/shared_image/src/nc_utils.c new file mode 100644 index 000000000..7cdcdc263 --- /dev/null +++ b/vic/drivers/shared_image/src/nc_utils.c @@ -0,0 +1,58 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Functions related to opening and closing netCDF files. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Open a netCDF file + *****************************************************************************/ +int +open_nc(char *nc_name) +{ + int nc_id; + int status; + + // open the netcdf file + status = nc_open(nc_name, NC_NOWRITE, &nc_id); + check_nc_status(status, "Error opening %s", nc_name); + + return(nc_id); +} + +/****************************************************************************** + * @brief Close a netCDF file + *****************************************************************************/ +int +close_nc(nameid_struct nc_nameid) +{ + int status; + + // close the netcdf file + status = nc_close(nc_nameid.nc_id); + check_nc_status(status, "Error closing %s", nc_nameid.nc_file); + + return(status); +} diff --git a/vic/drivers/shared_image/src/vic_image_timing.c b/vic/drivers/shared_image/src/vic_image_timing.c index 64034ddd7..6289ddfeb 100644 --- a/vic/drivers/shared_image/src/vic_image_timing.c +++ b/vic/drivers/shared_image/src/vic_image_timing.c @@ -89,7 +89,7 @@ write_vic_timing_table(timer_struct *timers, fprintf(LOG_DEST, " VIC_DRIVER : %s\n", driver); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, " Global Param File : %s\n", filenames.global); - fprintf(LOG_DEST, " Domain File : %s\n", filenames.domain); + fprintf(LOG_DEST, " Domain File : %s\n", filenames.domain.nc_file); fprintf(LOG_DEST, " Start Date : %04hu-%02hu-%02hu-%05u\n", global_param.startyear, global_param.startmonth, global_param.startday, global_param.startsec); diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index c1d678981..7c60b63e2 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -2042,7 +2042,7 @@ gather_put_nc_field_schar(int nc_id, * nodes *****************************************************************************/ void -get_scatter_nc_field_double(char *nc_name, +get_scatter_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, @@ -2073,7 +2073,7 @@ get_scatter_nc_field_double(char *nc_name, malloc(global_domain.ncells_active * sizeof(*dvar_mapped)); check_alloc_status(dvar_mapped, "Memory allocation error."); - get_nc_field_double(nc_name, var_name, start, count, dvar); + get_nc_field_double(nc_nameid, var_name, start, count, dvar); // filter the active cells only map(sizeof(double), global_domain.ncells_active, filter_active_cells, NULL, dvar, dvar_filtered); @@ -2103,7 +2103,7 @@ get_scatter_nc_field_double(char *nc_name, * nodes *****************************************************************************/ void -get_scatter_nc_field_float(char *nc_name, +get_scatter_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, @@ -2134,7 +2134,7 @@ get_scatter_nc_field_float(char *nc_name, malloc(global_domain.ncells_active * sizeof(*fvar_mapped)); check_alloc_status(fvar_mapped, "Memory allocation error."); - get_nc_field_float(nc_name, var_name, start, count, fvar); + get_nc_field_float(nc_nameid, var_name, start, count, fvar); // filter the active cells only map(sizeof(float), global_domain.ncells_active, filter_active_cells, NULL, @@ -2166,7 +2166,7 @@ get_scatter_nc_field_float(char *nc_name, * nodes *****************************************************************************/ void -get_scatter_nc_field_int(char *nc_name, +get_scatter_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, size_t *count, @@ -2196,7 +2196,7 @@ get_scatter_nc_field_int(char *nc_name, malloc(global_domain.ncells_active * sizeof(*ivar_mapped)); check_alloc_status(ivar_mapped, "Memory allocation error."); - get_nc_field_int(nc_name, var_name, start, count, ivar); + get_nc_field_int(nc_nameid, var_name, start, count, ivar); // filter the active cells only map(sizeof(int), global_domain.ncells_active, filter_active_cells, NULL, ivar, ivar_filtered); diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index f23cc3f92..a2eea26bb 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -59,6 +59,9 @@ vic_restore(void) size_t d6count[6]; size_t d6start[6]; + // open initial state file + filenames.init_state.nc_id = open_nc(filenames.init_state.nc_file); + // validate state file dimensions and coordinate variables check_init_state_file(); // read state variables @@ -866,6 +869,9 @@ vic_restore(void) free(ivar); free(dvar); + + // close initial state file + close_nc(filenames.init_state); } /****************************************************************************** @@ -897,11 +903,6 @@ check_init_state_file(void) double *dvar; double rtol = 0.0; // maybe move this to a .h file double abs_tol = 0.0001; // maybe move this to a .h file - nc_file_struct nc; - - // open the netcdf file - status = nc_open(filenames.init_state, NC_SHARE, &(nc.nc_id)); - check_nc_status(status, "Error opening %s", filenames.init_state); // read and validate dimension lengths if (mpi_rank == VIC_MPI_ROOT) { @@ -953,22 +954,22 @@ check_init_state_file(void) // lat/lon if (mpi_rank == VIC_MPI_ROOT) { - status = nc_inq_varid(nc.nc_id, global_domain.info.lon_var, &lon_var_id); + status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lon_var, &lon_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); - status = nc_inq_varid(nc.nc_id, global_domain.info.lat_var, &lat_var_id); + global_domain.info.lon_var, filenames.init_state.nc_file); + status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lat_var, &lat_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); + global_domain.info.lat_var, filenames.init_state.nc_file); if (global_domain.info.n_coord_dims == 1) { d1start[0] = 0; dvar = calloc(global_domain.n_nx, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); d1count[0] = global_domain.n_nx; - status = nc_get_vara_double(nc.nc_id, lon_var_id, + status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); + global_domain.info.lon_var, filenames.init_state.nc_file); // implicitly nested loop over ni and nj with j set to 0 for (i = 0; i < global_domain.n_nx; i++) { if (!assert_close_double(dvar[i], @@ -984,10 +985,10 @@ check_init_state_file(void) check_alloc_status(dvar, "Memory allocation error"); d1count[0] = global_domain.n_ny; - status = nc_get_vara_double(nc.nc_id, lat_var_id, + status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); + global_domain.info.lat_var, filenames.init_state.nc_file); // implicitly nested loop over ni and nj with i set to 0; // j stride = n_nx for (j = 0; j < global_domain.n_ny; j++) { @@ -1010,20 +1011,20 @@ check_init_state_file(void) d2count[0] = global_domain.n_ny; d2count[1] = global_domain.n_nx; - status = nc_get_vara_double(nc.nc_id, lon_var_id, + status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state); + global_domain.info.lon_var, filenames.init_state.nc_file); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].longitude) { log_err("Longitudes in initial state file do not " "match parameter file"); } } - status = nc_get_vara_double(nc.nc_id, lat_var_id, + status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state); + global_domain.info.lat_var, filenames.init_state.nc_file); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].latitude) { log_err("Latitudes in initial state file do not " From de656cddac2557de43d8f1960f9e8192a1149b50 Mon Sep 17 00:00:00 2001 From: ymao Date: Thu, 16 Feb 2017 15:16:01 -0800 Subject: [PATCH 090/294] Image initialization speedup - fixed MPI related bugs so now MPI run works --- vic/drivers/image/src/vic_force.c | 37 ++++++++++++++-------- vic/drivers/image/src/vic_image_init.c | 7 ++-- vic/drivers/image/src/vic_image_start.c | 14 +++++--- vic/drivers/shared_image/src/vic_restore.c | 11 +++++-- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index d8129a19c..b8af32edf 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -35,6 +35,7 @@ vic_force(void) extern size_t NF; extern size_t NR; extern size_t current; + extern int mpi_rank; extern force_data_struct *force; extern dmy_struct *dmy; extern domain_struct global_domain; @@ -76,10 +77,12 @@ vic_force(void) // file for the current new year // (forcing file for the first year should already be open in // get_global_param) - close_nc(filenames.forcing[0]); - sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], - dmy[current].year); - filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); + if (mpi_rank == VIC_MPI_ROOT) { + close_nc(filenames.forcing[0]); + sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], + dmy[current].year); + filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); + } } // only the time slice changes for the met file reads. The rest is constant @@ -232,9 +235,11 @@ vic_force(void) } } - // Close forcing file if it is the last time step - if (current == global_param.nrecs) { - close_nc(filenames.forcing[0]); + if (mpi_rank == VIC_MPI_ROOT) { + // Close forcing file if it is the last time step + if (current == global_param.nrecs) { + close_nc(filenames.forcing[0]); + } } // Update the offset counter @@ -278,10 +283,12 @@ vic_force(void) // file for the current new year // (forcing file for the first year should already be open in // get_global_param) - close_nc(filenames.forcing[1]); - sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], - dmy[current].year); - filenames.forcing[1].nc_id = open_nc(filenames.forcing[1].nc_file); + if (mpi_rank == VIC_MPI_ROOT) { + close_nc(filenames.forcing[1]); + sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], + dmy[current].year); + filenames.forcing[1].nc_id = open_nc(filenames.forcing[1].nc_file); + } } // only the time slice changes for the met file reads. The rest is constant @@ -349,9 +356,11 @@ vic_force(void) } } - // Close forcing file if it is the last time step - if (current == global_param.nrecs) { - close_nc(filenames.forcing[1]); + if (mpi_rank == VIC_MPI_ROOT) { + // Close forcing file if it is the last time step + if (current == global_param.nrecs) { + close_nc(filenames.forcing[1]); + } } // Update the offset counter diff --git a/vic/drivers/image/src/vic_image_init.c b/vic/drivers/image/src/vic_image_init.c index 1e47d9603..6fc06208a 100644 --- a/vic/drivers/image/src/vic_image_init.c +++ b/vic/drivers/image/src/vic_image_init.c @@ -35,6 +35,7 @@ vic_image_init(void) extern dmy_struct *dmy; extern global_param_struct global_param; extern filenames_struct filenames; + extern int mpi_rank; // make_dmy() initialize_time(); @@ -42,6 +43,8 @@ vic_image_init(void) vic_init(); - // close parameter netCDF file - close_nc(filenames.params); + if (mpi_rank == VIC_MPI_ROOT) { + // close parameter netCDF file + close_nc(filenames.params); + } } diff --git a/vic/drivers/image/src/vic_image_start.c b/vic/drivers/image/src/vic_image_start.c index 17fee6123..7bda6bc1f 100644 --- a/vic/drivers/image/src/vic_image_start.c +++ b/vic/drivers/image/src/vic_image_start.c @@ -45,13 +45,17 @@ vic_image_start(void) get_global_param(filep.globalparam); } - // Open domain and parameter netCDF files - filenames.domain.nc_id = open_nc(filenames.domain.nc_file); - filenames.params.nc_id = open_nc(filenames.params.nc_file); + if (mpi_rank == VIC_MPI_ROOT) { + // Open domain and parameter netCDF files + filenames.domain.nc_id = open_nc(filenames.domain.nc_file); + filenames.params.nc_id = open_nc(filenames.params.nc_file); + } // initialize image mode structures and settings vic_start(); - // Close domain file - close_nc(filenames.domain); + if (mpi_rank == VIC_MPI_ROOT) { + // Close domain file + close_nc(filenames.domain); + } } diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index a2eea26bb..2293eae2f 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -32,6 +32,7 @@ void vic_restore(void) { + extern int mpi_rank; extern all_vars_struct *all_vars; extern domain_struct global_domain; extern domain_struct local_domain; @@ -59,8 +60,10 @@ vic_restore(void) size_t d6count[6]; size_t d6start[6]; - // open initial state file - filenames.init_state.nc_id = open_nc(filenames.init_state.nc_file); + if (mpi_rank == VIC_MPI_ROOT) { + // open initial state file + filenames.init_state.nc_id = open_nc(filenames.init_state.nc_file); + } // validate state file dimensions and coordinate variables check_init_state_file(); @@ -871,7 +874,9 @@ vic_restore(void) free(dvar); // close initial state file - close_nc(filenames.init_state); + if (mpi_rank == VIC_MPI_ROOT) { + close_nc(filenames.init_state); + } } /****************************************************************************** From 9b900299c800907629086125841695d2bf492610 Mon Sep 17 00:00:00 2001 From: yixinmao Date: Thu, 16 Feb 2017 17:10:25 -0800 Subject: [PATCH 091/294] Fixed some remaining bugs related to reseting forceskip to zero (#683) * Fixed some remaining bugs related to reseting forceskip to zero that were missing in PR 671 * Fixed a typo --- vic/drivers/image/src/vic_force.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 11caca455..ce88a3e37 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -73,7 +73,7 @@ vic_force(void) // global_param.forceoffset[0] resets every year since the met file restarts // every year // global_param.forceskip[0] should also reset to 0 after the first year - if (current > 1 && (dmy[current].year != dmy[current - 1].year)) { + if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[0] = 0; global_param.forceskip[0] = 0; } @@ -264,8 +264,10 @@ vic_force(void) // global_param.forceoffset[1] resets every year since the met file restarts // every year - if (current > 1 && (dmy[current].year != dmy[current - 1].year)) { + // global_param.forceskip[1] should also reset to 0 after the first year + if (current > 0 && (dmy[current].year != dmy[current - 1].year)) { global_param.forceoffset[1] = 0; + global_param.forceskip[1] = 0; } // only the time slice changes for the met file reads. The rest is constant From 1f3a85d208e0647d0d695e5a1f88c689d038a5b6 Mon Sep 17 00:00:00 2001 From: ymao Date: Thu, 16 Feb 2017 18:03:56 -0800 Subject: [PATCH 092/294] Fixed bugs corresponding to initialization speedup in some printing commands --- vic/drivers/image/src/display_current_settings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 6df978b2e..8c30a0b9e 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -265,11 +265,11 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input Domain Data:\n"); - fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain); + fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain.nc_file); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Constants File\t\t%s\n", filenames.constants); - fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params); + fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params.nc_file); if (options.BASEFLOW == ARNO) { fprintf(LOG_DEST, "BASEFLOW\t\tARNO\n"); } @@ -378,7 +378,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input State File:\n"); if (options.INIT_STATE) { - fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state); + fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_file); if (options.STATE_FORMAT == NETCDF3_CLASSIC) { fprintf(LOG_DEST, "STATE_FORMAT\t\tNETCDF3_CLASSIC\n"); } From 85bb3679a9d6b5c158b0a984affb7fef538ae285 Mon Sep 17 00:00:00 2001 From: ymao Date: Wed, 22 Feb 2017 14:13:44 -0800 Subject: [PATCH 093/294] Fixed a bug when checking whether to open the second forcing file in "get_global_param" --- vic/drivers/image/src/get_global_param.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 3e8dc38f0..aa7e22c27 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -790,13 +790,13 @@ get_global_param(FILE *gp) sprintf(filenames.forcing[0], "%s%4d.nc", filenames.f_path_pfx[0], global_param.startyear); get_forcing_file_info(¶m_set, 0); - if (param_set.N_TYPES[1] != MISSING) { + if (param_set.N_TYPES[1] != 0) { sprintf(filenames.forcing[1], "%s%4d.nc", filenames.f_path_pfx[1], global_param.startyear); get_forcing_file_info(¶m_set, 1); } - if (param_set.N_TYPES[1] != MISSING && global_param.forceyear[1] == 0) { + if (param_set.N_TYPES[1] != 0 && global_param.forceyear[1] == 0) { global_param.forceyear[1] = global_param.forceyear[0]; global_param.forcemonth[1] = global_param.forcemonth[0]; global_param.forceday[1] = global_param.forceday[0]; From 1e12ef5a85d922967539225a0c6fa6887fd6c5b4 Mon Sep 17 00:00:00 2001 From: ymao Date: Wed, 22 Feb 2017 14:17:02 -0800 Subject: [PATCH 094/294] Fixed a bug in "get_forcing_file_info" - should read the time info from the corresponding forcing file ((1st or 2nd, specified by file_num) --- vic/drivers/image/src/vic_force.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index ce88a3e37..57d958324 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -479,9 +479,9 @@ get_forcing_file_info(param_set_struct *param_set, dmy_struct nc_start_dmy; // read time info from netcdf file - get_nc_field_double(filenames.forcing[0], "time", &start, &count, nc_times); - get_nc_var_attr(filenames.forcing[0], "time", "units", &nc_unit_chars); - get_nc_var_attr(filenames.forcing[0], "time", "calendar", &calendar_char); + get_nc_field_double(filenames.forcing[file_num], "time", &start, &count, nc_times); + get_nc_var_attr(filenames.forcing[file_num], "time", "units", &nc_unit_chars); + get_nc_var_attr(filenames.forcing[file_num], "time", "calendar", &calendar_char); // parse the calendar string and check to make sure it matches the global clock calendar = str_to_calendar(calendar_char); From 5cb7cbaa3b031b77ed0b08e862099065d34bb70b Mon Sep 17 00:00:00 2001 From: ymao Date: Wed, 22 Feb 2017 14:27:39 -0800 Subject: [PATCH 095/294] Speedup image driver initialization - incorporate Bart's comments, including: - pass the pointer of the new nameid_struct variables into functions (instead of passing in the structure itself) - rename the filename element in the nameid_struct from "nc_file" to "nc_filename" - remove the "open_nc" and "close_nc" wrapping functions - move the opening and closing of the domain and parameter nc files into either "vic_start" or "vic_init" --- samples/data | 2 +- .../image/src/display_current_settings.c | 6 +- vic/drivers/image/src/get_global_param.c | 33 ++-- vic/drivers/image/src/vic_force.c | 72 +++++--- vic/drivers/image/src/vic_image_init.c | 7 - vic/drivers/image/src/vic_image_start.c | 11 -- .../include/vic_driver_shared_image.h | 26 ++- vic/drivers/shared_image/include/vic_mpi.h | 8 +- .../shared_image/src/check_domain_info.c | 2 +- .../shared_image/src/get_global_domain.c | 12 +- .../shared_image/src/get_nc_dimension.c | 10 +- vic/drivers/shared_image/src/get_nc_field.c | 30 ++-- .../shared_image/src/get_nc_var_attr.c | 15 +- .../shared_image/src/get_nc_var_type.c | 12 +- .../shared_image/src/get_nc_varndimensions.c | 10 +- .../shared_image/src/initialize_files.c | 5 +- vic/drivers/shared_image/src/nc_utils.c | 58 ------ .../shared_image/src/vic_image_timing.c | 2 +- vic/drivers/shared_image/src/vic_init.c | 145 ++++++++------- .../shared_image/src/vic_mpi_support.c | 6 +- vic/drivers/shared_image/src/vic_restore.c | 166 +++++++++--------- vic/drivers/shared_image/src/vic_start.c | 28 ++- 22 files changed, 322 insertions(+), 344 deletions(-) delete mode 100644 vic/drivers/shared_image/src/nc_utils.c diff --git a/samples/data b/samples/data index 1554cb017..3f2dcb445 160000 --- a/samples/data +++ b/samples/data @@ -1 +1 @@ -Subproject commit 1554cb017c71e59e114b853af5808649f80ad836 +Subproject commit 3f2dcb445e3e985456589a29711a2fee59f8faaf diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 8c30a0b9e..d3994dceb 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -265,11 +265,11 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input Domain Data:\n"); - fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain.nc_file); + fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain.nc_filename); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Constants File\t\t%s\n", filenames.constants); - fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params.nc_file); + fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params.nc_filename); if (options.BASEFLOW == ARNO) { fprintf(LOG_DEST, "BASEFLOW\t\tARNO\n"); } @@ -378,7 +378,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input State File:\n"); if (options.INIT_STATE) { - fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_file); + fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_filename); if (options.STATE_FORMAT == NETCDF3_CLASSIC) { fprintf(LOG_DEST, "STATE_FORMAT\t\tNETCDF3_CLASSIC\n"); } diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 652600791..538ae1b55 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -46,6 +46,7 @@ get_global_param(FILE *gp) char flgstr2[MAXSTRING]; size_t file_num; int field; + int status; unsigned int tmpstartdate; unsigned int tmpenddate; unsigned short int lastday[MONTHS_PER_YEAR]; @@ -296,7 +297,7 @@ get_global_param(FILE *gp) } else { options.INIT_STATE = true; - strcpy(filenames.init_state.nc_file, flgstr); + strcpy(filenames.init_state.nc_filename, flgstr); } } else if (strcasecmp("STATENAME", optstr) == 0) { @@ -374,13 +375,13 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", filenames.constants); } else if (strcasecmp("DOMAIN", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.domain.nc_file); + sscanf(cmdstr, "%*s %s", filenames.domain.nc_filename); } else if (strcasecmp("DOMAIN_TYPE", optstr) == 0) { get_domain_type(cmdstr); } else if (strcasecmp("PARAMETERS", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.params.nc_file); + sscanf(cmdstr, "%*s %s", filenames.params.nc_filename); } else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -788,14 +789,20 @@ get_global_param(FILE *gp) // Get information from the forcing file(s) // Open first-year forcing files and get info - sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], - global_param.startyear); - filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); + sprintf(filenames.forcing[0].nc_filename, "%s%4d.nc", + filenames.f_path_pfx[0], global_param.startyear); + status = nc_open(filenames.forcing[0].nc_filename, NC_NOWRITE, + &(filenames.forcing[0].nc_id)); + check_nc_status(status, "Error opening %s", + filenames.forcing[0].nc_filename); get_forcing_file_info(¶m_set, 0); if (param_set.N_TYPES[1] != 0) { - sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], - global_param.startyear); - filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); + sprintf(filenames.forcing[1].nc_filename, "%s%4d.nc", + filenames.f_path_pfx[1], global_param.startyear); + status = nc_open(filenames.forcing[1].nc_filename, NC_NOWRITE, + &(filenames.forcing[1].nc_id)); + check_nc_status(status, "Error opening %s", + filenames.forcing[1].nc_filename); get_forcing_file_info(¶m_set, 1); } @@ -832,7 +839,7 @@ get_global_param(FILE *gp) } // Validate parameter file information - if (strcmp(filenames.params.nc_file, "MISSING") == 0) { + if (strcmp(filenames.params.nc_filename, "MISSING") == 0) { log_err("A parameters file has not been defined. Make sure that the " "global file defines the parameters parameter file on the line " "that begins with \"PARAMETERS\"."); @@ -871,7 +878,7 @@ get_global_param(FILE *gp) // Validate the input state file information if (options.INIT_STATE) { - if (strcmp(filenames.init_state.nc_file, "MISSING") == 0) { + if (strcmp(filenames.init_state.nc_filename, "MISSING") == 0) { log_err("\"INIT_STATE\" was specified, but no input state file " "has been defined. Make sure that the global file " "defines the inputstate file on the line that begins " @@ -922,11 +929,11 @@ get_global_param(FILE *gp) global_param.statesec); } if (options.INIT_STATE && options.SAVE_STATE && - (strcmp(filenames.init_state.nc_file, flgstr2) == 0)) { + (strcmp(filenames.init_state.nc_filename, flgstr2) == 0)) { log_err("The save state file (%s) has the same name as the " "initialize state file (%s). The initialize state file " "will be destroyed when the save state file is opened.", - filenames.statefile, filenames.init_state.nc_file); + filenames.statefile, filenames.init_state.nc_filename); } // Validate soil parameter/simulation mode combinations diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 99126fb72..be0c80017 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -57,6 +57,7 @@ vic_force(void) size_t v; size_t band; int vidx; + int status; size_t d3count[3]; size_t d3start[3]; size_t d4count[4]; @@ -78,10 +79,17 @@ vic_force(void) // (forcing file for the first year should already be open in // get_global_param) if (mpi_rank == VIC_MPI_ROOT) { - close_nc(filenames.forcing[0]); - sprintf(filenames.forcing[0].nc_file, "%s%4d.nc", filenames.f_path_pfx[0], - dmy[current].year); - filenames.forcing[0].nc_id = open_nc(filenames.forcing[0].nc_file); + // close previous forcing file + status = nc_close(filenames.forcing[0].nc_id); + check_nc_status(status, "Error closing %s", + filenames.forcing[0].nc_filename); + // open new forcing file + sprintf(filenames.forcing[0].nc_filename, "%s%4d.nc", + filenames.f_path_pfx[0], dmy[current].year); + status = nc_open(filenames.forcing[0].nc_filename, NC_NOWRITE, + &(filenames.forcing[0].nc_id)); + check_nc_status(status, "Error opening %s", + filenames.forcing[0].nc_filename); } } @@ -96,7 +104,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[AIR_TEMP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -108,7 +116,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[PREC].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -120,7 +128,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[SWDOWN].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -132,7 +140,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[LWDOWN].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -144,7 +152,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[WIND].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -156,7 +164,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[VP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -168,7 +176,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[PRESSURE].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -180,7 +188,7 @@ vic_force(void) // Channel inflow to lake d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[CHANNEL_IN].varname, d3start, d3count, dvar); for (j = 0; j < NF; j++) { @@ -194,7 +202,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[CATM].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -215,7 +223,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[FDIR].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -226,7 +234,7 @@ vic_force(void) for (j = 0; j < NF; j++) { d3start[0] = global_param.forceskip[0] + global_param.forceoffset[0] + j; - get_scatter_nc_field_double(filenames.forcing[0], + get_scatter_nc_field_double(&(filenames.forcing[0]), param_set.TYPE[PAR].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -238,7 +246,9 @@ vic_force(void) if (mpi_rank == VIC_MPI_ROOT) { // Close forcing file if it is the last time step if (current == global_param.nrecs) { - close_nc(filenames.forcing[0]); + status = nc_close(filenames.forcing[0].nc_id); + check_nc_status(status, "Error closing %s", + filenames.forcing[0].nc_filename); } } @@ -284,10 +294,18 @@ vic_force(void) // (forcing file for the first year should already be open in // get_global_param) if (mpi_rank == VIC_MPI_ROOT) { - close_nc(filenames.forcing[1]); - sprintf(filenames.forcing[1].nc_file, "%s%4d.nc", filenames.f_path_pfx[1], + // close previous forcing file + status = nc_close(filenames.forcing[1].nc_id); + check_nc_status(status, "Error closing %s", + filenames.forcing[1].nc_filename); + // open new forcing file + sprintf(filenames.forcing[1].nc_filename, "%s%4d.nc", + filenames.f_path_pfx[1], dmy[current].year); - filenames.forcing[1].nc_id = open_nc(filenames.forcing[1].nc_file); + status = nc_open(filenames.forcing[1].nc_filename, NC_NOWRITE, + &(filenames.forcing[1].nc_id)); + check_nc_status(status, "Error opening %s", + filenames.forcing[1].nc_filename); } } @@ -306,7 +324,7 @@ vic_force(void) global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(filenames.forcing[1], "lai", + get_scatter_nc_field_double(&(filenames.forcing[1]), "lai", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; @@ -325,7 +343,7 @@ vic_force(void) global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(filenames.forcing[1], "fcov", + get_scatter_nc_field_double(&(filenames.forcing[1]), "fcov", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; @@ -344,7 +362,7 @@ vic_force(void) global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(filenames.forcing[1], "alb", + get_scatter_nc_field_double(&(filenames.forcing[1]), "alb", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; @@ -359,7 +377,9 @@ vic_force(void) if (mpi_rank == VIC_MPI_ROOT) { // Close forcing file if it is the last time step if (current == global_param.nrecs) { - close_nc(filenames.forcing[1]); + status = nc_close(filenames.forcing[1].nc_id); + check_nc_status(status, "Error closing %s", + filenames.forcing[1].nc_filename); } } @@ -507,9 +527,9 @@ get_forcing_file_info(param_set_struct *param_set, dmy_struct nc_start_dmy; // read time info from netcdf file - get_nc_field_double(filenames.forcing[file_num], "time", &start, &count, nc_times); - get_nc_var_attr(filenames.forcing[file_num], "time", "units", &nc_unit_chars); - get_nc_var_attr(filenames.forcing[file_num], "time", "calendar", &calendar_char); + get_nc_field_double(&(filenames.forcing[file_num]), "time", &start, &count, nc_times); + get_nc_var_attr(&(filenames.forcing[file_num]), "time", "units", &nc_unit_chars); + get_nc_var_attr(&(filenames.forcing[file_num]), "time", "calendar", &calendar_char); // parse the calendar string and check to make sure it matches the global clock calendar = str_to_calendar(calendar_char); diff --git a/vic/drivers/image/src/vic_image_init.c b/vic/drivers/image/src/vic_image_init.c index 6fc06208a..cbb29eb93 100644 --- a/vic/drivers/image/src/vic_image_init.c +++ b/vic/drivers/image/src/vic_image_init.c @@ -34,17 +34,10 @@ vic_image_init(void) { extern dmy_struct *dmy; extern global_param_struct global_param; - extern filenames_struct filenames; - extern int mpi_rank; // make_dmy() initialize_time(); dmy = make_dmy(&global_param); vic_init(); - - if (mpi_rank == VIC_MPI_ROOT) { - // close parameter netCDF file - close_nc(filenames.params); - } } diff --git a/vic/drivers/image/src/vic_image_start.c b/vic/drivers/image/src/vic_image_start.c index 7bda6bc1f..401df8162 100644 --- a/vic/drivers/image/src/vic_image_start.c +++ b/vic/drivers/image/src/vic_image_start.c @@ -45,17 +45,6 @@ vic_image_start(void) get_global_param(filep.globalparam); } - if (mpi_rank == VIC_MPI_ROOT) { - // Open domain and parameter netCDF files - filenames.domain.nc_id = open_nc(filenames.domain.nc_file); - filenames.params.nc_id = open_nc(filenames.params.nc_file); - } - // initialize image mode structures and settings vic_start(); - - if (mpi_rank == VIC_MPI_ROOT) { - // Close domain file - close_nc(filenames.domain); - } } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index dfae537f3..9106e02cc 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -181,34 +181,32 @@ typedef struct { char log_path[MAXSTRING]; /**< Location to write log file to */ } filenames_struct; -void add_nveg_to_global_domain(nameid_struct nc_nameid, +void add_nveg_to_global_domain(nameid_struct *nc_nameid, domain_struct *global_domain); void alloc_force(force_data_struct *force); void alloc_veg_hist(veg_hist_struct *veg_hist); double air_density(double t, double p); double average(double *ar, size_t n); void check_init_state_file(void); -void compare_ncdomain_with_global_domain(nameid_struct nc_nameid); +void compare_ncdomain_with_global_domain(nameid_struct *nc_nameid); void free_force(force_data_struct *force); void free_veg_hist(veg_hist_struct *veg_hist); void get_domain_type(char *cmdstr); -size_t get_global_domain(nameid_struct domain_nc_nameid, - nameid_struct param_nc_nameid, +size_t get_global_domain(nameid_struct *domain_nc_nameid, + nameid_struct *param_nc_nameid, domain_struct *global_domain); void copy_domain_info(domain_struct *domain_from, domain_struct *domain_to); -int open_nc(char *nc_name); -int close_nc(nameid_struct nc_nameid); -void get_nc_latlon(nameid_struct nc_nameid, domain_struct *nc_domain); -size_t get_nc_dimension(nameid_struct nc_nameid, char *dim_name); -void get_nc_var_attr(nameid_struct nc_nameid, char *var_name, char *attr_name, +void get_nc_latlon(nameid_struct *nc_nameid, domain_struct *nc_domain); +size_t get_nc_dimension(nameid_struct *nc_nameid, char *dim_name); +void get_nc_var_attr(nameid_struct *nc_nameid, char *var_name, char *attr_name, char **attr); -int get_nc_var_type(nameid_struct nc_nameid, char *var_name); -int get_nc_varndimensions(nameid_struct nc_nameid, char *var_name); -int get_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, +int get_nc_var_type(nameid_struct *nc_nameid, char *var_name); +int get_nc_varndimensions(nameid_struct *nc_nameid, char *var_name); +int get_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, double *var); -int get_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, +int get_nc_field_float(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, float *var); -int get_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, +int get_nc_field_int(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, int *var); int get_nc_dtype(unsigned short int dtype); int get_nc_mode(unsigned short int format); diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index 13c25a3dc..63330ca0b 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -36,7 +36,7 @@ * * @brief This structure stores netCDF file name and corresponding nc_id * *****************************************************************************/ typedef struct { - char nc_file[MAXSTRING]; + char nc_filename[MAXSTRING]; int nc_id; } nameid_struct; @@ -56,11 +56,11 @@ void gather_put_nc_field_short(int nc_id, int var_id, short int fillval, size_t *start, size_t *count, short int *var); void gather_put_nc_field_schar(int nc_id, int var_id, char fillval, size_t *start, size_t *count, char *var); -void get_scatter_nc_field_double(nameid_struct nc_nameid, char *var_name, size_t *start, +void get_scatter_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, double *var); -void get_scatter_nc_field_float(nameid_struct nc_nameid, char *var_name, size_t *start, +void get_scatter_nc_field_float(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, float *var); -void get_scatter_nc_field_int(nameid_struct nc_nameid, char *var_name, size_t *start, +void get_scatter_nc_field_int(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, int *var); void initialize_mpi(void); void map(size_t size, size_t n, size_t *from_map, size_t *to_map, void *from, diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index e0efdf0be..26d6ae26c 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -32,7 +32,7 @@ the global domain. *****************************************************************************/ void -compare_ncdomain_with_global_domain(nameid_struct nc_nameid) +compare_ncdomain_with_global_domain(nameid_struct *nc_nameid) { extern domain_struct global_domain; diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index cb9441b89..4291b79d8 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -30,8 +30,8 @@ * @brief Get global domain information. *****************************************************************************/ size_t -get_global_domain(nameid_struct domain_nc_nameid, - nameid_struct param_nc_nameid, +get_global_domain(nameid_struct *domain_nc_nameid, + nameid_struct *param_nc_nameid, domain_struct *global_domain) { int *run = NULL; @@ -158,7 +158,7 @@ get_global_domain(nameid_struct domain_nc_nameid, store in nc_domain structure *****************************************************************************/ void -get_nc_latlon(nameid_struct nc_nameid, +get_nc_latlon(nameid_struct *nc_nameid, domain_struct *nc_domain) { double *var = NULL; @@ -184,7 +184,7 @@ get_nc_latlon(nameid_struct nc_nameid, (size_t) get_nc_varndimensions(nc_nameid, nc_domain->info.lat_var)) { log_err("Un even number of dimensions for %s and %s in: %s", nc_domain->info.lon_var, nc_domain->info.lat_var, - nc_nameid.nc_file); + nc_nameid->nc_filename); } if (nc_domain->info.n_coord_dims == 1) { @@ -265,7 +265,7 @@ get_nc_latlon(nameid_struct nc_nameid, else { log_err("Number of dimensions for %s and %s should be 1 or 2 in: %s", nc_domain->info.lon_var, nc_domain->info.lat_var, - nc_nameid.nc_file); + nc_nameid->nc_filename); } } @@ -331,7 +331,7 @@ initialize_location(location_struct *location) * @brief Read the number of vegetation type per grid cell from file *****************************************************************************/ void -add_nveg_to_global_domain(nameid_struct nc_nameid, +add_nveg_to_global_domain(nameid_struct *nc_nameid, domain_struct *global_domain) { size_t d2count[2]; diff --git a/vic/drivers/shared_image/src/get_nc_dimension.c b/vic/drivers/shared_image/src/get_nc_dimension.c index 96fb2527a..2561a1e4e 100644 --- a/vic/drivers/shared_image/src/get_nc_dimension.c +++ b/vic/drivers/shared_image/src/get_nc_dimension.c @@ -30,7 +30,7 @@ * @brief Get netCDF dimension. *****************************************************************************/ size_t -get_nc_dimension(nameid_struct nc_nameid, +get_nc_dimension(nameid_struct *nc_nameid, char *dim_name) { int dim_id; @@ -38,15 +38,15 @@ get_nc_dimension(nameid_struct nc_nameid, int status; // get dimension id - status = nc_inq_dimid(nc_nameid.nc_id, dim_name, &dim_id); + status = nc_inq_dimid(nc_nameid->nc_id, dim_name, &dim_id); check_nc_status(status, "Error getting dimension id %s in %s", dim_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); // get dimension size - status = nc_inq_dimlen(nc_nameid.nc_id, dim_id, &dim_size); + status = nc_inq_dimlen(nc_nameid->nc_id, dim_id, &dim_size); check_nc_status(status, "Error getting dimension size for dim %s in %s", dim_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return dim_size; } diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index d672106cd..5b79f218e 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -30,7 +30,7 @@ * @brief Read double precision netCDF field from file. *****************************************************************************/ int -get_nc_field_double(nameid_struct nc_nameid, +get_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, @@ -40,13 +40,13 @@ get_nc_field_double(nameid_struct nc_nameid, int var_id; /* get NetCDF variable */ - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); - status = nc_get_vara_double(nc_nameid.nc_id, var_id, start, count, var); + status = nc_get_vara_double(nc_nameid->nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return status; } @@ -55,7 +55,7 @@ get_nc_field_double(nameid_struct nc_nameid, * @brief Read single precision netCDF field from file. *****************************************************************************/ int -get_nc_field_float(nameid_struct nc_nameid, +get_nc_field_float(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, @@ -65,13 +65,13 @@ get_nc_field_float(nameid_struct nc_nameid, int var_id; /* get NetCDF variable */ - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); - status = nc_get_vara_float(nc_nameid.nc_id, var_id, start, count, var); + status = nc_get_vara_float(nc_nameid->nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return status; } @@ -80,7 +80,7 @@ get_nc_field_float(nameid_struct nc_nameid, * @brief Read integer netCDF field from file. *****************************************************************************/ int -get_nc_field_int(nameid_struct nc_nameid, +get_nc_field_int(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, @@ -90,13 +90,13 @@ get_nc_field_int(nameid_struct nc_nameid, int var_id; /* get NetCDF variable */ - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); - status = nc_get_vara_int(nc_nameid.nc_id, var_id, start, count, var); + status = nc_get_vara_int(nc_nameid->nc_id, var_id, start, count, var); check_nc_status(status, "Error getting values for %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return status; } diff --git a/vic/drivers/shared_image/src/get_nc_var_attr.c b/vic/drivers/shared_image/src/get_nc_var_attr.c index ee8dc537f..c16d24b50 100644 --- a/vic/drivers/shared_image/src/get_nc_var_attr.c +++ b/vic/drivers/shared_image/src/get_nc_var_attr.c @@ -30,37 +30,36 @@ * @brief Get netCDF variable attributes. *****************************************************************************/ void -get_nc_var_attr(nameid_struct nc_nameid, +get_nc_var_attr(nameid_struct *nc_nameid, char *var_name, char *attr_name, char **attr) { - int nc_id; int var_id; int status; size_t attr_len; // get variable id - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); // get size of the attribute - status = nc_inq_attlen(nc_nameid.nc_id, var_id, attr_name, &attr_len); + status = nc_inq_attlen(nc_nameid->nc_id, var_id, attr_name, &attr_len); check_nc_status(status, "Error getting attribute length for %s:%s in %s", var_name, - attr_name, nc_nameid.nc_file); + attr_name, nc_nameid->nc_filename); // allocate memory for attribute *attr = malloc((attr_len + 1) * sizeof(**attr)); check_alloc_status(*attr, "Memory allocation error."); // read attribute text - status = nc_get_att_text(nc_nameid.nc_id, var_id, attr_name, *attr); + status = nc_get_att_text(nc_nameid->nc_id, var_id, attr_name, *attr); check_nc_status(status, "Error getting netCDF attribute %s for var %s in %s", attr_name, - var_name, nc_nameid.nc_file); + var_name, nc_nameid->nc_filename); // we need to null terminate the string ourselves according to NetCDF docs (*attr)[attr_len] = '\0'; diff --git a/vic/drivers/shared_image/src/get_nc_var_type.c b/vic/drivers/shared_image/src/get_nc_var_type.c index e3fdd0253..67dc4d5ad 100644 --- a/vic/drivers/shared_image/src/get_nc_var_type.c +++ b/vic/drivers/shared_image/src/get_nc_var_type.c @@ -30,22 +30,22 @@ * @brief Get netCDF variable type. *****************************************************************************/ int -get_nc_var_type(nameid_struct nc_nameid, - char *var_name) +get_nc_var_type(nameid_struct *nc_nameid, + char *var_name) { int var_id; int status; int xtypep; // get variable id - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); // get type ID - status = nc_inq_var(nc_nameid.nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); + status = nc_inq_var(nc_nameid->nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); check_nc_status(status, "Error getting variable type %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return(xtypep); } diff --git a/vic/drivers/shared_image/src/get_nc_varndimensions.c b/vic/drivers/shared_image/src/get_nc_varndimensions.c index c3a0ebe38..de2eb5959 100644 --- a/vic/drivers/shared_image/src/get_nc_varndimensions.c +++ b/vic/drivers/shared_image/src/get_nc_varndimensions.c @@ -30,7 +30,7 @@ * @brief Get netCDF dimension. *****************************************************************************/ int -get_nc_varndimensions(nameid_struct nc_nameid, +get_nc_varndimensions(nameid_struct *nc_nameid, char *var_name) { int var_id; @@ -38,16 +38,16 @@ get_nc_varndimensions(nameid_struct nc_nameid, int status; // get variable id - status = nc_inq_varid(nc_nameid.nc_id, var_name, &var_id); + status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); check_nc_status(status, "Error getting variable id %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); // get number of dimensions - status = nc_inq_varndims(nc_nameid.nc_id, var_id, &ndims); + status = nc_inq_varndims(nc_nameid->nc_id, var_id, &ndims); check_nc_status(status, "Error getting number of dimensions for var %s in %s", var_name, - nc_nameid.nc_file); + nc_nameid->nc_filename); return ndims; } diff --git a/vic/drivers/shared_image/src/initialize_files.c b/vic/drivers/shared_image/src/initialize_files.c index 3357cb44c..6c4a201d3 100644 --- a/vic/drivers/shared_image/src/initialize_files.c +++ b/vic/drivers/shared_image/src/initialize_files.c @@ -38,10 +38,11 @@ initialize_filenames() size_t i; - strcpy(filenames.init_state.nc_file, "MISSING"); + strcpy(filenames.init_state.nc_filename, "MISSING"); strcpy(filenames.statefile, "MISSING"); strcpy(filenames.constants, "MISSING"); - strcpy(filenames.params.nc_file, "MISSING"); + strcpy(filenames.params.nc_filename, "MISSING"); + strcpy(filenames.domain.nc_filename, "MISSING"); strcpy(filenames.result_dir, "MISSING"); strcpy(filenames.log_path, "MISSING"); for (i = 0; i < 2; i++) { diff --git a/vic/drivers/shared_image/src/nc_utils.c b/vic/drivers/shared_image/src/nc_utils.c deleted file mode 100644 index 7cdcdc263..000000000 --- a/vic/drivers/shared_image/src/nc_utils.c +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Functions related to opening and closing netCDF files. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Open a netCDF file - *****************************************************************************/ -int -open_nc(char *nc_name) -{ - int nc_id; - int status; - - // open the netcdf file - status = nc_open(nc_name, NC_NOWRITE, &nc_id); - check_nc_status(status, "Error opening %s", nc_name); - - return(nc_id); -} - -/****************************************************************************** - * @brief Close a netCDF file - *****************************************************************************/ -int -close_nc(nameid_struct nc_nameid) -{ - int status; - - // close the netcdf file - status = nc_close(nc_nameid.nc_id); - check_nc_status(status, "Error closing %s", nc_nameid.nc_file); - - return(status); -} diff --git a/vic/drivers/shared_image/src/vic_image_timing.c b/vic/drivers/shared_image/src/vic_image_timing.c index 6289ddfeb..39cf8ff11 100644 --- a/vic/drivers/shared_image/src/vic_image_timing.c +++ b/vic/drivers/shared_image/src/vic_image_timing.c @@ -89,7 +89,7 @@ write_vic_timing_table(timer_struct *timers, fprintf(LOG_DEST, " VIC_DRIVER : %s\n", driver); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, " Global Param File : %s\n", filenames.global); - fprintf(LOG_DEST, " Domain File : %s\n", filenames.domain.nc_file); + fprintf(LOG_DEST, " Domain File : %s\n", filenames.domain.nc_filename); fprintf(LOG_DEST, " Start Date : %04hu-%02hu-%02hu-%05u\n", global_param.startyear, global_param.startmonth, global_param.startday, global_param.startsec); diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index d9e2a978b..44fef6f5a 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -44,6 +44,7 @@ vic_init(void) extern veg_lib_struct **veg_lib; extern lake_con_struct *lake_con; extern parameters_struct param; + extern int mpi_rank; bool found; char locstr[MAXSTRING]; @@ -52,6 +53,7 @@ vic_init(void) double *Cv_sum = NULL; double *dvar = NULL; int *ivar = NULL; + int status; size_t i; size_t j; size_t k; @@ -123,7 +125,7 @@ vic_init(void) // overstory for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_int(filenames.params, "overstory", + get_scatter_nc_field_int(&(filenames.params), "overstory", d3start, d3count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].overstory = ivar[i]; @@ -133,7 +135,7 @@ vic_init(void) // rarc for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "rarc", + get_scatter_nc_field_double(&(filenames.params), "rarc", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].rarc = (double) dvar[i]; @@ -143,7 +145,7 @@ vic_init(void) // rmin for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "rmin", + get_scatter_nc_field_double(&(filenames.params), "rmin", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].rmin = (double) dvar[i]; @@ -153,7 +155,7 @@ vic_init(void) // wind height for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "wind_h", + get_scatter_nc_field_double(&(filenames.params), "wind_h", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].wind_h = (double) dvar[i]; @@ -163,7 +165,7 @@ vic_init(void) // RGL for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "RGL", + get_scatter_nc_field_double(&(filenames.params), "RGL", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].RGL = (double)dvar[i]; @@ -173,7 +175,7 @@ vic_init(void) // rad_atten for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "rad_atten", + get_scatter_nc_field_double(&(filenames.params), "rad_atten", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].rad_atten = (double) dvar[i]; @@ -183,7 +185,7 @@ vic_init(void) // wind_atten for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "wind_atten", + get_scatter_nc_field_double(&(filenames.params), "wind_atten", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].wind_atten = (double) dvar[i]; @@ -193,7 +195,7 @@ vic_init(void) // trunk_ratio for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "trunk_ratio", + get_scatter_nc_field_double(&(filenames.params), "trunk_ratio", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].trunk_ratio = (double) dvar[i]; @@ -206,7 +208,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < MONTHS_PER_YEAR; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "LAI", + get_scatter_nc_field_double(&(filenames.params), "LAI", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].LAI[k] = (double) dvar[i]; @@ -223,7 +225,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < MONTHS_PER_YEAR; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "albedo", + get_scatter_nc_field_double(&(filenames.params), "albedo", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].albedo[k] = (double) dvar[i]; @@ -237,7 +239,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < MONTHS_PER_YEAR; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "veg_rough", + get_scatter_nc_field_double(&(filenames.params), "veg_rough", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].roughness[k] = (double) dvar[i]; @@ -250,7 +252,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < MONTHS_PER_YEAR; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "displacement", + get_scatter_nc_field_double(&(filenames.params), "displacement", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].displacement[k] = (double) dvar[i]; @@ -278,7 +280,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < MONTHS_PER_YEAR; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "fcanopy", + get_scatter_nc_field_double(&(filenames.params), "fcanopy", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].fcanopy[k] = (double) dvar[i]; @@ -292,7 +294,7 @@ vic_init(void) // Ctype for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_int(filenames.params, "Ctype", + get_scatter_nc_field_int(&(filenames.params), "Ctype", d3start, d3count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].Ctype = ivar[i]; @@ -308,7 +310,7 @@ vic_init(void) // MaxCarboxRate for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "MaxCarboxRate", + get_scatter_nc_field_double(&(filenames.params), "MaxCarboxRate", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].MaxCarboxRate = (double) dvar[i]; @@ -322,7 +324,7 @@ vic_init(void) // MaxETransport or CO2Specificity for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "MaxiE_or_CO2Spec", + get_scatter_nc_field_double(&(filenames.params), "MaxiE_or_CO2Spec", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { if (dvar[i] < 0) { @@ -342,7 +344,7 @@ vic_init(void) // LightUseEff for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "LUE", + get_scatter_nc_field_double(&(filenames.params), "LUE", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].LightUseEff = (double) dvar[i]; @@ -357,7 +359,7 @@ vic_init(void) // Nscale flag for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_int(filenames.params, "Nscale", + get_scatter_nc_field_int(&(filenames.params), "Nscale", d3start, d3count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].NscaleFlag = ivar[i]; @@ -372,7 +374,7 @@ vic_init(void) // Wnpp_inhib for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Wnpp_inhib", + get_scatter_nc_field_double(&(filenames.params), "Wnpp_inhib", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].Wnpp_inhib = (double) dvar[i]; @@ -387,7 +389,7 @@ vic_init(void) // NPPfactor_sat for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "NPPfactor_sat", + get_scatter_nc_field_double(&(filenames.params), "NPPfactor_sat", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_lib[i][j].NPPfactor_sat = (double) dvar[i]; @@ -429,35 +431,35 @@ vic_init(void) } // b_infilt - get_scatter_nc_field_double(filenames.params, "infilt", + get_scatter_nc_field_double(&(filenames.params), "infilt", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].b_infilt = (double) dvar[i]; } // Ds - get_scatter_nc_field_double(filenames.params, "Ds", + get_scatter_nc_field_double(&(filenames.params), "Ds", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Ds = (double) dvar[i]; } // Dsmax - get_scatter_nc_field_double(filenames.params, "Dsmax", + get_scatter_nc_field_double(&(filenames.params), "Dsmax", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Dsmax = (double) dvar[i]; } // Ws - get_scatter_nc_field_double(filenames.params, "Ws", + get_scatter_nc_field_double(&(filenames.params), "Ws", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Ws = (double) dvar[i]; } // c - get_scatter_nc_field_double(filenames.params, "c", + get_scatter_nc_field_double(&(filenames.params), "c", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].c = (double) dvar[i]; @@ -466,7 +468,7 @@ vic_init(void) // expt: unsaturated hydraulic conductivity exponent for each layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "expt", + get_scatter_nc_field_double(&(filenames.params), "expt", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].expt[j] = (double) dvar[i]; @@ -476,7 +478,7 @@ vic_init(void) // Ksat: saturated hydraulic conductivity for each layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Ksat", + get_scatter_nc_field_double(&(filenames.params), "Ksat", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Ksat[j] = (double) dvar[i]; @@ -486,7 +488,7 @@ vic_init(void) // init_moist: initial soil moisture for cold start for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "init_moist", + get_scatter_nc_field_double(&(filenames.params), "init_moist", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].init_moist[j] = (double) dvar[i]; @@ -496,7 +498,7 @@ vic_init(void) // phi_s for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "phi_s", + get_scatter_nc_field_double(&(filenames.params), "phi_s", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].phi_s[j] = (double) dvar[i]; @@ -504,7 +506,7 @@ vic_init(void) } // elevation: mean grid cell elevation - get_scatter_nc_field_double(filenames.params, "elev", + get_scatter_nc_field_double(&(filenames.params), "elev", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].elevation = (double) dvar[i]; @@ -513,7 +515,7 @@ vic_init(void) // depth: thickness for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "depth", + get_scatter_nc_field_double(&(filenames.params), "depth", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].depth[j] = (double) dvar[i]; @@ -521,14 +523,14 @@ vic_init(void) } // avg_temp: mean grid temperature - get_scatter_nc_field_double(filenames.params, "avg_T", + get_scatter_nc_field_double(&(filenames.params), "avg_T", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].avg_temp = (double) dvar[i]; } // dp: damping depth - get_scatter_nc_field_double(filenames.params, "dp", + get_scatter_nc_field_double(&(filenames.params), "dp", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].dp = (double) dvar[i]; @@ -537,7 +539,7 @@ vic_init(void) // bubble: bubbling pressure for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "bubble", + get_scatter_nc_field_double(&(filenames.params), "bubble", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].bubble[j] = (double) dvar[i]; @@ -547,7 +549,7 @@ vic_init(void) // quartz: quartz content for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "quartz", + get_scatter_nc_field_double(&(filenames.params), "quartz", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].quartz[j] = (double) dvar[i]; @@ -557,7 +559,7 @@ vic_init(void) // bulk_dens_min: mineral bulk density for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "bulk_density", + get_scatter_nc_field_double(&(filenames.params), "bulk_density", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].bulk_dens_min[j] = (double) dvar[i]; @@ -567,7 +569,7 @@ vic_init(void) // soil_dens_min: mineral soil density for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "soil_density", + get_scatter_nc_field_double(&(filenames.params), "soil_density", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].soil_dens_min[j] = (double) dvar[i]; @@ -580,7 +582,7 @@ vic_init(void) // organic for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "organic", + get_scatter_nc_field_double(&(filenames.params), "organic", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].organic[j] = (double) dvar[i]; @@ -590,7 +592,7 @@ vic_init(void) // bulk_dens_org: organic bulk density for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "bulk_density_org", + get_scatter_nc_field_double(&(filenames.params), "bulk_density_org", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].bulk_dens_org[j] = (double) dvar[i]; @@ -600,7 +602,7 @@ vic_init(void) // soil_dens_org: organic soil density for each soil layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "soil_density_org", + get_scatter_nc_field_double(&(filenames.params), "soil_density_org", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].soil_dens_org[j] = (double) dvar[i]; @@ -612,7 +614,7 @@ vic_init(void) // Note this value is multiplied with the maximum moisture in each layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Wcr_FRACT", + get_scatter_nc_field_double(&(filenames.params), "Wcr_FRACT", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Wcr[j] = (double) dvar[i]; @@ -623,7 +625,7 @@ vic_init(void) // Note this value is multiplied with the maximum moisture in each layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Wpwp_FRACT", + get_scatter_nc_field_double(&(filenames.params), "Wpwp_FRACT", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Wpwp[j] = (double) dvar[i]; @@ -631,21 +633,21 @@ vic_init(void) } // rough: soil roughness - get_scatter_nc_field_double(filenames.params, "rough", + get_scatter_nc_field_double(&(filenames.params), "rough", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].rough = (double) dvar[i]; } // snow_rough: snow roughness - get_scatter_nc_field_double(filenames.params, "snow_rough", + get_scatter_nc_field_double(&(filenames.params), "snow_rough", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].snow_rough = (double) dvar[i]; } // annual_prec: annual precipitation - get_scatter_nc_field_double(filenames.params, "annual_prec", + get_scatter_nc_field_double(&(filenames.params), "annual_prec", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].annual_prec = (double) dvar[i]; @@ -654,7 +656,7 @@ vic_init(void) // resid_moist: residual moisture content for each layer for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "resid_moist", + get_scatter_nc_field_double(&(filenames.params), "resid_moist", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].resid_moist[j] = (double) dvar[i]; @@ -662,7 +664,7 @@ vic_init(void) } // fs_active: frozen soil active flag - get_scatter_nc_field_int(filenames.params, "fs_active", + get_scatter_nc_field_int(&(filenames.params), "fs_active", d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].FS_ACTIVE = (char) ivar[i]; @@ -671,7 +673,7 @@ vic_init(void) // spatial snow if (options.SPATIAL_SNOW) { // max_snow_distrib_slope - get_scatter_nc_field_double(filenames.params, "max_snow_distrib_slope", + get_scatter_nc_field_double(&(filenames.params), "max_snow_distrib_slope", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].max_snow_distrib_slope = (double) dvar[i]; @@ -681,7 +683,7 @@ vic_init(void) // spatial frost if (options.SPATIAL_FROST) { // frost_slope: slope of frozen soil distribution - get_scatter_nc_field_double(filenames.params, "frost_slope", + get_scatter_nc_field_double(&(filenames.params), "frost_slope", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].frost_slope = (double) dvar[i]; @@ -948,7 +950,7 @@ vic_init(void) // AreaFract: fraction of grid cell in each snow band for (j = 0; j < options.SNOW_BAND; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "AreaFract", + get_scatter_nc_field_double(&(filenames.params), "AreaFract", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].AreaFract[j] = (double) dvar[i]; @@ -957,7 +959,7 @@ vic_init(void) // elevation: elevation of each snow band for (j = 0; j < options.SNOW_BAND; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "elevation", + get_scatter_nc_field_double(&(filenames.params), "elevation", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].BandElev[j] = (double) dvar[i]; @@ -966,7 +968,7 @@ vic_init(void) // Pfactor: precipitation multiplier for each snow band for (j = 0; j < options.SNOW_BAND; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Pfactor", + get_scatter_nc_field_double(&(filenames.params), "Pfactor", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].Pfactor[j] = (double) dvar[i]; @@ -1085,7 +1087,7 @@ vic_init(void) for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "Cv", + get_scatter_nc_field_double(&(filenames.params), "Cv", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { veg_con_map[i].Cv[j] = (double) dvar[i]; @@ -1135,7 +1137,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < options.ROOT_ZONES; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "root_depth", + get_scatter_nc_field_double(&(filenames.params), "root_depth", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[j]; @@ -1151,7 +1153,7 @@ vic_init(void) d4start[0] = j; for (k = 0; k < options.ROOT_ZONES; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.params, "root_fract", + get_scatter_nc_field_double(&(filenames.params), "root_fract", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[j]; @@ -1240,7 +1242,7 @@ vic_init(void) // sigma_slope for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "sigma_slope", + get_scatter_nc_field_double(&(filenames.params), "sigma_slope", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[j]; @@ -1257,7 +1259,7 @@ vic_init(void) // lag_one for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "lag_one", + get_scatter_nc_field_double(&(filenames.params), "lag_one", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[j]; @@ -1274,7 +1276,7 @@ vic_init(void) // fetch for (j = 0; j < options.NVEGTYPES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.params, "fetch", + get_scatter_nc_field_double(&(filenames.params), "fetch", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[j]; @@ -1294,7 +1296,7 @@ vic_init(void) // read_lake parameters if (options.LAKES) { // lake_idx - get_scatter_nc_field_int(filenames.params, "lake_idx", + get_scatter_nc_field_int(&(filenames.params), "lake_idx", d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].lake_idx = ivar[i]; @@ -1311,7 +1313,7 @@ vic_init(void) } // numnod - get_scatter_nc_field_int(filenames.params, "numnod", + get_scatter_nc_field_int(&(filenames.params), "numnod", d2start, d2count, ivar); max_numnod = 0; for (i = 0; i < local_domain.ncells_active; i++) { @@ -1341,7 +1343,7 @@ vic_init(void) } // mindepth (minimum depth for which channel outflow occurs) - get_scatter_nc_field_double(filenames.params, "mindepth", + get_scatter_nc_field_double(&(filenames.params), "mindepth", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].mindepth = (double) dvar[i]; @@ -1361,7 +1363,7 @@ vic_init(void) } // wfrac - get_scatter_nc_field_double(filenames.params, "wfrac", + get_scatter_nc_field_double(&(filenames.params), "wfrac", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].wfrac = (double) dvar[i]; @@ -1380,7 +1382,7 @@ vic_init(void) } // depth_in (initial depth for a cold start) - get_scatter_nc_field_double(filenames.params, "depth_in", + get_scatter_nc_field_double(&(filenames.params), "depth_in", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].depth_in = (double) dvar[i]; @@ -1400,7 +1402,7 @@ vic_init(void) } // rpercent - get_scatter_nc_field_double(filenames.params, "rpercent", + get_scatter_nc_field_double(&(filenames.params), "rpercent", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].rpercent = (double) dvar[i]; @@ -1432,14 +1434,14 @@ vic_init(void) d3start[0] = j; // basin_depth - get_scatter_nc_field_double(filenames.params, "basin_depth", + get_scatter_nc_field_double(&(filenames.params), "basin_depth", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].z[j] = (double) dvar[i]; } // basin_area - get_scatter_nc_field_double(filenames.params, "basin_area", + get_scatter_nc_field_double(&(filenames.params), "basin_area", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].Cl[j] = (double) dvar[i]; @@ -1448,14 +1450,14 @@ vic_init(void) } else { // basin_depth - get_scatter_nc_field_double(filenames.params, "basin_depth", + get_scatter_nc_field_double(&(filenames.params), "basin_depth", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].z[0] = (double) dvar[i]; } // basin_area - get_scatter_nc_field_double(filenames.params, "basin_area", + get_scatter_nc_field_double(&(filenames.params), "basin_area", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { lake_con[i].Cl[0] = (double) dvar[i]; @@ -1555,6 +1557,13 @@ vic_init(void) // set state metadata structure set_state_meta_data_info(); + // close parameter file + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_close(filenames.params.nc_id); + check_nc_status(status, "Error closing %s", + filenames.params.nc_filename); + } + // cleanup free(dvar); free(ivar); diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 7c60b63e2..294131758 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -2042,7 +2042,7 @@ gather_put_nc_field_schar(int nc_id, * nodes *****************************************************************************/ void -get_scatter_nc_field_double(nameid_struct nc_nameid, +get_scatter_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, @@ -2103,7 +2103,7 @@ get_scatter_nc_field_double(nameid_struct nc_nameid, * nodes *****************************************************************************/ void -get_scatter_nc_field_float(nameid_struct nc_nameid, +get_scatter_nc_field_float(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, @@ -2166,7 +2166,7 @@ get_scatter_nc_field_float(nameid_struct nc_nameid, * nodes *****************************************************************************/ void -get_scatter_nc_field_int(nameid_struct nc_nameid, +get_scatter_nc_field_int(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 2293eae2f..46abea478 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -48,6 +48,7 @@ vic_restore(void) size_t m; size_t p; int *ivar = NULL; + int status; double *dvar = NULL; size_t d2count[2]; size_t d2start[2]; @@ -62,7 +63,10 @@ vic_restore(void) if (mpi_rank == VIC_MPI_ROOT) { // open initial state file - filenames.init_state.nc_id = open_nc(filenames.init_state.nc_file); + status = nc_open(filenames.init_state.nc_filename, NC_NOWRITE, + &(filenames.init_state.nc_id)); + check_nc_status(status, "Error opening %s", + filenames.init_state.nc_filename); } // validate state file dimensions and coordinate variables @@ -129,7 +133,7 @@ vic_restore(void) d5start[1] = k; for (j = 0; j < options.Nlayer; j++) { d5start[2] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SOIL_MOISTURE].varname, d5start, d5count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -151,7 +155,7 @@ vic_restore(void) d6start[2] = j; for (p = 0; p < options.Nfrost; p++) { d6start[3] = p; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SOIL_ICE].varname, d6start, d6count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -170,7 +174,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_CANOPY_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -188,7 +192,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_ANNUALNPP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -205,7 +209,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_ANNUALNPPPREV].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -222,7 +226,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_CLITTER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -239,7 +243,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_CINTER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -256,7 +260,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_CSLOW].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -274,7 +278,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_int(filenames.init_state, + get_scatter_nc_field_int(&(filenames.init_state), state_metadata[STATE_SNOW_AGE].varname, d4start, d4count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -291,7 +295,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_int(filenames.init_state, + get_scatter_nc_field_int(&(filenames.init_state), state_metadata[STATE_SNOW_MELT_STATE].varname, d4start, d4count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -308,7 +312,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_COVERAGE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -325,7 +329,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_SNOW_WATER_EQUIVALENT].varname, d4start, d4count, dvar); @@ -343,7 +347,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_SURF_TEMP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -360,7 +364,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_SURF_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -377,7 +381,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_PACK_TEMP].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -394,7 +398,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_PACK_WATER].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -411,7 +415,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_DENSITY].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -428,7 +432,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_COLD_CONTENT].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -445,7 +449,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SNOW_CANOPY].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -464,7 +468,7 @@ vic_restore(void) d5start[1] = k; for (j = 0; j < options.Nnode; j++) { d5start[2] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_SOIL_NODE_TEMP].varname, d5start, d5count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -482,7 +486,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -500,7 +504,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -518,7 +522,7 @@ vic_restore(void) d4start[0] = m; for (k = 0; k < options.SNOW_BAND; k++) { d4start[1] = k; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_ENERGY_SNOW_FLUX].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -534,7 +538,7 @@ vic_restore(void) // total soil moisture for (j = 0; j < options.Nlayer; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -547,7 +551,7 @@ vic_restore(void) d4start[0] = j; for (p = 0; p < options.Nfrost; p++) { d4start[1] = p; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SOIL_ICE].varname, d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -558,7 +562,7 @@ vic_restore(void) if (options.CARBON) { // litter carbon: tmpval = lake_var.soil.CLitter; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_CLITTER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -566,7 +570,7 @@ vic_restore(void) } // intermediate carbon: tmpval = lake_var.soil.CInter; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_CINTER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -574,7 +578,7 @@ vic_restore(void) } // slow carbon: tmpval = lake_var.soil.CSlow; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_CSLOW].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -583,7 +587,7 @@ vic_restore(void) } // snow age: lake_var.snow.last_snow - get_scatter_nc_field_int(filenames.init_state, + get_scatter_nc_field_int(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_AGE].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -591,7 +595,7 @@ vic_restore(void) } // melting state: (int)lake_var.snow.MELTING - get_scatter_nc_field_int(filenames.init_state, + get_scatter_nc_field_int(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -599,7 +603,7 @@ vic_restore(void) } // snow covered fraction: lake_var.snow.coverage - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -607,7 +611,7 @@ vic_restore(void) } // snow water equivalent: lake_var.snow.swq - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, d2start, d2count, dvar); @@ -616,7 +620,7 @@ vic_restore(void) } // snow surface temperature: lake_var.snow.surf_temp - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -624,7 +628,7 @@ vic_restore(void) } // snow surface water: lake_var.snow.surf_water - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -632,7 +636,7 @@ vic_restore(void) } // snow pack temperature: lake_var.snow.pack_temp - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -640,7 +644,7 @@ vic_restore(void) } // snow pack water: lake_var.snow.pack_water - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -648,7 +652,7 @@ vic_restore(void) } // snow density: lake_var.snow.density - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -656,7 +660,7 @@ vic_restore(void) } // snow cold content: lake_var.snow.coldcontent - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -664,7 +668,7 @@ vic_restore(void) } // snow canopy storage: lake_var.snow.snow_canopy - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SNOW_CANOPY].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -674,7 +678,7 @@ vic_restore(void) // soil node temperatures: lake_var.energy.T[nidx] for (j = 0; j < options.Nnode; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -683,7 +687,7 @@ vic_restore(void) } // lake active layers: lake_var.activenod - get_scatter_nc_field_int(filenames.init_state, + get_scatter_nc_field_int(&(filenames.init_state), state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, d2start, d2count, ivar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -691,7 +695,7 @@ vic_restore(void) } // lake layer thickness: lake_var.dz - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_LAYER_DZ].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -699,7 +703,7 @@ vic_restore(void) } // lake surface layer thickness: lake_var.surfdz - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -707,7 +711,7 @@ vic_restore(void) } // lake depth: lake_var.ldepth - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_DEPTH].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -717,7 +721,7 @@ vic_restore(void) // lake layer surface areas: lake_var.surface[ndix] for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_LAYER_SURF_AREA].varname, d3start, d3count, dvar); @@ -727,7 +731,7 @@ vic_restore(void) } // lake surface area: lake_var.sarea - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_SURF_AREA].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -735,7 +739,7 @@ vic_restore(void) } // lake volume: lake_var.volume - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_VOLUME].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -745,7 +749,7 @@ vic_restore(void) // lake layer temperatures: lake_var.temp[nidx] for (j = 0; j < options.NLAKENODES; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_LAYER_TEMP].varname, d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -754,7 +758,7 @@ vic_restore(void) } // vertical average lake temperature: lake_var.tempavg - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -762,7 +766,7 @@ vic_restore(void) } // lake ice area fraction: lake_var.areai - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -770,7 +774,7 @@ vic_restore(void) } // new lake ice area fraction: lake_var.new_ice_area - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -778,7 +782,7 @@ vic_restore(void) } // lake ice water equivalent: lake_var.ice_water_eq - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_ICE_WATER_EQUIVALENT].varname, d2start, d2count, dvar); @@ -787,7 +791,7 @@ vic_restore(void) } // lake ice height: lake_var.hice - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_HEIGHT].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -795,7 +799,7 @@ vic_restore(void) } // lake ice temperature: lake_var.tempi - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -803,7 +807,7 @@ vic_restore(void) } // lake ice snow water equivalent: lake_var.swe - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_SWE].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -811,7 +815,7 @@ vic_restore(void) } // lake ice snow surface temperature: lake_var.surf_temp - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -819,7 +823,7 @@ vic_restore(void) } // lake ice snow pack temperature: lake_var.pack_temp - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -827,7 +831,7 @@ vic_restore(void) } // lake ice snow coldcontent: lake_var.coldcontent - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, d2start, d2count, dvar); @@ -836,7 +840,7 @@ vic_restore(void) } // lake ice snow surface water: lake_var.surf_water - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_ICE_SNOW_SURF_WATER].varname, d2start, d2count, dvar); @@ -845,7 +849,7 @@ vic_restore(void) } // lake ice snow pack water: lake_var.pack_water - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[ STATE_LAKE_ICE_SNOW_PACK_WATER].varname, d2start, d2count, dvar); @@ -854,7 +858,7 @@ vic_restore(void) } // lake ice snow albedo: lake_var.SAlbedo - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -862,7 +866,7 @@ vic_restore(void) } // lake ice snow depth: lake_var.sdepth - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -875,7 +879,9 @@ vic_restore(void) // close initial state file if (mpi_rank == VIC_MPI_ROOT) { - close_nc(filenames.init_state); + status = nc_close(filenames.init_state.nc_id); + check_nc_status(status, "Error closing %s", + filenames.init_state.nc_filename); } } @@ -911,43 +917,43 @@ check_init_state_file(void) // read and validate dimension lengths if (mpi_rank == VIC_MPI_ROOT) { - dimlen = get_nc_dimension(filenames.init_state, global_domain.info.x_dim); + dimlen = get_nc_dimension(&(filenames.init_state), global_domain.info.x_dim); if (dimlen != global_domain.n_nx) { log_err("Number of grid columns in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, global_domain.info.y_dim); + dimlen = get_nc_dimension(&(filenames.init_state), global_domain.info.y_dim); if (dimlen != global_domain.n_ny) { log_err("Number of grid rows in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, "veg_class"); + dimlen = get_nc_dimension(&(filenames.init_state), "veg_class"); if (dimlen != options.NVEGTYPES) { log_err("Number of veg classes in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, "snow_band"); + dimlen = get_nc_dimension(&(filenames.init_state), "snow_band"); if (dimlen != options.SNOW_BAND) { log_err("Number of snow bands in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, "nlayer"); + dimlen = get_nc_dimension(&(filenames.init_state), "nlayer"); if (dimlen != options.Nlayer) { log_err("Number of soil layers in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, "frost_area"); + dimlen = get_nc_dimension(&(filenames.init_state), "frost_area"); if (dimlen != options.Nfrost) { log_err("Number of frost areas in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(filenames.init_state, "soil_node"); + dimlen = get_nc_dimension(&(filenames.init_state), "soil_node"); if (dimlen != options.Nnode) { log_err("Number of soil nodes in state file does not " "match parameter file"); } if (options.LAKES) { - dimlen = get_nc_dimension(filenames.init_state, "lake_node"); + dimlen = get_nc_dimension(&(filenames.init_state), "lake_node"); if (dimlen != options.NLAKENODES) { log_err("Number of lake nodes in state file does not " "match parameter file"); @@ -961,10 +967,10 @@ check_init_state_file(void) if (mpi_rank == VIC_MPI_ROOT) { status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lon_var, &lon_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_file); + global_domain.info.lon_var, filenames.init_state.nc_filename); status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lat_var, &lat_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_file); + global_domain.info.lat_var, filenames.init_state.nc_filename); if (global_domain.info.n_coord_dims == 1) { d1start[0] = 0; dvar = calloc(global_domain.n_nx, sizeof(*dvar)); @@ -974,7 +980,7 @@ check_init_state_file(void) status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_file); + global_domain.info.lon_var, filenames.init_state.nc_filename); // implicitly nested loop over ni and nj with j set to 0 for (i = 0; i < global_domain.n_nx; i++) { if (!assert_close_double(dvar[i], @@ -993,7 +999,7 @@ check_init_state_file(void) status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_file); + global_domain.info.lat_var, filenames.init_state.nc_filename); // implicitly nested loop over ni and nj with i set to 0; // j stride = n_nx for (j = 0; j < global_domain.n_ny; j++) { @@ -1019,7 +1025,7 @@ check_init_state_file(void) status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_file); + global_domain.info.lon_var, filenames.init_state.nc_filename); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].longitude) { log_err("Longitudes in initial state file do not " @@ -1029,7 +1035,7 @@ check_init_state_file(void) status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_file); + global_domain.info.lat_var, filenames.init_state.nc_filename); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].latitude) { log_err("Latitudes in initial state file do not " @@ -1056,7 +1062,7 @@ check_init_state_file(void) d3count[2] = global_domain.n_nx; for (j = 0; j < options.Nnode; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), "dz_node", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { @@ -1076,7 +1082,7 @@ check_init_state_file(void) d3count[2] = global_domain.n_nx; for (j = 0; j < options.Nnode; j++) { d3start[0] = j; - get_scatter_nc_field_double(filenames.init_state, + get_scatter_nc_field_double(&(filenames.init_state), "node_depth", d3start, d3count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { diff --git a/vic/drivers/shared_image/src/vic_start.c b/vic/drivers/shared_image/src/vic_start.c index 147647e90..8c36b216f 100644 --- a/vic/drivers/shared_image/src/vic_start.c +++ b/vic/drivers/shared_image/src/vic_start.c @@ -73,13 +73,27 @@ vic_start(void) fclose(filep.constants); } + // open parameter file + status = nc_open(filenames.params.nc_filename, NC_NOWRITE, + &(filenames.params.nc_id)); + check_nc_status(status, "Error opening %s", + filenames.params.nc_filename); + // open domain file + status = nc_open(filenames.domain.nc_filename, NC_NOWRITE, + &(filenames.domain.nc_id)); + check_nc_status(status, "Error opening %s", + filenames.domain.nc_filename); // read domain info - get_global_domain(filenames.domain, filenames.params, + get_global_domain(&(filenames.domain), &(filenames.params), &global_domain); + // close domain file + status = nc_close(filenames.domain.nc_id); + check_nc_status(status, "Error closing %s", + filenames.domain.nc_filename); // add the number of vegetation type to the location info in the // global domain struct. This just makes life easier - add_nveg_to_global_domain(filenames.params, &global_domain); + add_nveg_to_global_domain(&(filenames.params), &global_domain); // decompose the mask mpi_map_decomp_domain(global_domain.ncells_active, mpi_size, @@ -100,14 +114,14 @@ vic_start(void) } // get dimensions (number of vegetation types, soil zones, etc) - options.ROOT_ZONES = get_nc_dimension(filenames.params, "root_zone"); - options.Nlayer = get_nc_dimension(filenames.params, "nlayer"); - options.NVEGTYPES = get_nc_dimension(filenames.params, "veg_class"); + options.ROOT_ZONES = get_nc_dimension(&(filenames.params), "root_zone"); + options.Nlayer = get_nc_dimension(&(filenames.params), "nlayer"); + options.NVEGTYPES = get_nc_dimension(&(filenames.params), "veg_class"); if (options.SNOW_BAND == SNOW_BAND_TRUE_BUT_UNSET) { - options.SNOW_BAND = get_nc_dimension(filenames.params, "snow_band"); + options.SNOW_BAND = get_nc_dimension(&(filenames.params), "snow_band"); } if (options.LAKES) { - options.NLAKENODES = get_nc_dimension(filenames.params, + options.NLAKENODES = get_nc_dimension(&(filenames.params), "lake_node"); } From 65346f6a26be47d78705acf4e749c91de81bb95a Mon Sep 17 00:00:00 2001 From: Bart Nijssen Date: Wed, 22 Feb 2017 21:14:10 -0800 Subject: [PATCH 096/294] Fixed line lengths in header files --- .../include/vic_driver_shared_image.h | 21 ++++++++++--------- vic/drivers/shared_image/include/vic_mpi.h | 20 +++++++++--------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 9106e02cc..e2d892e4d 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -169,16 +169,17 @@ typedef struct { * @brief This structure stores input and output filenames. *****************************************************************************/ typedef struct { - nameid_struct forcing[MAX_FORCE_FILES]; /**< atmospheric forcing data file names */ - char f_path_pfx[MAX_FORCE_FILES][MAXSTRING]; /**< path and prefix for atmospheric forcing data file names */ - char global[MAXSTRING]; /**< global control file name */ - nameid_struct domain; /**< domain file name and nc_id*/ - char constants[MAXSTRING]; /**< model constants file name */ - nameid_struct params; /**< model parameters file name and nc_id */ - nameid_struct init_state; /**< initial model state file name and nc_id */ - char result_dir[MAXSTRING]; /**< directory where results will be written */ - char statefile[MAXSTRING]; /**< name of file in which to store model state */ - char log_path[MAXSTRING]; /**< Location to write log file to */ + nameid_struct forcing[MAX_FORCE_FILES]; /**< atmospheric forcing files */ + char f_path_pfx[MAX_FORCE_FILES][MAXSTRING]; /**< path and prefix for + atmospheric forcing files */ + char global[MAXSTRING]; /**< global control file name */ + nameid_struct domain; /**< domain file name and nc_id*/ + char constants[MAXSTRING]; /**< model constants file name */ + nameid_struct params; /**< model parameters file name and nc_id */ + nameid_struct init_state; /**< initial model state file name and nc_id */ + char result_dir[MAXSTRING]; /**< result directory */ + char statefile[MAXSTRING]; /**< name of model state file */ + char log_path[MAXSTRING]; /**< Location to write log file to */ } filenames_struct; void add_nveg_to_global_domain(nameid_struct *nc_nameid, diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index 63330ca0b..e1f324d4a 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -33,11 +33,11 @@ #define VIC_MPI_ROOT 0 /****************************************************************************** - * * @brief This structure stores netCDF file name and corresponding nc_id - * *****************************************************************************/ + * @brief This structure stores netCDF file name and corresponding nc_id + *****************************************************************************/ typedef struct { - char nc_filename[MAXSTRING]; - int nc_id; + char nc_filename[MAXSTRING]; + int nc_id; } nameid_struct; void create_MPI_filenames_struct_type(MPI_Datatype *mpi_type); @@ -56,12 +56,12 @@ void gather_put_nc_field_short(int nc_id, int var_id, short int fillval, size_t *start, size_t *count, short int *var); void gather_put_nc_field_schar(int nc_id, int var_id, char fillval, size_t *start, size_t *count, char *var); -void get_scatter_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, - size_t *count, double *var); -void get_scatter_nc_field_float(nameid_struct *nc_nameid, char *var_name, size_t *start, - size_t *count, float *var); -void get_scatter_nc_field_int(nameid_struct *nc_nameid, char *var_name, size_t *start, - size_t *count, int *var); +void get_scatter_nc_field_double(nameid_struct *nc_nameid, char *var_name, + size_t *start, size_t *count, double *var); +void get_scatter_nc_field_float(nameid_struct *nc_nameid, char *var_name, + size_t *start, size_t *count, float *var); +void get_scatter_nc_field_int(nameid_struct *nc_nameid, char *var_name, + size_t *start, size_t *count, int *var); void initialize_mpi(void); void map(size_t size, size_t n, size_t *from_map, size_t *to_map, void *from, void *to); From 943c769bc319cee25984509370740e1cad96dd33 Mon Sep 17 00:00:00 2001 From: Bart Nijssen Date: Wed, 22 Feb 2017 21:21:36 -0800 Subject: [PATCH 097/294] remove unused dmy_struct from initialize_history_file() --- vic/drivers/shared_image/include/vic_driver_shared_image.h | 3 +-- vic/drivers/shared_image/src/vic_init_output.c | 3 +-- vic/drivers/shared_image/src/vic_write.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index e2d892e4d..fd6f4d66d 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -216,8 +216,7 @@ void initialize_domain_info(domain_info_struct *info); void initialize_filenames(void); void initialize_fileps(void); void initialize_global_structures(void); -void initialize_history_file(nc_file_struct *nc, stream_struct *stream, - dmy_struct *dmy_current); +void initialize_history_file(nc_file_struct *nc, stream_struct *stream); void initialize_state_file(char *filename, nc_file_struct *nc_state_file, dmy_struct *dmy_state); void initialize_location(location_struct *location); diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index e051cbc45..f8290e851 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -195,8 +195,7 @@ vic_init_output(dmy_struct *dmy_current) *****************************************************************************/ void initialize_history_file(nc_file_struct *nc, - stream_struct *stream, - dmy_struct *ref_dmy) + stream_struct *stream) { extern filenames_struct filenames; extern domain_struct global_domain; diff --git a/vic/drivers/shared_image/src/vic_write.c b/vic/drivers/shared_image/src/vic_write.c index c6d7b77f2..88e697b2c 100644 --- a/vic/drivers/shared_image/src/vic_write.c +++ b/vic/drivers/shared_image/src/vic_write.c @@ -84,7 +84,7 @@ vic_write(stream_struct *stream, // If the output file is not open, initialize the history file now. if (nc_hist_file->open == false) { // open the netcdf history file - initialize_history_file(nc_hist_file, stream, dmy_current); + initialize_history_file(nc_hist_file, stream); } } From 02f1495a7c42e05eed6d25793774415a9fd24017 Mon Sep 17 00:00:00 2001 From: Bart Nijssen Date: Wed, 22 Feb 2017 21:29:29 -0800 Subject: [PATCH 098/294] remove unused variables from vic_store.c --- vic/drivers/shared_image/src/vic_store.c | 99 +++++++++++------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 194ad1229..2fe4cf0d2 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -48,9 +48,6 @@ vic_store(dmy_struct *dmy_state, size_t k; size_t m; size_t p; - double offset; - double time_num; - double end_time_num; int *ivar = NULL; double *dvar = NULL; size_t d2start[2]; @@ -58,7 +55,6 @@ vic_store(dmy_struct *dmy_state, size_t d4start[4]; size_t d5start[5]; size_t d6start[6]; - dmy_struct end_time_date; nc_file_struct nc_state_file; nc_var_struct *nc_var; @@ -1557,7 +1553,6 @@ initialize_state_file(char *filename, double dtime; double *dvar = NULL; int *ivar = NULL; - double offset; // open the netcdf file if (mpi_rank == VIC_MPI_ROOT) { @@ -1570,16 +1565,16 @@ initialize_state_file(char *filename, if (mpi_rank == VIC_MPI_ROOT) { // Set netcdf file global attributes set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); - + // set the NC_FILL attribute status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); check_nc_status(status, "Error setting fill value in %s", filename); - + // define the time dimension status = nc_def_dim(nc_state_file->nc_id, "time", nc_state_file->time_size, &(nc_state_file->time_dimid)); check_nc_status(status, "Error defining time dimenension in %s", filename); - + // define the variable time status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, &(nc_state_file->time_dimid), @@ -1588,67 +1583,67 @@ initialize_state_file(char *filename, status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, "standard_name", strlen("time"), "time"); check_nc_status(status, "Error adding attribute in %s", filename); - + // adding units attribute to time variable str_from_time_units(global_param.time_units, unit_str); - + sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); - + status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, "units", strlen(str), str); check_nc_status(status, "Error adding attribute in %s", filename); - + // adding calendar attribute to time variable str_from_calendar(global_param.calendar, str); - + status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, "calendar", strlen(str), str); check_nc_status(status, "Error adding calendar attribute in %s", filename); - + // define netcdf dimensions status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, nc_state_file->ni_size, &(nc_state_file->ni_dimid)); check_nc_status(status, "Error defining \"%s\" in %s", global_domain.info.x_dim, filename); - + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, nc_state_file->nj_size, &(nc_state_file->nj_dimid)); check_nc_status(status, "Error defining \"%s\" in %s", global_domain.info.y_dim, filename); - + status = nc_def_dim(nc_state_file->nc_id, "veg_class", nc_state_file->veg_size, &(nc_state_file->veg_dimid)); check_nc_status(status, "Error defining veg_class in %s", filename); - + status = nc_def_dim(nc_state_file->nc_id, "snow_band", nc_state_file->band_size, &(nc_state_file->band_dimid)); check_nc_status(status, "Error defining snow_band in %s", filename); - + status = nc_def_dim(nc_state_file->nc_id, "nlayer", nc_state_file->layer_size, &(nc_state_file->layer_dimid)); check_nc_status(status, "Error defining nlayer in %s", filename); - + status = nc_def_dim(nc_state_file->nc_id, "frost_area", nc_state_file->frost_size, &(nc_state_file->frost_dimid)); check_nc_status(status, "Error defining frost_area in %s", filename); - + status = nc_def_dim(nc_state_file->nc_id, "soil_node", nc_state_file->node_size, &(nc_state_file->node_dimid)); check_nc_status(status, "Error defining soil_node in %s", filename); - + if (options.LAKES) { status = nc_def_dim(nc_state_file->nc_id, "lake_node", nc_state_file->lake_node_size, &(nc_state_file->lake_node_dimid)); check_nc_status(status, "Error defining lake_node in %s", filename); } - + set_nc_state_var_info(nc_state_file); } @@ -1665,7 +1660,7 @@ initialize_state_file(char *filename, ndims = global_domain.info.n_coord_dims; dstart[0] = 0; dstart[1] = 0; - + if (global_domain.info.n_coord_dims == 1) { dimids[0] = nc_state_file->ni_dimid; dcount[0] = nc_state_file->ni_size; @@ -1673,7 +1668,7 @@ initialize_state_file(char *filename, else if (global_domain.info.n_coord_dims == 2) { dimids[0] = nc_state_file->nj_dimid; dcount[0] = nc_state_file->nj_size; - + dimids[1] = nc_state_file->ni_dimid; dcount[1] = nc_state_file->ni_size; } @@ -1687,7 +1682,7 @@ initialize_state_file(char *filename, status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, NC_DOUBLE, ndims, dimids, &(lon_var_id)); check_nc_status(status, "Error defining lon variable in %s", filename); - + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( "longitude"), "longitude"); check_nc_status(status, "Error adding attribute in %s", filename); @@ -1698,12 +1693,12 @@ initialize_state_file(char *filename, "standard_name", strlen( "longitude"), "longitude"); check_nc_status(status, "Error adding attribute in %s", filename); - + if (global_domain.info.n_coord_dims == 1) { dimids[0] = nc_state_file->nj_dimid; dcount[0] = nc_state_file->nj_size; } - + // define the netcdf variable latitude status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, NC_DOUBLE, ndims, dimids, &(lat_var_id)); @@ -1723,7 +1718,7 @@ initialize_state_file(char *filename, dimids[i] = -1; dcount[i] = 0; } - + // veg_class dimids[0] = nc_state_file->veg_dimid; status = nc_def_var(nc_state_file->nc_id, "veg_class", @@ -1738,7 +1733,7 @@ initialize_state_file(char *filename, "vegetation_class_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; - + // snow_band dimids[0] = nc_state_file->band_dimid; status = nc_def_var(nc_state_file->nc_id, "snow_band", @@ -1755,7 +1750,7 @@ initialize_state_file(char *filename, "snow_elevation_band_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; - + // layer dimids[0] = nc_state_file->layer_dimid; status = @@ -1770,7 +1765,7 @@ initialize_state_file(char *filename, "soil_layer_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; - + // frost_area dimids[0] = nc_state_file->frost_dimid; status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, @@ -1786,7 +1781,7 @@ initialize_state_file(char *filename, "frost_area_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; - + // dz_node (dimension: node, lat, lon) dimids[0] = nc_state_file->node_dimid; dimids[1] = nc_state_file->nj_dimid; @@ -1808,7 +1803,7 @@ initialize_state_file(char *filename, dimids[0] = -1; dimids[1] = -1; dimids[2] = -1; - + // node_depth (dimension: node, lat, lon) dimids[0] = nc_state_file->node_dimid; dimids[1] = nc_state_file->nj_dimid; @@ -1830,7 +1825,7 @@ initialize_state_file(char *filename, dimids[0] = -1; dimids[1] = -1; dimids[2] = -1; - + if (options.LAKES) { // lake_node dimids[0] = nc_state_file->lake_node_dimid; @@ -1856,7 +1851,7 @@ initialize_state_file(char *filename, // skip variables not set in set_state_meta_data_info continue; } - + // create the variable status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, nc_state_file->nc_vars[i].nc_type, @@ -1865,7 +1860,7 @@ initialize_state_file(char *filename, &(nc_state_file->nc_vars[i].nc_varid)); check_nc_status(status, "Error defining state variable %s in %s", state_metadata[i].varname, filename); - + // set the fill value attribute if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { status = nc_put_att_double(nc_state_file->nc_id, @@ -1886,7 +1881,7 @@ initialize_state_file(char *filename, check_nc_status(status, "Error putting _FillValue attribute to %s in %s", state_metadata[i].varname, filename); - + // Set string attributes put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, "long_name", state_metadata[i].long_name); @@ -1897,7 +1892,7 @@ initialize_state_file(char *filename, put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, "description", state_metadata[i].description); } - + // leave define mode status = nc_enddef(nc_state_file->nc_id); check_nc_status(status, "Error leaving define mode for %s", filename); @@ -1920,7 +1915,7 @@ initialize_state_file(char *filename, if (global_domain.info.n_coord_dims == 1) { dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); - + dcount[0] = nc_state_file->ni_size; // implicitly nested loop over ni and nj with j set to 0 for (i = 0; i < nc_state_file->ni_size; i++) { @@ -1930,7 +1925,7 @@ initialize_state_file(char *filename, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); free(dvar); - + dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); dcount[0] = nc_state_file->nj_size; @@ -1942,7 +1937,7 @@ initialize_state_file(char *filename, nc_state_file->ni_size]. latitude; } - + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); @@ -1953,14 +1948,14 @@ initialize_state_file(char *filename, check_alloc_status(dvar, "Memory allocation error"); dcount[0] = nc_state_file->nj_size; dcount[1] = nc_state_file->ni_size; - + for (i = 0; i < global_domain.ncells_total; i++) { dvar[i] = (double) global_domain.locations[i].longitude; } status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); - + for (i = 0; i < global_domain.ncells_total; i++) { dvar[i] = (double) global_domain.locations[i].latitude; @@ -1968,7 +1963,7 @@ initialize_state_file(char *filename, status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, dcount, dvar); check_nc_status(status, "Error adding data to lat in %s", filename); - + free(dvar); } else { @@ -1979,13 +1974,13 @@ initialize_state_file(char *filename, // Variables for other dimensions (all 1-dimensional) if (mpi_rank == VIC_MPI_ROOT) { ndims = 1; - + // vegetation classes dimids[0] = nc_state_file->veg_dimid; dcount[0] = nc_state_file->veg_size; ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); check_alloc_status(ivar, "Memory allocation error"); - + for (j = 0; j < nc_state_file->veg_size; j++) { ivar[j] = (int) j + 1; } @@ -1997,13 +1992,13 @@ initialize_state_file(char *filename, dcount[i] = 0; } free(ivar); - + // snow bands dimids[0] = nc_state_file->band_dimid; dcount[0] = nc_state_file->band_size; ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); check_alloc_status(ivar, "Memory allocation error"); - + for (j = 0; j < nc_state_file->band_size; j++) { ivar[j] = (int) j; } @@ -2015,13 +2010,13 @@ initialize_state_file(char *filename, dcount[i] = 0; } free(ivar); - + // soil layers dimids[0] = nc_state_file->layer_dimid; dcount[0] = nc_state_file->layer_size; ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); check_alloc_status(ivar, "Memory allocation error"); - + for (j = 0; j < nc_state_file->layer_size; j++) { ivar[j] = (int) j; } @@ -2033,13 +2028,13 @@ initialize_state_file(char *filename, dcount[i] = 0; } free(ivar); - + // frost areas dimids[0] = nc_state_file->frost_dimid; dcount[0] = nc_state_file->frost_size; ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); check_alloc_status(ivar, "Memory allocation error"); - + for (j = 0; j < nc_state_file->frost_size; j++) { ivar[j] = (int) j; } From a91ee8b7effbb01b4369d23db7d5215be79109fc Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 27 Feb 2017 18:03:28 +0100 Subject: [PATCH 099/294] update with netcdf-speedup addition --- vic/drivers/image/src/get_global_param.c | 2 +- vic/drivers/shared_image/src/vic_restore.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 2 +- vic/extensions/rout_rvic/src/rout_alloc.c | 17 ++++++++++----- vic/extensions/rout_rvic/src/rout_init.c | 24 ++++++++++++++-------- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 85e028875..a63f13d24 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -384,7 +384,7 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", filenames.params.nc_filename); } else if (strcasecmp("ROUT_PARAM", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.rout_params); + sscanf(cmdstr, "%*s %s", filenames.rout_params.nc_filename); } else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 44af455f8..c58499cbe 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -138,7 +138,7 @@ vic_restore(void) d2count_rout[0] = rout.rout_param.n_timesteps; d2count_rout[1] = rout.rout_param.n_outlets; - get_nc_field_double(filenames.init_state, + get_nc_field_double(&(filenames.init_state), state_metadata[STATE_ROUT_RING].varname, d2start, d2count_rout, rout.ring); } diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index f7d3aa7e1..4f7556eef 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -40,7 +40,7 @@ vic_store(dmy_struct *dmy_state, extern option_struct options; extern veg_con_map_struct *veg_con_map; extern int mpi_rank; - extern global_param_struct global_param; + extern rout_struct rout; int status; int v; diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 6e0236892..156f11bc8 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -40,23 +40,30 @@ rout_alloc(void) size_t d1count[1]; size_t d1start[1]; extern filenames_struct filenames; - + int status; + + // open parameter file + status = nc_open(filenames.rout_params.nc_filename, NC_NOWRITE, + &(filenames.rout_params.nc_id)); + check_nc_status(status, "Error opening %s", + filenames.rout_params.nc_filename); + d1count[0] = 0; d1start[0] = 1; // Get some values and dimensions - get_nc_field_int(filenames.rout_params, + get_nc_field_int(&(filenames.rout_params), "full_time_length", d1start, d1count, &ivar); rout.rout_param.full_time_length = (int) ivar; - rout.rout_param.n_timesteps = get_nc_dimension(filenames.rout_params, + rout.rout_param.n_timesteps = get_nc_dimension(&(filenames.rout_params), "timesteps"); - rout.rout_param.n_outlets = get_nc_dimension(filenames.rout_params, + rout.rout_param.n_outlets = get_nc_dimension(&(filenames.rout_params), "outlets"); - rout.rout_param.n_sources = get_nc_dimension(filenames.rout_params, + rout.rout_param.n_sources = get_nc_dimension(&(filenames.rout_params), "sources"); // Allocate memory in rout param_struct diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 8ac6ba629..1ae161dac 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -36,6 +36,7 @@ rout_init(void) extern rout_struct rout; extern domain_struct global_domain; extern filenames_struct filenames; + int status; if (mpi_rank == VIC_MPI_ROOT) { int *ivar = NULL; @@ -79,7 +80,7 @@ rout_init(void) } // source2outlet_ind: source to outlet index mapping - get_nc_field_int(filenames.rout_params, + get_nc_field_int(&(filenames.rout_params), "source2outlet_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -87,7 +88,7 @@ rout_init(void) } // source_time_offset: Number of leading timesteps ommited - get_nc_field_int(filenames.rout_params, + get_nc_field_int(&(filenames.rout_params), "source_time_offset", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -95,7 +96,7 @@ rout_init(void) } // source_x_ind: x grid coordinate of source grid cell - get_nc_field_int(filenames.rout_params, + get_nc_field_int(&(filenames.rout_params), "source_x_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -103,7 +104,7 @@ rout_init(void) } // source_y_ind: y grid coordinate of source grid cell - get_nc_field_int(filenames.rout_params, + get_nc_field_int(&(filenames.rout_params), "source_y_ind", &i1start, &rout.rout_param.n_sources, ivar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -111,7 +112,7 @@ rout_init(void) } // source_lat: Latitude coordinate of source grid cell - get_nc_field_double(filenames.rout_params, + get_nc_field_double(&(filenames.rout_params), "source_lat", &i1start, &rout.rout_param.n_sources, dvar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -119,7 +120,7 @@ rout_init(void) } // source_lon: Longitude coordinate of source grid cell - get_nc_field_double(filenames.rout_params, + get_nc_field_double(&(filenames.rout_params), "source_lon", &i1start, &rout.rout_param.n_sources, dvar); for (i = 0; i < rout.rout_param.n_sources; i++) { @@ -127,7 +128,7 @@ rout_init(void) } // outlet_lat: Latitude coordinate of source grid cell - get_nc_field_double(filenames.rout_params, + get_nc_field_double(&(filenames.rout_params), "outlet_lat", &i1start, &rout.rout_param.n_outlets, dvar); for (i = 0; i < rout.rout_param.n_outlets; i++) { @@ -135,7 +136,7 @@ rout_init(void) } // outlet_lon: Longitude coordinate of source grid cell - get_nc_field_double(filenames.rout_params, + get_nc_field_double(&(filenames.rout_params), "outlet_lon", &i1start, &rout.rout_param.n_outlets, dvar); for (i = 0; i < rout.rout_param.n_outlets; i++) { @@ -143,7 +144,7 @@ rout_init(void) } // Unit Hydrograph: - get_nc_field_double(filenames.rout_params, + get_nc_field_double(&(filenames.rout_params), "unit_hydrograph", d3start, d3count, dvar); for (i = 0; @@ -197,6 +198,11 @@ rout_init(void) } } + // close parameter file + status = nc_close(filenames.rout_params.nc_id); + check_nc_status(status, "Error closing %s", + filenames.rout_params.nc_filename); + // cleanup free(ivar); free(dvar); From f6a4aefa5ed441ee0fc4c3e638ebf31fac0e89c5 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 28 Feb 2017 13:31:04 +0100 Subject: [PATCH 100/294] initialized discharge to zero --- vic/drivers/shared_image/src/initialize_files.c | 1 + vic/extensions/rout_rvic/src/rout_run.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/vic/drivers/shared_image/src/initialize_files.c b/vic/drivers/shared_image/src/initialize_files.c index 6c4a201d3..5e1677223 100644 --- a/vic/drivers/shared_image/src/initialize_files.c +++ b/vic/drivers/shared_image/src/initialize_files.c @@ -42,6 +42,7 @@ initialize_filenames() strcpy(filenames.statefile, "MISSING"); strcpy(filenames.constants, "MISSING"); strcpy(filenames.params.nc_filename, "MISSING"); + strcpy(filenames.rout_params.nc_filename, "MISSING"); strcpy(filenames.domain.nc_filename, "MISSING"); strcpy(filenames.result_dir, "MISSING"); strcpy(filenames.log_path, "MISSING"); diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 989aacc99..9fff1213b 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -62,6 +62,11 @@ rout_run(void) var_domain_discharge = malloc(global_domain.ncells_total * sizeof(*var_domain_discharge)); check_alloc_status(var_domain_discharge, "Memory allocation error."); + + // Initialize discharge to zero + for (i = 0; i < global_domain.ncells_total; i++) { + var_domain_discharge[i] = 0; + } } // Read from runoff and baseflow from out_data and sum to runoff From 1a880fa37eaa9f1ae377700af3242fd65cad2e8f Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 2 Mar 2017 16:24:04 +0100 Subject: [PATCH 101/294] adapted init to new timelenght --- vic/drivers/shared_image/src/vic_restore.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 2 +- vic/extensions/rout_rvic/src/rout_alloc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index c58499cbe..395a728b5 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -135,7 +135,7 @@ vic_restore(void) if (mpi_rank == VIC_MPI_ROOT) { d2start[0] = 0; d2start[1] = 0; - d2count_rout[0] = rout.rout_param.n_timesteps; + d2count_rout[0] = rout.rout_param.full_time_length; d2count_rout[1] = rout.rout_param.n_outlets; get_nc_field_double(&(filenames.init_state), diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 4f7556eef..3fbde0144 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1325,7 +1325,7 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->nj_size = global_domain.n_ny; nc_state_file->node_size = options.Nnode; nc_state_file->outlet_size = rout.rout_param.n_outlets; - nc_state_file->routing_timestep_size = rout.rout_param.n_timesteps; + nc_state_file->routing_timestep_size = rout.rout_param.full_time_length; nc_state_file->root_zone_size = options.ROOT_ZONES; nc_state_file->time_size = NC_UNLIMITED; nc_state_file->veg_size = options.NVEGTYPES; diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index 156f11bc8..fa4c8994e 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -138,7 +138,7 @@ rout_alloc(void) // Allocate memory for the ring rout.ring = malloc( - rout.rout_param.n_timesteps * rout.rout_param.n_outlets * + rout.rout_param.full_time_length * rout.rout_param.n_outlets * sizeof(*rout.ring)); check_alloc_status(rout.ring, "Memory allocation error."); } From 9579d830bb645490dfa98b0611a67b23bec18647 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 2 Mar 2017 16:35:30 +0100 Subject: [PATCH 102/294] adapted to cesm driver changes --- vic/drivers/cesm/Makefile | 13 ++----------- vic/drivers/cesm/src/cesm_interface_c.c | 4 ++++ vic/drivers/cesm/src/cesm_put_data.c | 16 ++++++++-------- vic/drivers/cesm/src/get_global_param.c | 9 +++++++++ vic/drivers/cesm/src/vic_cesm_start.c | 5 +++++ vic/drivers/cesm/src/vic_force.c | 4 ++-- vic/drivers/shared_image/src/vic_restore.c | 1 - vic/drivers/shared_image/src/vic_write.c | 2 +- vic/vic_run/include/vic_def.h | 2 +- vic/vic_run/include/vic_run.h | 1 + vic/vic_run/src/runoff.c | 10 ++++------ 11 files changed, 37 insertions(+), 30 deletions(-) diff --git a/vic/drivers/cesm/Makefile b/vic/drivers/cesm/Makefile index 1c5ecbf39..41029ed94 100644 --- a/vic/drivers/cesm/Makefile +++ b/vic/drivers/cesm/Makefile @@ -57,12 +57,6 @@ else MPIPATH = /opt/local endif -# VIC EXTENTIONS PATH -EXTPATH = ../../extensions - -# Set the routing model extension -include ${EXTPATH}/rout_stub/rout.mk - # Set SHELL = your shell here SHELL = /bin/bash @@ -88,7 +82,6 @@ INCLUDES = -I ${DRIVERPATH}/include \ -I ${SHAREDPATH}/include \ -I ${SHAREDIMAGEPATH}/include \ -I ${NETCDFPATH}/include \ - -I ${EXTPATH}/rout_stub/include # Set libraries LIBRARY = -lm -L${NETCDFPATH}/lib -lnetcdf @@ -125,15 +118,13 @@ HDRS = \ $(wildcard ${VICPATH}/include/*.h) \ $(wildcard ${DRIVERPATH}/include/*.h) \ $(wildcard ${SHAREDPATH}/include/*.h) \ - $(wildcard ${SHAREDIMAGEPATH}/include/*.h) \ - $(wildcard ${EXTPATH}/rout_stub/include/*.h) + $(wildcard ${SHAREDIMAGEPATH}/include/*.h) CSRCS = \ $(wildcard ${VICPATH}/src/*.c) \ $(wildcard ${DRIVERPATH}/src/*.c) \ $(wildcard ${SHAREDPATH}/src/*.c) \ - $(wildcard ${SHAREDIMAGEPATH}/src/*.c) \ - $(wildcard ${EXTPATH}/rout_stub/src/*.c) + $(wildcard ${SHAREDIMAGEPATH}/src/*.c) FSRCS = \ $(wildcard ${DRIVERPATH}/src/*.F90) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 923518a98..e5d1e500a 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -96,6 +96,9 @@ vic_cesm_init(vic_clock *vclock, // populate model state, either using a cold start or from a restart file vic_populate_model_state(trim(cmeta->starttype)); + // initialize forcings + vic_force(); + // initialize output structures vic_init_output(&dmy_current); @@ -141,6 +144,7 @@ vic_cesm_run(vic_clock *vclock) // if save: if (vclock->state_flag) { + // write state file vic_store(&dmy_current, state_filename); write_rpointer_file(state_filename); } diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 4e04a723a..e07eaf137 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -140,12 +140,12 @@ vic_cesm_put_data() // 2m reference temperature // CESM units: K - l2x_vic[i].l2x_Sl_tref += AreaFactor * force->air_temp[NR]; + l2x_vic[i].l2x_Sl_tref += AreaFactor * (force[i].air_temp[NR] + CONST_TKFRZ); // 2m reference specific humidity // CESM units: g/g l2x_vic[i].l2x_Sl_qref += AreaFactor * CONST_EPS * - force->vp[NR] / force->pressure[NR]; + force[i].vp[NR] / force[i].pressure[NR]; // Albedo Note: VIC does not partition its albedo, all returned // values will be the same @@ -156,10 +156,10 @@ vic_cesm_put_data() // force->NetShortAtmos net shortwave flux (+ down) // SWup = force->shortwave[NR] - energy.NetShortAtmos // Set the albedo to zero for the case where there is no shortwave down - if (force->shortwave[NR] > 0.) { + if (force[i].shortwave[NR] > 0.) { albedo = AreaFactor * - (force->shortwave[NR] - energy.NetShortAtmos) / - force->shortwave[NR]; + (force[i].shortwave[NR] - energy.NetShortAtmos) / + force[i].shortwave[NR]; } else { albedo = 0.; @@ -184,7 +184,7 @@ vic_cesm_put_data() // 10m wind // CESM units: m/s - l2x_vic[i].l2x_Sl_u10 += AreaFactor * force->wind[NR]; + l2x_vic[i].l2x_Sl_u10 += AreaFactor * force[i].wind[NR]; // dry deposition velocities (optional) // CESM units: ? @@ -259,7 +259,7 @@ vic_cesm_put_data() // upward longwave heat flux // CESM units: W m-2 l2x_vic[i].l2x_Fall_lwup += AreaFactor * - (force->longwave[NR] - + (force[i].longwave[NR] - energy.NetLongAtmos); // evaporation water flux @@ -278,7 +278,7 @@ vic_cesm_put_data() // heat flux shortwave net l2x_vic[i].l2x_Fall_swnet += AreaFactor * - (force->shortwave[NR] - + (force[i].shortwave[NR] - energy.NetShortAtmos); // co2 flux **For testing set to 0 diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 7cc7c7459..33068bd3e 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -385,6 +385,12 @@ get_global_param(FILE *gp) "control file."); } } + else if (strcasecmp("SNOW_BAND", optstr) == 0) { + sscanf(cmdstr, "%*s %s", flgstr); + if (str_to_bool(flgstr)) { + options.SNOW_BAND = SNOW_BAND_TRUE_BUT_UNSET; + } + } else if (strcasecmp("LAKES", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); if (strcasecmp("FALSE", flgstr) == 0) { @@ -415,6 +421,9 @@ get_global_param(FILE *gp) else if (strcasecmp("OUTVAR", optstr) == 0) { ; // do nothing } + else if (strcasecmp("AGGFREQ", optstr) == 0) { + ; // do nothing + } else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { ; // do nothing } diff --git a/vic/drivers/cesm/src/vic_cesm_start.c b/vic/drivers/cesm/src/vic_cesm_start.c index 3097fde1a..5db95a782 100644 --- a/vic/drivers/cesm/src/vic_cesm_start.c +++ b/vic/drivers/cesm/src/vic_cesm_start.c @@ -46,6 +46,11 @@ vic_cesm_start(vic_clock *vclock, // Driver specific settings if (mpi_rank == VIC_MPI_ROOT) { strcpy(filenames.global, GLOBALPARAM); + + // assign case name to state file name + strncpy(filenames.statefile, trim(cmeta->caseid), + sizeof(filenames.statefile)); + // read global settings filep.globalparam = open_file(filenames.global, "r"); get_global_param(filep.globalparam); diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index 252bb5bbd..616e809ee 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -127,8 +127,8 @@ vic_force(void) for (j = 0; j < NF; j++) { for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: Pa - // VIC units: kPa - force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot / PA_PER_KPA; + // VIC units: Pa + force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot; } } diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 395a728b5..30c189643 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -75,7 +75,6 @@ vic_restore(void) // validate state file dimensions and coordinate variables check_init_state_file(); - // read state variables // allocate memory for variables to be stored diff --git a/vic/drivers/shared_image/src/vic_write.c b/vic/drivers/shared_image/src/vic_write.c index 4cd346619..88e697b2c 100644 --- a/vic/drivers/shared_image/src/vic_write.c +++ b/vic/drivers/shared_image/src/vic_write.c @@ -194,7 +194,7 @@ vic_write(stream_struct *stream, } gather_put_nc_field_schar(nc_hist_file->nc_id, nc_hist_file->nc_vars[k].nc_varid, - nc_hist_file->d_fillvalue, + nc_hist_file->c_fillvalue, dstart, dcount, cvar); } else { diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index ddeffb3ce..3a34ae711 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -52,7 +52,7 @@ /***** Model Constants *****/ #define MAXSTRING 2048 #define MISSING -99999. /**< missing value */ -#define MISSING_USI 99999. /**< missing value for unsigned ints */ +#define MISSING_USI 99999 /**< missing value for unsigned ints */ #define MISSING_S "MISSING" /**< missing value for strings */ #define NODATA_VH -1 /**< missing value for veg_hist inputs */ #define NODATA_VEG -1 /**< flag for veg types not in grid cell */ diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 9ff2e294b..aba458c26 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -113,6 +113,7 @@ void compute_pot_evap(size_t, double, double, double, double, double, double, double, double *); void compute_runoff_and_asat(soil_con_struct *, double *, double, double *, double *); +double calc_Q12(double, double, double, double, double); void compute_soil_resp(int, double *, double, double, double *, double *, double, double, double, double *, double *, double *); void compute_soil_layer_thermal_properties(layer_data_struct *, double *, diff --git a/vic/vic_run/src/runoff.c b/vic/vic_run/src/runoff.c index ba11da4de..ed14df583 100644 --- a/vic/vic_run/src/runoff.c +++ b/vic/vic_run/src/runoff.c @@ -200,12 +200,10 @@ runoff(cell_data_struct *cell, } if (liq[lindex] > resid_moist[lindex]) { - Q12[lindex] = Ksat[lindex] * - pow(((tmp_liq - - resid_moist[lindex]) / - (soil_con->max_moist[lindex] - - resid_moist[lindex])), - soil_con->expt[lindex]); + Q12[lindex] = calc_Q12(Ksat[lindex], tmp_liq, + resid_moist[lindex], + soil_con->max_moist[lindex], + soil_con->expt[lindex]); } else { Q12[lindex] = 0.; From 8be9579dd7e2e8139e35f25c50be7c46896fb04d Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 2 Mar 2017 16:46:27 +0100 Subject: [PATCH 103/294] imagedriver timelength fix --- vic/extensions/rout_stub/include/rout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 7c20d8e06..db757a5a9 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -35,7 +35,7 @@ * @brief Routing Structs *****************************************************************************/ typedef struct { - size_t n_timesteps; /*scalar - number of timesteps*/ + size_t full_time_length; /*scalar - number of timesteps*/ size_t n_outlets; /*scalar - length of subset*/ } rout_param_struct; From 71a375ca0de40681dd076a0b65f3dc0cd8f4bdef Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 2 Mar 2017 17:59:30 +0100 Subject: [PATCH 104/294] reverted back Q12 and fixed rvic_stub --- vic/extensions/rout_stub/src/rout.c | 2 +- vic/vic_run/src/runoff.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 917bea43d..3130a485d 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -37,7 +37,7 @@ rout_alloc(void) // We need to write at least something to the VIC state file (if enabled). // Therefore we make the dimension size 1*1. rout.rout_param.n_outlets = 1; - rout.rout_param.n_timesteps = 1; + rout.rout_param.full_time_length = 1; rout.ring[1] = 0; } diff --git a/vic/vic_run/src/runoff.c b/vic/vic_run/src/runoff.c index ed14df583..ba11da4de 100644 --- a/vic/vic_run/src/runoff.c +++ b/vic/vic_run/src/runoff.c @@ -200,10 +200,12 @@ runoff(cell_data_struct *cell, } if (liq[lindex] > resid_moist[lindex]) { - Q12[lindex] = calc_Q12(Ksat[lindex], tmp_liq, - resid_moist[lindex], - soil_con->max_moist[lindex], - soil_con->expt[lindex]); + Q12[lindex] = Ksat[lindex] * + pow(((tmp_liq - + resid_moist[lindex]) / + (soil_con->max_moist[lindex] - + resid_moist[lindex])), + soil_con->expt[lindex]); } else { Q12[lindex] = 0.; From c956aca472aa63ecc9d9af187bcc4b77814cb4ee Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Thu, 2 Mar 2017 18:09:58 +0100 Subject: [PATCH 105/294] adapted to cesm driver changes makefile --- vic/drivers/cesm/Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/vic/drivers/cesm/Makefile b/vic/drivers/cesm/Makefile index 41029ed94..1c5ecbf39 100644 --- a/vic/drivers/cesm/Makefile +++ b/vic/drivers/cesm/Makefile @@ -57,6 +57,12 @@ else MPIPATH = /opt/local endif +# VIC EXTENTIONS PATH +EXTPATH = ../../extensions + +# Set the routing model extension +include ${EXTPATH}/rout_stub/rout.mk + # Set SHELL = your shell here SHELL = /bin/bash @@ -82,6 +88,7 @@ INCLUDES = -I ${DRIVERPATH}/include \ -I ${SHAREDPATH}/include \ -I ${SHAREDIMAGEPATH}/include \ -I ${NETCDFPATH}/include \ + -I ${EXTPATH}/rout_stub/include # Set libraries LIBRARY = -lm -L${NETCDFPATH}/lib -lnetcdf @@ -118,13 +125,15 @@ HDRS = \ $(wildcard ${VICPATH}/include/*.h) \ $(wildcard ${DRIVERPATH}/include/*.h) \ $(wildcard ${SHAREDPATH}/include/*.h) \ - $(wildcard ${SHAREDIMAGEPATH}/include/*.h) + $(wildcard ${SHAREDIMAGEPATH}/include/*.h) \ + $(wildcard ${EXTPATH}/rout_stub/include/*.h) CSRCS = \ $(wildcard ${VICPATH}/src/*.c) \ $(wildcard ${DRIVERPATH}/src/*.c) \ $(wildcard ${SHAREDPATH}/src/*.c) \ - $(wildcard ${SHAREDIMAGEPATH}/src/*.c) + $(wildcard ${SHAREDIMAGEPATH}/src/*.c) \ + $(wildcard ${EXTPATH}/rout_stub/src/*.c) FSRCS = \ $(wildcard ${DRIVERPATH}/src/*.F90) From 16273e09b35b4a025b98da3da4818df991f510e4 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 2 Mar 2017 18:55:01 -0500 Subject: [PATCH 106/294] implement run cell changes in CESM driver --- vic/drivers/cesm/src/display_current_settings.c | 4 ++-- vic/drivers/cesm/src/get_global_param.c | 8 ++++---- vic/drivers/cesm/src/vic_populate_model_state.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 86351b418..5a82a30ae 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -262,7 +262,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input Domain Data:\n"); - fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain); + fprintf(LOG_DEST, "Domain file\t\t%s\n", filenames.domain.nc_filename); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Constants File\t\t%s\n", filenames.constants); @@ -361,7 +361,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input State File:\n"); if (options.INIT_STATE) { - fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state); + fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_filename); if (options.STATE_FORMAT == NETCDF3_CLASSIC) { fprintf(LOG_DEST, "STATE_FORMAT\t\tNETCDF3_CLASSIC\n"); } diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 33068bd3e..67138a9e9 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -247,7 +247,7 @@ get_global_param(FILE *gp) } else { options.INIT_STATE = true; - strcpy(filenames.init_state, flgstr); + strcpy(filenames.init_state.nc_filename, flgstr); } } // Define state file format @@ -279,13 +279,13 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", filenames.constants); } else if (strcasecmp("DOMAIN", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.domain); + sscanf(cmdstr, "%*s %s", filenames.domain.nc_filename); } else if (strcasecmp("DOMAIN_TYPE", optstr) == 0) { get_domain_type(cmdstr); } else if (strcasecmp("PARAMETERS", optstr) == 0) { - sscanf(cmdstr, "%*s %s", filenames.params); + sscanf(cmdstr, "%*s %s", filenames.params.nc_filename); } else if (strcasecmp("ARNO_PARAMS", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); @@ -482,7 +482,7 @@ validate_filenames(filenames_struct *filenames) } // Validate parameter file information - if (strcmp(filenames->params, "MISSING") == 0) { + if (strcmp(filenames->params.nc_filename, "MISSING") == 0) { log_err("A parameters file has not been defined. Make sure that the " "global file defines the parameters parameter file on the line " "that begins with \"PARAMETERS\"."); diff --git a/vic/drivers/cesm/src/vic_populate_model_state.c b/vic/drivers/cesm/src/vic_populate_model_state.c index 4281d034e..ab9076e92 100644 --- a/vic/drivers/cesm/src/vic_populate_model_state.c +++ b/vic/drivers/cesm/src/vic_populate_model_state.c @@ -51,7 +51,7 @@ vic_populate_model_state(char *runtype_str) // read the model state from the netcdf file if (runtype == CESM_RUNTYPE_RESTART || runtype == CESM_RUNTYPE_BRANCH) { // Get restart file from rpointer file - read_rpointer_file(filenames.init_state); + read_rpointer_file(filenames.init_state.nc_filename); // set options.INIT_STATE to true since we have found a state file in // the rpointer file. From 97a0b448530a164d14c91f659bb7213729a8fdba Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 2 Mar 2017 18:58:57 -0500 Subject: [PATCH 107/294] fix check for Q12 calculation that initial moisture is greater than residual moisture --- vic/vic_run/src/runoff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/runoff.c b/vic/vic_run/src/runoff.c index 6308e28b0..0466dc847 100644 --- a/vic/vic_run/src/runoff.c +++ b/vic/vic_run/src/runoff.c @@ -199,7 +199,7 @@ runoff(cell_data_struct *cell, tmp_liq = resid_moist[lindex]; } - if (liq[lindex] > resid_moist[lindex]) { + if (tmp_liq > resid_moist[lindex]) { Q12[lindex] = calc_Q12(Ksat[lindex], tmp_liq, resid_moist[lindex], soil_con->max_moist[lindex], From 9faea53e62db04811aeb03210ebfb3a49b5763b8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 2 Mar 2017 20:07:45 -0500 Subject: [PATCH 108/294] update params type to nameid struct --- vic/drivers/cesm/src/display_current_settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 5a82a30ae..123e954e3 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -266,7 +266,7 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Constants File\t\t%s\n", filenames.constants); - fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params); + fprintf(LOG_DEST, "Parameters file\t\t%s\n", filenames.params.nc_filename); if (options.BASEFLOW == ARNO) { fprintf(LOG_DEST, "BASEFLOW\t\tARNO\n"); } From d885d9da07cb2e2894734fc757513a0d050e0e6f Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Fri, 3 Mar 2017 16:40:36 +0100 Subject: [PATCH 109/294] rolled back docs/Development/ReleaseNotes.md and vic/vic_run/src/runoff.c --- docs/Development/ReleaseNotes.md | 27 ++++++++++++++++++++++++++- vic/vic_run/src/runoff.c | 27 +++++++++++++++++++++------ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index e96ef1c2e..ba60d5d09 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -14,6 +14,30 @@ To check which release of VIC you are running: - For VIC 5 and later, type `vic_{classic,image}.exe -v` ------------------------------ + +## VIC 5.1.0 + +**Release date: (Unreleased)** + +#### Model enhancement: + +1. Improved calculation of drainage between soil layers ([GH#656](https://github.com/UW-Hydro/VIC/pull/656)) + + Drainage from upper layer to adjacent lower layer is calculated according to Brook & Corey curve (where drainage rate is a function of upper-layer soil moisture). In previous versions, a simple numerical solution is applied which uses the timestep-beginning upper-layer soil moisture to calculate drainage rate, and assume this constant rate over the entire timestep. This can cause unreasonably large drainage if the curve has a steep shape and when soil moisture is high. Now, the current version uses exact integral (instead of numerical solution) for layer drainage calculation. + +2. Fixes for the CESM driver ([GH#642](https://github.com/UW-Hydro/VIC/pull/642)) + + 1. Using correct fill value datatypes in MPI Gather steps + 2. Updated state file name time step to be period-ending rather than period-beginning + 3. Set the state file name to the RASM case ID + 4. Removed decimal point for missing values for unsigned integers + 5. Create dummy forcings when initializing the model (so that there is forcing data for the first time step) + 6. Changed pressure units from kPa to Pa + 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` + 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` + +------------------------------ + ## VIC 5.0.1 **Release date: (February 1, 2017)** @@ -61,7 +85,7 @@ To check which release of VIC you are running: ------------------------------ -## VIC 5.0.0 [![DOI](https://zenodo.org/badge/7766/UW-Hydro/VIC.svg)](https://zenodo.org/badge/latestdoi/7766/UW-Hydro/VIC) +## VIC 5.0.0 [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.61422.svg)](http://dx.doi.org/10.5281/zenodo.61422) **Release date: (September 2, 2016)** @@ -236,6 +260,7 @@ This is a major update from VIC 4. The VIC 5.0.0 release aims to have nearly ide Fixed a bug where volumetric heat capacity of water should be used in `func_canopy_energy_bal` (previously specific heat capacity was used). + ------------------------------ ## VIC 4.2.d [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.56058.svg)](http://dx.doi.org/10.5281/zenodo.56058) diff --git a/vic/vic_run/src/runoff.c b/vic/vic_run/src/runoff.c index ba11da4de..6308e28b0 100644 --- a/vic/vic_run/src/runoff.c +++ b/vic/vic_run/src/runoff.c @@ -200,12 +200,10 @@ runoff(cell_data_struct *cell, } if (liq[lindex] > resid_moist[lindex]) { - Q12[lindex] = Ksat[lindex] * - pow(((tmp_liq - - resid_moist[lindex]) / - (soil_con->max_moist[lindex] - - resid_moist[lindex])), - soil_con->expt[lindex]); + Q12[lindex] = calc_Q12(Ksat[lindex], tmp_liq, + resid_moist[lindex], + soil_con->max_moist[lindex], + soil_con->expt[lindex]); } else { Q12[lindex] = 0.; @@ -487,3 +485,20 @@ compute_runoff_and_asat(soil_con_struct *soil_con, *runoff = 0.; } } + +/****************************************************************************** +* @brief Calculate drainage between two layers +******************************************************************************/ +double +calc_Q12(double Ksat, double init_moist, double resid_moist, + double max_moist, double expt) +{ + double Q12; + + Q12 = init_moist - pow(pow(init_moist - resid_moist, 1.0 - expt) - + Ksat / pow(max_moist - resid_moist, expt) * (1.0 - expt), + 1.0 / (1.0 - expt)) - resid_moist; + + return Q12; +} + From 5f01dd4eee39b2cc28256e76b683d288c10787cf Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 3 Mar 2017 10:50:47 -0800 Subject: [PATCH 110/294] Feature/add run profiling for thunder (#682) * added section for running scaling tests on Thunder * update module loading and scaling run mpi processes options * export netcdf path to address libnetcdf.so.7 error * fix runtime * fix indentation and remove setting netcdf path * updated number of configurations and walltime --- tests/run_profiling.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/run_profiling.py b/tests/run_profiling.py index 9fb29bacb..10237a1e5 100755 --- a/tests/run_profiling.py +++ b/tests/run_profiling.py @@ -107,6 +107,36 @@ def log2_range(m): module load usp-netcdf/intel-15.0.3/4.3.3.1 +START=$(date +%s) +mpiexec_mpt -np ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global +END=$(date +%s) +DIFF=$(echo "$END - $START" | bc) +printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file'''), + 'thunder': host_config(profile=[dict(select=1, mpiprocs=36), + dict(select=2, mpiprocs=36), + dict(select=3, mpiprocs=36), + dict(select=4, mpiprocs=36), + dict(select=5, mpiprocs=36), + dict(select=6, mpiprocs=36), + dict(select=8, mpiprocs=36), + dict(select=10, mpiprocs=36), + dict(select=12, mpiprocs=36)], + submit='qsub', mpiexec='mpiexec_mpt', + template='''#!/bin/bash +#!/bin/bash +#PBS -N VIC$i +#PBS -q standard +#PBS -A NPSCA07935242 +#PBS -l application=VIC +#PBS -l select=$select:ncpus=36:mpiprocs=$mpiprocs +#PBS -l walltime=35:00:00 +#PBS -j oe + +# Qsub template for AFRL THUNDER +# Scheduler: PBS + +module load netcdf-fortran/intel/4.4.2 + START=$(date +%s) mpiexec_mpt -np ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global END=$(date +%s) From ae4e67d47acd8cdb04fcdb736d548cc569625095 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 6 Mar 2017 22:17:39 -0800 Subject: [PATCH 111/294] Feature/fix RASM RFR compiling conflict (#696) * rename trim function trimstr to avoid conflict with WRF trim function when compiling an RFR case * rename advance_time function to advance_vic_time to avoid conflict with WRF advance_time function when compiling an RFR case * add change log entry --- docs/Development/ReleaseNotes.md | 3 +++ vic/drivers/cesm/include/vic_driver_cesm.h | 4 ++-- vic/drivers/cesm/src/cesm_interface_c.c | 4 ++-- vic/drivers/cesm/src/print_library_cesm.c | 14 +++++++------- vic/drivers/cesm/src/vic_cesm_start.c | 6 +++--- vic/drivers/cesm/src/vic_cesm_time.c | 2 +- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index ba60d5d09..a837b94a3 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -36,6 +36,9 @@ To check which release of VIC you are running: 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` + [GH#696](https://github.com/UW-Hydro/VIC/pull/696) + + 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. ------------------------------ ## VIC 5.0.1 diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index f39097064..6b13daf25 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -157,7 +157,7 @@ typedef struct { bool l2x_vars_set; /** l2x set flag */ } l2x_data_struct; -void advance_time(void); +void advance_vic_time(void); void assert_time_insync(vic_clock *vclock, dmy_struct *dmy); void get_global_param(FILE *); void initialize_cesm_time(void); @@ -171,7 +171,7 @@ void print_vic_clock(vic_clock *vclock); void print_x2l_data(x2l_data_struct *x2l); void read_rpointer_file(char *fname); unsigned short int start_type_from_char(char *start_str); -char *trim(char *str); +char *trimstr(char *str); void validate_filenames(filenames_struct *filenames); void validate_global_param(global_param_struct *global_param); void validate_options(option_struct *options); diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index e5d1e500a..978b431dd 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -94,7 +94,7 @@ vic_cesm_init(vic_clock *vclock, vic_init(); // populate model state, either using a cold start or from a restart file - vic_populate_model_state(trim(cmeta->starttype)); + vic_populate_model_state(trimstr(cmeta->starttype)); // initialize forcings vic_force(); @@ -139,7 +139,7 @@ vic_cesm_run(vic_clock *vclock) vic_write_output(&dmy_current); // advance the clock - advance_time(); + advance_vic_time(); assert_time_insync(vclock, &dmy_current); // if save: diff --git a/vic/drivers/cesm/src/print_library_cesm.c b/vic/drivers/cesm/src/print_library_cesm.c index 1a562232f..6b7d04aae 100644 --- a/vic/drivers/cesm/src/print_library_cesm.c +++ b/vic/drivers/cesm/src/print_library_cesm.c @@ -41,7 +41,7 @@ print_vic_clock(vic_clock *vclock) vclock->current_dayseconds); fprintf(LOG_DEST, "\tstate_flag : %d\n", vclock->state_flag); fprintf(LOG_DEST, "\tstop_flag : %d\n", vclock->stop_flag); - fprintf(LOG_DEST, "\tcalendar : %s\n", trim(vclock->calendar)); + fprintf(LOG_DEST, "\tcalendar : %s\n", trimstr(vclock->calendar)); } /****************************************************************************** @@ -51,12 +51,12 @@ void print_case_metadata(case_metadata *cmeta) { fprintf(LOG_DEST, "case_metadata :\n"); - fprintf(LOG_DEST, "\tcaseid : %s\n", trim(cmeta->caseid)); - fprintf(LOG_DEST, "\tcasedesc : %s\n", trim(cmeta->casedesc)); - fprintf(LOG_DEST, "\tstarttype : %s\n", trim(cmeta->starttype)); - fprintf(LOG_DEST, "\tmodel_version : %s\n", trim(cmeta->model_version)); - fprintf(LOG_DEST, "\thostname : %s\n", trim(cmeta->hostname)); - fprintf(LOG_DEST, "\tusername : %s\n", trim(cmeta->username)); + fprintf(LOG_DEST, "\tcaseid : %s\n", trimstr(cmeta->caseid)); + fprintf(LOG_DEST, "\tcasedesc : %s\n", trimstr(cmeta->casedesc)); + fprintf(LOG_DEST, "\tstarttype : %s\n", trimstr(cmeta->starttype)); + fprintf(LOG_DEST, "\tmodel_version : %s\n", trimstr(cmeta->model_version)); + fprintf(LOG_DEST, "\thostname : %s\n", trimstr(cmeta->hostname)); + fprintf(LOG_DEST, "\tusername : %s\n", trimstr(cmeta->username)); } /****************************************************************************** diff --git a/vic/drivers/cesm/src/vic_cesm_start.c b/vic/drivers/cesm/src/vic_cesm_start.c index 5db95a782..635643cbc 100644 --- a/vic/drivers/cesm/src/vic_cesm_start.c +++ b/vic/drivers/cesm/src/vic_cesm_start.c @@ -48,7 +48,7 @@ vic_cesm_start(vic_clock *vclock, strcpy(filenames.global, GLOBALPARAM); // assign case name to state file name - strncpy(filenames.statefile, trim(cmeta->caseid), + strncpy(filenames.statefile, trimstr(cmeta->caseid), sizeof(filenames.statefile)); // read global settings @@ -76,7 +76,7 @@ vic_cesm_start(vic_clock *vclock, global_param.nrecs = 1; // Calendar - global_param.calendar = str_to_calendar(trim(vclock->calendar)); + global_param.calendar = str_to_calendar(trimstr(vclock->calendar)); // set NR and NF NF = global_param.snow_steps_per_day / global_param.model_steps_per_day; if (NF == 1) { @@ -107,7 +107,7 @@ vic_cesm_start(vic_clock *vclock, * using free() etc. *****************************************************************************/ char * -trim(char *str) +trimstr(char *str) { char *end; diff --git a/vic/drivers/cesm/src/vic_cesm_time.c b/vic/drivers/cesm/src/vic_cesm_time.c index 2377f90a5..bc99d5551 100644 --- a/vic/drivers/cesm/src/vic_cesm_time.c +++ b/vic/drivers/cesm/src/vic_cesm_time.c @@ -66,7 +66,7 @@ initialize_cesm_time(void) * @brief Advance one timestep *****************************************************************************/ void -advance_time(void) +advance_vic_time(void) { extern size_t current; extern dmy_struct dmy_current; From adc4c59849abdadfb692cfb3b7b3c9e51b86a07a Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 7 Mar 2017 16:19:33 -0800 Subject: [PATCH 112/294] Feature/fix latent heat and longwave coupler fields (#695) * fix sign for latent heat * fix sign for longwave up * change log entry for cesm_put_data changes * update to correct PR # --- docs/Development/ReleaseNotes.md | 10 ++++++++-- vic/drivers/cesm/src/cesm_put_data.c | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index a837b94a3..80353f2e5 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -25,7 +25,9 @@ To check which release of VIC you are running: Drainage from upper layer to adjacent lower layer is calculated according to Brook & Corey curve (where drainage rate is a function of upper-layer soil moisture). In previous versions, a simple numerical solution is applied which uses the timestep-beginning upper-layer soil moisture to calculate drainage rate, and assume this constant rate over the entire timestep. This can cause unreasonably large drainage if the curve has a steep shape and when soil moisture is high. Now, the current version uses exact integral (instead of numerical solution) for layer drainage calculation. -2. Fixes for the CESM driver ([GH#642](https://github.com/UW-Hydro/VIC/pull/642)) +2. Fixes for the CESM driver + + [GH#642](https://github.com/UW-Hydro/VIC/pull/642) 1. Using correct fill value datatypes in MPI Gather steps 2. Updated state file name time step to be period-ending rather than period-beginning @@ -36,10 +38,14 @@ To check which release of VIC you are running: 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` + [GH#695](https://github.com/UW-Hydro/VIC/pull/695) + + 1. Fix sign for latent heat fluxes passed from VIC to the coupler + 2. Fix sign for longwave radiation passed from VIC to the coupler + [GH#696](https://github.com/UW-Hydro/VIC/pull/696) 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. ------------------------------- ## VIC 5.0.1 diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index e07eaf137..587b1b29d 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -249,7 +249,7 @@ vic_cesm_put_data() // latent heat flux // CESM units: W m-2 - l2x_vic[i].l2x_Fall_lat += -1 * AreaFactor * energy.AtmosLatent; + l2x_vic[i].l2x_Fall_lat += AreaFactor * energy.AtmosLatent; // sensible heat flux // CESM units: W m-2 @@ -258,7 +258,7 @@ vic_cesm_put_data() // upward longwave heat flux // CESM units: W m-2 - l2x_vic[i].l2x_Fall_lwup += AreaFactor * + l2x_vic[i].l2x_Fall_lwup += -1 * AreaFactor * (force[i].longwave[NR] - energy.NetLongAtmos); From 1c98fcc4df2320f2d5e6c96fe1361f407322c255 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 9 Mar 2017 15:57:44 -0800 Subject: [PATCH 113/294] Feature/fix aerodynamic resistance and roughness (#697) * update veg hist structure to agree with image and classic drivers * read in FULL_ENERGY option from global parameter file, was previously defaulting to false since it wasn't being read in * add printing of global parameter file options to CESM driver after model initialization, as implemented in image mode * remove global param struct and option struct from within vic_cesm_init fctn * add warning when FULL_ENERGY is set to false --- vic/drivers/cesm/src/cesm_interface_c.c | 6 ++++++ vic/drivers/cesm/src/get_global_param.c | 8 ++++++++ vic/drivers/cesm/src/vic_force.c | 11 ++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 978b431dd..da7445654 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -102,6 +102,12 @@ vic_cesm_init(vic_clock *vclock, // initialize output structures vic_init_output(&dmy_current); + // initialization is complete, print settings + log_info( + "Initialization is complete, print global param and options structures"); + print_global_param(&global_param); + print_option(&options); + // stop init timer timer_stop(&(global_timers[TIMER_VIC_INIT])); // stop vic all timer diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 67138a9e9..26e01ea07 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -72,6 +72,14 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", flgstr); global_param.time_units = str_to_timeunits(flgstr); } + else if (strcasecmp("FULL_ENERGY", optstr) == 0) { + sscanf(cmdstr, "%*s %s", flgstr); + options.FULL_ENERGY = str_to_bool(flgstr); + if (options.FULL_ENERGY == false) { + log_warn("FULL_ENERGY is set to FALSE. Please double check " + "that this is the setting you intended."); + } + } else if (strcasecmp("FROZEN_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); options.FROZEN_SOIL = str_to_bool(flgstr); diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index 616e809ee..3d8e2e19e 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -45,6 +45,7 @@ vic_force(void) extern option_struct options; extern soil_con_struct *soil_con; extern veg_con_map_struct *veg_con_map; + extern veg_con_struct **veg_con; extern veg_hist_struct **veg_hist; extern veg_lib_struct **veg_lib; extern parameters_struct param; @@ -261,15 +262,15 @@ vic_force(void) if (vidx != NODATA_VEG) { for (j = 0; j < NF; j++) { veg_hist[i][vidx].albedo[j] = - veg_lib[i][v].albedo[dmy_current.month - 1]; + veg_con[i][vidx].albedo[dmy_current.month - 1]; veg_hist[i][vidx].displacement[j] = - veg_lib[i][v].displacement[dmy_current.month - 1]; + veg_con[i][vidx].displacement[dmy_current.month - 1]; veg_hist[i][vidx].fcanopy[j] = - veg_lib[i][v].fcanopy[dmy_current.month - 1]; + veg_con[i][vidx].fcanopy[dmy_current.month - 1]; veg_hist[i][vidx].LAI[j] = - veg_lib[i][v].LAI[dmy_current.month - 1]; + veg_con[i][vidx].LAI[dmy_current.month - 1]; veg_hist[i][vidx].roughness[j] = - veg_lib[i][v].roughness[dmy_current.month - 1]; + veg_con[i][vidx].roughness[dmy_current.month - 1]; } // not the correct way to calculate average albedo, but leave // for now From 6daa871af1bcdb3c3c5b7e096e69c92439bc1dfc Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 9 Mar 2017 15:58:31 -0800 Subject: [PATCH 114/294] feature/fix_vapor_pressure_deficit_check (#699) * implement vapor pressure deficit check in CESM driver as is implemented in image mode * added log warn to vapor pressure deficit check --- vic/drivers/cesm/src/vic_force.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index 3d8e2e19e..7b32f2a63 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -206,6 +206,14 @@ vic_force(void) for (j = 0; j < NF; j++) { // vapor pressure deficit force[i].vpd[j] = svp(force[i].air_temp[j]) - force[i].vp[j]; + if (force[i].vpd[j] < 0) { + log_warn("Vapor pressure deficit is %f which is < 0, " + "setting vapor pressure deficit to 0 and calculating " + "saturated vapor pressure using air temperature %f.", + force[i].vpd[j], force[i].air_temp[j]); + force[i].vpd[j] = 0; + force[i].vp[j] = svp(force[i].air_temp[j]); + } // photosynthetically active radiation // TODO: Add CARBON_SW2PAR back to the parameters structure // force[i].par[j] = param.CARBON_SW2PAR * force[i].shortwave[j]; From d00c3b276db8ce8c17c02a6de00f8e2061c4e752 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 15 Mar 2017 16:56:58 -0700 Subject: [PATCH 115/294] fix julian day in dmy struct --- vic/drivers/cesm/src/vic_cesm_time.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vic/drivers/cesm/src/vic_cesm_time.c b/vic/drivers/cesm/src/vic_cesm_time.c index bc99d5551..72c4ba384 100644 --- a/vic/drivers/cesm/src/vic_cesm_time.c +++ b/vic/drivers/cesm/src/vic_cesm_time.c @@ -60,6 +60,10 @@ initialize_cesm_time(void) // initialize numdate numdate = date2num(global_param.time_origin_num, &dmy_current, 0., global_param.calendar, global_param.time_units); + + num2date(global_param.time_origin_num, numdate, 0., global_param.calendar, + global_param.time_units, &dmy_current); + } /****************************************************************************** From 646c89525081f9008b5f854962c219b11fef97b8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 15 Mar 2017 20:20:11 -0700 Subject: [PATCH 116/294] add change log entry --- docs/Development/ReleaseNotes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 80353f2e5..6165e05dd 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -47,6 +47,9 @@ To check which release of VIC you are running: 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. + [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) + + 1. Fixes Julian day in the CESM driver in the dmy struct. ## VIC 5.0.1 **Release date: (February 1, 2017)** From 36158aa89f397e5ab46711a31a3227f024480f5b Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 15 Mar 2017 20:35:38 -0700 Subject: [PATCH 117/294] update change log entry --- docs/Development/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 6165e05dd..3e6452b54 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -49,7 +49,7 @@ To check which release of VIC you are running: [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) - 1. Fixes Julian day in the CESM driver in the dmy struct. + 1. Fixes Julian day for the first timestep in the dmy struct for the CESM driver. ## VIC 5.0.1 **Release date: (February 1, 2017)** From 4a4444ccf2ee180ac9e9a4f3ef36341492d1fa53 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 3 Apr 2017 11:15:37 -0700 Subject: [PATCH 118/294] add section for run profiling for Gordon (#708) --- tests/run_profiling.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/run_profiling.py b/tests/run_profiling.py index 10237a1e5..7593bf999 100755 --- a/tests/run_profiling.py +++ b/tests/run_profiling.py @@ -141,6 +141,35 @@ def log2_range(m): mpiexec_mpt -np ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global END=$(date +%s) DIFF=$(echo "$END - $START" | bc) +printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file'''), + 'gordon': host_config(profile=[dict(select=1, mpiprocs=32), + dict(select=2, mpiprocs=32), + dict(select=3, mpiprocs=32), + dict(select=4, mpiprocs=32), + dict(select=5, mpiprocs=32), + dict(select=6, mpiprocs=32), + dict(select=8, mpiprocs=32), + dict(select=10, mpiprocs=32), + dict(select=12, mpiprocs=32)], + submit='qsub', mpiexec='aprun', + template='''#!/bin/bash +#PBS -N VIC$i +#PBS -q frontier +#PBS -A NPSCA07935YF5 +#PBS -l application=VIC +#PBS -l select=$select:ncpus=32:mpiprocs=$mpiprocs +#PBS -l walltime=35:00:00 +#PBS -j oe + +# Qsub template for DSRC GORDON +# Scheduler: PBS + +module load cray-netcdf/4.3.2 + +START=$(date +%s) +aprun -n ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global +END=$(date +%s) +DIFF=$(echo "$END - $START" | bc) printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} OUT_WIDTH = 100 From 0c620942a50688dd78fca0c059f65e172fa0a094 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Mon, 3 Apr 2017 12:38:06 -0700 Subject: [PATCH 119/294] run uncrustify (#704) --- vic/drivers/cesm/src/cesm_interface_c.c | 2 +- vic/drivers/cesm/src/cesm_put_data.c | 8 +- .../cesm/src/display_current_settings.c | 3 +- vic/drivers/cesm/src/get_global_param.c | 22 +++--- vic/drivers/cesm/src/vic_cesm_start.c | 4 +- vic/drivers/cesm/src/vic_cesm_time.c | 1 - vic/drivers/cesm/src/vic_force.c | 16 ++-- vic/drivers/image/src/check_save_state_flag.c | 3 +- .../image/src/display_current_settings.c | 3 +- vic/drivers/image/src/get_global_param.c | 2 +- vic/drivers/image/src/vic_force.c | 10 ++- vic/drivers/image/src/vic_image_start.c | 6 +- vic/drivers/shared_all/src/make_dmy.c | 2 +- .../shared_all/src/set_output_defaults.c | 10 +-- vic/drivers/shared_all/src/vic_time.c | 4 +- .../include/vic_driver_shared_image.h | 2 +- .../shared_image/include/vic_image_log.h | 2 +- vic/drivers/shared_image/include/vic_mpi.h | 2 +- .../shared_image/src/get_global_domain.c | 9 ++- vic/drivers/shared_image/src/get_nc_field.c | 24 +++--- .../shared_image/src/get_nc_var_attr.c | 6 +- .../shared_image/src/get_nc_var_type.c | 9 ++- .../shared_image/src/get_nc_varndimensions.c | 2 +- .../shared_image/src/parse_output_info.c | 40 +++++----- .../shared_image/src/vic_image_timing.c | 3 +- vic/drivers/shared_image/src/vic_init.c | 3 +- .../shared_image/src/vic_mpi_support.c | 24 +++--- vic/drivers/shared_image/src/vic_restore.c | 47 +++++++---- vic/drivers/shared_image/src/vic_start.c | 3 +- vic/drivers/shared_image/src/vic_store.c | 78 ++++++++++++------- vic/vic_run/include/vic_log.h | 10 +-- vic/vic_run/src/func_canopy_energy_bal.c | 4 +- vic/vic_run/src/runoff.c | 13 ++-- vic/vic_run/src/snow_intercept.c | 2 +- 34 files changed, 216 insertions(+), 163 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index da7445654..1f8382eb6 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -104,7 +104,7 @@ vic_cesm_init(vic_clock *vclock, // initialization is complete, print settings log_info( - "Initialization is complete, print global param and options structures"); + "Initialization is complete, print global param and options structures"); print_global_param(&global_param); print_option(&options); diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 587b1b29d..da5f1d45f 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -140,12 +140,14 @@ vic_cesm_put_data() // 2m reference temperature // CESM units: K - l2x_vic[i].l2x_Sl_tref += AreaFactor * (force[i].air_temp[NR] + CONST_TKFRZ); + l2x_vic[i].l2x_Sl_tref += AreaFactor * + (force[i].air_temp[NR] + CONST_TKFRZ); // 2m reference specific humidity // CESM units: g/g l2x_vic[i].l2x_Sl_qref += AreaFactor * CONST_EPS * - force[i].vp[NR] / force[i].pressure[NR]; + force[i].vp[NR] / + force[i].pressure[NR]; // Albedo Note: VIC does not partition its albedo, all returned // values will be the same @@ -258,7 +260,7 @@ vic_cesm_put_data() // upward longwave heat flux // CESM units: W m-2 - l2x_vic[i].l2x_Fall_lwup += -1 * AreaFactor * + l2x_vic[i].l2x_Fall_lwup += -1 * AreaFactor * (force[i].longwave[NR] - energy.NetLongAtmos); diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 123e954e3..029575613 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -361,7 +361,8 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input State File:\n"); if (options.INIT_STATE) { - fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_filename); + fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", + filenames.init_state.nc_filename); if (options.STATE_FORMAT == NETCDF3_CLASSIC) { fprintf(LOG_DEST, "STATE_FORMAT\t\tNETCDF3_CLASSIC\n"); } diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 26e01ea07..89ab7c3c4 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -72,14 +72,14 @@ get_global_param(FILE *gp) sscanf(cmdstr, "%*s %s", flgstr); global_param.time_units = str_to_timeunits(flgstr); } - else if (strcasecmp("FULL_ENERGY", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - options.FULL_ENERGY = str_to_bool(flgstr); - if (options.FULL_ENERGY == false) { - log_warn("FULL_ENERGY is set to FALSE. Please double check " - "that this is the setting you intended."); - } - } + else if (strcasecmp("FULL_ENERGY", optstr) == 0) { + sscanf(cmdstr, "%*s %s", flgstr); + options.FULL_ENERGY = str_to_bool(flgstr); + if (options.FULL_ENERGY == false) { + log_warn("FULL_ENERGY is set to FALSE. Please double check " + "that this is the setting you intended."); + } + } else if (strcasecmp("FROZEN_SOIL", optstr) == 0) { sscanf(cmdstr, "%*s %s", flgstr); options.FROZEN_SOIL = str_to_bool(flgstr); @@ -394,8 +394,8 @@ get_global_param(FILE *gp) } } else if (strcasecmp("SNOW_BAND", optstr) == 0) { - sscanf(cmdstr, "%*s %s", flgstr); - if (str_to_bool(flgstr)) { + sscanf(cmdstr, "%*s %s", flgstr); + if (str_to_bool(flgstr)) { options.SNOW_BAND = SNOW_BAND_TRUE_BUT_UNSET; } } @@ -430,7 +430,7 @@ get_global_param(FILE *gp) ; // do nothing } else if (strcasecmp("AGGFREQ", optstr) == 0) { - ; // do nothing + ; // do nothing } else if (strcasecmp("OUTPUT_STEPS_PER_DAY", optstr) == 0) { ; // do nothing diff --git a/vic/drivers/cesm/src/vic_cesm_start.c b/vic/drivers/cesm/src/vic_cesm_start.c index 635643cbc..e79ccb173 100644 --- a/vic/drivers/cesm/src/vic_cesm_start.c +++ b/vic/drivers/cesm/src/vic_cesm_start.c @@ -47,8 +47,8 @@ vic_cesm_start(vic_clock *vclock, if (mpi_rank == VIC_MPI_ROOT) { strcpy(filenames.global, GLOBALPARAM); - // assign case name to state file name - strncpy(filenames.statefile, trimstr(cmeta->caseid), + // assign case name to state file name + strncpy(filenames.statefile, trimstr(cmeta->caseid), sizeof(filenames.statefile)); // read global settings diff --git a/vic/drivers/cesm/src/vic_cesm_time.c b/vic/drivers/cesm/src/vic_cesm_time.c index 72c4ba384..ec46bd8c4 100644 --- a/vic/drivers/cesm/src/vic_cesm_time.c +++ b/vic/drivers/cesm/src/vic_cesm_time.c @@ -63,7 +63,6 @@ initialize_cesm_time(void) num2date(global_param.time_origin_num, numdate, 0., global_param.calendar, global_param.time_units, &dmy_current); - } /****************************************************************************** diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index 7b32f2a63..b6a8db94e 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -206,14 +206,14 @@ vic_force(void) for (j = 0; j < NF; j++) { // vapor pressure deficit force[i].vpd[j] = svp(force[i].air_temp[j]) - force[i].vp[j]; - if (force[i].vpd[j] < 0) { - log_warn("Vapor pressure deficit is %f which is < 0, " - "setting vapor pressure deficit to 0 and calculating " - "saturated vapor pressure using air temperature %f.", - force[i].vpd[j], force[i].air_temp[j]); - force[i].vpd[j] = 0; - force[i].vp[j] = svp(force[i].air_temp[j]); - } + if (force[i].vpd[j] < 0) { + log_warn("Vapor pressure deficit is %f which is < 0, " + "setting vapor pressure deficit to 0 and calculating " + "saturated vapor pressure using air temperature %f.", + force[i].vpd[j], force[i].air_temp[j]); + force[i].vpd[j] = 0; + force[i].vp[j] = svp(force[i].air_temp[j]); + } // photosynthetically active radiation // TODO: Add CARBON_SW2PAR back to the parameters structure // force[i].par[j] = param.CARBON_SW2PAR * force[i].shortwave[j]; diff --git a/vic/drivers/image/src/check_save_state_flag.c b/vic/drivers/image/src/check_save_state_flag.c index d71099719..3b046df35 100644 --- a/vic/drivers/image/src/check_save_state_flag.c +++ b/vic/drivers/image/src/check_save_state_flag.c @@ -32,7 +32,8 @@ * current time step *****************************************************************************/ bool -check_save_state_flag(size_t current, dmy_struct *dmy_offset) +check_save_state_flag(size_t current, + dmy_struct *dmy_offset) { extern global_param_struct global_param; extern dmy_struct *dmy; diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index d3994dceb..81173eebd 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -378,7 +378,8 @@ display_current_settings(int mode) fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Input State File:\n"); if (options.INIT_STATE) { - fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", filenames.init_state.nc_filename); + fprintf(LOG_DEST, "INIT_STATE\t\tTRUE\t%s\n", + filenames.init_state.nc_filename); if (options.STATE_FORMAT == NETCDF3_CLASSIC) { fprintf(LOG_DEST, "STATE_FORMAT\t\tNETCDF3_CLASSIC\n"); } diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 538ae1b55..2b5ed9390 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -800,7 +800,7 @@ get_global_param(FILE *gp) sprintf(filenames.forcing[1].nc_filename, "%s%4d.nc", filenames.f_path_pfx[1], global_param.startyear); status = nc_open(filenames.forcing[1].nc_filename, NC_NOWRITE, - &(filenames.forcing[1].nc_id)); + &(filenames.forcing[1].nc_id)); check_nc_status(status, "Error opening %s", filenames.forcing[1].nc_filename); get_forcing_file_info(¶m_set, 1); diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index be0c80017..104be14ab 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -282,7 +282,6 @@ vic_force(void) if (options.LAI_SRC == FROM_VEGHIST || options.FCAN_SRC == FROM_VEGHIST || options.ALB_SRC == FROM_VEGHIST) { - // global_param.forceoffset[1] resets every year since the met file restarts // every year // global_param.forceskip[1] should also reset to 0 after the first year @@ -527,9 +526,12 @@ get_forcing_file_info(param_set_struct *param_set, dmy_struct nc_start_dmy; // read time info from netcdf file - get_nc_field_double(&(filenames.forcing[file_num]), "time", &start, &count, nc_times); - get_nc_var_attr(&(filenames.forcing[file_num]), "time", "units", &nc_unit_chars); - get_nc_var_attr(&(filenames.forcing[file_num]), "time", "calendar", &calendar_char); + get_nc_field_double(&(filenames.forcing[file_num]), "time", &start, &count, + nc_times); + get_nc_var_attr(&(filenames.forcing[file_num]), "time", "units", + &nc_unit_chars); + get_nc_var_attr(&(filenames.forcing[file_num]), "time", "calendar", + &calendar_char); // parse the calendar string and check to make sure it matches the global clock calendar = str_to_calendar(calendar_char); diff --git a/vic/drivers/image/src/vic_image_start.c b/vic/drivers/image/src/vic_image_start.c index 401df8162..5a2ee4f12 100644 --- a/vic/drivers/image/src/vic_image_start.c +++ b/vic/drivers/image/src/vic_image_start.c @@ -32,9 +32,9 @@ void vic_image_start(void) { - extern filep_struct filep; - extern filenames_struct filenames; - extern int mpi_rank; + extern filep_struct filep; + extern filenames_struct filenames; + extern int mpi_rank; // Initialize structures initialize_global_structures(); diff --git a/vic/drivers/shared_all/src/make_dmy.c b/vic/drivers/shared_all/src/make_dmy.c index 1b48cbdf0..ea113fd79 100644 --- a/vic/drivers/shared_all/src/make_dmy.c +++ b/vic/drivers/shared_all/src/make_dmy.c @@ -97,7 +97,7 @@ make_dmy(global_param_struct *global) global->forceskip[i] = (unsigned int) round((start_num - force_num) * - (double) param_set.force_steps_per_day[i]); + (double) param_set.force_steps_per_day[i]); } } diff --git a/vic/drivers/shared_all/src/set_output_defaults.c b/vic/drivers/shared_all/src/set_output_defaults.c index 0b53d7a13..82c4769af 100644 --- a/vic/drivers/shared_all/src/set_output_defaults.c +++ b/vic/drivers/shared_all/src/set_output_defaults.c @@ -98,12 +98,12 @@ set_output_defaults(stream_struct **streams, dmy_struct *dmy_current, unsigned short default_file_format) { - extern option_struct options; + extern option_struct options; - size_t streamnum; - size_t varnum; - alarm_struct default_alarm; - int default_freq_n = 1; + size_t streamnum; + size_t varnum; + alarm_struct default_alarm; + int default_freq_n = 1; set_alarm(dmy_current, FREQ_NDAYS, &default_freq_n, &default_alarm); diff --git a/vic/drivers/shared_all/src/vic_time.c b/vic/drivers/shared_all/src/vic_time.c index 0e57407ae..144fe742f 100644 --- a/vic/drivers/shared_all/src/vic_time.c +++ b/vic/drivers/shared_all/src/vic_time.c @@ -859,8 +859,8 @@ time_delta(dmy_struct *dmy_current, // if dmy_next.year is not leap year but date is Feb 29 !) make_lastday(global_param.calendar, dmy_next.year, lastday); dmy_next.day_in_year = 0; - for ( i = 0; i < MONTHS_PER_YEAR; i++ ) { - if ( (i+1) == dmy_next.month ) { + for (i = 0; i < MONTHS_PER_YEAR; i++) { + if ((i + 1) == dmy_next.month) { dmy_next.day_in_year += dmy_next.day; break; } diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index fd6f4d66d..dc4766cce 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -171,7 +171,7 @@ typedef struct { typedef struct { nameid_struct forcing[MAX_FORCE_FILES]; /**< atmospheric forcing files */ char f_path_pfx[MAX_FORCE_FILES][MAXSTRING]; /**< path and prefix for - atmospheric forcing files */ + atmospheric forcing files */ char global[MAXSTRING]; /**< global control file name */ nameid_struct domain; /**< domain file name and nc_id*/ char constants[MAXSTRING]; /**< model constants file name */ diff --git a/vic/drivers/shared_image/include/vic_image_log.h b/vic/drivers/shared_image/include/vic_image_log.h index 151f2c191..2b650fbe8 100644 --- a/vic/drivers/shared_image/include/vic_image_log.h +++ b/vic/drivers/shared_image/include/vic_image_log.h @@ -66,7 +66,7 @@ #define check_nc_status(A, M, ...) if (A != NC_NOERR) {log_ncerr(A, M, \ ## __VA_ARGS__); \ errno = 0; exit( \ - EXIT_FAILURE); } + EXIT_FAILURE);} #define log_mpi_err(e, M, ...) print_trace(); \ print_mpi_error_str(e); fprintf(LOG_DEST, \ diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index e1f324d4a..b46a1741c 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -37,7 +37,7 @@ *****************************************************************************/ typedef struct { char nc_filename[MAXSTRING]; - int nc_id; + int nc_id; } nameid_struct; void create_MPI_filenames_struct_type(MPI_Datatype *mpi_type); diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 4291b79d8..464bb5523 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -36,7 +36,7 @@ get_global_domain(nameid_struct *domain_nc_nameid, { int *run = NULL; int *mask = NULL; - int typeid; + int typeid; double *var = NULL; size_t i; size_t j; @@ -68,7 +68,8 @@ get_global_domain(nameid_struct *domain_nc_nameid, if (typeid != NC_INT) { log_err("Mask variable in the domain file must be integer type."); } - get_nc_field_int(domain_nc_nameid, global_domain->info.mask_var, d2start, d2count, + get_nc_field_int(domain_nc_nameid, global_domain->info.mask_var, d2start, + d2count, mask); // Get run_cell variable from the parameter file @@ -152,7 +153,6 @@ get_global_domain(nameid_struct *domain_nc_nameid, return global_domain->ncells_active; } - /****************************************************************************** * @brief Get lat and lon coordinates information from a netCDF file and store in nc_domain structure @@ -273,7 +273,8 @@ get_nc_latlon(nameid_struct *nc_nameid, * @brief Copy domain info from one domain structure to another *****************************************************************************/ void -copy_domain_info(domain_struct *domain_from, domain_struct *domain_to) +copy_domain_info(domain_struct *domain_from, + domain_struct *domain_to) { strcpy(domain_to->info.x_dim, domain_from->info.x_dim); strcpy(domain_to->info.y_dim, domain_from->info.y_dim); diff --git a/vic/drivers/shared_image/src/get_nc_field.c b/vic/drivers/shared_image/src/get_nc_field.c index 5b79f218e..cf3404122 100644 --- a/vic/drivers/shared_image/src/get_nc_field.c +++ b/vic/drivers/shared_image/src/get_nc_field.c @@ -31,10 +31,10 @@ *****************************************************************************/ int get_nc_field_double(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - double *var) + char *var_name, + size_t *start, + size_t *count, + double *var) { int status; int var_id; @@ -56,10 +56,10 @@ get_nc_field_double(nameid_struct *nc_nameid, *****************************************************************************/ int get_nc_field_float(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - float *var) + char *var_name, + size_t *start, + size_t *count, + float *var) { int status; int var_id; @@ -81,10 +81,10 @@ get_nc_field_float(nameid_struct *nc_nameid, *****************************************************************************/ int get_nc_field_int(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - int *var) + char *var_name, + size_t *start, + size_t *count, + int *var) { int status; int var_id; diff --git a/vic/drivers/shared_image/src/get_nc_var_attr.c b/vic/drivers/shared_image/src/get_nc_var_attr.c index c16d24b50..4e1c07839 100644 --- a/vic/drivers/shared_image/src/get_nc_var_attr.c +++ b/vic/drivers/shared_image/src/get_nc_var_attr.c @@ -31,9 +31,9 @@ *****************************************************************************/ void get_nc_var_attr(nameid_struct *nc_nameid, - char *var_name, - char *attr_name, - char **attr) + char *var_name, + char *attr_name, + char **attr) { int var_id; int status; diff --git a/vic/drivers/shared_image/src/get_nc_var_type.c b/vic/drivers/shared_image/src/get_nc_var_type.c index 67dc4d5ad..d75586a2f 100644 --- a/vic/drivers/shared_image/src/get_nc_var_type.c +++ b/vic/drivers/shared_image/src/get_nc_var_type.c @@ -33,9 +33,9 @@ int get_nc_var_type(nameid_struct *nc_nameid, char *var_name) { - int var_id; - int status; - int xtypep; + int var_id; + int status; + int xtypep; // get variable id status = nc_inq_varid(nc_nameid->nc_id, var_name, &var_id); @@ -43,7 +43,8 @@ get_nc_var_type(nameid_struct *nc_nameid, nc_nameid->nc_filename); // get type ID - status = nc_inq_var(nc_nameid->nc_id, var_id, NULL, &xtypep, NULL, NULL, NULL); + status = nc_inq_var(nc_nameid->nc_id, var_id, NULL, &xtypep, NULL, NULL, + NULL); check_nc_status(status, "Error getting variable type %s in %s", var_name, nc_nameid->nc_filename); diff --git a/vic/drivers/shared_image/src/get_nc_varndimensions.c b/vic/drivers/shared_image/src/get_nc_varndimensions.c index de2eb5959..1f70b1adc 100644 --- a/vic/drivers/shared_image/src/get_nc_varndimensions.c +++ b/vic/drivers/shared_image/src/get_nc_varndimensions.c @@ -31,7 +31,7 @@ *****************************************************************************/ int get_nc_varndimensions(nameid_struct *nc_nameid, - char *var_name) + char *var_name) { int var_id; int ndims; diff --git a/vic/drivers/shared_image/src/parse_output_info.c b/vic/drivers/shared_image/src/parse_output_info.c index a9f0749a0..8977eb605 100644 --- a/vic/drivers/shared_image/src/parse_output_info.c +++ b/vic/drivers/shared_image/src/parse_output_info.c @@ -35,27 +35,27 @@ parse_output_info(FILE *gp, stream_struct **streams, dmy_struct *dmy_current) { - extern option_struct options; + extern option_struct options; - char cmdstr[MAXSTRING]; - char optstr[MAXSTRING]; - char flgstr[MAXSTRING]; - short int streamnum; - char varname[MAXSTRING]; - int outvarnum; - char freq_type_str[MAXSTRING]; - char freq_value_str[MAXSTRING]; - char format[MAXSTRING]; - char typestr[MAXSTRING]; - int type; - char multstr[MAXSTRING]; - char aggstr[MAXSTRING]; - double mult; - unsigned short int freq; - int freq_n; - dmy_struct freq_dmy; - unsigned short int agg_type; - int found; + char cmdstr[MAXSTRING]; + char optstr[MAXSTRING]; + char flgstr[MAXSTRING]; + short int streamnum; + char varname[MAXSTRING]; + int outvarnum; + char freq_type_str[MAXSTRING]; + char freq_value_str[MAXSTRING]; + char format[MAXSTRING]; + char typestr[MAXSTRING]; + int type; + char multstr[MAXSTRING]; + char aggstr[MAXSTRING]; + double mult; + unsigned short int freq; + int freq_n; + dmy_struct freq_dmy; + unsigned short int agg_type; + int found; streamnum = -1; diff --git a/vic/drivers/shared_image/src/vic_image_timing.c b/vic/drivers/shared_image/src/vic_image_timing.c index 39cf8ff11..ebc0ae5d9 100644 --- a/vic/drivers/shared_image/src/vic_image_timing.c +++ b/vic/drivers/shared_image/src/vic_image_timing.c @@ -89,7 +89,8 @@ write_vic_timing_table(timer_struct *timers, fprintf(LOG_DEST, " VIC_DRIVER : %s\n", driver); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, " Global Param File : %s\n", filenames.global); - fprintf(LOG_DEST, " Domain File : %s\n", filenames.domain.nc_filename); + fprintf(LOG_DEST, " Domain File : %s\n", + filenames.domain.nc_filename); fprintf(LOG_DEST, " Start Date : %04hu-%02hu-%02hu-%05u\n", global_param.startyear, global_param.startmonth, global_param.startday, global_param.startsec); diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 44fef6f5a..fdfcc0a83 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -673,7 +673,8 @@ vic_init(void) // spatial snow if (options.SPATIAL_SNOW) { // max_snow_distrib_slope - get_scatter_nc_field_double(&(filenames.params), "max_snow_distrib_slope", + get_scatter_nc_field_double(&(filenames.params), + "max_snow_distrib_slope", d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { soil_con[i].max_snow_distrib_slope = (double) dvar[i]; diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 294131758..1cd8141f6 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -2043,10 +2043,10 @@ gather_put_nc_field_schar(int nc_id, *****************************************************************************/ void get_scatter_nc_field_double(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - double *var) + char *var_name, + size_t *start, + size_t *count, + double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -2104,10 +2104,10 @@ get_scatter_nc_field_double(nameid_struct *nc_nameid, *****************************************************************************/ void get_scatter_nc_field_float(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - float *var) + char *var_name, + size_t *start, + size_t *count, + float *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -2167,10 +2167,10 @@ get_scatter_nc_field_float(nameid_struct *nc_nameid, *****************************************************************************/ void get_scatter_nc_field_int(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - int *var) + char *var_name, + size_t *start, + size_t *count, + int *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 46abea478..bf1b656ad 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -917,12 +917,14 @@ check_init_state_file(void) // read and validate dimension lengths if (mpi_rank == VIC_MPI_ROOT) { - dimlen = get_nc_dimension(&(filenames.init_state), global_domain.info.x_dim); + dimlen = get_nc_dimension(&(filenames.init_state), + global_domain.info.x_dim); if (dimlen != global_domain.n_nx) { log_err("Number of grid columns in state file does not " "match parameter file"); } - dimlen = get_nc_dimension(&(filenames.init_state), global_domain.info.y_dim); + dimlen = get_nc_dimension(&(filenames.init_state), + global_domain.info.y_dim); if (dimlen != global_domain.n_ny) { log_err("Number of grid rows in state file does not " "match parameter file"); @@ -965,47 +967,55 @@ check_init_state_file(void) // lat/lon if (mpi_rank == VIC_MPI_ROOT) { - status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lon_var, &lon_var_id); + status = nc_inq_varid(filenames.init_state.nc_id, + global_domain.info.lon_var, &lon_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_filename); - status = nc_inq_varid(filenames.init_state.nc_id, global_domain.info.lat_var, &lat_var_id); + global_domain.info.lon_var, + filenames.init_state.nc_filename); + status = nc_inq_varid(filenames.init_state.nc_id, + global_domain.info.lat_var, &lat_var_id); check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_filename); + global_domain.info.lat_var, + filenames.init_state.nc_filename); if (global_domain.info.n_coord_dims == 1) { d1start[0] = 0; dvar = calloc(global_domain.n_nx, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); - + d1count[0] = global_domain.n_nx; status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_filename); + global_domain.info.lon_var, + filenames.init_state.nc_filename); // implicitly nested loop over ni and nj with j set to 0 for (i = 0; i < global_domain.n_nx; i++) { if (!assert_close_double(dvar[i], - global_domain.locations[i].longitude, rtol, + global_domain.locations[i].longitude, + rtol, abs_tol)) { log_err("Longitudes in initial state file do not " "match parameter file"); } } free(dvar); - + dvar = calloc(global_domain.n_ny, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); - + d1count[0] = global_domain.n_ny; status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d1start, d1count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_filename); + global_domain.info.lat_var, + filenames.init_state.nc_filename); // implicitly nested loop over ni and nj with i set to 0; // j stride = n_nx for (j = 0; j < global_domain.n_ny; j++) { if (!assert_close_double(dvar[j], global_domain.locations[j * - global_domain.n_nx] + global_domain. + n_nx] .latitude, rtol, abs_tol)) { log_err("Latitudes in initial state file do not " @@ -1017,15 +1027,17 @@ check_init_state_file(void) else if (global_domain.info.n_coord_dims == 2) { d2start[0] = 0; d2start[1] = 0; - dvar = calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); + dvar = + calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); check_alloc_status(dvar, "Memory allocation error"); - + d2count[0] = global_domain.n_ny; d2count[1] = global_domain.n_nx; status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, filenames.init_state.nc_filename); + global_domain.info.lon_var, + filenames.init_state.nc_filename); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].longitude) { log_err("Longitudes in initial state file do not " @@ -1035,7 +1047,8 @@ check_init_state_file(void) status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, d2start, d2count, dvar); check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, filenames.init_state.nc_filename); + global_domain.info.lat_var, + filenames.init_state.nc_filename); for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { if (dvar[i] != (double) global_domain.locations[i].latitude) { log_err("Latitudes in initial state file do not " diff --git a/vic/drivers/shared_image/src/vic_start.c b/vic/drivers/shared_image/src/vic_start.c index 8c36b216f..32cbc2c57 100644 --- a/vic/drivers/shared_image/src/vic_start.c +++ b/vic/drivers/shared_image/src/vic_start.c @@ -118,7 +118,8 @@ vic_start(void) options.Nlayer = get_nc_dimension(&(filenames.params), "nlayer"); options.NVEGTYPES = get_nc_dimension(&(filenames.params), "veg_class"); if (options.SNOW_BAND == SNOW_BAND_TRUE_BUT_UNSET) { - options.SNOW_BAND = get_nc_dimension(&(filenames.params), "snow_band"); + options.SNOW_BAND = get_nc_dimension(&(filenames.params), + "snow_band"); } if (options.LAKES) { options.NLAKENODES = get_nc_dimension(&(filenames.params), diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 2fe4cf0d2..6389468de 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1571,16 +1571,19 @@ initialize_state_file(char *filename, check_nc_status(status, "Error setting fill value in %s", filename); // define the time dimension - status = nc_def_dim(nc_state_file->nc_id, "time", nc_state_file->time_size, + status = nc_def_dim(nc_state_file->nc_id, "time", + nc_state_file->time_size, &(nc_state_file->time_dimid)); - check_nc_status(status, "Error defining time dimenension in %s", filename); + check_nc_status(status, "Error defining time dimenension in %s", + filename); // define the variable time status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, &(nc_state_file->time_dimid), &(nc_state_file->time_varid)); check_nc_status(status, "Error defining time variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, "standard_name", strlen("time"), "time"); check_nc_status(status, "Error adding attribute in %s", filename); @@ -1589,16 +1592,19 @@ initialize_state_file(char *filename, sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, "units", strlen(str), str); check_nc_status(status, "Error adding attribute in %s", filename); // adding calendar attribute to time variable str_from_calendar(global_param.calendar, str); - status = nc_put_att_text(nc_state_file->nc_id, nc_state_file->time_varid, + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, "calendar", strlen(str), str); - check_nc_status(status, "Error adding calendar attribute in %s", filename); + check_nc_status(status, "Error adding calendar attribute in %s", + filename); // define netcdf dimensions status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, @@ -1614,7 +1620,8 @@ initialize_state_file(char *filename, filename); status = nc_def_dim(nc_state_file->nc_id, "veg_class", - nc_state_file->veg_size, &(nc_state_file->veg_dimid)); + nc_state_file->veg_size, + &(nc_state_file->veg_dimid)); check_nc_status(status, "Error defining veg_class in %s", filename); status = nc_def_dim(nc_state_file->nc_id, "snow_band", @@ -1729,7 +1736,8 @@ initialize_state_file(char *filename, strlen("veg_class"), "veg_class"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, - "standard_name", strlen("vegetation_class_number"), + "standard_name", + strlen("vegetation_class_number"), "vegetation_class_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; @@ -1756,8 +1764,10 @@ initialize_state_file(char *filename, status = nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, &(layer_var_id)); - check_nc_status(status, "Error defining layer variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, "long_name", + check_nc_status(status, "Error defining layer variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, + "long_name", strlen("layer"), "layer"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, @@ -1789,7 +1799,8 @@ initialize_state_file(char *filename, status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 3, dimids, &(dz_node_var_id)); check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "long_name", + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "long_name", strlen("dz_node"), "dz_node"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, @@ -1816,10 +1827,12 @@ initialize_state_file(char *filename, strlen("node_depth"), "node_depth"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "standard_name", strlen("soil_thermal_node_depth"), + "standard_name", + strlen("soil_thermal_node_depth"), "soil_thermal_node_depth"); check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, "units", + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "units", strlen("m"), "m"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; @@ -1831,13 +1844,15 @@ initialize_state_file(char *filename, dimids[0] = nc_state_file->lake_node_dimid; status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, dimids, &(lake_node_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); + check_nc_status(status, "Error defining node variable in %s", + filename); status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, "long_name", strlen("lake_node"), "lake_node"); check_nc_status(status, "Error adding attribute in %s", filename); status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "standard_name", strlen("lake_node_number"), + "standard_name", strlen( + "lake_node_number"), "lake_node_number"); check_nc_status(status, "Error adding attribute in %s", filename); dimids[0] = -1; @@ -1883,13 +1898,17 @@ initialize_state_file(char *filename, state_metadata[i].varname, filename); // Set string attributes - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, "long_name", state_metadata[i].long_name); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, "standard_name", state_metadata[i].standard_name); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, "units", state_metadata[i].units); - put_nc_attr(nc_state_file->nc_id, nc_state_file->nc_vars[i].nc_varid, + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, "description", state_metadata[i].description); } @@ -1921,7 +1940,8 @@ initialize_state_file(char *filename, for (i = 0; i < nc_state_file->ni_size; i++) { dvar[i] = (double) global_domain.locations[i].longitude; } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, + dstart, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); free(dvar); @@ -1938,7 +1958,8 @@ initialize_state_file(char *filename, latitude; } - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, + dstart, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); free(dvar); @@ -1952,7 +1973,8 @@ initialize_state_file(char *filename, for (i = 0; i < global_domain.ncells_total; i++) { dvar[i] = (double) global_domain.locations[i].longitude; } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, dstart, + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, + dstart, dcount, dvar); check_nc_status(status, "Error adding data to lon in %s", filename); @@ -1960,7 +1982,8 @@ initialize_state_file(char *filename, i++) { dvar[i] = (double) global_domain.locations[i].latitude; } - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, dstart, + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, + dstart, dcount, dvar); check_nc_status(status, "Error adding data to lat in %s", filename); @@ -1984,7 +2007,8 @@ initialize_state_file(char *filename, for (j = 0; j < nc_state_file->veg_size; j++) { ivar[j] = (int) j + 1; } - status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, dcount, + status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, + dcount, ivar); check_nc_status(status, "Error writing veg var id"); for (i = 0; i < ndims; i++) { @@ -2020,7 +2044,8 @@ initialize_state_file(char *filename, for (j = 0; j < nc_state_file->layer_size; j++) { ivar[j] = (int) j; } - status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, dcount, + status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, + dcount, ivar); check_nc_status(status, "Error writing layer id"); for (i = 0; i < ndims; i++) { @@ -2038,7 +2063,8 @@ initialize_state_file(char *filename, for (j = 0; j < nc_state_file->frost_size; j++) { ivar[j] = (int) j; } - status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, dstart, + status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, + dstart, dcount, ivar); check_nc_status(status, "Error writing frost id"); for (i = 0; i < ndims; i++) { diff --git a/vic/vic_run/include/vic_log.h b/vic/vic_run/include/vic_log.h index 819e17457..cfaf4a174 100644 --- a/vic/vic_run/include/vic_log.h +++ b/vic/vic_run/include/vic_log.h @@ -126,17 +126,17 @@ void setup_logging(int id, char log_path[], FILE **logfile); // here means that it just doesn't print a message, it still does the // check. MKAY? #define check_debug(A, M, ...) if (!(A)) {debug(M, ## __VA_ARGS__); errno = 0; \ - exit(EXIT_FAILURE); } + exit(EXIT_FAILURE);} #define check(A, M, ...) if (!(A)) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ - EXIT_FAILURE); } + EXIT_FAILURE);} #define check_alloc_status(A, M, \ ...) if (A == NULL) {log_err(M, ## __VA_ARGS__); \ errno = 0; exit( \ - EXIT_FAILURE); } + EXIT_FAILURE);} #define sentinel(M, ...) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ - EXIT_FAILURE); } + EXIT_FAILURE);} #define check_mem(A) check((A), "Out of memory.") @@ -144,7 +144,7 @@ void setup_logging(int id, char log_path[], FILE **logfile); E), E, __FUNCTION__, __LINE__) #define error_response(F, C, M, ...) {Response_send_status(F, &HTTP_ ## C); \ - sentinel(M, ## __VA_ARGS__); } + sentinel(M, ## __VA_ARGS__);} #define error_unless(T, F, C, M, ...) if (!(T)) \ error_response(F, C, M, ## __VA_ARGS__) diff --git a/vic/vic_run/src/func_canopy_energy_bal.c b/vic/vic_run/src/func_canopy_energy_bal.c index 5f5a9d066..8aeea60e7 100644 --- a/vic/vic_run/src/func_canopy_energy_bal.c +++ b/vic/vic_run/src/func_canopy_energy_bal.c @@ -217,7 +217,7 @@ func_canopy_energy_bal(double Tfoliage, /* Calculate the latent heat flux */ Ls = calc_latent_heat_of_sublimation(Tfoliage); - *LatentHeatSub = Ls * *VaporMassFlux * CONST_RHOFW; + *LatentHeatSub = Ls **VaporMassFlux * CONST_RHOFW; *LatentHeat = 0; *Evap = 0; veg_var->throughfall = 0; @@ -246,7 +246,7 @@ func_canopy_energy_bal(double Tfoliage, root, dryFrac, shortwave, Catm, CanopLayerBnd); *Wdew /= MM_PER_M; - *LatentHeat = Le * *Evap * CONST_RHOFW; + *LatentHeat = Le **Evap * CONST_RHOFW; *LatentHeatSub = 0; } diff --git a/vic/vic_run/src/runoff.c b/vic/vic_run/src/runoff.c index 0466dc847..a72a988a0 100644 --- a/vic/vic_run/src/runoff.c +++ b/vic/vic_run/src/runoff.c @@ -490,15 +490,18 @@ compute_runoff_and_asat(soil_con_struct *soil_con, * @brief Calculate drainage between two layers ******************************************************************************/ double -calc_Q12(double Ksat, double init_moist, double resid_moist, - double max_moist, double expt) +calc_Q12(double Ksat, + double init_moist, + double resid_moist, + double max_moist, + double expt) { double Q12; Q12 = init_moist - pow(pow(init_moist - resid_moist, 1.0 - expt) - - Ksat / pow(max_moist - resid_moist, expt) * (1.0 - expt), - 1.0 / (1.0 - expt)) - resid_moist; + Ksat / + pow(max_moist - resid_moist, expt) * (1.0 - expt), + 1.0 / (1.0 - expt)) - resid_moist; return Q12; } - diff --git a/vic/vic_run/src/snow_intercept.c b/vic/vic_run/src/snow_intercept.c index ebc13174b..f803dbaab 100644 --- a/vic/vic_run/src/snow_intercept.c +++ b/vic/vic_run/src/snow_intercept.c @@ -518,7 +518,7 @@ snow_intercept(double Dt, /* Energy released by freezing of intercepted water is added to the MeltEnergy */ - *MeltEnergy += (CONST_LATICE * *IntRain * CONST_RHOFW) / (Dt); + *MeltEnergy += (CONST_LATICE **IntRain * CONST_RHOFW) / (Dt); *IntRain = 0.0; } From ca2702df7b2d71177532afa41b466aacb885a279 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Mon, 3 Apr 2017 13:10:33 -0700 Subject: [PATCH 120/294] add timers to vic_force and vic_write (#703) * add timers to vic_force and vic_write * add release notes * run uncrustify * uncrustify timers --- docs/Development/ReleaseNotes.md | 24 ++++++++++++------- vic/drivers/image/src/vic_image.c | 7 ++++++ .../include/vic_driver_shared_all.h | 2 ++ .../shared_image/src/vic_image_timing.c | 12 ++++++++++ vic/drivers/shared_image/src/vic_store.c | 1 - 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 3e6452b54..30ea3f1db 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -25,11 +25,11 @@ To check which release of VIC you are running: Drainage from upper layer to adjacent lower layer is calculated according to Brook & Corey curve (where drainage rate is a function of upper-layer soil moisture). In previous versions, a simple numerical solution is applied which uses the timestep-beginning upper-layer soil moisture to calculate drainage rate, and assume this constant rate over the entire timestep. This can cause unreasonably large drainage if the curve has a steep shape and when soil moisture is high. Now, the current version uses exact integral (instead of numerical solution) for layer drainage calculation. -2. Fixes for the CESM driver +2. Fixes for the CESM driver [GH#642](https://github.com/UW-Hydro/VIC/pull/642) - 1. Using correct fill value datatypes in MPI Gather steps + 1. Using correct fill value datatypes in MPI Gather steps 2. Updated state file name time step to be period-ending rather than period-beginning 3. Set the state file name to the RASM case ID 4. Removed decimal point for missing values for unsigned integers @@ -45,11 +45,20 @@ To check which release of VIC you are running: [GH#696](https://github.com/UW-Hydro/VIC/pull/696) - 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. + 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) - 1. Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + 1. Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + +3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) + + These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. + +4. Added two new timers to measure time in I/O operations ([GH#703](https://github.com/UW-Hydro/VIC/pull/703)) + + These two timers count the CPU and WALL time spent in ``vic_force`` and ``vic_write``. The accumulated time from these timers is printed out at the end of each simulation in the timing table. See also [GH#442](https://github.com/UW-Hydro/VIC/pull/442). + ## VIC 5.0.1 **Release date: (February 1, 2017)** @@ -65,7 +74,7 @@ To check which release of VIC you are running: After the fix, the `forceskip` variable in the global parameter structure (i.e., the number of timesteps to skip in the forcing data for the simulatin period) is rounded correctly (before the fix, rounding error might cause 1-timestep offset in the simulation results). 3. Fixed a problem with image restarts when using multiple processors ([GH#638](https://github.com/UW-Hydro/VIC/pull/638)) - + After the fix, only the master node is assigned the task of validating state file dimensions and coordinate variables. Multiprocessing was also added to the VIC testing framework. 4. Ensured that the mask variable in the input domain file must be integer type; otherwise an error is raised. ([GH#645](https://github.com/UW-Hydro/VIC/pull/645)) @@ -76,8 +85,8 @@ To check which release of VIC you are running: 6. Fixed a bug related to writing two-dimensional lat/lon variables to a state file ([GH#652](https://github.com/UW-Hydro/VIC/pull/652)) - Before the bug fix, two-dimensional lat/lon variables were not populated correctly and were written as fill values to a state file. Now two-dimensional lat/lon variables are correctly populated and written. - + Before the bug fix, two-dimensional lat/lon variables were not populated correctly and were written as fill values to a state file. Now two-dimensional lat/lon variables are correctly populated and written. + 7. Fixed a bug related to `dz_node` and `node_depth` variables in image driver output state file ([GH#657](https://github.com/UW-Hydro/VIC/pull/657)) Before the fix, `dz_node` and `node_depth` in image driver output state file were not spatially distributed, which was wrong. Now these two variables are spatially distributed in the output state file. @@ -94,7 +103,6 @@ To check which release of VIC you are running: Before the fix, there would be an error if the simulation start time is later than the forcing start time that year AND the simulation spans multiple years. Fixed this bug. - ------------------------------ ## VIC 5.0.0 [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.61422.svg)](http://dx.doi.org/10.5281/zenodo.61422) diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 20a4000d7..b7ee1d9a6 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -131,16 +131,23 @@ main(int argc, // start vic run timer timer_start(&(global_timers[TIMER_VIC_RUN])); + timer_init(&(global_timers[TIMER_VIC_FORCE])); + timer_init(&(global_timers[TIMER_VIC_WRITE])); + // loop over all timesteps for (current = 0; current < global_param.nrecs; current++) { // read forcing data + timer_continue(&(global_timers[TIMER_VIC_FORCE])); vic_force(); + timer_stop(&(global_timers[TIMER_VIC_FORCE])); // run vic over the domain vic_image_run(&(dmy[current])); // Write history files + timer_continue(&(global_timers[TIMER_VIC_WRITE])); vic_write_output(&(dmy[current])); + timer_stop(&(global_timers[TIMER_VIC_WRITE])); // Write state file if (check_save_state_flag(current, &dmy_state)) { diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 5d53a9175..893df7a3a 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -451,6 +451,8 @@ enum timers TIMER_VIC_INIT, TIMER_VIC_RUN, TIMER_VIC_FINAL, + TIMER_VIC_FORCE, + TIMER_VIC_WRITE, N_TIMERS }; diff --git a/vic/drivers/shared_image/src/vic_image_timing.c b/vic/drivers/shared_image/src/vic_image_timing.c index ebc0ae5d9..d5f0d41c6 100644 --- a/vic/drivers/shared_image/src/vic_image_timing.c +++ b/vic/drivers/shared_image/src/vic_image_timing.c @@ -147,6 +147,18 @@ write_vic_timing_table(timer_struct *timers, timers[TIMER_VIC_ALL].delta_cpu / ndays); fprintf(LOG_DEST, "|------------|----------------------|----------------------|----------------------|----------------------|\n"); + fprintf(LOG_DEST, "| Force Time | %20g | %20g | %20g | %20g |\n", + timers[TIMER_VIC_FORCE].delta_wall, + timers[TIMER_VIC_FORCE].delta_cpu, + timers[TIMER_VIC_FORCE].delta_wall / ndays, + timers[TIMER_VIC_FORCE].delta_cpu / ndays); + fprintf(LOG_DEST, "| Write Time | %20g | %20g | %20g | %20g |\n", + timers[TIMER_VIC_WRITE].delta_wall, + timers[TIMER_VIC_WRITE].delta_cpu, + timers[TIMER_VIC_WRITE].delta_wall / ndays, + timers[TIMER_VIC_WRITE].delta_cpu / ndays); + fprintf(LOG_DEST, + "|------------|----------------------|----------------------|----------------------|----------------------|\n"); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 6389468de..594108d21 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -39,7 +39,6 @@ vic_store(dmy_struct *dmy_state, extern option_struct options; extern veg_con_map_struct *veg_con_map; extern int mpi_rank; - extern global_param_struct global_param; int status; int v; From 4b9353b5b274e140ccfcdabe1804b54adcb7e66d Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Mon, 3 Apr 2017 15:43:55 -0700 Subject: [PATCH 121/294] Feature/cheyenne scaling headers (#707) * add timers to vic_force and vic_write * initial scaling test setup cheyenne * fixes to cheyenne scaling config --- tests/run_profiling.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/tests/run_profiling.py b/tests/run_profiling.py index 7593bf999..2140ad87f 100755 --- a/tests/run_profiling.py +++ b/tests/run_profiling.py @@ -121,8 +121,8 @@ def log2_range(m): dict(select=8, mpiprocs=36), dict(select=10, mpiprocs=36), dict(select=12, mpiprocs=36)], - submit='qsub', mpiexec='mpiexec_mpt', - template='''#!/bin/bash + submit='qsub', mpiexec='mpiexec_mpt', + template='''#!/bin/bash #!/bin/bash #PBS -N VIC$i #PBS -q standard @@ -170,7 +170,37 @@ def log2_range(m): aprun -n ${BC_MPI_TASKS_ALLOC} $vic_exe -g $vic_global END=$(date +%s) DIFF=$(echo "$END - $START" | bc) -printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''')} +printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file'''), + 'cheyenne': host_config(profile=[dict(select=1, mpiprocs=36), + dict(select=2, mpiprocs=36), + dict(select=3, mpiprocs=36), + dict(select=4, mpiprocs=36), + dict(select=5, mpiprocs=36), + dict(select=6, mpiprocs=36), + dict(select=8, mpiprocs=36), + dict(select=10, mpiprocs=36), + dict(select=12, mpiprocs=36)], + submit='qsub', mpiexec='mpiexec_mpt', + template='''#!/bin/bash +#!/bin/bash +#PBS -N VIC$i +#PBS -q regular +#PBS -A P48500028 +#PBS -l select=$select:ncpus=36:mpiprocs=$mpiprocs +#PBS -l walltime=12:00:00 +#PBS -j oe +#PBS -m abe + +# Qsub template for UCAR CHEYENNE +# Scheduler: PBS + +START=$(date +%s) + +$mpiexec $vic_exe -g $vic_global +END=$(date +%s) +DIFF=$(echo "$END - $START" | bc) +printf "%5s | %f\n" ${BC_MPI_TASKS_ALLOC} $DIFF >> $timing_table_file''') +} OUT_WIDTH = 100 @@ -276,7 +306,8 @@ def run_scaling(args): run_string = template.safe_substitute( vic_exe=args.vic_exe, vic_global=args.global_param, - timing_table_file=args.timing, i=i, **kwargs) + timing_table_file=args.timing, i=i, + mpiexec=config.mpiexec, **kwargs) run_file = 'vic_{host}_{i}.sh'.format(host=args.host, i=i) with open(run_file, 'w') as f: f.write(run_string) From b1781bb9283334e3b67e75d724859f9f15cbede9 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 18 Apr 2017 17:13:52 -0400 Subject: [PATCH 122/294] implement initializing albedo --- vic/drivers/cesm/include/vic_driver_cesm.h | 1 + vic/drivers/cesm/src/cesm_interface_c.c | 3 ++ vic/drivers/cesm/src/vic_cesm_init_library.c | 22 ++++++++++++++ .../include/vic_driver_shared_all.h | 1 + .../shared_all/src/generate_default_state.c | 30 +++++++++++++++++++ vic/drivers/shared_image/src/state_metadata.c | 11 +++++++ vic/drivers/shared_image/src/vic_restore.c | 8 +++++ vic/drivers/shared_image/src/vic_store.c | 13 ++++++++ vic/vic_run/include/vic_def.h | 9 ++++++ 9 files changed, 98 insertions(+) diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index 6b13daf25..8601edf1e 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -187,5 +187,6 @@ void vic_cesm_run_model(void); void vic_cesm_start(vic_clock *vclock, case_metadata *cmeta); void vic_populate_model_state(char *runtype_str); void write_rpointer_file(char *fname); +void vic_initialize_albedo(void); #endif diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 1f8382eb6..5eebd33d8 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -102,6 +102,9 @@ vic_cesm_init(vic_clock *vclock, // initialize output structures vic_init_output(&dmy_current); + // initialize albedo + vic_initialize_albedo(); + // initialization is complete, print settings log_info( "Initialization is complete, print global param and options structures"); diff --git a/vic/drivers/cesm/src/vic_cesm_init_library.c b/vic/drivers/cesm/src/vic_cesm_init_library.c index d1e4f2562..90562e3c4 100644 --- a/vic/drivers/cesm/src/vic_cesm_init_library.c +++ b/vic/drivers/cesm/src/vic_cesm_init_library.c @@ -122,3 +122,25 @@ initialize_l2x_data(void) l2x_vic[i].l2x_vars_set = true; } } + +/****************************************************************************** + * @brief Initialize albedo values in l2x_data_struct. + *****************************************************************************/ +void +vic_initialize_albedo(void) +{ + extern l2x_data_struct *l2x_vic; + extern domain_struct local_domain; + extern all_vars_struct *all_vars; + + size_t i; + + log_info("Initializing albedo values"); + + for (i = 0; i < local_domain.ncells_active; i++) { + l2x_vic[i].l2x_Sl_avsdr = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidr = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_avsdf = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidf = all_vars[i].gc_avg.avg_albedo; + } +} diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 893df7a3a..88bb38181 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -354,6 +354,7 @@ enum STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ + STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gc_avg.avg_albedo */ // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! // used as a loop counter and must be >= the largest value in this enum N_STATE_VARS /**< used as a loop counter*/ diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 7bb50f793..c23ad83cf 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -53,15 +53,22 @@ generate_default_state(all_vars_struct *all_vars, }; double Cv; double tmp; + double AreaFactor; + double TreeAdjustFactor = 1.; + double lakefactor = 1.; + double albedo_sum; double ***tmpT; double **tmpZ; int ErrorFlag; cell_data_struct **cell; energy_bal_struct **energy; + veg_var_struct **veg_var; cell = all_vars->cell; energy = all_vars->energy; + veg_var = all_vars->veg_var; + gc_avg = all_vars->gc_avg; Nveg = veg_con[0].vegetat_type_num; // allocate memory for tmpT and tmpZ @@ -125,6 +132,29 @@ generate_default_state(all_vars_struct *all_vars, } } + + /************************************************************************ + Initialize gridcell-averaged albedo + ************************************************************************/ + // vegetation class-weighted albedo over gridcell + albedo_sum = 0; + for (veg = 0; veg <= Nveg; veg++) { + Cv = veg_con[veg].Cv; + if (Cv > 0) { + // TO-DO: account for treeline and lake factors + AreaFactor = Cv * TreeAdjustFactor * lakefactor; + // cold start, so assuming bare (free of snow) albedo + if (veg != Nveg) { + albedo_sum += AreaFactor * veg_var[veg][band].albedo; + } + else { + // this is the bare soil class, so use bare soil albedo parameter + albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; + } + } + } + gc_avg.avg_albedo = albedo_sum; + /************************************************************************ Initialize soil layer ice content ************************************************************************/ diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c index 5ed707d55..06df2fe7b 100644 --- a/vic/drivers/shared_image/src/state_metadata.c +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -275,6 +275,17 @@ set_state_meta_data_info() strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].description, "thermal flux through snowpack"); + // STATE_GRIDCELL_AVG_ALBEDO + strcpy(state_metadata[STATE_AVG_ALBEDO].varname, + "STATE_AVG_ALBEDO"); + strcpy(state_metadata[STATE_AVG_ALBEDO].long_name, + "state_avg_albedo"); + strcpy(state_metadata[STATE_AVG_ALBEDO].standard_name, + "state_gridcell_avg_albedo"); + strcpy(state_metadata[STATE_AVG_ALBEDO].units, "fraction"); + strcpy(state_metadata[STATE_AVG_ALBEDO].description, + "gridcell averaged albedo"); + if (options.LAKES) { // STATE_LAKE_SOIL_MOISTURE strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index bf1b656ad..ea5b9ba84 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -461,6 +461,14 @@ vic_restore(void) } } + // grid cell-averaged albedo: gc_avg.avg_albedo + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_AVG_ALBEDO].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].gc_avg.avg_albedo = dvar[i]; + } + // soil node temperatures: energy[veg][band].T[nidx] for (m = 0; m < options.NVEGTYPES; m++) { d5start[0] = m; diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 594108d21..6cecec9fc 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -725,6 +725,19 @@ vic_store(dmy_struct *dmy_state, } } + // Grid cell averaged albedo + nc_var = &(nc_state_file.nc_vars[STATE_AVG_ALBEDO]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].gc_avg.avg_albedo; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + if (options.LAKES) { // total soil moisture diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 3a34ae711..72fc15168 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -999,6 +999,14 @@ typedef struct { condensation from snow pack (m) */ } snow_data_struct; +/****************************************************************************** + * @brief This structures stores variables averaged over a grid cell + *****************************************************************************/ +typedef struct { + // Grid cell averaged variables + double avg_albedo; /**< Average albedo over a grid cell */ +} gridcell_avg_struct; + /****************************************************************************** * @brief This structure stores the lake/wetland parameters for a grid cell *****************************************************************************/ @@ -1085,6 +1093,7 @@ typedef struct { lake_var_struct lake_var; /**< Stores lake/wetland variables */ snow_data_struct **snow; /**< Stores snow variables */ veg_var_struct **veg_var; /**< Stores vegetation variables */ + gridcell_avg_struct gc_avg; /**< Stores gridcell average variables */ } all_vars_struct; #endif From d0d0643854b4768990af2802437d4e47e1e48cc3 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 18 Apr 2017 17:25:21 -0700 Subject: [PATCH 123/294] fix indentation --- vic/drivers/cesm/src/vic_cesm_init_library.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vic/drivers/cesm/src/vic_cesm_init_library.c b/vic/drivers/cesm/src/vic_cesm_init_library.c index 90562e3c4..f71bdd7fb 100644 --- a/vic/drivers/cesm/src/vic_cesm_init_library.c +++ b/vic/drivers/cesm/src/vic_cesm_init_library.c @@ -138,9 +138,9 @@ vic_initialize_albedo(void) log_info("Initializing albedo values"); for (i = 0; i < local_domain.ncells_active; i++) { - l2x_vic[i].l2x_Sl_avsdr = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_anidr = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_avsdf = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_anidf = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_avsdr = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidr = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_avsdf = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidf = all_vars[i].gc_avg.avg_albedo; } -} +} From 8f780231b929e19057f1f8bb69ae2d81866acd46 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 18 Apr 2017 20:29:36 -0400 Subject: [PATCH 124/294] fix indentation --- .../shared_all/src/generate_default_state.c | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index c23ad83cf..f989f0400 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -64,6 +64,7 @@ generate_default_state(all_vars_struct *all_vars, cell_data_struct **cell; energy_bal_struct **energy; veg_var_struct **veg_var; + gridcell_avg_struct gc_avg; cell = all_vars->cell; energy = all_vars->energy; @@ -141,16 +142,16 @@ generate_default_state(all_vars_struct *all_vars, for (veg = 0; veg <= Nveg; veg++) { Cv = veg_con[veg].Cv; if (Cv > 0) { - // TO-DO: account for treeline and lake factors - AreaFactor = Cv * TreeAdjustFactor * lakefactor; - // cold start, so assuming bare (free of snow) albedo - if (veg != Nveg) { - albedo_sum += AreaFactor * veg_var[veg][band].albedo; - } - else { - // this is the bare soil class, so use bare soil albedo parameter - albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; - } + // TO-DO: account for treeline and lake factors + AreaFactor = Cv * TreeAdjustFactor * lakefactor; + // cold start, so assuming bare (free of snow) albedo + if (veg != Nveg) { + albedo_sum += AreaFactor * veg_var[veg][band].albedo; + } + else { + // this is the bare soil class, so use bare soil albedo parameter + albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; + } } } gc_avg.avg_albedo = albedo_sum; From b13eb625b1f34b6b35cf72787a4b923b15ec5afc Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 19 Apr 2017 11:56:30 -0700 Subject: [PATCH 125/294] ran uncrustify --- vic/drivers/shared_all/src/generate_default_state.c | 6 +++--- vic/drivers/shared_image/src/state_metadata.c | 6 +++--- vic/drivers/shared_image/src/vic_restore.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 4 ++-- vic/vic_run/include/vic_def.h | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index f989f0400..f1fa893a5 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -135,19 +135,19 @@ generate_default_state(all_vars_struct *all_vars, /************************************************************************ - Initialize gridcell-averaged albedo + Initialize gridcell-averaged albedo ************************************************************************/ // vegetation class-weighted albedo over gridcell albedo_sum = 0; for (veg = 0; veg <= Nveg; veg++) { Cv = veg_con[veg].Cv; if (Cv > 0) { - // TO-DO: account for treeline and lake factors + // TO-DO: account for treeline and lake factors AreaFactor = Cv * TreeAdjustFactor * lakefactor; // cold start, so assuming bare (free of snow) albedo if (veg != Nveg) { albedo_sum += AreaFactor * veg_var[veg][band].albedo; - } + } else { // this is the bare soil class, so use bare soil albedo parameter albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c index 06df2fe7b..5792160fe 100644 --- a/vic/drivers/shared_image/src/state_metadata.c +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -277,11 +277,11 @@ set_state_meta_data_info() // STATE_GRIDCELL_AVG_ALBEDO strcpy(state_metadata[STATE_AVG_ALBEDO].varname, - "STATE_AVG_ALBEDO"); + "STATE_AVG_ALBEDO"); strcpy(state_metadata[STATE_AVG_ALBEDO].long_name, - "state_avg_albedo"); + "state_avg_albedo"); strcpy(state_metadata[STATE_AVG_ALBEDO].standard_name, - "state_gridcell_avg_albedo"); + "state_gridcell_avg_albedo"); strcpy(state_metadata[STATE_AVG_ALBEDO].units, "fraction"); strcpy(state_metadata[STATE_AVG_ALBEDO].description, "gridcell averaged albedo"); diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index ea5b9ba84..9b2edd911 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -466,7 +466,7 @@ vic_restore(void) state_metadata[STATE_AVG_ALBEDO].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].gc_avg.avg_albedo = dvar[i]; + all_vars[i].gc_avg.avg_albedo = dvar[i]; } // soil node temperatures: energy[veg][band].T[nidx] diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 6cecec9fc..b7ce73687 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -728,14 +728,14 @@ vic_store(dmy_struct *dmy_state, // Grid cell averaged albedo nc_var = &(nc_state_file.nc_vars[STATE_AVG_ALBEDO]); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].gc_avg.avg_albedo; + dvar[i] = (double) all_vars[i].gc_avg.avg_albedo; } gather_put_nc_field_double(nc_state_file.nc_id, nc_var->nc_varid, nc_state_file.d_fillvalue, d2start, nc_var->nc_counts, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; + dvar[i] = nc_state_file.d_fillvalue; } diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 72fc15168..0f82ef499 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -1000,10 +1000,10 @@ typedef struct { } snow_data_struct; /****************************************************************************** - * @brief This structures stores variables averaged over a grid cell + * @brief This structures stores variables averaged over a grid cell *****************************************************************************/ typedef struct { - // Grid cell averaged variables + // Grid cell averaged variables double avg_albedo; /**< Average albedo over a grid cell */ } gridcell_avg_struct; From 57556b6e7a53bf2b138fabe7113192571e1e6f9d Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 19 Apr 2017 16:38:53 -0700 Subject: [PATCH 126/294] add state file variable dimensions --- vic/drivers/shared_image/src/vic_store.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index b7ce73687..384c4078d 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1488,6 +1488,7 @@ set_nc_state_var_info(nc_file_struct *nc) case STATE_LAKE_ICE_SNOW_PACK_WATER: case STATE_LAKE_ICE_SNOW_ALBEDO: case STATE_LAKE_ICE_SNOW_DEPTH: + case STATE_AVG_ALBEDO: // 2d vars [j, i] nc->nc_vars[i].nc_dims = 2; nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; From 58f6348ef9bceeaf7396238176f194930e910741 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 20 Apr 2017 12:18:08 -0700 Subject: [PATCH 127/294] fix setting dimensions --- vic/drivers/shared_image/src/vic_store.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 384c4078d..d3db15489 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1435,6 +1435,15 @@ set_nc_state_var_info(nc_file_struct *nc) nc->nc_vars[i].nc_counts[3] = nc->nj_size; nc->nc_vars[i].nc_counts[4] = nc->ni_size; break; + case STATE_AVG_ALBEDO: + // 2d vars [j, i] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = nc->nj_size; + nc->nc_vars[i].nc_counts[1] = nc->ni_size; + break; + case STATE_LAKE_SOIL_MOISTURE: // 3d vars [layer, j, i] nc->nc_vars[i].nc_dims = 3; @@ -1488,7 +1497,6 @@ set_nc_state_var_info(nc_file_struct *nc) case STATE_LAKE_ICE_SNOW_PACK_WATER: case STATE_LAKE_ICE_SNOW_ALBEDO: case STATE_LAKE_ICE_SNOW_DEPTH: - case STATE_AVG_ALBEDO: // 2d vars [j, i] nc->nc_vars[i].nc_dims = 2; nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; From a7e2bf2790a14b8d5d6a9d21e04c3769d0db8802 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 20 Apr 2017 15:51:27 -0700 Subject: [PATCH 128/294] fix bug with looping over bands --- .../shared_all/src/generate_default_state.c | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index f1fa893a5..986f09f34 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -142,16 +142,21 @@ generate_default_state(all_vars_struct *all_vars, for (veg = 0; veg <= Nveg; veg++) { Cv = veg_con[veg].Cv; if (Cv > 0) { - // TO-DO: account for treeline and lake factors - AreaFactor = Cv * TreeAdjustFactor * lakefactor; - // cold start, so assuming bare (free of snow) albedo - if (veg != Nveg) { - albedo_sum += AreaFactor * veg_var[veg][band].albedo; - } - else { - // this is the bare soil class, so use bare soil albedo parameter - albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; - } + for (band = 0; band < options.SNOW_BAND; band++) { + if (soil_con->AreaFract[band] > 0.) { + // TO-DO: account for treeline and lake factors + AreaFactor = (Cv * soil_con->AreaFract[band] * + TreeAdjustFactor * lakefactor); + // cold start, so assuming bare (free of snow) albedo + if (veg != Nveg) { + albedo_sum += AreaFactor * veg_var[veg][band].albedo; + } + else { + // this is the bare soil class, so use bare soil albedo parameter + albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; + } + } + } } } gc_avg.avg_albedo = albedo_sum; From 07c4b5785b381e5f9107a51af0f379e4f95de63c Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 21 Apr 2017 12:13:05 -0700 Subject: [PATCH 129/294] free memory for local mask variable --- vic/drivers/shared_image/src/get_global_domain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 464bb5523..8d288ef7c 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -149,6 +149,7 @@ get_global_domain(nameid_struct *domain_nc_nameid, // free memory free(var); free(run); + free(mask); return global_domain->ncells_active; } From 95b629028f1d642df9e9ac9f89fe390f746e0bcb Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 23 Apr 2017 17:30:16 -0700 Subject: [PATCH 130/294] remove memory leak with out_data array --- .../include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/vic_history.c | 21 ++++++------------- .../shared_image/src/vic_init_output.c | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 893df7a3a..fe9efc62e 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -584,7 +584,7 @@ void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, double all_30_day_from_dmy(dmy_struct *dmy); double all_leap_from_dmy(dmy_struct *dmy); void alloc_aggdata(stream_struct *stream); -void alloc_out_data(size_t ngridcells, double ****out_data); +void alloc_out_data(size_t ngridcells, double ***out_data); double average(double *ar, size_t n); double calc_energy_balance_error(double, double, double, double, double); void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index 6a5278a21..8f6f65fab 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -31,30 +31,21 @@ *****************************************************************************/ void alloc_out_data(size_t ngridcells, - double ****out_data) + double ***out_data) { extern metadata_struct out_metadata[N_OUTVAR_TYPES]; size_t i; size_t j; - size_t k; - - *out_data = calloc(ngridcells, sizeof(*(*out_data))); - check_alloc_status(*out_data, "Memory allocation error."); for (i = 0; i < ngridcells; i++) { - (*out_data)[i] = calloc(N_OUTVAR_TYPES, sizeof(*((*out_data)[i]))); - check_alloc_status((*out_data)[i], "Memory allocation error."); + out_data[i] = calloc(N_OUTVAR_TYPES, sizeof(*(out_data)[i])); + check_alloc_status(out_data[i], "Memory allocation error."); // Allocate space for data for (j = 0; j < N_OUTVAR_TYPES; j++) { - (*out_data)[i][j] = - calloc(out_metadata[j].nelem, sizeof(*((*out_data)[i][j]))); - check_alloc_status((*out_data)[i][j], "Memory allocation error."); - - // initialize data member - for (k = 0; k < out_metadata[j].nelem; k++) { - (*out_data)[i][j][k] = 0; - } + out_data[i][j] = + calloc(out_metadata[j].nelem, sizeof(*(out_data[i][j]))); + check_alloc_status(out_data[i][j], "Memory allocation error."); } } } diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index f8290e851..ecd3fd751 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -61,7 +61,7 @@ vic_init_output(dmy_struct *dmy_current) set_output_met_data_info(); // allocate out_data - alloc_out_data(local_domain.ncells_active, &out_data); + alloc_out_data(local_domain.ncells_active, out_data); // initialize the save data structures for (i = 0; i < local_domain.ncells_active; i++) { From cde924fc8977a3e814b67225238d22b4daf5e1b8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 23 Apr 2017 17:45:25 -0700 Subject: [PATCH 131/294] remove soil node dvar memory leak in initialize_state_file fctn --- vic/drivers/shared_image/src/vic_store.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 594108d21..fb9e81724 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -2122,6 +2122,7 @@ initialize_state_file(char *filename, dvar[i] = nc_state_file->d_fillvalue; } } + free(dvar); if (options.LAKES) { // lake nodes From e7be214a1b2db7f8809e612f76f67229f9412831 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 23 Apr 2017 17:54:55 -0700 Subject: [PATCH 132/294] eliminate memory leak from compare_ncdomain_with_global_domain fctn --- vic/drivers/shared_image/src/check_domain_info.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index 26d6ae26c..b32c0d00d 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -80,4 +80,5 @@ compare_ncdomain_with_global_domain(nameid_struct *nc_nameid) global_domain.locations[i].longitude, i); } } + free(ncfile_domain.locations); } From 9f0de7981cd3cfddab89bfc0c364cd1cde5c2a64 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 23 Apr 2017 18:13:34 -0700 Subject: [PATCH 133/294] fix memory leak with not freeing memory in nc_state_file.nc_vars --- vic/drivers/shared_image/src/vic_store.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index fb9e81724..18502f28e 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1266,6 +1266,9 @@ vic_store(dmy_struct *dmy_state, free(ivar); free(dvar); + + // free memory + free(nc_state_file.nc_vars); } /****************************************************************************** From df989e4e2e4a047ede4ae6ddb77185c76dec583e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 23 Apr 2017 18:19:33 -0700 Subject: [PATCH 134/294] fix leak with t_offset --- vic/drivers/image/src/vic_force.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 104be14ab..04a3aa05a 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -502,6 +502,7 @@ vic_force(void) // cleanup free(dvar); + free(t_offset); } /****************************************************************************** From 1a34c2cfcae9d09c1f7f2a8aaaeaf24edab4c21c Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 11:58:54 -0700 Subject: [PATCH 135/294] attempt to fix travis build --- vic/drivers/python/vic_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/python/vic_build.py b/vic/drivers/python/vic_build.py index 730dad9ea..f8c243379 100644 --- a/vic/drivers/python/vic_build.py +++ b/vic/drivers/python/vic_build.py @@ -3,7 +3,7 @@ ffi = FFI() ffi.cdef(headers) -ffi.set_source('vic/_vic', None) +ffi.set_source('vic._vic', None) if __name__ == '__main__': ffi.compile() From d2dbe2dbedc012869377ef968a7dfd2d271b2906 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 12:14:17 -0700 Subject: [PATCH 136/294] corresponding changes in classic driver for alloc_out_data --- vic/drivers/classic/src/vic_classic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 4a2e7de4c..62d0e99c6 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -124,7 +124,7 @@ main(int argc, /** Set up output data structures **/ set_output_met_data_info(); // out_data is shape [ngridcells (1), N_OUTVAR_TYPES] - alloc_out_data(1, &out_data); + alloc_out_data(1, out_data); filep.globalparam = open_file(filenames.global, "r"); parse_output_info(filep.globalparam, &streams, &(dmy[0])); validate_streams(&streams); From f6b349d68b7a3040cb8c3e86137dc864cbd59796 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 13:14:01 -0700 Subject: [PATCH 137/294] further update to classic driver for alloc_out_data --- vic/drivers/classic/src/vic_classic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 62d0e99c6..d15f3fb78 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -76,7 +76,7 @@ main(int argc, all_vars_struct all_vars; lake_con_struct lake_con; stream_struct *streams = NULL; - double ***out_data; // [1, nvars, nelem] + double ***out_data = NULL; // [1, nvars, nelem] save_data_struct save_data; timer_struct global_timers[N_TIMERS]; timer_struct cell_timer; From 29944d03badf05dd65218cdae898ffffa7869489 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 13:37:28 -0700 Subject: [PATCH 138/294] further fix --- vic/drivers/classic/src/vic_classic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index d15f3fb78..00099772e 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -76,7 +76,7 @@ main(int argc, all_vars_struct all_vars; lake_con_struct lake_con; stream_struct *streams = NULL; - double ***out_data = NULL; // [1, nvars, nelem] + double ***out_data; // [1, nvars, nelem] save_data_struct save_data; timer_struct global_timers[N_TIMERS]; timer_struct cell_timer; @@ -121,6 +121,10 @@ main(int argc, initialize_time(); dmy = make_dmy(&global_param); + // Allocate memory for out_data + out_data = malloc(1 * sizeof(*out_data)); + check_alloc_status(out_data, "Memory allocation error."); + /** Set up output data structures **/ set_output_met_data_info(); // out_data is shape [ngridcells (1), N_OUTVAR_TYPES] From 77f2e7ac1e7fdf8810e10d6e43bab8c8288e6be5 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 14:29:21 -0700 Subject: [PATCH 139/294] address PR review comments --- vic/drivers/shared_all/src/vic_history.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index 8f6f65fab..88c310de1 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -39,7 +39,7 @@ alloc_out_data(size_t ngridcells, size_t j; for (i = 0; i < ngridcells; i++) { - out_data[i] = calloc(N_OUTVAR_TYPES, sizeof(*(out_data)[i])); + out_data[i] = calloc(N_OUTVAR_TYPES, sizeof(*(out_data[i]))); check_alloc_status(out_data[i], "Memory allocation error."); // Allocate space for data for (j = 0; j < N_OUTVAR_TYPES; j++) { diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 18502f28e..20f5e995b 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1266,8 +1266,6 @@ vic_store(dmy_struct *dmy_state, free(ivar); free(dvar); - - // free memory free(nc_state_file.nc_vars); } From e1d5d173db0e4b3d49863cd933efb5a700a08bd1 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 18:57:27 -0400 Subject: [PATCH 140/294] Revert "Merge branch 'develop' of github.com:UW-Hydro/VIC into feature/initialize_albedo_cesm_driver_2" This reverts commit 191c1577cf7ac637779630857c72607f4d244e82, reversing changes made to a7e2bf2790a14b8d5d6a9d21e04c3769d0db8802. --- vic/drivers/classic/src/vic_classic.c | 6 +----- vic/drivers/image/src/vic_force.c | 1 - vic/drivers/python/vic_build.py | 2 +- .../include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/vic_history.c | 21 +++++++++++++------ .../shared_image/src/check_domain_info.c | 1 - .../shared_image/src/get_global_domain.c | 1 - .../shared_image/src/vic_init_output.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 2 -- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 00099772e..4a2e7de4c 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -121,14 +121,10 @@ main(int argc, initialize_time(); dmy = make_dmy(&global_param); - // Allocate memory for out_data - out_data = malloc(1 * sizeof(*out_data)); - check_alloc_status(out_data, "Memory allocation error."); - /** Set up output data structures **/ set_output_met_data_info(); // out_data is shape [ngridcells (1), N_OUTVAR_TYPES] - alloc_out_data(1, out_data); + alloc_out_data(1, &out_data); filep.globalparam = open_file(filenames.global, "r"); parse_output_info(filep.globalparam, &streams, &(dmy[0])); validate_streams(&streams); diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 04a3aa05a..104be14ab 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -502,7 +502,6 @@ vic_force(void) // cleanup free(dvar); - free(t_offset); } /****************************************************************************** diff --git a/vic/drivers/python/vic_build.py b/vic/drivers/python/vic_build.py index f8c243379..730dad9ea 100644 --- a/vic/drivers/python/vic_build.py +++ b/vic/drivers/python/vic_build.py @@ -3,7 +3,7 @@ ffi = FFI() ffi.cdef(headers) -ffi.set_source('vic._vic', None) +ffi.set_source('vic/_vic', None) if __name__ == '__main__': ffi.compile() diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index f832e06b9..88bb38181 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -585,7 +585,7 @@ void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, double all_30_day_from_dmy(dmy_struct *dmy); double all_leap_from_dmy(dmy_struct *dmy); void alloc_aggdata(stream_struct *stream); -void alloc_out_data(size_t ngridcells, double ***out_data); +void alloc_out_data(size_t ngridcells, double ****out_data); double average(double *ar, size_t n); double calc_energy_balance_error(double, double, double, double, double); void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index 88c310de1..6a5278a21 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -31,21 +31,30 @@ *****************************************************************************/ void alloc_out_data(size_t ngridcells, - double ***out_data) + double ****out_data) { extern metadata_struct out_metadata[N_OUTVAR_TYPES]; size_t i; size_t j; + size_t k; + + *out_data = calloc(ngridcells, sizeof(*(*out_data))); + check_alloc_status(*out_data, "Memory allocation error."); for (i = 0; i < ngridcells; i++) { - out_data[i] = calloc(N_OUTVAR_TYPES, sizeof(*(out_data[i]))); - check_alloc_status(out_data[i], "Memory allocation error."); + (*out_data)[i] = calloc(N_OUTVAR_TYPES, sizeof(*((*out_data)[i]))); + check_alloc_status((*out_data)[i], "Memory allocation error."); // Allocate space for data for (j = 0; j < N_OUTVAR_TYPES; j++) { - out_data[i][j] = - calloc(out_metadata[j].nelem, sizeof(*(out_data[i][j]))); - check_alloc_status(out_data[i][j], "Memory allocation error."); + (*out_data)[i][j] = + calloc(out_metadata[j].nelem, sizeof(*((*out_data)[i][j]))); + check_alloc_status((*out_data)[i][j], "Memory allocation error."); + + // initialize data member + for (k = 0; k < out_metadata[j].nelem; k++) { + (*out_data)[i][j][k] = 0; + } } } } diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index b32c0d00d..26d6ae26c 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -80,5 +80,4 @@ compare_ncdomain_with_global_domain(nameid_struct *nc_nameid) global_domain.locations[i].longitude, i); } } - free(ncfile_domain.locations); } diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 8d288ef7c..464bb5523 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -149,7 +149,6 @@ get_global_domain(nameid_struct *domain_nc_nameid, // free memory free(var); free(run); - free(mask); return global_domain->ncells_active; } diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index ecd3fd751..f8290e851 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -61,7 +61,7 @@ vic_init_output(dmy_struct *dmy_current) set_output_met_data_info(); // allocate out_data - alloc_out_data(local_domain.ncells_active, out_data); + alloc_out_data(local_domain.ncells_active, &out_data); // initialize the save data structures for (i = 0; i < local_domain.ncells_active; i++) { diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index f344e6976..d3db15489 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1279,7 +1279,6 @@ vic_store(dmy_struct *dmy_state, free(ivar); free(dvar); - free(nc_state_file.nc_vars); } /****************************************************************************** @@ -2145,7 +2144,6 @@ initialize_state_file(char *filename, dvar[i] = nc_state_file->d_fillvalue; } } - free(dvar); if (options.LAKES) { // lake nodes From 598fd84b4c77959e6172690dca3c59db84ddde5f Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 24 Apr 2017 20:00:35 -0400 Subject: [PATCH 141/294] Revert "Revert "Merge branch 'develop' of github.com:UW-Hydro/VIC into feature/initialize_albedo_cesm_driver_2"" This reverts commit e1d5d173db0e4b3d49863cd933efb5a700a08bd1. --- vic/drivers/classic/src/vic_classic.c | 6 +++++- vic/drivers/image/src/vic_force.c | 1 + vic/drivers/python/vic_build.py | 2 +- .../include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/vic_history.c | 21 ++++++------------- .../shared_image/src/check_domain_info.c | 1 + .../shared_image/src/get_global_domain.c | 1 + .../shared_image/src/vic_init_output.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 2 ++ 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 4a2e7de4c..00099772e 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -121,10 +121,14 @@ main(int argc, initialize_time(); dmy = make_dmy(&global_param); + // Allocate memory for out_data + out_data = malloc(1 * sizeof(*out_data)); + check_alloc_status(out_data, "Memory allocation error."); + /** Set up output data structures **/ set_output_met_data_info(); // out_data is shape [ngridcells (1), N_OUTVAR_TYPES] - alloc_out_data(1, &out_data); + alloc_out_data(1, out_data); filep.globalparam = open_file(filenames.global, "r"); parse_output_info(filep.globalparam, &streams, &(dmy[0])); validate_streams(&streams); diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 104be14ab..04a3aa05a 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -502,6 +502,7 @@ vic_force(void) // cleanup free(dvar); + free(t_offset); } /****************************************************************************** diff --git a/vic/drivers/python/vic_build.py b/vic/drivers/python/vic_build.py index 730dad9ea..f8c243379 100644 --- a/vic/drivers/python/vic_build.py +++ b/vic/drivers/python/vic_build.py @@ -3,7 +3,7 @@ ffi = FFI() ffi.cdef(headers) -ffi.set_source('vic/_vic', None) +ffi.set_source('vic._vic', None) if __name__ == '__main__': ffi.compile() diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 88bb38181..f832e06b9 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -585,7 +585,7 @@ void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, double all_30_day_from_dmy(dmy_struct *dmy); double all_leap_from_dmy(dmy_struct *dmy); void alloc_aggdata(stream_struct *stream); -void alloc_out_data(size_t ngridcells, double ****out_data); +void alloc_out_data(size_t ngridcells, double ***out_data); double average(double *ar, size_t n); double calc_energy_balance_error(double, double, double, double, double); void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index 6a5278a21..88c310de1 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -31,30 +31,21 @@ *****************************************************************************/ void alloc_out_data(size_t ngridcells, - double ****out_data) + double ***out_data) { extern metadata_struct out_metadata[N_OUTVAR_TYPES]; size_t i; size_t j; - size_t k; - - *out_data = calloc(ngridcells, sizeof(*(*out_data))); - check_alloc_status(*out_data, "Memory allocation error."); for (i = 0; i < ngridcells; i++) { - (*out_data)[i] = calloc(N_OUTVAR_TYPES, sizeof(*((*out_data)[i]))); - check_alloc_status((*out_data)[i], "Memory allocation error."); + out_data[i] = calloc(N_OUTVAR_TYPES, sizeof(*(out_data[i]))); + check_alloc_status(out_data[i], "Memory allocation error."); // Allocate space for data for (j = 0; j < N_OUTVAR_TYPES; j++) { - (*out_data)[i][j] = - calloc(out_metadata[j].nelem, sizeof(*((*out_data)[i][j]))); - check_alloc_status((*out_data)[i][j], "Memory allocation error."); - - // initialize data member - for (k = 0; k < out_metadata[j].nelem; k++) { - (*out_data)[i][j][k] = 0; - } + out_data[i][j] = + calloc(out_metadata[j].nelem, sizeof(*(out_data[i][j]))); + check_alloc_status(out_data[i][j], "Memory allocation error."); } } } diff --git a/vic/drivers/shared_image/src/check_domain_info.c b/vic/drivers/shared_image/src/check_domain_info.c index 26d6ae26c..b32c0d00d 100644 --- a/vic/drivers/shared_image/src/check_domain_info.c +++ b/vic/drivers/shared_image/src/check_domain_info.c @@ -80,4 +80,5 @@ compare_ncdomain_with_global_domain(nameid_struct *nc_nameid) global_domain.locations[i].longitude, i); } } + free(ncfile_domain.locations); } diff --git a/vic/drivers/shared_image/src/get_global_domain.c b/vic/drivers/shared_image/src/get_global_domain.c index 464bb5523..8d288ef7c 100644 --- a/vic/drivers/shared_image/src/get_global_domain.c +++ b/vic/drivers/shared_image/src/get_global_domain.c @@ -149,6 +149,7 @@ get_global_domain(nameid_struct *domain_nc_nameid, // free memory free(var); free(run); + free(mask); return global_domain->ncells_active; } diff --git a/vic/drivers/shared_image/src/vic_init_output.c b/vic/drivers/shared_image/src/vic_init_output.c index f8290e851..ecd3fd751 100644 --- a/vic/drivers/shared_image/src/vic_init_output.c +++ b/vic/drivers/shared_image/src/vic_init_output.c @@ -61,7 +61,7 @@ vic_init_output(dmy_struct *dmy_current) set_output_met_data_info(); // allocate out_data - alloc_out_data(local_domain.ncells_active, &out_data); + alloc_out_data(local_domain.ncells_active, out_data); // initialize the save data structures for (i = 0; i < local_domain.ncells_active; i++) { diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index d3db15489..f344e6976 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1279,6 +1279,7 @@ vic_store(dmy_struct *dmy_state, free(ivar); free(dvar); + free(nc_state_file.nc_vars); } /****************************************************************************** @@ -2144,6 +2145,7 @@ initialize_state_file(char *filename, dvar[i] = nc_state_file->d_fillvalue; } } + free(dvar); if (options.LAKES) { // lake nodes From 366972ba844c0ef9ac394a9da4bb79e4856d40e0 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 26 Apr 2017 18:16:46 -0400 Subject: [PATCH 142/294] use calloc instead of malloc to address nan bug --- vic/drivers/shared_image/src/vic_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_alloc.c b/vic/drivers/shared_image/src/vic_alloc.c index 9c4a0b2cc..34ecfec9d 100644 --- a/vic/drivers/shared_image/src/vic_alloc.c +++ b/vic/drivers/shared_image/src/vic_alloc.c @@ -86,7 +86,7 @@ vic_alloc(void) check_alloc_status(out_data, "Memory allocation error."); // save_data allocation - save_data = malloc(local_domain.ncells_active * sizeof(*save_data)); + save_data = calloc(local_domain.ncells_active, sizeof(*save_data)); check_alloc_status(save_data, "Memory allocation error."); // allocate memory for individual grid cells From bb2ebcce7385aab5692c00b7d8c1dc9cc1a506d1 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 27 Apr 2017 12:59:11 -0700 Subject: [PATCH 143/294] add variable name for restart test debugging --- tests/test_image_driver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_image_driver.py b/tests/test_image_driver.py index 1759e2e2f..4dcf7a09b 100644 --- a/tests/test_image_driver.py +++ b/tests/test_image_driver.py @@ -291,4 +291,5 @@ def check_mpi_states(state_basedir, list_n_proc): for var in ds_first_run.data_vars: npt.assert_array_equal(ds_current_run[var].values, ds_first_run[var].values, - err_msg='States are not an exact match') + err_msg='States are not an exact match ' + 'for variable: {}'.format(var)) From ef14be50594f9eb0282077756fadaffd9e946353 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sat, 29 Apr 2017 15:19:55 -0700 Subject: [PATCH 144/294] gc_avg --> gridcell_avg --- vic/drivers/shared_all/include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_all/src/generate_default_state.c | 6 +++--- vic/drivers/shared_image/src/vic_restore.c | 4 ++-- vic/drivers/shared_image/src/vic_store.c | 2 +- vic/vic_run/include/vic_def.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index f832e06b9..0b4ad77a1 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -354,7 +354,7 @@ enum STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ - STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gc_avg.avg_albedo */ + STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gridcell_avg.avg_albedo */ // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! // used as a loop counter and must be >= the largest value in this enum N_STATE_VARS /**< used as a loop counter*/ diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 986f09f34..d2756e5d8 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -64,12 +64,12 @@ generate_default_state(all_vars_struct *all_vars, cell_data_struct **cell; energy_bal_struct **energy; veg_var_struct **veg_var; - gridcell_avg_struct gc_avg; + gridcell_avg_struct gridcell_avg; cell = all_vars->cell; energy = all_vars->energy; veg_var = all_vars->veg_var; - gc_avg = all_vars->gc_avg; + gridcell_avg = all_vars->gridcell_avg; Nveg = veg_con[0].vegetat_type_num; // allocate memory for tmpT and tmpZ @@ -159,7 +159,7 @@ generate_default_state(all_vars_struct *all_vars, } } } - gc_avg.avg_albedo = albedo_sum; + gridcell_avg.avg_albedo = albedo_sum; /************************************************************************ Initialize soil layer ice content diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 9b2edd911..e1389b3ba 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -461,12 +461,12 @@ vic_restore(void) } } - // grid cell-averaged albedo: gc_avg.avg_albedo + // grid cell-averaged albedo: gridcell_avg.avg_albedo get_scatter_nc_field_double(&(filenames.init_state), state_metadata[STATE_AVG_ALBEDO].varname, d2start, d2count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].gc_avg.avg_albedo = dvar[i]; + all_vars[i].gridcell_avg.avg_albedo = dvar[i]; } // soil node temperatures: energy[veg][band].T[nidx] diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index f344e6976..602dac2a2 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -728,7 +728,7 @@ vic_store(dmy_struct *dmy_state, // Grid cell averaged albedo nc_var = &(nc_state_file.nc_vars[STATE_AVG_ALBEDO]); for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].gc_avg.avg_albedo; + dvar[i] = (double) all_vars[i].gridcell_avg.avg_albedo; } gather_put_nc_field_double(nc_state_file.nc_id, nc_var->nc_varid, diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 0f82ef499..5044035e2 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -1093,7 +1093,7 @@ typedef struct { lake_var_struct lake_var; /**< Stores lake/wetland variables */ snow_data_struct **snow; /**< Stores snow variables */ veg_var_struct **veg_var; /**< Stores vegetation variables */ - gridcell_avg_struct gc_avg; /**< Stores gridcell average variables */ + gridcell_avg_struct gridcell_avg; /**< Stores gridcell average variables */ } all_vars_struct; #endif From fcce4d0b0a9e5bcdc5030c168408c1aa6f20c1bf Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 30 Apr 2017 17:55:32 -0700 Subject: [PATCH 145/294] fix travis tests and update albedo at each time step --- vic/vic_run/include/vic_run.h | 2 + vic/vic_run/src/calc_gridcell_avg_albedo.c | 77 ++++++++++++++++++++++ vic/vic_run/src/vic_run.c | 7 ++ 3 files changed, 86 insertions(+) create mode 100644 vic/vic_run/src/calc_gridcell_avg_albedo.c diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index aba458c26..8dc48c706 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -49,6 +49,8 @@ double calc_atmos_energy_bal(double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *, bool *, unsigned int*); double calc_density(double); +void calc_gridcell_avg_albedo(double *, double, size_t, energy_bal_struct **, + veg_con_struct *, soil_con_struct *); double calc_latent_heat_of_sublimation(double temp); double calc_latent_heat_of_vaporization(double temp); int calc_layer_average_thermal_props(energy_bal_struct *, layer_data_struct *, diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c new file mode 100644 index 000000000..678290f7e --- /dev/null +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -0,0 +1,77 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This routine computes gridcell-averaged albedo. + * + * Note: this routine is specifically designed for the CESM driver, for WRF, + * but has been implemented in other drivers as well for the sake of consistency. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Compute gridcell-averaged albedo. + *****************************************************************************/ +void +calc_gridcell_avg_albedo(double *albedo, + double shortwave, + size_t Nveg, + energy_bal_struct **energy, + veg_con_struct *veg_con, + soil_con_struct *soil_con) +{ + extern option_struct options; + size_t veg; + size_t band; + double Cv; + double AreaFactor; + double TreeAdjustFactor = 1.; + double lakefactor = 1; + double swnet; + + swnet = 0; + + for (veg = 0; veg <= Nveg; veg++) { + Cv = veg_con[veg].Cv; + if (Cv > 0) { + for (band = 0; band < options.SNOW_BAND; band++) { + if (soil_con->AreaFract[band] > 0.) { + // TO-DO: account for treeline and lake factors + AreaFactor = (Cv * soil_con->AreaFract[band] * + TreeAdjustFactor * lakefactor); + swnet += energy[veg][band].NetShortAtmos; + } + } + } + } + + // compute gridcell-averaged albedo using average longwave + // and shortwave over gridcell + if (shortwave > 0) { + *albedo = 1.0 - (swnet / shortwave); + } + else { + *albedo = 0.0; + } + +} diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 98b763655..0ef952632 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -93,6 +93,7 @@ vic_run(force_data_struct *force, veg_var_struct **veg_var; energy_bal_struct **energy; snow_data_struct **snow; + gridcell_avg_struct gridcell_avg; // assign vic_run_veg_lib to veg_lib, so that the veg_lib for the correct // grid cell is used within vic_run. For simplicity sake, use vic_run_veg_lib @@ -105,6 +106,7 @@ vic_run(force_data_struct *force, lake_var = &all_vars->lake_var; snow = all_vars->snow; veg_var = all_vars->veg_var; + gridcell_avg = all_vars->gridcell_avg; Nbands = options.SNOW_BAND; @@ -382,6 +384,11 @@ vic_run(force_data_struct *force, } } + // Compute gridcell-averaged albedo + calc_gridcell_avg_albedo(&gridcell_avg.avg_albedo, + force->shortwave[NR], Nveg, energy, + veg_con, soil_con); + /**************************** Run Lake Model ****************************/ From c64d2844e2f17c0ce65b0e2ceb901f62ddf644b3 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 30 Apr 2017 18:33:37 -0700 Subject: [PATCH 146/294] gc_avg -> gridcell_avg in cesm driver --- vic/drivers/cesm/src/vic_cesm_init_library.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vic/drivers/cesm/src/vic_cesm_init_library.c b/vic/drivers/cesm/src/vic_cesm_init_library.c index f71bdd7fb..afd2170a7 100644 --- a/vic/drivers/cesm/src/vic_cesm_init_library.c +++ b/vic/drivers/cesm/src/vic_cesm_init_library.c @@ -138,9 +138,9 @@ vic_initialize_albedo(void) log_info("Initializing albedo values"); for (i = 0; i < local_domain.ncells_active; i++) { - l2x_vic[i].l2x_Sl_avsdr = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_anidr = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_avsdf = all_vars[i].gc_avg.avg_albedo; - l2x_vic[i].l2x_Sl_anidf = all_vars[i].gc_avg.avg_albedo; + l2x_vic[i].l2x_Sl_avsdr = all_vars[i].gridcell_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidr = all_vars[i].gridcell_avg.avg_albedo; + l2x_vic[i].l2x_Sl_avsdf = all_vars[i].gridcell_avg.avg_albedo; + l2x_vic[i].l2x_Sl_anidf = all_vars[i].gridcell_avg.avg_albedo; } } From 33421a60036fa514efeb636dc442bdbaee53adb6 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Sun, 30 Apr 2017 18:35:58 -0700 Subject: [PATCH 147/294] test out travis test failure precision issue --- vic/vic_run/src/calc_gridcell_avg_albedo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index 678290f7e..aa5eace42 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -71,7 +71,7 @@ calc_gridcell_avg_albedo(double *albedo, *albedo = 1.0 - (swnet / shortwave); } else { - *albedo = 0.0; + *albedo = 0.00001; } } From 08903ffad302d7760ef039833f81a031edf7a9b9 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 May 2017 13:04:25 -0700 Subject: [PATCH 148/294] update actual all_vars struct rather than just local pointer and remove travis test debugging value from calc_gridcell_avg_albedo --- vic/vic_run/src/calc_gridcell_avg_albedo.c | 2 +- vic/vic_run/src/vic_run.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index aa5eace42..678290f7e 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -71,7 +71,7 @@ calc_gridcell_avg_albedo(double *albedo, *albedo = 1.0 - (swnet / shortwave); } else { - *albedo = 0.00001; + *albedo = 0.0; } } diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 0ef952632..d84304ef0 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -93,7 +93,6 @@ vic_run(force_data_struct *force, veg_var_struct **veg_var; energy_bal_struct **energy; snow_data_struct **snow; - gridcell_avg_struct gridcell_avg; // assign vic_run_veg_lib to veg_lib, so that the veg_lib for the correct // grid cell is used within vic_run. For simplicity sake, use vic_run_veg_lib @@ -106,7 +105,6 @@ vic_run(force_data_struct *force, lake_var = &all_vars->lake_var; snow = all_vars->snow; veg_var = all_vars->veg_var; - gridcell_avg = all_vars->gridcell_avg; Nbands = options.SNOW_BAND; @@ -385,7 +383,7 @@ vic_run(force_data_struct *force, } // Compute gridcell-averaged albedo - calc_gridcell_avg_albedo(&gridcell_avg.avg_albedo, + calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, force->shortwave[NR], Nveg, energy, veg_con, soil_con); From ffeb046af5d77cb29fd2148fd80657a34738d57e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 May 2017 16:07:33 -0700 Subject: [PATCH 149/294] add AreaFactor to weight swnet --- vic/vic_run/src/calc_gridcell_avg_albedo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index 678290f7e..bdd23b439 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -59,7 +59,7 @@ calc_gridcell_avg_albedo(double *albedo, // TO-DO: account for treeline and lake factors AreaFactor = (Cv * soil_con->AreaFract[band] * TreeAdjustFactor * lakefactor); - swnet += energy[veg][band].NetShortAtmos; + swnet += energy[veg][band].NetShortAtmos * AreaFactor; } } } @@ -67,11 +67,11 @@ calc_gridcell_avg_albedo(double *albedo, // compute gridcell-averaged albedo using average longwave // and shortwave over gridcell + if (shortwave > 0) { - *albedo = 1.0 - (swnet / shortwave); + *albedo = 1. - (swnet / shortwave); } else { *albedo = 0.0; } - } From 5225ff0ea1683538be0735408288fea268527acf Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 May 2017 19:36:36 -0700 Subject: [PATCH 150/294] ran uncrustify --- .../shared_all/src/generate_default_state.c | 6 ++-- vic/drivers/shared_all/src/vic_history.c | 2 +- vic/vic_run/src/calc_gridcell_avg_albedo.c | 36 +++++++++---------- vic/vic_run/src/vic_run.c | 8 ++--- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index d2756e5d8..122667cb2 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -145,18 +145,18 @@ generate_default_state(all_vars_struct *all_vars, for (band = 0; band < options.SNOW_BAND; band++) { if (soil_con->AreaFract[band] > 0.) { // TO-DO: account for treeline and lake factors - AreaFactor = (Cv * soil_con->AreaFract[band] * + AreaFactor = (Cv * soil_con->AreaFract[band] * TreeAdjustFactor * lakefactor); // cold start, so assuming bare (free of snow) albedo if (veg != Nveg) { albedo_sum += AreaFactor * veg_var[veg][band].albedo; - } + } else { // this is the bare soil class, so use bare soil albedo parameter albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; } } - } + } } } gridcell_avg.avg_albedo = albedo_sum; diff --git a/vic/drivers/shared_all/src/vic_history.c b/vic/drivers/shared_all/src/vic_history.c index 88c310de1..c05ca8332 100644 --- a/vic/drivers/shared_all/src/vic_history.c +++ b/vic/drivers/shared_all/src/vic_history.c @@ -30,7 +30,7 @@ * @brief This routine creates the list of output data. *****************************************************************************/ void -alloc_out_data(size_t ngridcells, +alloc_out_data(size_t ngridcells, double ***out_data) { extern metadata_struct out_metadata[N_OUTVAR_TYPES]; diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index bdd23b439..df8517fdf 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -1,10 +1,10 @@ /****************************************************************************** * @section DESCRIPTION * - * This routine computes gridcell-averaged albedo. + * This routine computes gridcell-averaged albedo. * - * Note: this routine is specifically designed for the CESM driver, for WRF, - * but has been implemented in other drivers as well for the sake of consistency. + * Note: this routine is specifically designed for the CESM driver, for WRF, + * but has been implemented in other drivers as well for the sake of consistency. * * @section LICENSE * @@ -21,7 +21,7 @@ * 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. @@ -30,24 +30,24 @@ #include /****************************************************************************** - * @brief Compute gridcell-averaged albedo. + * @brief Compute gridcell-averaged albedo. *****************************************************************************/ -void +void calc_gridcell_avg_albedo(double *albedo, - double shortwave, + double shortwave, size_t Nveg, energy_bal_struct **energy, - veg_con_struct *veg_con, + veg_con_struct *veg_con, soil_con_struct *soil_con) { - extern option_struct options; - size_t veg; - size_t band; - double Cv; - double AreaFactor; - double TreeAdjustFactor = 1.; - double lakefactor = 1; - double swnet; + extern option_struct options; + size_t veg; + size_t band; + double Cv; + double AreaFactor; + double TreeAdjustFactor = 1.; + double lakefactor = 1; + double swnet; swnet = 0; @@ -57,7 +57,7 @@ calc_gridcell_avg_albedo(double *albedo, for (band = 0; band < options.SNOW_BAND; band++) { if (soil_con->AreaFract[band] > 0.) { // TO-DO: account for treeline and lake factors - AreaFactor = (Cv * soil_con->AreaFract[band] * + AreaFactor = (Cv * soil_con->AreaFract[band] * TreeAdjustFactor * lakefactor); swnet += energy[veg][band].NetShortAtmos * AreaFactor; } @@ -65,7 +65,7 @@ calc_gridcell_avg_albedo(double *albedo, } } - // compute gridcell-averaged albedo using average longwave + // compute gridcell-averaged albedo using average longwave // and shortwave over gridcell if (shortwave > 0) { diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index d84304ef0..66e7e8b83 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -382,10 +382,10 @@ vic_run(force_data_struct *force, } } - // Compute gridcell-averaged albedo - calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, - force->shortwave[NR], Nveg, energy, - veg_con, soil_con); + // Compute gridcell-averaged albedo + calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, + force->shortwave[NR], Nveg, energy, + veg_con, soil_con); /**************************** Run Lake Model From 335c10b1935b8aaf90e403fc4cdbd0587978effa Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 May 2017 19:46:58 -0700 Subject: [PATCH 151/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 30ea3f1db..16bc318c1 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -51,14 +51,14 @@ To check which release of VIC you are running: 1. Fixes Julian day for the first timestep in the dmy struct for the CESM driver. -3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) - These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. 4. Added two new timers to measure time in I/O operations ([GH#703](https://github.com/UW-Hydro/VIC/pull/703)) These two timers count the CPU and WALL time spent in ``vic_force`` and ``vic_write``. The accumulated time from these timers is printed out at the end of each simulation in the timing table. See also [GH#442](https://github.com/UW-Hydro/VIC/pull/442). +5. Added gridcell-averaged albedo as a state file variable (STATE_AVG_ALBEDO). This is for use in the CESM driver for VIC to pass to WRF, but has been implemented in the core structure of VIC (in vic_run) for consistency with the classic and image drivers. Running VIC from a cold start now also includes calculation of gridcell-averaged albedo. + ## VIC 5.0.1 **Release date: (February 1, 2017)** From 9f04af5c48a6152a13a48c4e4eb36af551d3cb1c Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 May 2017 21:56:21 -0700 Subject: [PATCH 152/294] add PR # to release notes entry --- docs/Development/ReleaseNotes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 16bc318c1..6e02c29dc 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -57,7 +57,9 @@ To check which release of VIC you are running: These two timers count the CPU and WALL time spent in ``vic_force`` and ``vic_write``. The accumulated time from these timers is printed out at the end of each simulation in the timing table. See also [GH#442](https://github.com/UW-Hydro/VIC/pull/442). -5. Added gridcell-averaged albedo as a state file variable (STATE_AVG_ALBEDO). This is for use in the CESM driver for VIC to pass to WRF, but has been implemented in the core structure of VIC (in vic_run) for consistency with the classic and image drivers. Running VIC from a cold start now also includes calculation of gridcell-averaged albedo. +5. Added gridcell-averaged albedo (STATE_AVG_ALBEDO) as a state file variable ([GH#712](https://github.com/UW-Hydro/VIC/pull/712)) + + This is for use in the CESM driver for VIC to pass to WRF, but has been implemented in the core structure of VIC (in vic_run) for consistency with the classic and image drivers. Running VIC from a cold start now also includes calculation of gridcell-averaged albedo. ## VIC 5.0.1 From f6019578d11a2f995e8351234e03c0b6c58b328f Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 19 May 2017 18:57:00 -0400 Subject: [PATCH 153/294] small bug fix to adding albedo to all_vars --- vic/drivers/shared_all/src/generate_default_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 vic/drivers/shared_all/src/generate_default_state.c diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c old mode 100644 new mode 100755 index 122667cb2..9154f206d --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -159,7 +159,7 @@ generate_default_state(all_vars_struct *all_vars, } } } - gridcell_avg.avg_albedo = albedo_sum; + all_vars->gridcell_avg.avg_albedo = albedo_sum; /************************************************************************ Initialize soil layer ice content From 76159bc2b490b9ab4b6c42a5a74f51bb056f2b7e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 19 May 2017 18:59:12 -0400 Subject: [PATCH 154/294] Revert "small bug fix to adding albedo to all_vars" This reverts commit f6019578d11a2f995e8351234e03c0b6c58b328f. --- vic/drivers/shared_all/src/generate_default_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 vic/drivers/shared_all/src/generate_default_state.c diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c old mode 100755 new mode 100644 index 9154f206d..122667cb2 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -159,7 +159,7 @@ generate_default_state(all_vars_struct *all_vars, } } } - all_vars->gridcell_avg.avg_albedo = albedo_sum; + gridcell_avg.avg_albedo = albedo_sum; /************************************************************************ Initialize soil layer ice content From 319f7bf13c6a1f67edba2aeb5741bad584d1227b Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 19 May 2017 19:17:46 -0400 Subject: [PATCH 155/294] small bug fix to adding gridcell averaged albedo to all_vars struct --- vic/drivers/shared_all/src/generate_default_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 122667cb2..9154f206d 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -159,7 +159,7 @@ generate_default_state(all_vars_struct *all_vars, } } } - gridcell_avg.avg_albedo = albedo_sum; + all_vars->gridcell_avg.avg_albedo = albedo_sum; /************************************************************************ Initialize soil layer ice content From f1b50279c133c0e0e7f3f449f7b93f29c9a48eba Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 19 May 2017 17:28:34 -0700 Subject: [PATCH 156/294] update for debug flag and supported machines --- vic/drivers/cesm/readme.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vic/drivers/cesm/readme.md b/vic/drivers/cesm/readme.md index a7814946b..44f6077b3 100644 --- a/vic/drivers/cesm/readme.md +++ b/vic/drivers/cesm/readme.md @@ -42,10 +42,12 @@ The CESM driver for VIC can be built in two ways. git checkout develop # follow typical steps to build RASM + # NOTE: only set DEBUG flag to TRUE if running RI compset + # (it does not work with WRF) cd $HOME/rasm_vic5/scripts today=$(date +'%Y%m%d') - compset=RI - mach=spirit_intel + compset=RI # adjust for compset + mach=spirit_intel # adjust for machine case_name=vic5.${compset}.test.${today}a create_newcase -case ${case_name} -res w5a_a94 -compset ${compset} -mach ${mach} cd ${case_name} @@ -56,7 +58,7 @@ The CESM driver for VIC can be built in two ways. ``` ** Supported Machines ** - - [x] Spirit + - [x] Thunder - [x] Lightning - [x] Garnet - [ ] Copper *(Not currently supported by RASM)* From 5cc2c13019e43ca25c7b933e2ffc50a86f99d655 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 5 Jun 2017 19:04:54 -0400 Subject: [PATCH 157/294] address PR review comments --- docs/Development/ReleaseNotes.md | 30 ++++++++++--------- .../shared_all/src/generate_default_state.c | 2 -- vic/vic_run/src/calc_gridcell_avg_albedo.c | 4 +-- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 6e02c29dc..e81209600 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -29,29 +29,31 @@ To check which release of VIC you are running: [GH#642](https://github.com/UW-Hydro/VIC/pull/642) - 1. Using correct fill value datatypes in MPI Gather steps - 2. Updated state file name time step to be period-ending rather than period-beginning - 3. Set the state file name to the RASM case ID - 4. Removed decimal point for missing values for unsigned integers - 5. Create dummy forcings when initializing the model (so that there is forcing data for the first time step) - 6. Changed pressure units from kPa to Pa - 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` - 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` + 1. Using correct fill value datatypes in MPI Gather steps + 2. Updated state file name time step to be period-ending rather than period-beginning + 3. Set the state file name to the RASM case ID + 4. Removed decimal point for missing values for unsigned integers + 5. Create dummy forcings when initializing the model (so that there is forcing data for the first time step) + 6. Changed pressure units from kPa to Pa + 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` + 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` [GH#695](https://github.com/UW-Hydro/VIC/pull/695) - 1. Fix sign for latent heat fluxes passed from VIC to the coupler - 2. Fix sign for longwave radiation passed from VIC to the coupler + 1. Fix sign for latent heat fluxes passed from VIC to the coupler + 2. Fix sign for longwave radiation passed from VIC to the coupler [GH#696](https://github.com/UW-Hydro/VIC/pull/696) - 1. Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. + Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. - [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) + [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) - 1. Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + Fixes Julian day for the first timestep in the dmy struct for the CESM driver. - These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. +3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) + + These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. 4. Added two new timers to measure time in I/O operations ([GH#703](https://github.com/UW-Hydro/VIC/pull/703)) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 9154f206d..f8e78a3e8 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -64,12 +64,10 @@ generate_default_state(all_vars_struct *all_vars, cell_data_struct **cell; energy_bal_struct **energy; veg_var_struct **veg_var; - gridcell_avg_struct gridcell_avg; cell = all_vars->cell; energy = all_vars->energy; veg_var = all_vars->veg_var; - gridcell_avg = all_vars->gridcell_avg; Nveg = veg_con[0].vegetat_type_num; // allocate memory for tmpT and tmpZ diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index df8517fdf..addd363c3 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -65,9 +65,7 @@ calc_gridcell_avg_albedo(double *albedo, } } - // compute gridcell-averaged albedo using average longwave - // and shortwave over gridcell - + // compute gridcell-averaged albedo using average longwave shortwave if (shortwave > 0) { *albedo = 1. - (swnet / shortwave); } From 5d4bfcc30be719f5be674537ecb6137cc28b4223 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 6 Jun 2017 11:25:48 -0700 Subject: [PATCH 158/294] fix typo in comment --- vic/vic_run/src/calc_gridcell_avg_albedo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index addd363c3..4ae7021e3 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -65,7 +65,7 @@ calc_gridcell_avg_albedo(double *albedo, } } - // compute gridcell-averaged albedo using average longwave shortwave + // compute gridcell-averaged albedo using average shortwave if (shortwave > 0) { *albedo = 1. - (swnet / shortwave); } From 6728d96e499746996cf514ad7568e29ecdc8ab8f Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 7 Jun 2017 11:33:26 -0700 Subject: [PATCH 159/294] Feature/refactor cesm put data (#710) * initial stab at refactoring cesm_put_data * further refactoring, adding placeholder for aerodynamical resistances, roughness and wind stresses --- docs/Development/ReleaseNotes.md | 8 +- vic/drivers/cesm/src/cesm_put_data.c | 231 +++++++++++---------------- 2 files changed, 95 insertions(+), 144 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index e81209600..9e3fdf89e 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -47,9 +47,13 @@ To check which release of VIC you are running: Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. - [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) + [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) - Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + + [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) + + Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index da5f1d45f..3c61cff7e 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -44,6 +44,7 @@ vic_cesm_put_data() extern global_param_struct global_param; extern option_struct options; extern parameters_struct param; + extern double ***out_data; bool IsWet = false; // TODO: add lake fraction bool overstory; @@ -63,14 +64,13 @@ vic_cesm_put_data() double wind_stress; double wind_stress_x; double wind_stress_y; - double evap; cell_data_struct cell; energy_bal_struct energy; snow_data_struct snow; veg_var_struct veg_var; for (i = 0; i < local_domain.ncells_active; i++) { - // Zero l2x vars (leave unused fields as MISSING values) + // Zero l2x vars l2x_vic[i].l2x_Sl_t = 0; l2x_vic[i].l2x_Sl_tref = 0; l2x_vic[i].l2x_Sl_qref = 0; @@ -80,7 +80,7 @@ vic_cesm_put_data() l2x_vic[i].l2x_Sl_anidf = 0; l2x_vic[i].l2x_Sl_snowh = 0; l2x_vic[i].l2x_Sl_u10 = 0; - // l2x_vic[i].l2x_Sl_ddvel = 0; + l2x_vic[i].l2x_Sl_ddvel = 0; l2x_vic[i].l2x_Sl_fv = 0; l2x_vic[i].l2x_Sl_ram1 = 0; l2x_vic[i].l2x_Sl_logz0 = 0; @@ -91,14 +91,84 @@ vic_cesm_put_data() l2x_vic[i].l2x_Fall_lwup = 0; l2x_vic[i].l2x_Fall_evap = 0; l2x_vic[i].l2x_Fall_swnet = 0; - // l2x_vic[i].l2x_Fall_fco2_lnd = 0; - // l2x_vic[i].l2x_Fall_flxdst1 = 0; - // l2x_vic[i].l2x_Fall_flxdst2 = 0; - // l2x_vic[i].l2x_Fall_flxdst3 = 0; - // l2x_vic[i].l2x_Fall_flxdst4 = 0; - // l2x_vic[i].l2x_Fall_flxvoc = 0; + l2x_vic[i].l2x_Fall_fco2_lnd = 0; + l2x_vic[i].l2x_Fall_flxdst1 = 0; + l2x_vic[i].l2x_Fall_flxdst2 = 0; + l2x_vic[i].l2x_Fall_flxdst3 = 0; + l2x_vic[i].l2x_Fall_flxdst4 = 0; + l2x_vic[i].l2x_Fall_flxvoc = 0; l2x_vic[i].l2x_Flrl_rofliq = 0; - // l2x_vic[i].l2x_Flrl_rofice = 0; + l2x_vic[i].l2x_Flrl_rofice = 0; + + // populate reference values + + // 10m wind, VIC: m/s, CESM: m/s + l2x_vic[i].l2x_Sl_u10 = out_data[i][OUT_WIND][0]; + + // 2m reference temperature, VIC: C, CESM: K + l2x_vic[i].l2x_Sl_tref = out_data[i][OUT_AIR_TEMP][0] + CONST_TKFRZ; + + // 2m reference specific humidity, VIC: kg/kg, CESM: g/g + l2x_vic[i].l2x_Sl_qref = CONST_EPS * + out_data[i][OUT_VP][0] / + out_data[i][OUT_PRESSURE][0]; + + // band-specific quantities + // note that these include a veg correction (AreaFactor) + // that is already in the put_data routine + + // temperature, VIC: K, CESM: K + l2x_vic[i].l2x_Sl_t = out_data[i][OUT_RAD_TEMP][0]; + + // albedo, VIC: fraction, CESM: fraction + // Note: VIC does not partition its albedo, thus all types are + // the same value + // TBD: this will be fixed in a subsequent PR + albedo = out_data[i][OUT_ALBEDO][0]; + + // albedo: direct, visible + l2x_vic[i].l2x_Sl_avsdr = albedo; + + // albedo: direct , near-ir + l2x_vic[i].l2x_Sl_anidr = albedo; + + // albedo: diffuse, visible + l2x_vic[i].l2x_Sl_avsdf = albedo; + + // albedo: diffuse, near-ir + l2x_vic[i].l2x_Sl_anidf = albedo; + + // snow height, VIC: mm, CESM: m + // convert to VIC units + l2x_vic[i].l2x_Sl_snowh = out_data[i][OUT_SWE][0] / MM_PER_M; + + // net shortwave, VIC: W/m2, CESM: W/m2 + l2x_vic[i].l2x_Fall_swnet = out_data[i][OUT_SWNET][0]; + + // longwave up, VIC: W/m2, CESM: W/m2 + // adjust sign for CESM sign convention + l2x_vic[i].l2x_Fall_lwup = -1 * + (out_data[i][OUT_LWDOWN][0] - + out_data[i][OUT_LWNET][0]); + + // turbulent heat fluxes + // latent heat, VIC: W/m2, CESM: W/m2 + l2x_vic[i].l2x_Fall_lat = out_data[i][OUT_LATENT][0]; + + // sensible heat, VIC: W/m2, CESM: W/m2 + l2x_vic[i].l2x_Fall_sen += -1 * out_data[i][OUT_SENSIBLE][0]; + + // evaporation, VIC: mm, CESM: kg m-2 s-1 + // TO-DO should we incorporate bare soil evap? + l2x_vic[i].l2x_Fall_evap += -1 * + (out_data[i][OUT_EVAP][0] * MM_PER_M / + global_param.dt); + + // lnd->rtm input fluxes + l2x_vic[i].l2x_Flrl_rofliq = out_data[i][OUT_RUNOFF][0] + + out_data[i][OUT_BASEFLOW][0] / + global_param.dt; + // running sum to make sure we get the full grid cell AreaFactorSum = 0; @@ -128,72 +198,8 @@ vic_cesm_put_data() } AreaFactorSum += AreaFactor; - // temperature - // CESM units: K - if (overstory && snow.snow && !(options.LAKES && IsWet)) { - rad_temp = energy.Tfoliage + CONST_TKFRZ; - } - else { - rad_temp = energy.Tsurf + CONST_TKFRZ; - } - l2x_vic[i].l2x_Sl_t += AreaFactor * rad_temp; - - // 2m reference temperature - // CESM units: K - l2x_vic[i].l2x_Sl_tref += AreaFactor * - (force[i].air_temp[NR] + CONST_TKFRZ); - - // 2m reference specific humidity - // CESM units: g/g - l2x_vic[i].l2x_Sl_qref += AreaFactor * CONST_EPS * - force[i].vp[NR] / - force[i].pressure[NR]; - - // Albedo Note: VIC does not partition its albedo, all returned - // values will be the same - - // albedo: direct, visible - // CESM units: unitless - // force->shortwave is the incoming shortwave (+ down) - // force->NetShortAtmos net shortwave flux (+ down) - // SWup = force->shortwave[NR] - energy.NetShortAtmos - // Set the albedo to zero for the case where there is no shortwave down - if (force[i].shortwave[NR] > 0.) { - albedo = AreaFactor * - (force[i].shortwave[NR] - energy.NetShortAtmos) / - force[i].shortwave[NR]; - } - else { - albedo = 0.; - } - l2x_vic[i].l2x_Sl_avsdr += albedo; - - // albedo: direct , near-ir - // CESM units: unitless - l2x_vic[i].l2x_Sl_anidr += albedo; - - // albedo: diffuse, visible - // CESM units: unitless - l2x_vic[i].l2x_Sl_avsdf += albedo; - - // albedo: diffuse, near-ir - // CESM units: unitless - l2x_vic[i].l2x_Sl_anidf += albedo; - - // snow height - // CESM units: m - l2x_vic[i].l2x_Sl_snowh += AreaFactor * snow.depth; - - // 10m wind - // CESM units: m/s - l2x_vic[i].l2x_Sl_u10 += AreaFactor * force[i].wind[NR]; - - // dry deposition velocities (optional) - // CESM units: ? - // l2x_vic[i].l2x_Sl_ddvel; - - // aerodynamical resistance - // CESM units: s/m + // aerodynamical resistance, VIC: s/m, CESM: s/m + // TO-DO: update in future PR if (overstory) { aero_resist = cell.aero_resist[1]; } @@ -232,13 +238,13 @@ vic_cesm_put_data() // wind stress, zonal // CESM units: N m-2 - wind_stress_x = -1 * force[i].density[NR] * + wind_stress_x = -1 * out_data[i][OUT_DENSITY][0] * x2l_vic[i].x2l_Sa_u / aero_resist; l2x_vic[i].l2x_Fall_taux += AreaFactor * wind_stress_x; // wind stress, meridional // CESM units: N m-2 - wind_stress_y = -1 * force[i].density[NR] * + wind_stress_y = -1 * out_data[i][OUT_DENSITY][0] * x2l_vic[i].x2l_Sa_v / aero_resist; l2x_vic[i].l2x_Fall_tauy += AreaFactor * wind_stress_y; @@ -247,73 +253,14 @@ vic_cesm_put_data() wind_stress = sqrt(pow(wind_stress_x, 2) + pow(wind_stress_y, 2)); l2x_vic[i].l2x_Sl_fv += AreaFactor * - (wind_stress / force[i].density[NR]); - - // latent heat flux - // CESM units: W m-2 - l2x_vic[i].l2x_Fall_lat += AreaFactor * energy.AtmosLatent; - - // sensible heat flux - // CESM units: W m-2 - l2x_vic[i].l2x_Fall_sen += -1 * AreaFactor * - energy.AtmosSensible; - - // upward longwave heat flux - // CESM units: W m-2 - l2x_vic[i].l2x_Fall_lwup += -1 * AreaFactor * - (force[i].longwave[NR] - - energy.NetLongAtmos); - - // evaporation water flux - // CESM units: kg m-2 s-1 - evap = 0.0; - for (index = 0; index < options.Nlayer; index++) { - evap += cell.layer[index].evap; - } - evap += snow.vapor_flux * MM_PER_M; - if (HasVeg) { - evap += snow.canopy_vapor_flux * MM_PER_M; - evap += veg_var.canopyevap; - } - l2x_vic[i].l2x_Fall_evap += -1 * AreaFactor * evap / - global_param.dt; - - // heat flux shortwave net - l2x_vic[i].l2x_Fall_swnet += AreaFactor * - (force[i].shortwave[NR] - - energy.NetShortAtmos); - - // co2 flux **For testing set to 0 - // l2x_vic[i].l2x_Fall_fco2_lnd; - - // dust flux size bin 1 - // l2x_vic[i].l2x_Fall_flxdst1; - - // dust flux size bin 2 - // l2x_vic[i].l2x_Fall_flxdst2; - - // dust flux size bin 3 - // l2x_vic[i].l2x_Fall_flxdst3; - - // dust flux size bin 4 - // l2x_vic[i].l2x_Fall_flxdst4; - - // MEGAN fluxes - // l2x_vic[i].l2x_Fall_flxvoc; - - // lnd->rtm input fluxes - l2x_vic[i].l2x_Flrl_rofliq += AreaFactor * - (cell.runoff + - cell.baseflow) / global_param.dt; - - // lnd->rtm input fluxes - // l2x_vic[i].l2x_Flrl_rofice; - - // vars set flag - l2x_vic[i].l2x_vars_set = true; + (wind_stress / + out_data[i][OUT_DENSITY][0]); } } + // set variables-set flag + l2x_vic[i].l2x_vars_set = true; + if (!assert_close_double(AreaFactorSum, 1., 0., 1e-3)) { log_warn("AreaFactorSum (%f) is not 1", AreaFactorSum); From ec96d1ffa87a074efbd9aba80d6692f746713320 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 12 Jul 2017 09:46:22 -0700 Subject: [PATCH 160/294] Feature/fix initialization of coupler fields (#716) * initialize coupler fields * update lwup calculation to include emissivity * ran uncrustify * add release notes entry * update stefan-boltzmann constant and add negative sign to lwup * use bare soil albedo if no incoming shortwave * remove stefan boltzmann constant from vic_driver_cesm.h * go back to setting coupler fields to SHR_CONST_SPVAL * ran uncrustify * Revert "use bare soil albedo if no incoming shortwave" This reverts commit d99a92977ab30cd219dc283fa104c23020bc38df. * fix typo --- docs/Development/ReleaseNotes.md | 4 ++ vic/drivers/cesm/include/vic_driver_cesm.h | 4 +- vic/drivers/cesm/src/cesm_interface_c.c | 6 +++ vic/drivers/cesm/src/vic_cesm_init_library.c | 42 +++++++++++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 9e3fdf89e..53cc57f50 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -55,6 +55,10 @@ To check which release of VIC you are running: Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. + [GH#716] (https://github.com/UW-Hydro/VIC/pull/716) + + Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. + 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index 8601edf1e..ef29d6ee8 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -185,8 +185,10 @@ void vic_force(void); void vic_cesm_put_data(void); void vic_cesm_run_model(void); void vic_cesm_start(vic_clock *vclock, case_metadata *cmeta); +void vic_initialize_albedo(void); +void vic_initialize_lwup(void); +void vic_initialize_temperature(void); void vic_populate_model_state(char *runtype_str); void write_rpointer_file(char *fname); -void vic_initialize_albedo(void); #endif diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 5eebd33d8..0061d9885 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -105,6 +105,12 @@ vic_cesm_init(vic_clock *vclock, // initialize albedo vic_initialize_albedo(); + // initialize temperature + vic_initialize_temperature(); + + // initialize upwelling longwave + vic_initialize_lwup(); + // initialization is complete, print settings log_info( "Initialization is complete, print global param and options structures"); diff --git a/vic/drivers/cesm/src/vic_cesm_init_library.c b/vic/drivers/cesm/src/vic_cesm_init_library.c index afd2170a7..ab2b73d23 100644 --- a/vic/drivers/cesm/src/vic_cesm_init_library.c +++ b/vic/drivers/cesm/src/vic_cesm_init_library.c @@ -88,7 +88,7 @@ initialize_l2x_data(void) size_t i; - log_info("Setting all l2x fields to %f", SHR_CONST_SPVAL); + log_info("Initializing l2x_data_struct"); for (i = 0; i < local_domain.ncells_active; i++) { l2x_vic[i].l2x_Sl_t = SHR_CONST_SPVAL; @@ -144,3 +144,43 @@ vic_initialize_albedo(void) l2x_vic[i].l2x_Sl_anidf = all_vars[i].gridcell_avg.avg_albedo; } } + +/***************************************************************************** + * @brief Initialize temperature in l2x_data_struct. + ****************************************************************************/ +void +vic_initialize_temperature(void) +{ + extern l2x_data_struct *l2x_vic; + extern domain_struct local_domain; + extern soil_con_struct *soil_con; + + size_t i; + + log_info("Initializing temperature"); + + for (i = 0; i < local_domain.ncells_active; i++) { + l2x_vic[i].l2x_Sl_t = soil_con[i].avg_temp + CONST_TKFRZ; + } +} + +/***************************************************************************** + * @brief Initialize upwelling longwave in l2x_data_struct. + ****************************************************************************/ +void +vic_initialize_lwup(void) +{ + extern l2x_data_struct *l2x_vic; + extern domain_struct local_domain; + extern parameters_struct param; + + size_t i; + + log_info("Initializing upwelling longwave"); + + for (i = 0; i < local_domain.ncells_active; i++) { + // adjust sign for CESM sign convention + l2x_vic[i].l2x_Fall_lwup = -1 * param.EMISS_GRND * CONST_STEBOL * pow( + l2x_vic[i].l2x_Sl_t, 4); + } +} From f55555168fc9d161f05f3b5a16be20b36f32fb01 Mon Sep 17 00:00:00 2001 From: Ted Bohn Date: Wed, 12 Jul 2017 13:14:20 -0700 Subject: [PATCH 161/294] Cleanup after merging with develop, which seemed to have removed my changes. --- vic/vic_run/src/vic_run.c | 234 ++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 123 deletions(-) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 66e7e8b83..565ab0789 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -47,7 +47,6 @@ vic_run(force_data_struct *force, extern parameters_struct param; char overstory; - int j; size_t lidx; unsigned short iveg; size_t Nveg; @@ -55,9 +54,9 @@ vic_run(force_data_struct *force, unsigned short band; size_t Nbands; int ErrorFlag; - double out_prec[2 * MAX_BANDS]; - double out_rain[2 * MAX_BANDS]; - double out_snow[2 * MAX_BANDS]; + double out_prec[MAX_BANDS]; + double out_rain[MAX_BANDS]; + double out_snow[MAX_BANDS]; double dp; double ice0[MAX_BANDS]; double moist0[MAX_BANDS]; @@ -70,7 +69,7 @@ vic_run(force_data_struct *force, double aero_resist[3]; double Cv; double Le; - double Melt[2 * MAX_BANDS]; + double Melt[MAX_BANDS]; double bare_albedo; double snow_inflow[MAX_BANDS]; double rainonly; @@ -108,7 +107,7 @@ vic_run(force_data_struct *force, Nbands = options.SNOW_BAND; - /* Set number of vegetation types */ + /* Set number of vegetation tiles */ Nveg = veg_con[0].vegetat_type_num; /** Set Damping Depth **/ @@ -129,28 +128,23 @@ vic_run(force_data_struct *force, force->out_rain = 0; force->out_snow = 0; - // Convert LAI from global to local - for (iveg = 0; iveg < Nveg; iveg++) { - veg_class = veg_con[iveg].veg_class; - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].LAI /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdew /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax = veg_var[iveg][band].LAI * - param.VEG_LAI_WATER_FACTOR; - snow[iveg][band].snow_canopy /= veg_var[iveg][band].fcanopy; - } - } - /************************************************** Solve Energy and/or Water Balance for Each - Vegetation Type + Vegetation Tile **************************************************/ for (iveg = 0; iveg <= Nveg; iveg++) { - /** Solve Veg Type only if Coverage Greater than 0% **/ + /** Solve Veg Tile only if Coverage Greater than 0% **/ if (veg_con[iveg].Cv > 0.0) { Cv = veg_con[iveg].Cv; Nbands = options.SNOW_BAND; + /** Define vegetation class number **/ + veg_class = veg_con[iveg].veg_class; + + /************************************************** + Initialize Model Parameters + **************************************************/ + /** Lake-specific processing **/ if (veg_con[iveg].LAKE) { /* Update areai to equal new ice area from previous time step. */ @@ -179,66 +173,10 @@ vic_run(force_data_struct *force, } } - /************************************************** - Initialize Model Parameters - **************************************************/ - - for (band = 0; band < Nbands; band++) { - if (soil_con->AreaFract[band] > 0) { - /* Initialize energy balance variables */ - energy[iveg][band].shortwave = 0; - energy[iveg][band].longwave = 0.; - - /* Initialize snow variables */ - snow[iveg][band].vapor_flux = 0.; - snow[iveg][band].canopy_vapor_flux = 0.; - snow_inflow[band] = 0.; - Melt[band * 2] = 0.; - } - } - - /* Initialize precipitation storage */ - for (j = 0; j < 2 * MAX_BANDS; j++) { - out_prec[j] = 0; - out_rain[j] = 0; - out_snow[j] = 0; - } - - /** Define vegetation class number **/ - veg_class = veg_con[iveg].veg_class; - - /** Initialize other veg vars **/ - if (iveg < Nveg) { - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].rc = param.HUGE_RESIST; - } - } - /** Assign wind_h **/ /** Note: this is ignored below **/ wind_h = vic_run_veg_lib[veg_class].wind_h; - /** Compute Surface Attenuation due to Vegetation Coverage **/ - surf_atten = (1 - veg_var[iveg][0].fcanopy) * 1.0 + - veg_var[iveg][0].fcanopy * - exp(-vic_run_veg_lib[veg_class].rad_atten * - veg_var[iveg][0].LAI); - - /* Initialize soil thermal properties for the top two layers */ - prepare_full_energy(iveg, all_vars, soil_con, moist0, ice0); - - /** Compute Bare (free of snow) Albedo **/ - if (iveg != Nveg) { - bare_albedo = veg_var[iveg][0].albedo; - } - else { - bare_albedo = param.ALBEDO_BARE_SOIL; - } - - /************************************* - Compute the aerodynamic resistance - *************************************/ - /* Initialize wind speeds */ tmp_wind[0] = force->wind[NR]; tmp_wind[1] = MISSING; @@ -275,60 +213,113 @@ vic_run(force_data_struct *force, return (ERROR); } - /* Initialize final aerodynamic resistance values */ + /** Compute Surface Attenuation due to Vegetation Coverage **/ + surf_atten = (1 - veg_var[iveg][0].fcanopy) * 1.0 + + veg_var[iveg][0].fcanopy * + exp(-vic_run_veg_lib[veg_class].rad_atten * + veg_var[iveg][0].LAI); + + /* Initialize soil thermal properties for the top two layers */ + prepare_full_energy(iveg, all_vars, soil_con, moist0, ice0); + + /** Compute Bare (free of snow) Albedo **/ + if (iveg != Nveg) { + bare_albedo = veg_var[iveg][0].albedo; + } + else { + bare_albedo = param.ALBEDO_BARE_SOIL; + } + + /************************************************** + Loop over elevation bands + **************************************************/ for (band = 0; band < Nbands; band++) { + /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { + + /****************************************** + Initialize Band-dependent Model Parameters + ******************************************/ + + /* Initialize final aerodynamic resistance values */ cell[iveg][band].aero_resist[0] = aero_resist[0]; cell[iveg][band].aero_resist[1] = aero_resist[1]; - } - } - // Compute nitrogen scaling factors and initialize other veg vars - if (options.CARBON && iveg < Nveg) { - for (band = 0; band < Nbands; band++) { - for (cidx = 0; cidx < options.Ncanopy; cidx++) { - veg_var[iveg][band].rsLayer[cidx] = param.HUGE_RESIST; - } - veg_var[iveg][band].aPAR = 0; - calc_Nscale_factors( - vic_run_veg_lib[veg_class].NscaleFlag, - veg_con[iveg].CanopLayerBnd, - veg_var[iveg][band].LAI, - force->coszen[NR], - veg_var[iveg][band].NscaleFactor); - // TBD: move this outside of vic_run() - if (dmy->day_in_year == 1) { - veg_var[iveg][band].AnnualNPPPrev = - veg_var[iveg][band].AnnualNPP; - veg_var[iveg][band].AnnualNPP = 0; - } - } - } + /* Initialize pot_evap */ + cell[iveg][band].pot_evap = 0; - /****************************** - Solve ground surface fluxes - ******************************/ + // Convert LAI from global to local + veg_var[iveg][band].LAI /= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdew /= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdmax = veg_var[iveg][band].LAI * + param.VEG_LAI_WATER_FACTOR; + snow[iveg][band].snow_canopy /= veg_var[iveg][band].fcanopy; + + /** Initialize other veg vars **/ + if (iveg < Nveg) { + + veg_var[iveg][band].rc = param.HUGE_RESIST; + + /* Carbon-related variables */ + if (options.CARBON) { + + for (cidx = 0; cidx < options.Ncanopy; cidx++) { + veg_var[iveg][band].rsLayer[cidx] = param.HUGE_RESIST; + } + veg_var[iveg][band].aPAR = 0; + + calc_Nscale_factors( + vic_run_veg_lib[veg_class].NscaleFlag, + veg_con[iveg].CanopLayerBnd, + veg_var[iveg][band].LAI, + force->coszen[NR], + veg_var[iveg][band].NscaleFactor); + + // TBD: move this outside of vic_run() + if (dmy->day_in_year == 1) { + veg_var[iveg][band].AnnualNPPPrev = + veg_var[iveg][band].AnnualNPP; + veg_var[iveg][band].AnnualNPP = 0; + } + + } // if options.CARBON + + } // if iveg < Nveg + + /* Initialize energy balance variables */ + energy[iveg][band].shortwave = 0; + energy[iveg][band].longwave = 0.; + + /* Initialize snow variables */ + snow[iveg][band].vapor_flux = 0.; + snow[iveg][band].canopy_vapor_flux = 0.; + snow_inflow[band] = 0.; + Melt[band] = 0.; + + /* Initialize precipitation storage */ + out_prec[band] = 0; + out_rain[band] = 0; + out_snow[band] = 0; + + /****************************** + Solve ground surface fluxes + ******************************/ - for (band = 0; band < Nbands; band++) { - if (soil_con->AreaFract[band] > 0) { lag_one = veg_con[iveg].lag_one; sigma_slope = veg_con[iveg].sigma_slope; fetch = veg_con[iveg].fetch; - /* Initialize pot_evap */ - cell[iveg][band].pot_evap = 0; - ErrorFlag = surface_fluxes(overstory, bare_albedo, ice0[band], moist0[band], - surf_atten, &(Melt[band * 2]), + surf_atten, &(Melt[band]), &Le, aero_resist, displacement, gauge_correction, - &out_prec[band * 2], - &out_rain[band * 2], - &out_snow[band * 2], + &out_prec[band], + &out_rain[band], + &out_snow[band], ref_height, roughness, &snow_inflow[band], tmp_wind, veg_con[iveg].root, @@ -346,11 +337,11 @@ vic_run(force_data_struct *force, } force->out_prec += - out_prec[band * 2] * Cv * soil_con->AreaFract[band]; + out_prec[band] * Cv * soil_con->AreaFract[band]; force->out_rain += - out_rain[band * 2] * Cv * soil_con->AreaFract[band]; + out_rain[band] * Cv * soil_con->AreaFract[band]; force->out_snow += - out_snow[band * 2] * Cv * soil_con->AreaFract[band]; + out_snow[band] * Cv * soil_con->AreaFract[band]; /******************************************************** Compute soil wetness and root zone soil moisture @@ -369,19 +360,16 @@ vic_run(force_data_struct *force, MM_PER_M - soil_con->Wpwp[lidx]); } cell[iveg][band].wetness /= options.Nlayer; + + /* Convert LAI back to global */ + veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; + } /** End non-zero area band **/ } /** End Loop Through Elevation Bands **/ } /** end non-zero area veg tile **/ } /** end of vegetation loop **/ - /* Convert LAI back to global */ - for (iveg = 0; iveg < Nveg; iveg++) { - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; - } - } - // Compute gridcell-averaged albedo calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, force->shortwave[NR], Nveg, energy, From acb99aeee027e50617a0dab14d7b4117a2cd22d9 Mon Sep 17 00:00:00 2001 From: Ted Bohn Date: Wed, 12 Jul 2017 14:05:05 -0700 Subject: [PATCH 162/294] Simplified prepare_full_energy() to operate on a single instance of cell_data and energy_bal structs (removed loop over bands). --- vic/vic_run/include/vic_run.h | 239 +++++++++++++++++--------- vic/vic_run/src/prepare_full_energy.c | 100 +++++------ vic/vic_run/src/vic_run.c | 25 +-- 3 files changed, 211 insertions(+), 153 deletions(-) diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 8dc48c706..236dae0a6 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -41,87 +41,105 @@ void alblake(double, double, double *, double *, double *, double *, double, double, double, unsigned int *, double, bool *, unsigned short int, double); double arno_evap(layer_data_struct *, double, double, double, double, double, - double, double, double, double, double, double *); + double, double, double, double, double, + double *); bool assert_close_double(double x, double y, double rtol, double abs_tol); bool assert_close_float(float x, float y, float rtol, float abs_tol); double calc_atmos_energy_bal(double, double, double, double, double, double, double, double, double, double, double, double, - double, double *, double *, double *, double *, - double *, double *, bool *, unsigned int*); + double, double *, double *, + double *, double *, double *, double *, bool *, + unsigned int*); double calc_density(double); void calc_gridcell_avg_albedo(double *, double, size_t, energy_bal_struct **, - veg_con_struct *, soil_con_struct *); + veg_con_struct *, + soil_con_struct *); double calc_latent_heat_of_sublimation(double temp); double calc_latent_heat_of_vaporization(double temp); int calc_layer_average_thermal_props(energy_bal_struct *, layer_data_struct *, - soil_con_struct *, size_t, double *); + soil_con_struct *, size_t, + double *); double calc_outgoing_longwave(double temp, double emis); double calc_scale_height(double tair, double elevation); -double calc_sensible_heat(double atmos_density, double t1, double t0, - double Ra); +double calc_sensible_heat(double atmos_density, double t1, double t0, double Ra); void calc_Nscale_factors(bool, double *, double, double, double *); double calc_rainonly(double, double, double, double); double calc_rc(double, double, double, double, double, double, double, char); void calc_rc_ps(char, double, double, double, double *, double, double, double *, double, double, double *, double, double, double, - double *, double *); + double *, + double *); double calc_snow_coverage(bool *, double, double, double, double, double, double, double, double *, double, double *, double *, double *); int calc_soil_thermal_fluxes(int, double *, double *, char *, unsigned int *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, - double *, int, int, int); + double *, double *, double *, + double *, double *, double *, int, int, + int); double calc_surf_energy_bal(double, double, double, double, double, double, double, double, double, double, double, double, + double, double, double, double, double, double, double, double, double, double, - double, double, double, double, double, double *, - double *, double *, double *, double *, double *, - double, double *, double *, double, double *, - double *, int, int, size_t, size_t, double, size_t, - unsigned short int, int, unsigned short int, - double *, double *, force_data_struct *, - dmy_struct *, energy_bal_struct *, - layer_data_struct *, snow_data_struct *, - soil_con_struct *, veg_var_struct *); + double, double *, double *, + double *, double *, double *, double *, double, + double *, double *, double, + double *, double *, int, int, size_t, size_t, + double, size_t, unsigned short int, + int, unsigned short int, double *, double *, + force_data_struct *, dmy_struct *, + energy_bal_struct *, layer_data_struct *, + snow_data_struct *, soil_con_struct *, + veg_var_struct *); double calc_veg_displacement(double); double calc_veg_height(double); double calc_veg_roughness(double); int CalcAerodynamic(bool, double, double, double, double, double, double *, - double *, double *, double *, double *); + double *, double *, double *, + double *); double CalcBlowingSnow(double, double, unsigned int, double, double, double, double, double, double, double, double, double, double, - double, int, int, double, double, double, double *); + double, int, int, double, + double, double, + double *); double CalcIcePackEnergyBalance(double Tsurf, ...); double CalcSnowPackEnergyBalance(double Tsurf, ...); double CalcSubFlux(double EactAir, double es, double Zrh, double AirDens, double utshear, double ushear, double fe, double Tsnow, - double Tair, double U10, double Zo_salt, double F, + double Tair, double U10, + double Zo_salt, double F, double *Transport); void canopy_assimilation(char, double, double, double, double *, double, double, double *, double, double, double *, double, char *, + double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *); + double *, + double *); double canopy_evap(layer_data_struct *, veg_var_struct *, bool, unsigned short int, double *, double, double, double, double, - double, double, double, double, double *, double *, double *, - double *, double *, double *, double, double, double *); -void colavg(double *, double *, double *, double, double *, int, double, - double); + double, double, + double, double, double *, double *, double *, double *, + double *, double *, + double, double, + double *); +void colavg(double *, double *, double *, double, double *, int, double, double); double compute_coszen(double, double, double, unsigned short int, unsigned int); void compute_derived_lake_dimensions(lake_var_struct *, lake_con_struct); void compute_pot_evap(size_t, double, double, double, double, double, double, double, double, double, double *, char, double, double, - double, double *); + double, + double *); void compute_runoff_and_asat(soil_con_struct *, double *, double, double *, double *); double calc_Q12(double, double, double, double, double); void compute_soil_resp(int, double *, double, double, double *, double *, - double, double, double, double *, double *, double *); + double, double, double, double *, double *, + double *); void compute_soil_layer_thermal_properties(layer_data_struct *, double *, double *, double *, double *, double *, double *, double *, - double *, size_t); + double *, + size_t); double compute_zwt(soil_con_struct *, int, double); void correct_precip(double *, double, double, double, double); double darkinhib(double); @@ -129,7 +147,8 @@ int distribute_node_moisture_properties(double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, - double *, int, int, char); + double *, int, int, + char); void eddy(int, double, double *, double *, double, int, double, double); void energycalc(double *, double *, int, double, double, double *, double *, double *); @@ -149,19 +168,25 @@ int ErrorPrintSnowPackEnergyBalance(double, va_list); int ErrorSnowPackEnergyBalance(double Tsurf, ...); void estimate_frost_temperature_and_depth(double ***, double **, double *, double *, double *, double *, double, - size_t, size_t); + size_t, + size_t); int estimate_layer_ice_content(layer_data_struct *, double ***, double **, double *, double *, double *, double *, double *, - size_t, size_t, char); + size_t, size_t, + char); int estimate_layer_temperature(layer_data_struct *, double ***, double **, - double *, double *, size_t, size_t); + double *, double *, size_t, + size_t); int estimate_layer_temperature_quick_flux(layer_data_struct *, double *, double, - double, double, double); + double, double, + double); int estimate_layer_ice_content_quick_flux(layer_data_struct *, double *, double *, double *, double *, - double *, double, char); + double *, double, + char); double estimate_T1(double, double, double, double, double, double, double, - double, double, double); + double, double, + double); void faparl(double *, double, double, double, double, double *, double *); void fda_heat_eqn(double *, double *, int, int, ...); void fdjac3(double *, double *, double *, double *, double *, void (*vecfunc)( @@ -175,8 +200,7 @@ double func_canopy_energy_bal(double, va_list); double func_surf_energy_bal(double, va_list); double (*funcd)(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, - double ushear, - double Zrh); + double ushear, double Zrh); int get_depth(lake_con_struct, double, double *); double get_prob(double Tair, double Age, double SurfaceLiquidWater, double U10); int get_sarea(lake_con_struct, double, double *); @@ -186,22 +210,29 @@ int get_volume(lake_con_struct, double, double *); double hiTinhib(double); int ice_melt(double, double, double *, double, snow_data_struct *, lake_var_struct *, double, double, double, double, double, double, + double, double, double, double, double, double, double, double, double, - double, double *, double *, double *, double *, double *, double *, - double *, double *, double *); + double *, + double *, double *, double *, double *, double *, double *, + double *, + double *); double IceEnergyBalance(double, va_list); void iceform(double *, double *, double, double, double *, int, double, double, - double, double *, double *, double *, double *, double); + double, double *, double *, double *, double *, + double); void icerad(double, double, double, double *, double *, double *); void initialize_lake(lake_var_struct *, lake_con_struct, soil_con_struct *, - cell_data_struct *, bool); + cell_data_struct *, + bool); int lakeice(double, double, double, double, double, double *, double, double *, - double *, double, double); + double *, double, + double); void latent_heat_from_snow(double, double, double, double, double, double, double, double *, double *, double *, double *, double *); void latsens(double, double, double, double, double, double, double, double, - double *, double *, double); + double *, double *, + double); double linear_interp(double, double, double, double, double); double lkdrag(double, double, double, double, double); void malloc_2d_double(size_t *shape, double ***array); @@ -209,18 +240,21 @@ void malloc_3d_double(size_t *shape, double ****array); void MassRelease(double *, double *, double *, double *); double maximum_unfrozen_water(double, double, double, double); double new_snow_density(double); -int newt_raph(void (*vecfunc)(double *, double *, int, int, - ...), double *, int); +int newt_raph(void (*vecfunc)(double *, double *, int, int, ...), double *, int); double penman(double, double, double, double, double, double, double); void photosynth(char, double, double, double, double, double, double, double, double, double, char *, double *, double *, double *, double *, double *); void polint(double xa[], double ya[], int n, double x, double *y, double *dy); -void prepare_full_energy(int, all_vars_struct *, soil_con_struct *, double *, +void prepare_full_energy(cell_data_struct *, energy_bal_struct *, + soil_con_struct *, double *, double *); double qromb( - double (*sub_with_height)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, - double b); + double (*sub_with_height)(), double es, double Wind, double AirDens, + double ZO, + double EactAir, double F, double hsalt, double phi_r, double ushear, + double Zrh, + double a, double b); void rescale_snow_energy_fluxes(double, double, snow_data_struct *, energy_bal_struct *); void rescale_snow_storage(double, double, snow_data_struct *); @@ -230,32 +264,42 @@ void rhoinit(double *, double); double root_brent(double, double, double (*Function)(double, va_list), ...); double rtnewt(double x1, double x2, double xacc, double Ur, double Zr); int runoff(cell_data_struct *, energy_bal_struct *, soil_con_struct *, double, - double *, int); + double *, + int); void set_node_parameters(double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, - double *, int, int); + double *, int, + int); void shear_stress(double U10, double ZO, double *ushear, double *Zo_salt, double utshear); double snow_albedo(double, double, double, double, double, int, bool); double snow_density(snow_data_struct *, double, double, double, double); int snow_intercept(double, double, double, double, double, double, double, double, double, double, double *, double *, double *, + double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, double *, - double *, bool *, unsigned int *, double *, double *, + double *, double *, + double *, double *, double *, bool *, unsigned int *, + double *, double *, double *, double *, double *, double *, double *, int, int, - int, int, int, unsigned short int, double *, double *, - force_data_struct *, layer_data_struct *, soil_con_struct *, + int, int, int, + unsigned short int, double *, double *, force_data_struct *, + layer_data_struct *, + soil_con_struct *, veg_var_struct *); int snow_melt(double, double, double, double, double *, double, double *, double, double, double, double, double, double, double, double, - double, double, double, double, double, double *, double *, + double, double, + double, double, double, double *, double *, double *, double *, + double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, int, int, int, + double *, int, int, + int, snow_data_struct *); double SnowPackEnergyBalance(double, va_list); void soil_carbon_balance(soil_con_struct *, energy_bal_struct *, - cell_data_struct *, veg_var_struct *); + cell_data_struct *, + veg_var_struct *); double soil_conductivity(double, double, double, double, double, double, double, double); double soil_thermal_eqn(double, va_list); @@ -264,41 +308,54 @@ double solve_atmos_moist_bal(double, ...); double solve_canopy_energy_bal(double Tfoliage, ...); int solve_lake(double, double, double, double, double, double, double, double, double, double, lake_var_struct *, soil_con_struct, double, - double, dmy_struct, double); + double, dmy_struct, + double); double solve_snow(char, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, + double *, double *, double *, double *, double *, double *, double *, double *, + double *, double *, double *, double *, double *, double *, double *, double *, + double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, double *, - int, size_t, unsigned short int, unsigned short int, double, - size_t, int, int *, double *, double *, dmy_struct *, - force_data_struct *, energy_bal_struct *, layer_data_struct *, - snow_data_struct *, soil_con_struct *, veg_var_struct *); + int, size_t, + unsigned short int, unsigned short int, double, size_t, int, + int *, double *, + double *, dmy_struct *, force_data_struct *, + energy_bal_struct *, + layer_data_struct *, snow_data_struct *, soil_con_struct *, + veg_var_struct *); double solve_surf_energy_bal(double Tsurf, ...); int solve_T_profile(double *, double *, char *, unsigned int *, double *, double *, double *, double *, double, double *, double *, - double *, double *, double *, double *, double *, double, - int, int *, int, int, int); + double *, double *, + double *, double *, double *, double, int, int *, int, int, + int); int solve_T_profile_implicit(double *, double *, char *, unsigned int *, double *, double *, double *, double *, double, + double *, double *, double *, + double *, double *, double *, double *, double, + int, int *, int, int, double *, double *, double *, double *, double *, double *, - double *, double *, double, int, int *, int, int, - double *, double *, double *, double *, double *, - double *, double *); + double *); double specheat(double); double StabilityCorrection(double, double, double, double, double, double); double sub_with_height(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, - double phi_r, double ushear, double Zrh); + double phi_r, double ushear, + double Zrh); int surface_fluxes(bool, double, double, double, double, double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, size_t, - size_t, unsigned short int, double, unsigned short int, - unsigned short int, force_data_struct *, dmy_struct *, + double *, double *, + double *, double *, double *, size_t, size_t, + unsigned short int, double, + unsigned short int, unsigned short int, force_data_struct *, + dmy_struct *, energy_bal_struct *, global_param_struct *, - cell_data_struct *, snow_data_struct *, soil_con_struct *, - veg_var_struct *, double, double, double, double *); + cell_data_struct *, + snow_data_struct *, soil_con_struct *, veg_var_struct *, + double, double, double, + double *); double svp(double); double svp_slope(double); void temp_area(double, double, double, double *, double *, double *, double *, @@ -307,31 +364,41 @@ void temp_area(double, double, double, double *, double *, double *, double *, void tracer_mixer(double *, int *, double *, int, double, double, double *); void transpiration(layer_data_struct *, veg_var_struct *, unsigned short int, double, double, double, double, double, double, double, - double, double *, double *, double *, double *, double *, - double *, double, double, double *); + double, double *, + double *, double *, double *, double *, double *, double, + double, + double *); double transport_with_height(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, - double phi_r, double ushear, double Zrh); + double phi_r, double ushear, + double Zrh); double trapzd( - double (*funcd)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, double b, - int n); + double (*funcd)(), double es, double Wind, double AirDens, double ZO, + double EactAir, double F, double hsalt, double phi_r, double ushear, + double Zrh, + double a, double b, int n); void tridia(int, double *, double *, double *, double *, double *); void tridiag(double *, double *, double *, double *, unsigned int); int vic_run(force_data_struct *, all_vars_struct *, dmy_struct *, global_param_struct *, lake_con_struct *, soil_con_struct *, - veg_con_struct *, veg_lib_struct *); + veg_con_struct *, + veg_lib_struct *); double volumetric_heat_capacity(double, double, double, double); int water_balance(lake_var_struct *, lake_con_struct, double, all_vars_struct *, - int, int, double, soil_con_struct, veg_con_struct); + int, int, double, soil_con_struct, + veg_con_struct); int water_energy_balance(int, double *, double *, double, double, double, double, double, double, double, double, double, double, - double, double, double, double *, double *, double *, - double *, double *, double *, double *, double, + double, double, double, + double *, double *, double *, double *, double *, + double *, double *, double, double *, double *, double *, double *, double *, double); int water_under_ice(int, double, double, double *, double *, double, int, double, double, double, double *, double *, double *, - double *, int, double, double, double, double *); + double *, int, double, + double, double, + double *); void wrap_compute_zwt(soil_con_struct *, cell_data_struct *); void write_layer(layer_data_struct *, int, double *); void write_vegvar(veg_var_struct *, int); diff --git a/vic/vic_run/src/prepare_full_energy.c b/vic/vic_run/src/prepare_full_energy.c index 409803c87..33f1c3f38 100644 --- a/vic/vic_run/src/prepare_full_energy.c +++ b/vic/vic_run/src/prepare_full_energy.c @@ -34,78 +34,64 @@ * ground heat flux solution. *****************************************************************************/ void -prepare_full_energy(int iveg, - all_vars_struct *all_vars, - soil_con_struct *soil_con, - double *moist0, - double *ice0) +prepare_full_energy(cell_data_struct *cell, + energy_bal_struct *energy, + soil_con_struct *soil_con, + double *moist0, + double *ice0) { extern option_struct options; - size_t i, band; + size_t i; layer_data_struct *layer = NULL; layer = calloc(options.Nlayer, sizeof(*layer)); check_alloc_status(layer, "Memory allocation error."); - for (band = 0; band < options.SNOW_BAND; band++) { - if (soil_con->AreaFract[band] > 0.0) { - for (i = 0; i < options.Nlayer; i++) { - layer[i] = all_vars->cell[iveg][band].layer[i]; - } - - /* Compute top soil layer moisture content (mm/mm) */ - - moist0[band] = layer[0].moist / (soil_con->depth[0] * MM_PER_M); + for (i = 0; i < options.Nlayer; i++) { + layer[i] = cell->layer[i]; + } - /* Compute top soil layer ice content (mm/mm) */ + /* Compute top soil layer moisture content (mm/mm) */ + *moist0 = layer[0].moist / (soil_con->depth[0] * MM_PER_M); - if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { - if ((all_vars->energy[iveg][band].T[0] + - all_vars->energy[iveg][band].T[1]) / 2. < 0.) { - ice0[band] = moist0[band] - - maximum_unfrozen_water((all_vars->energy[iveg][ - band].T[0] + - all_vars->energy[iveg][ - band].T[1]) / 2., - soil_con->max_moist[0] / - (soil_con->depth[0] * - MM_PER_M), - soil_con->bubble[0], - soil_con->expt[0]); - if (ice0[band] < 0.) { - ice0[band] = 0.; - } - } - else { - ice0[band] = 0.; - } - } - else { - ice0[band] = 0.; + /* Compute top soil layer ice content (mm/mm) */ + if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { + if ((energy->T[0] + energy->T[1]) / 2. < 0.) { + *ice0 = *moist0 - + maximum_unfrozen_water((energy->T[0] + energy->T[1]) / 2., + soil_con->max_moist[0] / + (soil_con->depth[0] * MM_PER_M), + soil_con->bubble[0], + soil_con->expt[0]); + if (*ice0 < 0.) { + *ice0 = 0.; } - - /** Compute Soil Thermal Properties **/ - compute_soil_layer_thermal_properties(layer, soil_con->depth, - soil_con->bulk_dens_min, - soil_con->soil_dens_min, - soil_con->quartz, - soil_con->bulk_density, - soil_con->soil_density, - soil_con->organic, - soil_con->frost_fract, - options.Nlayer); - - /** Save Thermal Conductivities for Energy Balance **/ - all_vars->energy[iveg][band].kappa[0] = layer[0].kappa; - all_vars->energy[iveg][band].Cs[0] = layer[0].Cs; - all_vars->energy[iveg][band].kappa[1] = layer[1].kappa; - all_vars->energy[iveg][band].Cs[1] = layer[1].Cs; } else { - ice0[band] = 0.; + *ice0 = 0.; } } + else { + *ice0 = 0.; + } + + /** Compute Soil Thermal Properties **/ + compute_soil_layer_thermal_properties(layer, soil_con->depth, + soil_con->bulk_dens_min, + soil_con->soil_dens_min, + soil_con->quartz, + soil_con->bulk_density, + soil_con->soil_density, + soil_con->organic, + soil_con->frost_fract, + options.Nlayer); + + /** Save Thermal Conductivities for Energy Balance **/ + energy->kappa[0] = layer[0].kappa; + energy->Cs[0] = layer[0].Cs; + energy->kappa[1] = layer[1].kappa; + energy->Cs[1] = layer[1].Cs; free((char *) layer); } diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 565ab0789..59d529235 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -128,6 +128,13 @@ vic_run(force_data_struct *force, force->out_rain = 0; force->out_snow = 0; + /** initialize moist0 and ice0 **/ + // this could be removed if we make them scalars + for (band = 0; band < options.SNOW_BAND; band++) { + moist0[band] = 0; + ice0[band] = 0; + } + /************************************************** Solve Energy and/or Water Balance for Each Vegetation Tile @@ -219,9 +226,6 @@ vic_run(force_data_struct *force, exp(-vic_run_veg_lib[veg_class].rad_atten * veg_var[iveg][0].LAI); - /* Initialize soil thermal properties for the top two layers */ - prepare_full_energy(iveg, all_vars, soil_con, moist0, ice0); - /** Compute Bare (free of snow) Albedo **/ if (iveg != Nveg) { bare_albedo = veg_var[iveg][0].albedo; @@ -236,11 +240,16 @@ vic_run(force_data_struct *force, for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { - /****************************************** Initialize Band-dependent Model Parameters ******************************************/ + /* Initialize soil thermal properties for the top two layers */ + prepare_full_energy(&(cell[iveg][band]), + &(energy[iveg][band]), + soil_con, &(moist0[band]), + &(ice0[band])); + /* Initialize final aerodynamic resistance values */ cell[iveg][band].aero_resist[0] = aero_resist[0]; @@ -259,14 +268,13 @@ vic_run(force_data_struct *force, /** Initialize other veg vars **/ if (iveg < Nveg) { - veg_var[iveg][band].rc = param.HUGE_RESIST; /* Carbon-related variables */ if (options.CARBON) { - for (cidx = 0; cidx < options.Ncanopy; cidx++) { - veg_var[iveg][band].rsLayer[cidx] = param.HUGE_RESIST; + veg_var[iveg][band].rsLayer[cidx] = + param.HUGE_RESIST; } veg_var[iveg][band].aPAR = 0; @@ -283,9 +291,7 @@ vic_run(force_data_struct *force, veg_var[iveg][band].AnnualNPP; veg_var[iveg][band].AnnualNPP = 0; } - } // if options.CARBON - } // if iveg < Nveg /* Initialize energy balance variables */ @@ -364,7 +370,6 @@ vic_run(force_data_struct *force, /* Convert LAI back to global */ veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; - } /** End non-zero area band **/ } /** End Loop Through Elevation Bands **/ } /** end non-zero area veg tile **/ From 40263f1b5b04f21bcf68228f8240015b1e16e7c9 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 17 Jul 2017 12:47:33 -0700 Subject: [PATCH 163/294] fixes mistake in comment for veg and bare soil albedos (#724) --- vic/drivers/cesm/src/cesm_put_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 3c61cff7e..f4170c3b4 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -222,12 +222,13 @@ vic_cesm_put_data() roughness = soil_con[i].snow_rough; } else if (HasVeg) { - // bare soil roughness + // vegetation roughness roughness = veg_lib[i][veg_con[i][veg].veg_class].roughness[ dmy_current.month - 1]; } else { + // bare soil roughness roughness = soil_con[i].rough; } if (roughness < DBL_EPSILON) { From ffad6a73e1a6a1ed7124b202cfbe60549f42c5f9 Mon Sep 17 00:00:00 2001 From: Ted Bohn Date: Mon, 17 Jul 2017 15:44:38 -0700 Subject: [PATCH 164/294] Removed re-formatting from uncrustify. --- vic/vic_run/include/vic_run.h | 239 ++++++++++++---------------------- 1 file changed, 86 insertions(+), 153 deletions(-) diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 236dae0a6..80f5c3a3e 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -41,105 +41,87 @@ void alblake(double, double, double *, double *, double *, double *, double, double, double, unsigned int *, double, bool *, unsigned short int, double); double arno_evap(layer_data_struct *, double, double, double, double, double, - double, double, double, double, double, - double *); + double, double, double, double, double, double *); bool assert_close_double(double x, double y, double rtol, double abs_tol); bool assert_close_float(float x, float y, float rtol, float abs_tol); double calc_atmos_energy_bal(double, double, double, double, double, double, double, double, double, double, double, double, - double, double *, double *, - double *, double *, double *, double *, bool *, - unsigned int*); + double, double *, double *, double *, double *, + double *, double *, bool *, unsigned int*); double calc_density(double); void calc_gridcell_avg_albedo(double *, double, size_t, energy_bal_struct **, - veg_con_struct *, - soil_con_struct *); + veg_con_struct *, soil_con_struct *); double calc_latent_heat_of_sublimation(double temp); double calc_latent_heat_of_vaporization(double temp); int calc_layer_average_thermal_props(energy_bal_struct *, layer_data_struct *, - soil_con_struct *, size_t, - double *); + soil_con_struct *, size_t, double *); double calc_outgoing_longwave(double temp, double emis); double calc_scale_height(double tair, double elevation); -double calc_sensible_heat(double atmos_density, double t1, double t0, double Ra); +double calc_sensible_heat(double atmos_density, double t1, double t0, + double Ra); void calc_Nscale_factors(bool, double *, double, double, double *); double calc_rainonly(double, double, double, double); double calc_rc(double, double, double, double, double, double, double, char); void calc_rc_ps(char, double, double, double, double *, double, double, double *, double, double, double *, double, double, double, - double *, - double *); + double *, double *); double calc_snow_coverage(bool *, double, double, double, double, double, double, double, double *, double, double *, double *, double *); int calc_soil_thermal_fluxes(int, double *, double *, char *, unsigned int *, double *, double *, double *, double *, double *, - double *, double *, double *, - double *, double *, double *, int, int, - int); + double *, double *, double *, double *, double *, + double *, int, int, int); double calc_surf_energy_bal(double, double, double, double, double, double, double, double, double, double, double, double, - double, double, double, double, double, double, double, double, double, double, - double, double *, double *, - double *, double *, double *, double *, double, - double *, double *, double, - double *, double *, int, int, size_t, size_t, - double, size_t, unsigned short int, - int, unsigned short int, double *, double *, - force_data_struct *, dmy_struct *, - energy_bal_struct *, layer_data_struct *, - snow_data_struct *, soil_con_struct *, - veg_var_struct *); + double, double, double, double, double, double *, + double *, double *, double *, double *, double *, + double, double *, double *, double, double *, + double *, int, int, size_t, size_t, double, size_t, + unsigned short int, int, unsigned short int, + double *, double *, force_data_struct *, + dmy_struct *, energy_bal_struct *, + layer_data_struct *, snow_data_struct *, + soil_con_struct *, veg_var_struct *); double calc_veg_displacement(double); double calc_veg_height(double); double calc_veg_roughness(double); int CalcAerodynamic(bool, double, double, double, double, double, double *, - double *, double *, double *, - double *); + double *, double *, double *, double *); double CalcBlowingSnow(double, double, unsigned int, double, double, double, double, double, double, double, double, double, double, - double, int, int, double, - double, double, - double *); + double, int, int, double, double, double, double *); double CalcIcePackEnergyBalance(double Tsurf, ...); double CalcSnowPackEnergyBalance(double Tsurf, ...); double CalcSubFlux(double EactAir, double es, double Zrh, double AirDens, double utshear, double ushear, double fe, double Tsnow, - double Tair, double U10, - double Zo_salt, double F, + double Tair, double U10, double Zo_salt, double F, double *Transport); void canopy_assimilation(char, double, double, double, double *, double, double, double *, double, double, double *, double, char *, - double *, double *, double *, double *, double *, double *, double *, double *, - double *, - double *); + double *, double *, double *, double *, double *); double canopy_evap(layer_data_struct *, veg_var_struct *, bool, unsigned short int, double *, double, double, double, double, - double, double, - double, double, double *, double *, double *, double *, - double *, double *, - double, double, - double *); -void colavg(double *, double *, double *, double, double *, int, double, double); + double, double, double, double, double *, double *, double *, + double *, double *, double *, double, double, double *); +void colavg(double *, double *, double *, double, double *, int, double, + double); double compute_coszen(double, double, double, unsigned short int, unsigned int); void compute_derived_lake_dimensions(lake_var_struct *, lake_con_struct); void compute_pot_evap(size_t, double, double, double, double, double, double, double, double, double, double *, char, double, double, - double, - double *); + double, double *); void compute_runoff_and_asat(soil_con_struct *, double *, double, double *, double *); double calc_Q12(double, double, double, double, double); void compute_soil_resp(int, double *, double, double, double *, double *, - double, double, double, double *, double *, - double *); + double, double, double, double *, double *, double *); void compute_soil_layer_thermal_properties(layer_data_struct *, double *, double *, double *, double *, double *, double *, double *, - double *, - size_t); + double *, size_t); double compute_zwt(soil_con_struct *, int, double); void correct_precip(double *, double, double, double, double); double darkinhib(double); @@ -147,8 +129,7 @@ int distribute_node_moisture_properties(double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, - double *, int, int, - char); + double *, int, int, char); void eddy(int, double, double *, double *, double, int, double, double); void energycalc(double *, double *, int, double, double, double *, double *, double *); @@ -168,25 +149,19 @@ int ErrorPrintSnowPackEnergyBalance(double, va_list); int ErrorSnowPackEnergyBalance(double Tsurf, ...); void estimate_frost_temperature_and_depth(double ***, double **, double *, double *, double *, double *, double, - size_t, - size_t); + size_t, size_t); int estimate_layer_ice_content(layer_data_struct *, double ***, double **, double *, double *, double *, double *, double *, - size_t, size_t, - char); + size_t, size_t, char); int estimate_layer_temperature(layer_data_struct *, double ***, double **, - double *, double *, size_t, - size_t); + double *, double *, size_t, size_t); int estimate_layer_temperature_quick_flux(layer_data_struct *, double *, double, - double, double, - double); + double, double, double); int estimate_layer_ice_content_quick_flux(layer_data_struct *, double *, double *, double *, double *, - double *, double, - char); + double *, double, char); double estimate_T1(double, double, double, double, double, double, double, - double, double, - double); + double, double, double); void faparl(double *, double, double, double, double, double *, double *); void fda_heat_eqn(double *, double *, int, int, ...); void fdjac3(double *, double *, double *, double *, double *, void (*vecfunc)( @@ -200,7 +175,8 @@ double func_canopy_energy_bal(double, va_list); double func_surf_energy_bal(double, va_list); double (*funcd)(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, - double ushear, double Zrh); + double ushear, + double Zrh); int get_depth(lake_con_struct, double, double *); double get_prob(double Tair, double Age, double SurfaceLiquidWater, double U10); int get_sarea(lake_con_struct, double, double *); @@ -210,29 +186,22 @@ int get_volume(lake_con_struct, double, double *); double hiTinhib(double); int ice_melt(double, double, double *, double, snow_data_struct *, lake_var_struct *, double, double, double, double, double, double, - double, double, double, double, double, double, double, double, double, - double *, - double *, double *, double *, double *, double *, double *, - double *, - double *); + double, double *, double *, double *, double *, double *, double *, + double *, double *, double *); double IceEnergyBalance(double, va_list); void iceform(double *, double *, double, double, double *, int, double, double, - double, double *, double *, double *, double *, - double); + double, double *, double *, double *, double *, double); void icerad(double, double, double, double *, double *, double *); void initialize_lake(lake_var_struct *, lake_con_struct, soil_con_struct *, - cell_data_struct *, - bool); + cell_data_struct *, bool); int lakeice(double, double, double, double, double, double *, double, double *, - double *, double, - double); + double *, double, double); void latent_heat_from_snow(double, double, double, double, double, double, double, double *, double *, double *, double *, double *); void latsens(double, double, double, double, double, double, double, double, - double *, double *, - double); + double *, double *, double); double linear_interp(double, double, double, double, double); double lkdrag(double, double, double, double, double); void malloc_2d_double(size_t *shape, double ***array); @@ -240,21 +209,18 @@ void malloc_3d_double(size_t *shape, double ****array); void MassRelease(double *, double *, double *, double *); double maximum_unfrozen_water(double, double, double, double); double new_snow_density(double); -int newt_raph(void (*vecfunc)(double *, double *, int, int, ...), double *, int); +int newt_raph(void (*vecfunc)(double *, double *, int, int, + ...), double *, int); double penman(double, double, double, double, double, double, double); void photosynth(char, double, double, double, double, double, double, double, double, double, char *, double *, double *, double *, double *, double *); void polint(double xa[], double ya[], int n, double x, double *y, double *dy); void prepare_full_energy(cell_data_struct *, energy_bal_struct *, - soil_con_struct *, double *, - double *); + soil_con_struct *, double *, double *); double qromb( - double (*sub_with_height)(), double es, double Wind, double AirDens, - double ZO, - double EactAir, double F, double hsalt, double phi_r, double ushear, - double Zrh, - double a, double b); + double (*sub_with_height)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, + double b); void rescale_snow_energy_fluxes(double, double, snow_data_struct *, energy_bal_struct *); void rescale_snow_storage(double, double, snow_data_struct *); @@ -264,42 +230,32 @@ void rhoinit(double *, double); double root_brent(double, double, double (*Function)(double, va_list), ...); double rtnewt(double x1, double x2, double xacc, double Ur, double Zr); int runoff(cell_data_struct *, energy_bal_struct *, soil_con_struct *, double, - double *, - int); + double *, int); void set_node_parameters(double *, double *, double *, double *, double *, double *, double *, double *, double *, double *, - double *, int, - int); + double *, int, int); void shear_stress(double U10, double ZO, double *ushear, double *Zo_salt, double utshear); double snow_albedo(double, double, double, double, double, int, bool); double snow_density(snow_data_struct *, double, double, double, double); int snow_intercept(double, double, double, double, double, double, double, double, double, double, double *, double *, double *, - double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, - double *, double *, double *, bool *, unsigned int *, - double *, double *, + double *, double *, double *, double *, double *, double *, + double *, bool *, unsigned int *, double *, double *, double *, double *, double *, double *, double *, int, int, - int, int, int, - unsigned short int, double *, double *, force_data_struct *, - layer_data_struct *, - soil_con_struct *, + int, int, int, unsigned short int, double *, double *, + force_data_struct *, layer_data_struct *, soil_con_struct *, veg_var_struct *); int snow_melt(double, double, double, double, double *, double, double *, double, double, double, double, double, double, double, double, - double, double, - double, double, double, double *, double *, double *, double *, - double *, + double, double, double, double, double, double *, double *, double *, double *, double *, double *, double *, double *, - double *, int, int, - int, + double *, double *, double *, double *, int, int, int, snow_data_struct *); double SnowPackEnergyBalance(double, va_list); void soil_carbon_balance(soil_con_struct *, energy_bal_struct *, - cell_data_struct *, - veg_var_struct *); + cell_data_struct *, veg_var_struct *); double soil_conductivity(double, double, double, double, double, double, double, double); double soil_thermal_eqn(double, va_list); @@ -308,54 +264,41 @@ double solve_atmos_moist_bal(double, ...); double solve_canopy_energy_bal(double Tfoliage, ...); int solve_lake(double, double, double, double, double, double, double, double, double, double, lake_var_struct *, soil_con_struct, double, - double, dmy_struct, - double); + double, dmy_struct, double); double solve_snow(char, double, double, double, double, double, double, double, double, double, double *, double *, double *, double *, - double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, double *, double *, double *, double *, double *, double *, - int, size_t, - unsigned short int, unsigned short int, double, size_t, int, - int *, double *, - double *, dmy_struct *, force_data_struct *, - energy_bal_struct *, - layer_data_struct *, snow_data_struct *, soil_con_struct *, - veg_var_struct *); + double *, double *, double *, double *, double *, double *, + int, size_t, unsigned short int, unsigned short int, double, + size_t, int, int *, double *, double *, dmy_struct *, + force_data_struct *, energy_bal_struct *, layer_data_struct *, + snow_data_struct *, soil_con_struct *, veg_var_struct *); double solve_surf_energy_bal(double Tsurf, ...); int solve_T_profile(double *, double *, char *, unsigned int *, double *, double *, double *, double *, double, double *, double *, - double *, double *, - double *, double *, double *, double, int, int *, int, int, - int); + double *, double *, double *, double *, double *, double, + int, int *, int, int, int); int solve_T_profile_implicit(double *, double *, char *, unsigned int *, double *, double *, double *, double *, double, - double *, double *, double *, - double *, double *, double *, double *, double, - int, int *, int, int, double *, double *, double *, double *, double *, double *, - double *); + double *, double *, double, int, int *, int, int, + double *, double *, double *, double *, double *, + double *, double *); double specheat(double); double StabilityCorrection(double, double, double, double, double, double); double sub_with_height(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, - double phi_r, double ushear, - double Zrh); + double phi_r, double ushear, double Zrh); int surface_fluxes(bool, double, double, double, double, double *, double *, double *, double *, double *, double *, double *, double *, - double *, double *, - double *, double *, double *, size_t, size_t, - unsigned short int, double, - unsigned short int, unsigned short int, force_data_struct *, - dmy_struct *, + double *, double *, double *, double *, double *, size_t, + size_t, unsigned short int, double, unsigned short int, + unsigned short int, force_data_struct *, dmy_struct *, energy_bal_struct *, global_param_struct *, - cell_data_struct *, - snow_data_struct *, soil_con_struct *, veg_var_struct *, - double, double, double, - double *); + cell_data_struct *, snow_data_struct *, soil_con_struct *, + veg_var_struct *, double, double, double, double *); double svp(double); double svp_slope(double); void temp_area(double, double, double, double *, double *, double *, double *, @@ -364,41 +307,31 @@ void temp_area(double, double, double, double *, double *, double *, double *, void tracer_mixer(double *, int *, double *, int, double, double, double *); void transpiration(layer_data_struct *, veg_var_struct *, unsigned short int, double, double, double, double, double, double, double, - double, double *, - double *, double *, double *, double *, double *, double, - double, - double *); + double, double *, double *, double *, double *, double *, + double *, double, double, double *); double transport_with_height(double z, double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, - double phi_r, double ushear, - double Zrh); + double phi_r, double ushear, double Zrh); double trapzd( - double (*funcd)(), double es, double Wind, double AirDens, double ZO, - double EactAir, double F, double hsalt, double phi_r, double ushear, - double Zrh, - double a, double b, int n); + double (*funcd)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, double b, + int n); void tridia(int, double *, double *, double *, double *, double *); void tridiag(double *, double *, double *, double *, unsigned int); int vic_run(force_data_struct *, all_vars_struct *, dmy_struct *, global_param_struct *, lake_con_struct *, soil_con_struct *, - veg_con_struct *, - veg_lib_struct *); + veg_con_struct *, veg_lib_struct *); double volumetric_heat_capacity(double, double, double, double); int water_balance(lake_var_struct *, lake_con_struct, double, all_vars_struct *, - int, int, double, soil_con_struct, - veg_con_struct); + int, int, double, soil_con_struct, veg_con_struct); int water_energy_balance(int, double *, double *, double, double, double, double, double, double, double, double, double, double, - double, double, double, - double *, double *, double *, double *, double *, - double *, double *, double, + double, double, double, double *, double *, double *, + double *, double *, double *, double *, double, double *, double *, double *, double *, double *, double); int water_under_ice(int, double, double, double *, double *, double, int, double, double, double, double *, double *, double *, - double *, int, double, - double, double, - double *); + double *, int, double, double, double, double *); void wrap_compute_zwt(soil_con_struct *, cell_data_struct *); void write_layer(layer_data_struct *, int, double *); void write_vegvar(veg_var_struct *, int); From 1352b6d5a6431332c005275d434611575db251cb Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 3 Aug 2017 12:55:54 -0700 Subject: [PATCH 165/294] pass gridcell averaged albedo from all_vars struct to wrf (#718) * pass gridcell averaged albedo from all_vars struct to wrf * add release notes entry * clean up albedo implementation and use canopy albedo if overstory present * ran uncrustify * fix bug and clean up * run uncrustify * fix cold start albedo to use veg_var_struct and bare soil albedo * ran uncrustify * remove debug statement * fix formatting errors * attempt at fixing travis tests * pass dmy_struct as argument to generate_default_state.c and consequently to vic_populate_model_state in each driver-specific version * fix typos * ran uncrustify --- docs/Development/ReleaseNotes.md | 7 ++- vic/drivers/cesm/include/vic_driver_cesm.h | 2 +- vic/drivers/cesm/src/cesm_interface_c.c | 2 +- vic/drivers/cesm/src/cesm_put_data.c | 3 +- .../cesm/src/vic_populate_model_state.c | 5 +- .../classic/include/vic_driver_classic.h | 2 +- vic/drivers/classic/src/vic_classic.c | 2 +- .../classic/src/vic_populate_model_state.c | 5 +- vic/drivers/image/include/vic_driver_image.h | 2 +- vic/drivers/image/src/vic_image.c | 2 +- .../image/src/vic_populate_model_state.c | 5 +- .../include/vic_driver_shared_all.h | 2 +- .../shared_all/src/generate_default_state.c | 29 ++++++------ vic/vic_run/include/vic_run.h | 3 +- vic/vic_run/src/calc_gridcell_avg_albedo.c | 47 +++++++++++++++---- vic/vic_run/src/vic_run.c | 4 +- 16 files changed, 78 insertions(+), 44 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 53cc57f50..681534b39 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -51,7 +51,7 @@ To check which release of VIC you are running: Fixes Julian day for the first timestep in the dmy struct for the CESM driver. - [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) + [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. @@ -59,6 +59,11 @@ To check which release of VIC you are running: Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. + [GH#718] (https://github.com/UW-Hydro/VIC/pull/718) + + Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. + + 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index ef29d6ee8..6a55e3507 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -188,7 +188,7 @@ void vic_cesm_start(vic_clock *vclock, case_metadata *cmeta); void vic_initialize_albedo(void); void vic_initialize_lwup(void); void vic_initialize_temperature(void); -void vic_populate_model_state(char *runtype_str); +void vic_populate_model_state(char *runtype_str, dmy_struct *dmy_current); void write_rpointer_file(char *fname); #endif diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 0061d9885..b9070968a 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -94,7 +94,7 @@ vic_cesm_init(vic_clock *vclock, vic_init(); // populate model state, either using a cold start or from a restart file - vic_populate_model_state(trimstr(cmeta->starttype)); + vic_populate_model_state(trimstr(cmeta->starttype), &dmy_current); // initialize forcings vic_force(); diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index f4170c3b4..9b4846230 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -123,8 +123,7 @@ vic_cesm_put_data() // albedo, VIC: fraction, CESM: fraction // Note: VIC does not partition its albedo, thus all types are // the same value - // TBD: this will be fixed in a subsequent PR - albedo = out_data[i][OUT_ALBEDO][0]; + albedo = all_vars[i].gridcell_avg.avg_albedo; // albedo: direct, visible l2x_vic[i].l2x_Sl_avsdr = albedo; diff --git a/vic/drivers/cesm/src/vic_populate_model_state.c b/vic/drivers/cesm/src/vic_populate_model_state.c index ab9076e92..4eac3393f 100644 --- a/vic/drivers/cesm/src/vic_populate_model_state.c +++ b/vic/drivers/cesm/src/vic_populate_model_state.c @@ -30,7 +30,8 @@ * @brief This function handles tasks related to populating model state. *****************************************************************************/ void -vic_populate_model_state(char *runtype_str) +vic_populate_model_state(char *runtype_str, + dmy_struct *dmy_current) { extern all_vars_struct *all_vars; extern lake_con_struct *lake_con; @@ -69,7 +70,7 @@ vic_populate_model_state(char *runtype_str) // no initial state file specified - generate default state for (i = 0; i < local_domain.ncells_active; i++) { generate_default_state(&(all_vars[i]), &(soil_con[i]), - veg_con[i]); + veg_con[i], dmy_current); if (options.LAKES) { generate_default_lake_state(&(all_vars[i]), &(soil_con[i]), lake_con[i]); diff --git a/vic/drivers/classic/include/vic_driver_classic.h b/vic/drivers/classic/include/vic_driver_classic.h index 4ca25e1d6..85cfe0b6e 100644 --- a/vic/drivers/classic/include/vic_driver_classic.h +++ b/vic/drivers/classic/include/vic_driver_classic.h @@ -111,7 +111,7 @@ void vic_force(force_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); + lake_con_struct, dmy_struct *); void write_data(stream_struct *streams); void write_header(stream_struct **streams, dmy_struct *dmy); void write_model_state(all_vars_struct *, int, int, filep_struct *, diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 00099772e..51be1d43d 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -225,7 +225,7 @@ main(int argc, **************************************************/ vic_populate_model_state(&all_vars, filep, soil_con.gridcel, - &soil_con, veg_con, lake_con); + &soil_con, veg_con, lake_con, &(dmy[0])); /** Initialize the storage terms in the water and energy balances **/ initialize_save_data(&all_vars, &force[0], &soil_con, veg_con, diff --git a/vic/drivers/classic/src/vic_populate_model_state.c b/vic/drivers/classic/src/vic_populate_model_state.c index 20b0f2eba..cd7d7aeaf 100644 --- a/vic/drivers/classic/src/vic_populate_model_state.c +++ b/vic/drivers/classic/src/vic_populate_model_state.c @@ -44,7 +44,8 @@ vic_populate_model_state(all_vars_struct *all_vars, size_t cellnum, soil_con_struct *soil_con, veg_con_struct *veg_con, - lake_con_struct lake_con) + lake_con_struct lake_con, + dmy_struct *dmy_current) { extern option_struct options; @@ -87,7 +88,7 @@ vic_populate_model_state(all_vars_struct *all_vars, } else { // else generate a default state - generate_default_state(all_vars, soil_con, veg_con); + generate_default_state(all_vars, soil_con, veg_con, dmy_current); if (options.LAKES) { generate_default_lake_state(all_vars, soil_con, lake_con); } diff --git a/vic/drivers/image/include/vic_driver_image.h b/vic/drivers/image/include/vic_driver_image.h index 0c64a2d39..25d828df7 100644 --- a/vic/drivers/image/include/vic_driver_image.h +++ b/vic/drivers/image/include/vic_driver_image.h @@ -39,6 +39,6 @@ void vic_force(void); void vic_image_init(void); void vic_image_finalize(); void vic_image_start(void); -void vic_populate_model_state(void); +void vic_populate_model_state(dmy_struct *dmy_current); #endif diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index b7ee1d9a6..9e0a87283 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -115,7 +115,7 @@ main(int argc, vic_image_init(); // populate model state, either using a cold start or from a restart file - vic_populate_model_state(); + vic_populate_model_state(&(dmy[0])); // initialize output structures vic_init_output(&(dmy[0])); diff --git a/vic/drivers/image/src/vic_populate_model_state.c b/vic/drivers/image/src/vic_populate_model_state.c index d65f2852f..4ea9ab7db 100644 --- a/vic/drivers/image/src/vic_populate_model_state.c +++ b/vic/drivers/image/src/vic_populate_model_state.c @@ -36,7 +36,7 @@ * @brief This function handles tasks related to populating model state. *****************************************************************************/ void -vic_populate_model_state(void) +vic_populate_model_state(dmy_struct *dmy_current) { extern all_vars_struct *all_vars; extern lake_con_struct *lake_con; @@ -54,7 +54,8 @@ vic_populate_model_state(void) else { // else generate a default state for (i = 0; i < local_domain.ncells_active; i++) { - generate_default_state(&(all_vars[i]), &(soil_con[i]), veg_con[i]); + generate_default_state(&(all_vars[i]), &(soil_con[i]), veg_con[i], + dmy_current); if (options.LAKES) { generate_default_lake_state(&(all_vars[i]), &(soil_con[i]), lake_con[i]); diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 0b4ad77a1..d71963606 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -629,7 +629,7 @@ void free_out_data(size_t ngridcells, double ***out_data); void free_streams(stream_struct **streams); void free_vegcon(veg_con_struct **veg_con); void generate_default_state(all_vars_struct *, soil_con_struct *, - veg_con_struct *); + veg_con_struct *, dmy_struct *); void generate_default_lake_state(all_vars_struct *, soil_con_struct *, lake_con_struct); void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index f8e78a3e8..5c5cb7ef5 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -34,7 +34,8 @@ void generate_default_state(all_vars_struct *all_vars, soil_con_struct *soil_con, - veg_con_struct *veg_con) + veg_con_struct *veg_con, + dmy_struct *dmy_current) { extern option_struct options; extern parameters_struct param; @@ -140,20 +141,18 @@ generate_default_state(all_vars_struct *all_vars, for (veg = 0; veg <= Nveg; veg++) { Cv = veg_con[veg].Cv; if (Cv > 0) { - for (band = 0; band < options.SNOW_BAND; band++) { - if (soil_con->AreaFract[band] > 0.) { - // TO-DO: account for treeline and lake factors - AreaFactor = (Cv * soil_con->AreaFract[band] * - TreeAdjustFactor * lakefactor); - // cold start, so assuming bare (free of snow) albedo - if (veg != Nveg) { - albedo_sum += AreaFactor * veg_var[veg][band].albedo; - } - else { - // this is the bare soil class, so use bare soil albedo parameter - albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; - } - } + // TO-DO: account for treeline and lake factors + AreaFactor = (Cv * TreeAdjustFactor * lakefactor); + + if (veg != Nveg) { + // cold start, so using climatological albedo for all veg classes + // except for bare soil + albedo_sum += (AreaFactor * + veg_con[veg].albedo[dmy_current->month - 1]); + } + else { + // bare soil class, use bare soil albedo + albedo_sum += AreaFactor * param.ALBEDO_BARE_SOIL; } } } diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 8dc48c706..02ae0c073 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -49,7 +49,8 @@ double calc_atmos_energy_bal(double, double, double, double, double, double, double, double *, double *, double *, double *, double *, double *, bool *, unsigned int*); double calc_density(double); -void calc_gridcell_avg_albedo(double *, double, size_t, energy_bal_struct **, +void calc_gridcell_avg_albedo(double *, double, size_t, bool, + energy_bal_struct **, snow_data_struct **, veg_con_struct *, soil_con_struct *); double calc_latent_heat_of_sublimation(double temp); double calc_latent_heat_of_vaporization(double temp); diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index 4ae7021e3..4d400d965 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -36,20 +36,24 @@ void calc_gridcell_avg_albedo(double *albedo, double shortwave, size_t Nveg, + bool overstory, energy_bal_struct **energy, + snow_data_struct **snow, veg_con_struct *veg_con, soil_con_struct *soil_con) { - extern option_struct options; - size_t veg; - size_t band; - double Cv; - double AreaFactor; - double TreeAdjustFactor = 1.; - double lakefactor = 1; - double swnet; + extern option_struct options; + extern parameters_struct param; + size_t veg; + size_t band; + double Cv; + double AreaFactor; + double TreeAdjustFactor = 1.; + double lakefactor = 1; + double swnet; swnet = 0; + *albedo = 0; for (veg = 0; veg <= Nveg; veg++) { Cv = veg_con[veg].Cv; @@ -59,7 +63,7 @@ calc_gridcell_avg_albedo(double *albedo, // TO-DO: account for treeline and lake factors AreaFactor = (Cv * soil_con->AreaFract[band] * TreeAdjustFactor * lakefactor); - swnet += energy[veg][band].NetShortAtmos * AreaFactor; + swnet += AreaFactor * energy[veg][band].NetShortAtmos; } } } @@ -67,9 +71,32 @@ calc_gridcell_avg_albedo(double *albedo, // compute gridcell-averaged albedo using average shortwave if (shortwave > 0) { + // use average shortwave for albedo calculation *albedo = 1. - (swnet / shortwave); } else { - *albedo = 0.0; + // use vegetation, snow or bare soil albedo + for (veg = 0; veg <= Nveg; veg++) { + Cv = veg_con[veg].Cv; + if (Cv > 0) { + for (band = 0; band < options.SNOW_BAND; band++) { + if (soil_con->AreaFract[band] > 0.) { + // TO-DO: account for treeline and lake factors + AreaFactor = (Cv * soil_con->AreaFract[band] * + TreeAdjustFactor * lakefactor); + if (snow[veg][band].snow && overstory) { + // use snow canopy albedo + *albedo += AreaFactor * + energy[veg][band].AlbedoOver; + } + else { + // use surface albedo + *albedo += AreaFactor * + energy[veg][band].AlbedoUnder; + } + } + } + } + } } } diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 66e7e8b83..f885d7514 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -384,8 +384,8 @@ vic_run(force_data_struct *force, // Compute gridcell-averaged albedo calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, - force->shortwave[NR], Nveg, energy, - veg_con, soil_con); + force->shortwave[NR], Nveg, overstory, + energy, snow, veg_con, soil_con); /**************************** Run Lake Model From ddc679a1de7fb87b8febc5e6ff78656eb3ec6ca2 Mon Sep 17 00:00:00 2001 From: dgergel Date: Mon, 7 Aug 2017 18:41:55 -0400 Subject: [PATCH 166/294] fix evap units and sign --- vic/drivers/cesm/src/cesm_put_data.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 9b4846230..f84c7800b 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -159,9 +159,8 @@ vic_cesm_put_data() // evaporation, VIC: mm, CESM: kg m-2 s-1 // TO-DO should we incorporate bare soil evap? - l2x_vic[i].l2x_Fall_evap += -1 * - (out_data[i][OUT_EVAP][0] * MM_PER_M / - global_param.dt); + l2x_vic[i].l2x_Fall_evap += out_data[i][OUT_EVAP][0] / + global_param.dt; // lnd->rtm input fluxes l2x_vic[i].l2x_Flrl_rofliq = out_data[i][OUT_RUNOFF][0] + From 076722cf7ce3a6e979e1e4144d5b352f97d8a762 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 2 Feb 2017 13:57:36 -0800 Subject: [PATCH 167/294] Revert "Merge VIC5.0.1 release into develop branch" --- docs/Development/ReleaseNotes.md | 3 +- vic/drivers/cesm/src/cesm_interface_c.c | 4 --- vic/drivers/cesm/src/cesm_put_data.c | 37 ++++++++++++++++++++++-- vic/drivers/cesm/src/vic_force.c | 4 +-- vic/drivers/shared_image/src/vic_store.c | 6 ++-- vic/drivers/shared_image/src/vic_write.c | 2 +- vic/vic_run/include/vic_def.h | 2 +- vic/vic_run/include/vic_run.h | 1 - 8 files changed, 43 insertions(+), 16 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 681534b39..a64827aef 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -122,7 +122,7 @@ To check which release of VIC you are running: ------------------------------ -## VIC 5.0.0 [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.61422.svg)](http://dx.doi.org/10.5281/zenodo.61422) +## VIC 5.0.0 [![DOI](https://zenodo.org/badge/7766/UW-Hydro/VIC.svg)](https://zenodo.org/badge/latestdoi/7766/UW-Hydro/VIC) **Release date: (September 2, 2016)** @@ -297,7 +297,6 @@ This is a major update from VIC 4. The VIC 5.0.0 release aims to have nearly ide Fixed a bug where volumetric heat capacity of water should be used in `func_canopy_energy_bal` (previously specific heat capacity was used). - ------------------------------ ## VIC 4.2.d [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.56058.svg)](http://dx.doi.org/10.5281/zenodo.56058) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index b9070968a..36b755402 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -96,9 +96,6 @@ vic_cesm_init(vic_clock *vclock, // populate model state, either using a cold start or from a restart file vic_populate_model_state(trimstr(cmeta->starttype), &dmy_current); - // initialize forcings - vic_force(); - // initialize output structures vic_init_output(&dmy_current); @@ -159,7 +156,6 @@ vic_cesm_run(vic_clock *vclock) // if save: if (vclock->state_flag) { - // write state file vic_store(&dmy_current, state_filename); write_rpointer_file(state_filename); } diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 9b4846230..acc52a511 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -258,8 +258,41 @@ vic_cesm_put_data() } } - // set variables-set flag - l2x_vic[i].l2x_vars_set = true; + // heat flux shortwave net + l2x_vic[i].l2x_Fall_swnet += AreaFactor * + (force[i].shortwave[NR] - + energy.NetShortAtmos); + + // co2 flux **For testing set to 0 + // l2x_vic[i].l2x_Fall_fco2_lnd; + + // dust flux size bin 1 + // l2x_vic[i].l2x_Fall_flxdst1; + + // dust flux size bin 2 + // l2x_vic[i].l2x_Fall_flxdst2; + + // dust flux size bin 3 + // l2x_vic[i].l2x_Fall_flxdst3; + + // dust flux size bin 4 + // l2x_vic[i].l2x_Fall_flxdst4; + + // MEGAN fluxes + // l2x_vic[i].l2x_Fall_flxvoc; + + // lnd->rtm input fluxes + l2x_vic[i].l2x_Flrl_rofliq += AreaFactor * + (cell.runoff + + cell.baseflow) / global_param.dt; + + // lnd->rtm input fluxes + // l2x_vic[i].l2x_Flrl_rofice; + + // vars set flag + l2x_vic[i].l2x_vars_set = true; + } + } if (!assert_close_double(AreaFactorSum, 1., 0., 1e-3)) { log_warn("AreaFactorSum (%f) is not 1", diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index b6a8db94e..7eaaa2d19 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -128,8 +128,8 @@ vic_force(void) for (j = 0; j < NF; j++) { for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: Pa - // VIC units: Pa - force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot; + // VIC units: kPa + force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot / PA_PER_KPA; } } diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 602dac2a2..a91929f64 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -824,7 +824,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.i_fillvalue, + nc_state_file.d_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; @@ -837,7 +837,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.i_fillvalue, + nc_state_file.d_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; @@ -983,7 +983,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.i_fillvalue, + nc_state_file.d_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; diff --git a/vic/drivers/shared_image/src/vic_write.c b/vic/drivers/shared_image/src/vic_write.c index 88e697b2c..4cd346619 100644 --- a/vic/drivers/shared_image/src/vic_write.c +++ b/vic/drivers/shared_image/src/vic_write.c @@ -194,7 +194,7 @@ vic_write(stream_struct *stream, } gather_put_nc_field_schar(nc_hist_file->nc_id, nc_hist_file->nc_vars[k].nc_varid, - nc_hist_file->c_fillvalue, + nc_hist_file->d_fillvalue, dstart, dcount, cvar); } else { diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 5044035e2..aa9f12449 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -52,7 +52,7 @@ /***** Model Constants *****/ #define MAXSTRING 2048 #define MISSING -99999. /**< missing value */ -#define MISSING_USI 99999 /**< missing value for unsigned ints */ +#define MISSING_USI 99999. /**< missing value for unsigned ints */ #define MISSING_S "MISSING" /**< missing value for strings */ #define NODATA_VH -1 /**< missing value for veg_hist inputs */ #define NODATA_VEG -1 /**< flag for veg types not in grid cell */ diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 02ae0c073..f63d4098b 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -116,7 +116,6 @@ void compute_pot_evap(size_t, double, double, double, double, double, double, double, double *); void compute_runoff_and_asat(soil_con_struct *, double *, double, double *, double *); -double calc_Q12(double, double, double, double, double); void compute_soil_resp(int, double *, double, double, double *, double *, double, double, double, double *, double *, double *); void compute_soil_layer_thermal_properties(layer_data_struct *, double *, From 070bd92916143a69a5ed60790dac853700aad434 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 15 Mar 2017 10:44:23 -0600 Subject: [PATCH 168/294] improve floating point comparisons in vic_init.c and fix typo in print_library_shared_image.c --- .../shared_image/src/print_library_shared_image.c | 2 +- vic/drivers/shared_image/src/vic_init.c | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/vic/drivers/shared_image/src/print_library_shared_image.c b/vic/drivers/shared_image/src/print_library_shared_image.c index c3d33fb0b..1872928ae 100644 --- a/vic/drivers/shared_image/src/print_library_shared_image.c +++ b/vic/drivers/shared_image/src/print_library_shared_image.c @@ -110,7 +110,7 @@ sprint_location(char *str, "\tlongitude : %.4f\n" "\tarea : %.4f\n" "\tfrac : %.4f\n" - "\nveg : %zd\n" + "\tnveg : %zd\n" "\tglobal_idx : %zd\n" "\tio_idx : %zd\n" "\tlocal_idx : %zd\n", diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index fdfcc0a83..cfd485ee0 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -987,8 +987,7 @@ vic_init(void) } sum += soil_con[i].AreaFract[j]; } - // TBD: Need better check for equal to 1. - if (sum != 1.) { + if (!assert_close_double(sum, 1.0, 0., 0.001)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Sum of the snow band area fractions does not equal " "1 (%f), dividing each fraction by the sum\n%s", @@ -1003,7 +1002,7 @@ vic_init(void) for (j = 0; j < options.SNOW_BAND; j++) { mean += soil_con[i].BandElev[j] * soil_con[i].AreaFract[j]; } - if (fabs(soil_con[i].elevation - soil_con[i].BandElev[j]) > 1.0) { + if (!assert_close_double(soil_con[i].elevation, mean, 0., 0.001)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("average band elevation %f not equal to grid_cell " "average elevation %f; setting grid cell elevation " @@ -1041,8 +1040,7 @@ vic_init(void) } sum += soil_con[i].Pfactor[j]; } - // TBD: Need better check for equal to 1. - if (sum != 1.) { + if (!assert_close_double(sum, 1.0, 0., 0.001)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Sum of the snow band precipitation fractions does " "not equal 1 (%f), dividing each fraction by the " @@ -1192,7 +1190,7 @@ vic_init(void) sum += veg_con[i][vidx].zone_fract[k]; } // TBD: Need better test for not equal to 1. - if (sum != 1.) { + if (!assert_close_double(sum, 1.0, 0., 0.001)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Root zone fractions sum to more than 1 (%f), " "normalizing fractions. If the sum is large, " From 97d60de7bf49d7406fee52619d4baac43fed9002 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 15 Mar 2017 17:08:53 -0600 Subject: [PATCH 169/294] cleanup print library a bit --- .../shared_all/src/initialize_global.c | 2 +- .../shared_all/src/print_library_shared.c | 109 ++++++++---------- vic/vic_run/include/vic_def.h | 2 +- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_global.c b/vic/drivers/shared_all/src/initialize_global.c index b61457f7b..5bf50dc65 100644 --- a/vic/drivers/shared_all/src/initialize_global.c +++ b/vic/drivers/shared_all/src/initialize_global.c @@ -54,7 +54,7 @@ initialize_global() global_param.endyear = 0; global_param.endmonth = 0; global_param.endday = 0; - global_param.resolution = 0; + global_param.resolution = MISSING; global_param.wind_h = 10.0; for (i = 0; i < 2; i++) { global_param.forceyear[i] = 0; diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index f6ae45509..3bd5d61e0 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -265,14 +265,14 @@ print_global_param(global_param_struct *gp) fprintf(LOG_DEST, "\tendmonth : %hu\n", gp->endmonth); fprintf(LOG_DEST, "\tendyear : %hu\n", gp->endyear); for (i = 0; i < 2; i++) { - fprintf(LOG_DEST, "\tforceday[%zd] : %hu\n", i, gp->forceday[i]); - fprintf(LOG_DEST, "\tforcesec[%zd] : %u\n", i, gp->forcesec[i]); - fprintf(LOG_DEST, "\tforcemonth[%zd] : %hu\n", i, + fprintf(LOG_DEST, "\tforceday[%zd] : %hu\n", i, gp->forceday[i]); + fprintf(LOG_DEST, "\tforcesec[%zd] : %u\n", i, gp->forcesec[i]); + fprintf(LOG_DEST, "\tforcemonth[%zd] : %hu\n", i, gp->forcemonth[i]); - fprintf(LOG_DEST, "\tforceoffset[%zd] : %hu\n", i, + fprintf(LOG_DEST, "\tforceoffset[%zd] : %hu\n", i, gp->forceoffset[i]); - fprintf(LOG_DEST, "\tforceskip[%zd] : %u\n", i, gp->forceskip[i]); - fprintf(LOG_DEST, "\tforceyear[%zd] : %hu\n", i, gp->forceyear[i]); + fprintf(LOG_DEST, "\tforceskip[%zd] : %u\n", i, gp->forceskip[i]); + fprintf(LOG_DEST, "\tforceyear[%zd] : %hu\n", i, gp->forceyear[i]); } fprintf(LOG_DEST, "\tnrecs : %zu\n", gp->nrecs); fprintf(LOG_DEST, "\tstartday : %hu\n", gp->startday); @@ -430,68 +430,59 @@ void print_option(option_struct *option) { fprintf(LOG_DEST, "option:\n"); - fprintf(LOG_DEST, "\tAboveTreelineVeg : %d\n", - option->AboveTreelineVeg); - fprintf(LOG_DEST, "\tAERO_RESIST_CANSNOW : %d\n", - option->AERO_RESIST_CANSNOW); - fprintf(LOG_DEST, "\tBLOWING : %d\n", option->BLOWING); - fprintf(LOG_DEST, "\tBLOWING_VAR_THRESHOLD: %d\n", - option->BLOWING_VAR_THRESHOLD); - fprintf(LOG_DEST, "\tBLOWING_CALC_PROB : %d\n", - option->BLOWING_CALC_PROB); - fprintf(LOG_DEST, "\tBLOWING_SIMPLE : %d\n", option->BLOWING_SIMPLE); - fprintf(LOG_DEST, "\tBLOWING_FETCH : %d\n", option->BLOWING_FETCH); - fprintf(LOG_DEST, "\tBLOWING_SPATIAL_WIND : %d\n", - option->BLOWING_SPATIAL_WIND); - fprintf(LOG_DEST, "\tCARBON : %d\n", option->CARBON); - fprintf(LOG_DEST, "\tCLOSE_ENERGY : %d\n", option->CLOSE_ENERGY); - fprintf(LOG_DEST, "\tCOMPUTE_TREELINE : %d\n", - option->COMPUTE_TREELINE); - fprintf(LOG_DEST, "\tCONTINUEONERROR : %d\n", option->CONTINUEONERROR); - fprintf(LOG_DEST, "\tCORRPREC : %d\n", option->CORRPREC); - fprintf(LOG_DEST, "\tEQUAL_AREA : %d\n", option->EQUAL_AREA); - fprintf(LOG_DEST, "\tEXP_TRANS : %d\n", option->EXP_TRANS); - fprintf(LOG_DEST, "\tFROZEN_SOIL : %d\n", option->FROZEN_SOIL); - fprintf(LOG_DEST, "\tFULL_ENERGY : %d\n", option->FULL_ENERGY); + fprintf(LOG_DEST, "\tAboveTreelineVeg : %d\n", option->AboveTreelineVeg); + fprintf(LOG_DEST, "\tAERO_RESIST_CANSNOW : %d\n", option->AERO_RESIST_CANSNOW); + fprintf(LOG_DEST, "\tBLOWING : %s\n", option->BLOWING ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_VAR_THRESHOLD: %s\n", option->BLOWING_VAR_THRESHOLD ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_CALC_PROB : %s\n", option->BLOWING_CALC_PROB ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_SIMPLE : %s\n", option->BLOWING_SIMPLE ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_FETCH : %s\n", option->BLOWING_FETCH ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_SPATIAL_WIND : %s\n", option->BLOWING_SPATIAL_WIND ? "true" : "false"); + fprintf(LOG_DEST, "\tCARBON : %s\n", option->CARBON ? "true" : "false"); + fprintf(LOG_DEST, "\tCLOSE_ENERGY : %s\n", option->CLOSE_ENERGY ? "true" : "false"); + fprintf(LOG_DEST, "\tCOMPUTE_TREELINE : %s\n", option->COMPUTE_TREELINE ? "true" : "false"); + fprintf(LOG_DEST, "\tCONTINUEONERROR : %s\n", option->CONTINUEONERROR ? "true" : "false"); + fprintf(LOG_DEST, "\tCORRPREC : %s\n", option->CORRPREC ? "true" : "false"); + fprintf(LOG_DEST, "\tEQUAL_AREA : %s\n", option->EQUAL_AREA ? "true" : "false"); + fprintf(LOG_DEST, "\tEXP_TRANS : %s\n", option->EXP_TRANS ? "true" : "false"); + fprintf(LOG_DEST, "\tFROZEN_SOIL : %s\n", option->FROZEN_SOIL ? "true" : "false"); + fprintf(LOG_DEST, "\tFULL_ENERGY : %s\n", option->FULL_ENERGY ? "true" : "false"); fprintf(LOG_DEST, "\tGRND_FLUX_TYPE : %d\n", option->GRND_FLUX_TYPE); - fprintf(LOG_DEST, "\tIMPLICIT : %d\n", option->IMPLICIT); - fprintf(LOG_DEST, "\tJULY_TAVG_SUPPLIED : %d\n", - option->JULY_TAVG_SUPPLIED); - fprintf(LOG_DEST, "\tLAKES : %d\n", option->LAKES); + fprintf(LOG_DEST, "\tIMPLICIT : %s\n", option->IMPLICIT ? "true" : "false"); + fprintf(LOG_DEST, "\tJULY_TAVG_SUPPLIED : %s\n", option->JULY_TAVG_SUPPLIED ? "true" : "false"); + fprintf(LOG_DEST, "\tLAKES : %s\n", option->LAKES ? "true" : "false"); fprintf(LOG_DEST, "\tNcanopy : %zu\n", option->Ncanopy); fprintf(LOG_DEST, "\tNfrost : %zu\n", option->Nfrost); fprintf(LOG_DEST, "\tNlakenode : %zu\n", option->Nlakenode); fprintf(LOG_DEST, "\tNlayer : %zu\n", option->Nlayer); fprintf(LOG_DEST, "\tNnode : %zu\n", option->Nnode); - fprintf(LOG_DEST, "\tNOFLUX : %d\n", option->NOFLUX); + fprintf(LOG_DEST, "\tNOFLUX : %s\n", option->NOFLUX ? "true" : "false"); fprintf(LOG_DEST, "\tNVEGTYPES : %zu\n", option->NVEGTYPES); fprintf(LOG_DEST, "\tRC_MODE : %d\n", option->RC_MODE); fprintf(LOG_DEST, "\tROOT_ZONES : %zu\n", option->ROOT_ZONES); - fprintf(LOG_DEST, "\tQUICK_FLUX : %d\n", option->QUICK_FLUX); - fprintf(LOG_DEST, "\tQUICK_SOLVE : %d\n", option->QUICK_SOLVE); - fprintf(LOG_DEST, "\tSHARE_LAYER_MOIST : %d\n", - option->SHARE_LAYER_MOIST); + fprintf(LOG_DEST, "\tQUICK_FLUX : %s\n", option->QUICK_FLUX ? "true" : "false"); + fprintf(LOG_DEST, "\tQUICK_SOLVE : %s\n", option->QUICK_SOLVE ? "true" : "false"); + fprintf(LOG_DEST, "\tSHARE_LAYER_MOIST : %s\n", option->SHARE_LAYER_MOIST ? "true" : "false"); fprintf(LOG_DEST, "\tSNOW_DENSITY : %d\n", option->SNOW_DENSITY); fprintf(LOG_DEST, "\tSNOW_BAND : %zu\n", option->SNOW_BAND); - fprintf(LOG_DEST, "\tSPATIAL_FROST : %d\n", option->SPATIAL_FROST); - fprintf(LOG_DEST, "\tSPATIAL_SNOW : %d\n", option->SPATIAL_SNOW); - fprintf(LOG_DEST, "\tTFALLBACK : %d\n", option->TFALLBACK); + fprintf(LOG_DEST, "\tSPATIAL_FROST : %s\n", option->SPATIAL_FROST ? "true" : "false"); + fprintf(LOG_DEST, "\tSPATIAL_SNOW : %s\n", option->SPATIAL_SNOW ? "true" : "false"); + fprintf(LOG_DEST, "\tTFALLBACK : %s\n", option->TFALLBACK ? "true" : "false"); fprintf(LOG_DEST, "\tBASEFLOW : %d\n", option->BASEFLOW); fprintf(LOG_DEST, "\tGRID_DECIMAL : %d\n", option->GRID_DECIMAL); - fprintf(LOG_DEST, "\tVEGLIB_PHOTO : %d\n", option->VEGLIB_PHOTO); - fprintf(LOG_DEST, "\tVEGLIB_FCAN : %d\n", option->VEGLIB_FCAN); - fprintf(LOG_DEST, "\tVEGPARAM_ALB : %d\n", option->VEGPARAM_ALB); - fprintf(LOG_DEST, "\tVEGPARAM_LAI : %d\n", option->VEGPARAM_LAI); - fprintf(LOG_DEST, "\tVEGPARAM_FCAN : %d\n", - option->VEGPARAM_FCAN); + fprintf(LOG_DEST, "\tVEGLIB_PHOTO : %s\n", option->VEGLIB_PHOTO ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGLIB_FCAN : %s\n", option->VEGLIB_FCAN ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_ALB : %s\n", option->VEGPARAM_ALB ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_LAI : %s\n", option->VEGPARAM_LAI ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_FCAN : %s\n", option->VEGPARAM_FCAN ? "true" : "false"); fprintf(LOG_DEST, "\tALB_SRC : %d\n", option->ALB_SRC); fprintf(LOG_DEST, "\tLAI_SRC : %d\n", option->LAI_SRC); fprintf(LOG_DEST, "\tFCAN_SRC : %d\n", option->FCAN_SRC); - fprintf(LOG_DEST, "\tLAKE_PROFILE : %d\n", option->LAKE_PROFILE); - fprintf(LOG_DEST, "\tORGANIC_FRACT : %d\n", option->ORGANIC_FRACT); + fprintf(LOG_DEST, "\tLAKE_PROFILE : %s\n", option->LAKE_PROFILE ? "true" : "false"); + fprintf(LOG_DEST, "\tORGANIC_FRACT : %s\n", option->ORGANIC_FRACT ? "true" : "false"); fprintf(LOG_DEST, "\tSTATE_FORMAT : %d\n", option->STATE_FORMAT); - fprintf(LOG_DEST, "\tINIT_STATE : %d\n", option->INIT_STATE); - fprintf(LOG_DEST, "\tSAVE_STATE : %d\n", option->SAVE_STATE); + fprintf(LOG_DEST, "\tINIT_STATE : %s\n", option->INIT_STATE ? "true" : "false"); + fprintf(LOG_DEST, "\tSAVE_STATE : %s\n", option->SAVE_STATE ? "true" : "false"); fprintf(LOG_DEST, "\tNoutstreams : %zu\n", option->Noutstreams); } @@ -817,17 +808,17 @@ print_snow_data(snow_data_struct *snow) fprintf(LOG_DEST, "\tdepth : %f\n", snow->depth); fprintf(LOG_DEST, "\tlast_snow : %d\n", snow->last_snow); fprintf(LOG_DEST, "\tmax_snow_depth : %f\n", snow->max_snow_depth); - fprintf(LOG_DEST, "\tMELTING : %d\n", snow->MELTING); + fprintf(LOG_DEST, "\tMELTING : %s\n", snow->MELTING ? "true" : "false"); fprintf(LOG_DEST, "\tpack_temp : %f\n", snow->pack_temp); fprintf(LOG_DEST, "\tpack_water : %f\n", snow->pack_water); - fprintf(LOG_DEST, "\tsnow : %d\n", snow->snow); + fprintf(LOG_DEST, "\tsnow : %s\n", snow->snow ? "true" : "false"); fprintf(LOG_DEST, "\tsnow_canopy : %f\n", snow->snow_canopy); fprintf(LOG_DEST, "\tstore_coverage : %f\n", snow->store_coverage); - fprintf(LOG_DEST, "\tstore_snow : %d\n", snow->store_snow); + fprintf(LOG_DEST, "\tstore_snow : %s\n", snow->store_snow ? "true" : "false"); fprintf(LOG_DEST, "\tstore_swq : %f\n", snow->store_swq); fprintf(LOG_DEST, "\tsurf_temp : %f\n", snow->surf_temp); fprintf(LOG_DEST, "\tsurf_temp_fbcount : %u\n", snow->surf_temp_fbcount); - fprintf(LOG_DEST, "\tsurf_temp_fbflag : %d\n", snow->surf_temp_fbflag); + fprintf(LOG_DEST, "\tsurf_temp_fbflag : %s\n", snow->surf_temp_fbflag ? "true" : "false"); fprintf(LOG_DEST, "\tsurf_water : %f\n", snow->surf_water); fprintf(LOG_DEST, "\tswq : %f\n", snow->swq); fprintf(LOG_DEST, "\tsnow_distrib_slope: %f\n", @@ -861,7 +852,7 @@ print_soil_con(soil_con_struct *scon, size_t j; fprintf(LOG_DEST, "soil_con:\n"); - fprintf(LOG_DEST, "\tFS_ACTIVE : %d\n", scon->FS_ACTIVE); + fprintf(LOG_DEST, "\tFS_ACTIVE : %s\n", scon->FS_ACTIVE ? "true" : "false"); fprintf(LOG_DEST, "\tDs : %f\n", scon->Ds); fprintf(LOG_DEST, "\tDsmax : %f\n", scon->Dsmax); fprintf(LOG_DEST, "\tKsat :"); @@ -1041,7 +1032,7 @@ print_soil_con(soil_con_struct *scon, fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "AboveTreeLine :"); for (i = 0; i < nbands; i++) { - fprintf(LOG_DEST, "\t%d", scon->AboveTreeLine[i]); + fprintf(LOG_DEST, "\t%s", scon->AboveTreeLine[i] ? "true" : "false"); } fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "\televation : %f\n", scon->elevation); @@ -1130,7 +1121,7 @@ print_veg_lib(veg_lib_struct *vlib, size_t i; fprintf(LOG_DEST, "veg_lib:\n"); - fprintf(LOG_DEST, "\toverstory : %d\n", vlib->overstory); + fprintf(LOG_DEST, "\toverstory : %s\n", vlib->overstory ? "true" : "false"); fprintf(LOG_DEST, "\tLAI :"); for (i = 0; i < MONTHS_PER_YEAR; i++) { fprintf(LOG_DEST, "\t%.2f", vlib->LAI[i]); @@ -1181,7 +1172,7 @@ print_veg_lib(veg_lib_struct *vlib, fprintf(LOG_DEST, "\tMaxETransport : %.4f\n", vlib->MaxETransport); fprintf(LOG_DEST, "\tCO2Specificity: %.4f\n", vlib->CO2Specificity); fprintf(LOG_DEST, "\tLightUseEff : %.4f\n", vlib->LightUseEff); - fprintf(LOG_DEST, "\tNscaleFlag : %d\n", vlib->NscaleFlag); + fprintf(LOG_DEST, "\tNscaleFlag : %s\n", vlib->NscaleFlag ? "true" : "false"); fprintf(LOG_DEST, "\tWnpp_inhib : %.4f\n", vlib->Wnpp_inhib); fprintf(LOG_DEST, "\tNPPfactor_sat : %.4f\n", vlib->NPPfactor_sat); } diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index aa9f12449..184ede176 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -268,7 +268,7 @@ typedef struct { Default = TRUE */ // input options - bool BASEFLOW; /**< ARNO: read Ds, Dm, Ws, c; NIJSSEN2001: read d1, d2, d3, d4 */ + unsigned short int BASEFLOW; /**< ARNO: read Ds, Dm, Ws, c; NIJSSEN2001: read d1, d2, d3, d4 */ unsigned short int GRID_DECIMAL; /**< Number of decimal places in grid file extensions */ bool VEGLIB_FCAN; /**< TRUE = veg library file contains monthly fcanopy values */ bool VEGLIB_PHOTO; /**< TRUE = veg library contains photosynthesis parameters */ From 43c184a92eb6aa8bdf38066c45dee40b3cce6ec6 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 16 Mar 2017 10:38:01 -0600 Subject: [PATCH 170/294] possible fix to calc_root_fraction.c to avoid infinite loop --- vic/drivers/shared_all/src/calc_root_fraction.c | 10 ++++++++++ vic/drivers/shared_image/src/vic_init.c | 3 --- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/vic/drivers/shared_all/src/calc_root_fraction.c b/vic/drivers/shared_all/src/calc_root_fraction.c index 87e7988d0..31442d27f 100644 --- a/vic/drivers/shared_all/src/calc_root_fraction.c +++ b/vic/drivers/shared_all/src/calc_root_fraction.c @@ -42,6 +42,7 @@ calc_root_fractions(veg_con_struct *veg_con, size_t layer; size_t zone; size_t i; + size_t max_itter; double sum_fract; double dum; double Zstep; @@ -62,7 +63,15 @@ calc_root_fractions(veg_con_struct *veg_con, Zsum = 0; zone = 0; + max_itter = -1; while (zone < options.ROOT_ZONES) { + max_itter ++; + if (max_itter > 9999) { + log_warn("veg=%d of Nveg=%d", veg, Nveg); + log_warn("zone %zu of %zu ROOT_ZONES", zone, options.ROOT_ZONES); + log_err("stuck in an infinite loop"); + } + Zstep = veg_con[veg].zone_depth[zone]; if ((Zsum + Zstep) <= Lsum && Zsum >= Lsum - Lstep) { /** CASE 1: Root Zone Completely in Soil Layer **/ @@ -124,6 +133,7 @@ calc_root_fractions(veg_con_struct *veg_con, } } else if (Zsum + Zstep > Lsum) { + zone ++; // should this be here? if (layer < options.Nlayer) { veg_con[veg].root[layer] = sum_fract; sum_fract = 0.; diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index cfd485ee0..4020c1c6e 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -576,7 +576,6 @@ vic_init(void) } } - // organic soils if (options.ORGANIC_FRACT) { // organic @@ -1189,7 +1188,6 @@ vic_init(void) for (k = 0; k < options.ROOT_ZONES; k++) { sum += veg_con[i][vidx].zone_fract[k]; } - // TBD: Need better test for not equal to 1. if (!assert_close_double(sum, 1.0, 0., 0.001)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Root zone fractions sum to more than 1 (%f), " @@ -1291,7 +1289,6 @@ vic_init(void) } } - // read_lake parameters if (options.LAKES) { // lake_idx From 4892027304f7df2b283f310ed93edb9ff5369dea Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 16 Mar 2017 13:28:30 -0600 Subject: [PATCH 171/294] support integer output types --- vic/drivers/image/Makefile | 4 ++-- vic/drivers/shared_all/src/input_tools.c | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index b80455cd4..9182dbf5d 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -80,10 +80,10 @@ CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ -DUSERNAME=\"$(USER)\" \ -DHOSTNAME=\"$(HOSTNAME)\" -ifeq (true, ${TRAVIS}) +# ifeq (true, ${TRAVIS}) # Add extra debugging for builds on travis CFLAGS += -rdynamic -Wl,-export-dynamic -endif +# endif LIBRARY = -lm ${NC_LIBS} diff --git a/vic/drivers/shared_all/src/input_tools.c b/vic/drivers/shared_all/src/input_tools.c index 8f31e53bb..e70d49972 100644 --- a/vic/drivers/shared_all/src/input_tools.c +++ b/vic/drivers/shared_all/src/input_tools.c @@ -150,7 +150,13 @@ str_to_out_type(char typestr[]) else if (strcasecmp("OUT_TYPE_SINT", typestr) == 0) { return OUT_TYPE_SINT; } - else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { + else if (strcasecmp("OUT_TYPE_INT", typestr) == 0) { + return OUT_TYPE_INT; + } + else if (strcasecmp("OUT_TYPE_CHAR", typestr) == 0) { + return OUT_TYPE_CHAR; + } + else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { return OUT_TYPE_FLOAT; } else if (strcasecmp("OUT_TYPE_DOUBLE", typestr) == 0) { From 8efdbecc67c10715d97b1e5be486555e610ca1b3 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 16 Mar 2017 12:51:23 -0700 Subject: [PATCH 172/294] uncrustify init fixes --- .../shared_all/src/calc_root_fraction.c | 7 +- vic/drivers/shared_all/src/input_tools.c | 14 +- .../shared_all/src/print_library_shared.c | 132 ++++++++++++------ 3 files changed, 99 insertions(+), 54 deletions(-) diff --git a/vic/drivers/shared_all/src/calc_root_fraction.c b/vic/drivers/shared_all/src/calc_root_fraction.c index 31442d27f..a677f5a15 100644 --- a/vic/drivers/shared_all/src/calc_root_fraction.c +++ b/vic/drivers/shared_all/src/calc_root_fraction.c @@ -65,10 +65,11 @@ calc_root_fractions(veg_con_struct *veg_con, max_itter = -1; while (zone < options.ROOT_ZONES) { - max_itter ++; + max_itter++; if (max_itter > 9999) { log_warn("veg=%d of Nveg=%d", veg, Nveg); - log_warn("zone %zu of %zu ROOT_ZONES", zone, options.ROOT_ZONES); + log_warn("zone %zu of %zu ROOT_ZONES", zone, + options.ROOT_ZONES); log_err("stuck in an infinite loop"); } @@ -133,7 +134,7 @@ calc_root_fractions(veg_con_struct *veg_con, } } else if (Zsum + Zstep > Lsum) { - zone ++; // should this be here? + zone++; // should this be here? if (layer < options.Nlayer) { veg_con[veg].root[layer] = sum_fract; sum_fract = 0.; diff --git a/vic/drivers/shared_all/src/input_tools.c b/vic/drivers/shared_all/src/input_tools.c index e70d49972..82e3d904f 100644 --- a/vic/drivers/shared_all/src/input_tools.c +++ b/vic/drivers/shared_all/src/input_tools.c @@ -150,13 +150,13 @@ str_to_out_type(char typestr[]) else if (strcasecmp("OUT_TYPE_SINT", typestr) == 0) { return OUT_TYPE_SINT; } - else if (strcasecmp("OUT_TYPE_INT", typestr) == 0) { - return OUT_TYPE_INT; - } - else if (strcasecmp("OUT_TYPE_CHAR", typestr) == 0) { - return OUT_TYPE_CHAR; - } - else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { + else if (strcasecmp("OUT_TYPE_INT", typestr) == 0) { + return OUT_TYPE_INT; + } + else if (strcasecmp("OUT_TYPE_CHAR", typestr) == 0) { + return OUT_TYPE_CHAR; + } + else if (strcasecmp("OUT_TYPE_FLOAT", typestr) == 0) { return OUT_TYPE_FLOAT; } else if (strcasecmp("OUT_TYPE_DOUBLE", typestr) == 0) { diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index 3bd5d61e0..ef9efdeaa 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -272,7 +272,8 @@ print_global_param(global_param_struct *gp) fprintf(LOG_DEST, "\tforceoffset[%zd] : %hu\n", i, gp->forceoffset[i]); fprintf(LOG_DEST, "\tforceskip[%zd] : %u\n", i, gp->forceskip[i]); - fprintf(LOG_DEST, "\tforceyear[%zd] : %hu\n", i, gp->forceyear[i]); + fprintf(LOG_DEST, "\tforceyear[%zd] : %hu\n", i, + gp->forceyear[i]); } fprintf(LOG_DEST, "\tnrecs : %zu\n", gp->nrecs); fprintf(LOG_DEST, "\tstartday : %hu\n", gp->startday); @@ -430,59 +431,95 @@ void print_option(option_struct *option) { fprintf(LOG_DEST, "option:\n"); - fprintf(LOG_DEST, "\tAboveTreelineVeg : %d\n", option->AboveTreelineVeg); - fprintf(LOG_DEST, "\tAERO_RESIST_CANSNOW : %d\n", option->AERO_RESIST_CANSNOW); - fprintf(LOG_DEST, "\tBLOWING : %s\n", option->BLOWING ? "true" : "false"); - fprintf(LOG_DEST, "\tBLOWING_VAR_THRESHOLD: %s\n", option->BLOWING_VAR_THRESHOLD ? "true" : "false"); - fprintf(LOG_DEST, "\tBLOWING_CALC_PROB : %s\n", option->BLOWING_CALC_PROB ? "true" : "false"); - fprintf(LOG_DEST, "\tBLOWING_SIMPLE : %s\n", option->BLOWING_SIMPLE ? "true" : "false"); - fprintf(LOG_DEST, "\tBLOWING_FETCH : %s\n", option->BLOWING_FETCH ? "true" : "false"); - fprintf(LOG_DEST, "\tBLOWING_SPATIAL_WIND : %s\n", option->BLOWING_SPATIAL_WIND ? "true" : "false"); - fprintf(LOG_DEST, "\tCARBON : %s\n", option->CARBON ? "true" : "false"); - fprintf(LOG_DEST, "\tCLOSE_ENERGY : %s\n", option->CLOSE_ENERGY ? "true" : "false"); - fprintf(LOG_DEST, "\tCOMPUTE_TREELINE : %s\n", option->COMPUTE_TREELINE ? "true" : "false"); - fprintf(LOG_DEST, "\tCONTINUEONERROR : %s\n", option->CONTINUEONERROR ? "true" : "false"); - fprintf(LOG_DEST, "\tCORRPREC : %s\n", option->CORRPREC ? "true" : "false"); - fprintf(LOG_DEST, "\tEQUAL_AREA : %s\n", option->EQUAL_AREA ? "true" : "false"); - fprintf(LOG_DEST, "\tEXP_TRANS : %s\n", option->EXP_TRANS ? "true" : "false"); - fprintf(LOG_DEST, "\tFROZEN_SOIL : %s\n", option->FROZEN_SOIL ? "true" : "false"); - fprintf(LOG_DEST, "\tFULL_ENERGY : %s\n", option->FULL_ENERGY ? "true" : "false"); + fprintf(LOG_DEST, "\tAboveTreelineVeg : %d\n", + option->AboveTreelineVeg); + fprintf(LOG_DEST, "\tAERO_RESIST_CANSNOW : %d\n", + option->AERO_RESIST_CANSNOW); + fprintf(LOG_DEST, "\tBLOWING : %s\n", + option->BLOWING ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_VAR_THRESHOLD: %s\n", + option->BLOWING_VAR_THRESHOLD ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_CALC_PROB : %s\n", + option->BLOWING_CALC_PROB ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_SIMPLE : %s\n", + option->BLOWING_SIMPLE ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_FETCH : %s\n", + option->BLOWING_FETCH ? "true" : "false"); + fprintf(LOG_DEST, "\tBLOWING_SPATIAL_WIND : %s\n", + option->BLOWING_SPATIAL_WIND ? "true" : "false"); + fprintf(LOG_DEST, "\tCARBON : %s\n", + option->CARBON ? "true" : "false"); + fprintf(LOG_DEST, "\tCLOSE_ENERGY : %s\n", + option->CLOSE_ENERGY ? "true" : "false"); + fprintf(LOG_DEST, "\tCOMPUTE_TREELINE : %s\n", + option->COMPUTE_TREELINE ? "true" : "false"); + fprintf(LOG_DEST, "\tCONTINUEONERROR : %s\n", + option->CONTINUEONERROR ? "true" : "false"); + fprintf(LOG_DEST, "\tCORRPREC : %s\n", + option->CORRPREC ? "true" : "false"); + fprintf(LOG_DEST, "\tEQUAL_AREA : %s\n", + option->EQUAL_AREA ? "true" : "false"); + fprintf(LOG_DEST, "\tEXP_TRANS : %s\n", + option->EXP_TRANS ? "true" : "false"); + fprintf(LOG_DEST, "\tFROZEN_SOIL : %s\n", + option->FROZEN_SOIL ? "true" : "false"); + fprintf(LOG_DEST, "\tFULL_ENERGY : %s\n", + option->FULL_ENERGY ? "true" : "false"); fprintf(LOG_DEST, "\tGRND_FLUX_TYPE : %d\n", option->GRND_FLUX_TYPE); - fprintf(LOG_DEST, "\tIMPLICIT : %s\n", option->IMPLICIT ? "true" : "false"); - fprintf(LOG_DEST, "\tJULY_TAVG_SUPPLIED : %s\n", option->JULY_TAVG_SUPPLIED ? "true" : "false"); - fprintf(LOG_DEST, "\tLAKES : %s\n", option->LAKES ? "true" : "false"); + fprintf(LOG_DEST, "\tIMPLICIT : %s\n", + option->IMPLICIT ? "true" : "false"); + fprintf(LOG_DEST, "\tJULY_TAVG_SUPPLIED : %s\n", + option->JULY_TAVG_SUPPLIED ? "true" : "false"); + fprintf(LOG_DEST, "\tLAKES : %s\n", + option->LAKES ? "true" : "false"); fprintf(LOG_DEST, "\tNcanopy : %zu\n", option->Ncanopy); fprintf(LOG_DEST, "\tNfrost : %zu\n", option->Nfrost); fprintf(LOG_DEST, "\tNlakenode : %zu\n", option->Nlakenode); fprintf(LOG_DEST, "\tNlayer : %zu\n", option->Nlayer); fprintf(LOG_DEST, "\tNnode : %zu\n", option->Nnode); - fprintf(LOG_DEST, "\tNOFLUX : %s\n", option->NOFLUX ? "true" : "false"); + fprintf(LOG_DEST, "\tNOFLUX : %s\n", + option->NOFLUX ? "true" : "false"); fprintf(LOG_DEST, "\tNVEGTYPES : %zu\n", option->NVEGTYPES); fprintf(LOG_DEST, "\tRC_MODE : %d\n", option->RC_MODE); fprintf(LOG_DEST, "\tROOT_ZONES : %zu\n", option->ROOT_ZONES); - fprintf(LOG_DEST, "\tQUICK_FLUX : %s\n", option->QUICK_FLUX ? "true" : "false"); - fprintf(LOG_DEST, "\tQUICK_SOLVE : %s\n", option->QUICK_SOLVE ? "true" : "false"); - fprintf(LOG_DEST, "\tSHARE_LAYER_MOIST : %s\n", option->SHARE_LAYER_MOIST ? "true" : "false"); + fprintf(LOG_DEST, "\tQUICK_FLUX : %s\n", + option->QUICK_FLUX ? "true" : "false"); + fprintf(LOG_DEST, "\tQUICK_SOLVE : %s\n", + option->QUICK_SOLVE ? "true" : "false"); + fprintf(LOG_DEST, "\tSHARE_LAYER_MOIST : %s\n", + option->SHARE_LAYER_MOIST ? "true" : "false"); fprintf(LOG_DEST, "\tSNOW_DENSITY : %d\n", option->SNOW_DENSITY); fprintf(LOG_DEST, "\tSNOW_BAND : %zu\n", option->SNOW_BAND); - fprintf(LOG_DEST, "\tSPATIAL_FROST : %s\n", option->SPATIAL_FROST ? "true" : "false"); - fprintf(LOG_DEST, "\tSPATIAL_SNOW : %s\n", option->SPATIAL_SNOW ? "true" : "false"); - fprintf(LOG_DEST, "\tTFALLBACK : %s\n", option->TFALLBACK ? "true" : "false"); + fprintf(LOG_DEST, "\tSPATIAL_FROST : %s\n", + option->SPATIAL_FROST ? "true" : "false"); + fprintf(LOG_DEST, "\tSPATIAL_SNOW : %s\n", + option->SPATIAL_SNOW ? "true" : "false"); + fprintf(LOG_DEST, "\tTFALLBACK : %s\n", + option->TFALLBACK ? "true" : "false"); fprintf(LOG_DEST, "\tBASEFLOW : %d\n", option->BASEFLOW); fprintf(LOG_DEST, "\tGRID_DECIMAL : %d\n", option->GRID_DECIMAL); - fprintf(LOG_DEST, "\tVEGLIB_PHOTO : %s\n", option->VEGLIB_PHOTO ? "true" : "false"); - fprintf(LOG_DEST, "\tVEGLIB_FCAN : %s\n", option->VEGLIB_FCAN ? "true" : "false"); - fprintf(LOG_DEST, "\tVEGPARAM_ALB : %s\n", option->VEGPARAM_ALB ? "true" : "false"); - fprintf(LOG_DEST, "\tVEGPARAM_LAI : %s\n", option->VEGPARAM_LAI ? "true" : "false"); - fprintf(LOG_DEST, "\tVEGPARAM_FCAN : %s\n", option->VEGPARAM_FCAN ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGLIB_PHOTO : %s\n", + option->VEGLIB_PHOTO ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGLIB_FCAN : %s\n", + option->VEGLIB_FCAN ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_ALB : %s\n", + option->VEGPARAM_ALB ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_LAI : %s\n", + option->VEGPARAM_LAI ? "true" : "false"); + fprintf(LOG_DEST, "\tVEGPARAM_FCAN : %s\n", + option->VEGPARAM_FCAN ? "true" : "false"); fprintf(LOG_DEST, "\tALB_SRC : %d\n", option->ALB_SRC); fprintf(LOG_DEST, "\tLAI_SRC : %d\n", option->LAI_SRC); fprintf(LOG_DEST, "\tFCAN_SRC : %d\n", option->FCAN_SRC); - fprintf(LOG_DEST, "\tLAKE_PROFILE : %s\n", option->LAKE_PROFILE ? "true" : "false"); - fprintf(LOG_DEST, "\tORGANIC_FRACT : %s\n", option->ORGANIC_FRACT ? "true" : "false"); + fprintf(LOG_DEST, "\tLAKE_PROFILE : %s\n", + option->LAKE_PROFILE ? "true" : "false"); + fprintf(LOG_DEST, "\tORGANIC_FRACT : %s\n", + option->ORGANIC_FRACT ? "true" : "false"); fprintf(LOG_DEST, "\tSTATE_FORMAT : %d\n", option->STATE_FORMAT); - fprintf(LOG_DEST, "\tINIT_STATE : %s\n", option->INIT_STATE ? "true" : "false"); - fprintf(LOG_DEST, "\tSAVE_STATE : %s\n", option->SAVE_STATE ? "true" : "false"); + fprintf(LOG_DEST, "\tINIT_STATE : %s\n", + option->INIT_STATE ? "true" : "false"); + fprintf(LOG_DEST, "\tSAVE_STATE : %s\n", + option->SAVE_STATE ? "true" : "false"); fprintf(LOG_DEST, "\tNoutstreams : %zu\n", option->Noutstreams); } @@ -808,17 +845,21 @@ print_snow_data(snow_data_struct *snow) fprintf(LOG_DEST, "\tdepth : %f\n", snow->depth); fprintf(LOG_DEST, "\tlast_snow : %d\n", snow->last_snow); fprintf(LOG_DEST, "\tmax_snow_depth : %f\n", snow->max_snow_depth); - fprintf(LOG_DEST, "\tMELTING : %s\n", snow->MELTING ? "true" : "false"); + fprintf(LOG_DEST, "\tMELTING : %s\n", + snow->MELTING ? "true" : "false"); fprintf(LOG_DEST, "\tpack_temp : %f\n", snow->pack_temp); fprintf(LOG_DEST, "\tpack_water : %f\n", snow->pack_water); - fprintf(LOG_DEST, "\tsnow : %s\n", snow->snow ? "true" : "false"); + fprintf(LOG_DEST, "\tsnow : %s\n", + snow->snow ? "true" : "false"); fprintf(LOG_DEST, "\tsnow_canopy : %f\n", snow->snow_canopy); fprintf(LOG_DEST, "\tstore_coverage : %f\n", snow->store_coverage); - fprintf(LOG_DEST, "\tstore_snow : %s\n", snow->store_snow ? "true" : "false"); + fprintf(LOG_DEST, "\tstore_snow : %s\n", + snow->store_snow ? "true" : "false"); fprintf(LOG_DEST, "\tstore_swq : %f\n", snow->store_swq); fprintf(LOG_DEST, "\tsurf_temp : %f\n", snow->surf_temp); fprintf(LOG_DEST, "\tsurf_temp_fbcount : %u\n", snow->surf_temp_fbcount); - fprintf(LOG_DEST, "\tsurf_temp_fbflag : %s\n", snow->surf_temp_fbflag ? "true" : "false"); + fprintf(LOG_DEST, "\tsurf_temp_fbflag : %s\n", + snow->surf_temp_fbflag ? "true" : "false"); fprintf(LOG_DEST, "\tsurf_water : %f\n", snow->surf_water); fprintf(LOG_DEST, "\tswq : %f\n", snow->swq); fprintf(LOG_DEST, "\tsnow_distrib_slope: %f\n", @@ -852,7 +893,8 @@ print_soil_con(soil_con_struct *scon, size_t j; fprintf(LOG_DEST, "soil_con:\n"); - fprintf(LOG_DEST, "\tFS_ACTIVE : %s\n", scon->FS_ACTIVE ? "true" : "false"); + fprintf(LOG_DEST, "\tFS_ACTIVE : %s\n", + scon->FS_ACTIVE ? "true" : "false"); fprintf(LOG_DEST, "\tDs : %f\n", scon->Ds); fprintf(LOG_DEST, "\tDsmax : %f\n", scon->Dsmax); fprintf(LOG_DEST, "\tKsat :"); @@ -1121,7 +1163,8 @@ print_veg_lib(veg_lib_struct *vlib, size_t i; fprintf(LOG_DEST, "veg_lib:\n"); - fprintf(LOG_DEST, "\toverstory : %s\n", vlib->overstory ? "true" : "false"); + fprintf(LOG_DEST, "\toverstory : %s\n", + vlib->overstory ? "true" : "false"); fprintf(LOG_DEST, "\tLAI :"); for (i = 0; i < MONTHS_PER_YEAR; i++) { fprintf(LOG_DEST, "\t%.2f", vlib->LAI[i]); @@ -1172,7 +1215,8 @@ print_veg_lib(veg_lib_struct *vlib, fprintf(LOG_DEST, "\tMaxETransport : %.4f\n", vlib->MaxETransport); fprintf(LOG_DEST, "\tCO2Specificity: %.4f\n", vlib->CO2Specificity); fprintf(LOG_DEST, "\tLightUseEff : %.4f\n", vlib->LightUseEff); - fprintf(LOG_DEST, "\tNscaleFlag : %s\n", vlib->NscaleFlag ? "true" : "false"); + fprintf(LOG_DEST, "\tNscaleFlag : %s\n", + vlib->NscaleFlag ? "true" : "false"); fprintf(LOG_DEST, "\tWnpp_inhib : %.4f\n", vlib->Wnpp_inhib); fprintf(LOG_DEST, "\tNPPfactor_sat : %.4f\n", vlib->NPPfactor_sat); } From d8797e28df15f79c188d57c4195195ff5d1cb161 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 17 Mar 2017 16:39:30 -0600 Subject: [PATCH 173/294] replace missing Q12 in vic_run header --- vic/vic_run/include/vic_run.h | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index f63d4098b..02ae0c073 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -116,6 +116,7 @@ void compute_pot_evap(size_t, double, double, double, double, double, double, double, double *); void compute_runoff_and_asat(soil_con_struct *, double *, double, double *, double *); +double calc_Q12(double, double, double, double, double); void compute_soil_resp(int, double *, double, double, double *, double *, double, double, double, double *, double *, double *); void compute_soil_layer_thermal_properties(layer_data_struct *, double *, From f69229a4fe48c7450edb82f21a235f36efe97253 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 27 Apr 2017 13:44:02 -0700 Subject: [PATCH 174/294] use minimum tolerance threshold defined in header file for area/elevation sums --- docs/Documentation/Drivers/Image/Params.md | 3 +++ .../shared_image/include/vic_driver_shared_image.h | 1 + vic/drivers/shared_image/src/vic_init.c | 14 ++++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index 243904ba2..5be216247 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -2,6 +2,9 @@ The Image Driver uses the [NetCDF](http://www.unidata.ucar.edu/software/netcdf/) file format for its input model parameters. It is possible to convert the VIC ASCII style parameters to this format. We have put together an example ([Tutorial](Ascii_to_NetCDF_params.md) and [Ipython Notebook](https://github.com/UW-Hydro/VIC/blob/develop/samples/notebooks/example_reformat_vic4_parameters_to_vic5image.ipynb)) that provide examples of how to do this conversion. Our example uses the `tonic` [Python](https://www.python.org/) Package. +!!! Note + It is the user's responsibility to ensure that parameter files are formatted appropriately. Notably, the variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *** warnings *** if any of these criteria are violated. + # Soil Parameters The Soil Parameters serve three main purposes: diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index dc4766cce..00e8d6597 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -34,6 +34,7 @@ #include #define MAXDIMS 10 +#define AREA_SUM_ERROR_THRESH 1e-20 /****************************************************************************** * @brief NetCDF file types diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 4020c1c6e..625d2ad5e 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -986,7 +986,7 @@ vic_init(void) } sum += soil_con[i].AreaFract[j]; } - if (!assert_close_double(sum, 1.0, 0., 0.001)) { + if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Sum of the snow band area fractions does not equal " "1 (%f), dividing each fraction by the sum\n%s", @@ -1001,7 +1001,8 @@ vic_init(void) for (j = 0; j < options.SNOW_BAND; j++) { mean += soil_con[i].BandElev[j] * soil_con[i].AreaFract[j]; } - if (!assert_close_double(soil_con[i].elevation, mean, 0., 0.001)) { + if (!assert_close_double(soil_con[i].elevation, mean, 0., + AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("average band elevation %f not equal to grid_cell " "average elevation %f; setting grid cell elevation " @@ -1039,7 +1040,7 @@ vic_init(void) } sum += soil_con[i].Pfactor[j]; } - if (!assert_close_double(sum, 1.0, 0., 0.001)) { + if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Sum of the snow band precipitation fractions does " "not equal 1 (%f), dividing each fraction by the " @@ -1188,7 +1189,7 @@ vic_init(void) for (k = 0; k < options.ROOT_ZONES; k++) { sum += veg_con[i][vidx].zone_fract[k]; } - if (!assert_close_double(sum, 1.0, 0., 0.001)) { + if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Root zone fractions sum to more than 1 (%f), " "normalizing fractions. If the sum is large, " @@ -1226,8 +1227,9 @@ vic_init(void) // TODO: handle bare soil adjustment for compute treeline option - // If the sum of the tile fractions is not within a tolerance, throw an error - if (!assert_close_double(Cv_sum[i], 1., 0., 0.001)) { + // If the sum of the tile fractions is not within a tolerance, + // throw an error + if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_err("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", Cv_sum[i], i, locstr); From 4a5ec66e62e4f3054c9934490af8705d35d0bb1c Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 27 Apr 2017 17:57:56 -0700 Subject: [PATCH 175/294] divide Cv by Cv_sum --- vic/drivers/shared_image/src/vic_init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 625d2ad5e..fd0ca0233 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1231,8 +1231,12 @@ vic_init(void) // throw an error if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_err("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", + log_warn("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", Cv_sum[i], i, locstr); + for (j = 0; j < options.NVEGTYPES; j++) { + vidx = veg_con_map[i].vidx[j]; + veg_con[i][vidx].Cv /= Cv_sum[i]; + } } } From 5284d2dd316769376e374da9f2a00bc6eca5fae8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 7 Aug 2017 16:42:53 -0700 Subject: [PATCH 176/294] add release notes entry --- docs/Development/ReleaseNotes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 681534b39..a1f701bb3 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -63,6 +63,9 @@ To check which release of VIC you are running: Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. + [GH#726] (https://github.com/UW-Hydro/VIC/pull/726) + + Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) From 906cc8472fadd18844446e8127fcefb6ee56fdb3 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Mon, 7 Aug 2017 16:44:53 -0700 Subject: [PATCH 177/294] roll back accidental changes --- docs/Development/ReleaseNotes.md | 10 +++---- vic/drivers/cesm/src/cesm_interface_c.c | 4 +++ vic/drivers/cesm/src/cesm_put_data.c | 37 ++---------------------- vic/drivers/cesm/src/vic_force.c | 4 +-- vic/drivers/image/Makefile | 4 +-- vic/drivers/shared_image/src/vic_store.c | 6 ++-- vic/drivers/shared_image/src/vic_write.c | 2 +- 7 files changed, 19 insertions(+), 48 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index a64827aef..4dc8e93ff 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -53,15 +53,15 @@ To check which release of VIC you are running: [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) - Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. + Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. [GH#716] (https://github.com/UW-Hydro/VIC/pull/716) - Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. + Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. [GH#718] (https://github.com/UW-Hydro/VIC/pull/718) - Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. + Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) @@ -88,7 +88,7 @@ To check which release of VIC you are running: 2. Fixed forceskip rounding bug ([GH#639](https://github.com/UW-Hydro/VIC/pull/639)) - After the fix, the `forceskip` variable in the global parameter structure (i.e., the number of timesteps to skip in the forcing data for the simulatin period) is rounded correctly (before the fix, rounding error might cause 1-timestep offset in the simulation results). + After the fix, the `forceskip` variable in the global parameter structure (i.e., the number of timesteps to skip in the forcing data for the simulation period) is rounded correctly (before the fix, rounding error might cause 1-timestep offset in the simulation results). 3. Fixed a problem with image restarts when using multiple processors ([GH#638](https://github.com/UW-Hydro/VIC/pull/638)) @@ -122,7 +122,7 @@ To check which release of VIC you are running: ------------------------------ -## VIC 5.0.0 [![DOI](https://zenodo.org/badge/7766/UW-Hydro/VIC.svg)](https://zenodo.org/badge/latestdoi/7766/UW-Hydro/VIC) +## VIC 5.0.0 [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.61422.svg)](http://dx.doi.org/10.5281/zenodo.61422) **Release date: (September 2, 2016)** diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 36b755402..b9070968a 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -96,6 +96,9 @@ vic_cesm_init(vic_clock *vclock, // populate model state, either using a cold start or from a restart file vic_populate_model_state(trimstr(cmeta->starttype), &dmy_current); + // initialize forcings + vic_force(); + // initialize output structures vic_init_output(&dmy_current); @@ -156,6 +159,7 @@ vic_cesm_run(vic_clock *vclock) // if save: if (vclock->state_flag) { + // write state file vic_store(&dmy_current, state_filename); write_rpointer_file(state_filename); } diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index acc52a511..9b4846230 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -258,41 +258,8 @@ vic_cesm_put_data() } } - // heat flux shortwave net - l2x_vic[i].l2x_Fall_swnet += AreaFactor * - (force[i].shortwave[NR] - - energy.NetShortAtmos); - - // co2 flux **For testing set to 0 - // l2x_vic[i].l2x_Fall_fco2_lnd; - - // dust flux size bin 1 - // l2x_vic[i].l2x_Fall_flxdst1; - - // dust flux size bin 2 - // l2x_vic[i].l2x_Fall_flxdst2; - - // dust flux size bin 3 - // l2x_vic[i].l2x_Fall_flxdst3; - - // dust flux size bin 4 - // l2x_vic[i].l2x_Fall_flxdst4; - - // MEGAN fluxes - // l2x_vic[i].l2x_Fall_flxvoc; - - // lnd->rtm input fluxes - l2x_vic[i].l2x_Flrl_rofliq += AreaFactor * - (cell.runoff + - cell.baseflow) / global_param.dt; - - // lnd->rtm input fluxes - // l2x_vic[i].l2x_Flrl_rofice; - - // vars set flag - l2x_vic[i].l2x_vars_set = true; - } - } + // set variables-set flag + l2x_vic[i].l2x_vars_set = true; if (!assert_close_double(AreaFactorSum, 1., 0., 1e-3)) { log_warn("AreaFactorSum (%f) is not 1", diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index 7eaaa2d19..b6a8db94e 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -128,8 +128,8 @@ vic_force(void) for (j = 0; j < NF; j++) { for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: Pa - // VIC units: kPa - force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot / PA_PER_KPA; + // VIC units: Pa + force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot; } } diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 9182dbf5d..b80455cd4 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -80,10 +80,10 @@ CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ -DUSERNAME=\"$(USER)\" \ -DHOSTNAME=\"$(HOSTNAME)\" -# ifeq (true, ${TRAVIS}) +ifeq (true, ${TRAVIS}) # Add extra debugging for builds on travis CFLAGS += -rdynamic -Wl,-export-dynamic -# endif +endif LIBRARY = -lm ${NC_LIBS} diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index a91929f64..602dac2a2 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -824,7 +824,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.d_fillvalue, + nc_state_file.i_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; @@ -837,7 +837,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.d_fillvalue, + nc_state_file.i_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; @@ -983,7 +983,7 @@ vic_store(dmy_struct *dmy_state, } gather_put_nc_field_int(nc_state_file.nc_id, nc_var->nc_varid, - nc_state_file.d_fillvalue, + nc_state_file.i_fillvalue, d2start, nc_var->nc_counts, ivar); for (i = 0; i < local_domain.ncells_active; i++) { ivar[i] = nc_state_file.i_fillvalue; diff --git a/vic/drivers/shared_image/src/vic_write.c b/vic/drivers/shared_image/src/vic_write.c index 4cd346619..88e697b2c 100644 --- a/vic/drivers/shared_image/src/vic_write.c +++ b/vic/drivers/shared_image/src/vic_write.c @@ -194,7 +194,7 @@ vic_write(stream_struct *stream, } gather_put_nc_field_schar(nc_hist_file->nc_id, nc_hist_file->nc_vars[k].nc_varid, - nc_hist_file->d_fillvalue, + nc_hist_file->c_fillvalue, dstart, dcount, cvar); } else { From d9e58530749e2cc62a2e91ad2ffec5eb4f1be0f0 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Mon, 7 Aug 2017 16:55:03 -0700 Subject: [PATCH 178/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 4dc8e93ff..5561d1b5b 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -76,6 +76,10 @@ To check which release of VIC you are running: This is for use in the CESM driver for VIC to pass to WRF, but has been implemented in the core structure of VIC (in vic_run) for consistency with the classic and image drivers. Running VIC from a cold start now also includes calculation of gridcell-averaged albedo. +6. Cleanup of the initialization sections of the ``image`` and ``cesm`` drivers ([GH#701](https://github.com/UW-Hydro/VIC/pull/701)) + + Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. + ## VIC 5.0.1 **Release date: (February 1, 2017)** From 3fadb778976f2539a2f4514eb39f2587672bbb24 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 7 Aug 2017 21:09:31 -0400 Subject: [PATCH 179/294] remove comment --- vic/drivers/cesm/src/cesm_put_data.c | 1 - 1 file changed, 1 deletion(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index f84c7800b..0db0c0fe1 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -158,7 +158,6 @@ vic_cesm_put_data() l2x_vic[i].l2x_Fall_sen += -1 * out_data[i][OUT_SENSIBLE][0]; // evaporation, VIC: mm, CESM: kg m-2 s-1 - // TO-DO should we incorporate bare soil evap? l2x_vic[i].l2x_Fall_evap += out_data[i][OUT_EVAP][0] / global_param.dt; From 322259a135771486920fd9f809b47723cb77a0c9 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Tue, 8 Aug 2017 07:55:42 -0700 Subject: [PATCH 180/294] run uncrustify, no code changes (#725) --- vic/vic_run/src/CalcBlowingSnow.c | 50 ++++++++++++------------ vic/vic_run/src/func_canopy_energy_bal.c | 4 +- vic/vic_run/src/snow_intercept.c | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/vic/vic_run/src/CalcBlowingSnow.c b/vic/vic_run/src/CalcBlowingSnow.c index 84357919d..7d3f458f7 100644 --- a/vic/vic_run/src/CalcBlowingSnow.c +++ b/vic/vic_run/src/CalcBlowingSnow.c @@ -271,18 +271,18 @@ CalcBlowingSnow(double Dt, *****************************************************************************/ double qromb(double (*funcd)(), - double es, - double Wind, - double AirDens, - double ZO, - double EactAir, - double F, - double hsalt, - double phi_r, - double ushear, - double Zrh, - double a, - double b) + double es, + double Wind, + double AirDens, + double ZO, + double EactAir, + double F, + double hsalt, + double phi_r, + double ushear, + double Zrh, + double a, + double b) { extern parameters_struct param; @@ -363,19 +363,19 @@ polint(double xa[], *****************************************************************************/ double trapzd(double (*funcd)(), - double es, - double Wind, - double AirDens, - double ZO, - double EactAir, - double F, - double hsalt, - double phi_r, - double ushear, - double Zrh, - double a, - double b, - int n) + double es, + double Wind, + double AirDens, + double ZO, + double EactAir, + double F, + double hsalt, + double phi_r, + double ushear, + double Zrh, + double a, + double b, + int n) { double x, tnm, sum, del; static double s; diff --git a/vic/vic_run/src/func_canopy_energy_bal.c b/vic/vic_run/src/func_canopy_energy_bal.c index 8aeea60e7..5f5a9d066 100644 --- a/vic/vic_run/src/func_canopy_energy_bal.c +++ b/vic/vic_run/src/func_canopy_energy_bal.c @@ -217,7 +217,7 @@ func_canopy_energy_bal(double Tfoliage, /* Calculate the latent heat flux */ Ls = calc_latent_heat_of_sublimation(Tfoliage); - *LatentHeatSub = Ls **VaporMassFlux * CONST_RHOFW; + *LatentHeatSub = Ls * *VaporMassFlux * CONST_RHOFW; *LatentHeat = 0; *Evap = 0; veg_var->throughfall = 0; @@ -246,7 +246,7 @@ func_canopy_energy_bal(double Tfoliage, root, dryFrac, shortwave, Catm, CanopLayerBnd); *Wdew /= MM_PER_M; - *LatentHeat = Le **Evap * CONST_RHOFW; + *LatentHeat = Le * *Evap * CONST_RHOFW; *LatentHeatSub = 0; } diff --git a/vic/vic_run/src/snow_intercept.c b/vic/vic_run/src/snow_intercept.c index f803dbaab..ebc13174b 100644 --- a/vic/vic_run/src/snow_intercept.c +++ b/vic/vic_run/src/snow_intercept.c @@ -518,7 +518,7 @@ snow_intercept(double Dt, /* Energy released by freezing of intercepted water is added to the MeltEnergy */ - *MeltEnergy += (CONST_LATICE **IntRain * CONST_RHOFW) / (Dt); + *MeltEnergy += (CONST_LATICE * *IntRain * CONST_RHOFW) / (Dt); *IntRain = 0.0; } From 56d1e840cef20b9cae9da7331e50cc770d6497ea Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Tue, 8 Aug 2017 09:00:57 -0700 Subject: [PATCH 181/294] cleanup after review --- vic/drivers/shared_all/include/vic_driver_shared_all.h | 2 ++ vic/drivers/shared_all/src/calc_root_fraction.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index d71963606..e1464f49b 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -45,6 +45,8 @@ // Default snow band setting #define SNOW_BAND_TRUE_BUT_UNSET 99999 +// Max counter for root distribution iteration +#define MAX_ROOT_ITER 9999 /****************************************************************************** * @brief File formats *****************************************************************************/ diff --git a/vic/drivers/shared_all/src/calc_root_fraction.c b/vic/drivers/shared_all/src/calc_root_fraction.c index a677f5a15..ff9efb9a1 100644 --- a/vic/drivers/shared_all/src/calc_root_fraction.c +++ b/vic/drivers/shared_all/src/calc_root_fraction.c @@ -42,7 +42,7 @@ calc_root_fractions(veg_con_struct *veg_con, size_t layer; size_t zone; size_t i; - size_t max_itter; + size_t n_iter; double sum_fract; double dum; double Zstep; @@ -63,10 +63,10 @@ calc_root_fractions(veg_con_struct *veg_con, Zsum = 0; zone = 0; - max_itter = -1; + n_iter = 0; while (zone < options.ROOT_ZONES) { - max_itter++; - if (max_itter > 9999) { + n_iter++; + if (n_iter > MAX_ROOT_ITER) { log_warn("veg=%d of Nveg=%d", veg, Nveg); log_warn("zone %zu of %zu ROOT_ZONES", zone, options.ROOT_ZONES); @@ -134,7 +134,7 @@ calc_root_fractions(veg_con_struct *veg_con, } } else if (Zsum + Zstep > Lsum) { - zone++; // should this be here? + zone++; if (layer < options.Nlayer) { veg_con[veg].root[layer] = sum_fract; sum_fract = 0.; From 0e3eaa8cc282d8b3f7ad4c7ec2f703632e57a9dc Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 15:26:40 -0400 Subject: [PATCH 182/294] add comment for the sake of clarity for pressure and vapor pressure units in CESM driver --- vic/drivers/cesm/src/vic_force.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index b6a8db94e..e7abd88ee 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -137,7 +137,7 @@ vic_force(void) for (j = 0; j < NF; j++) { for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: shum is specific humidity (g/g) - // VIC units: kPa + // VIC units: kPa inputs, uses Pa force[i].vp[j] = q_to_vp(x2l_vic[i].x2l_Sa_shum, force[i].pressure[j]); } From 55d5eddb517aa64b9f41e3f479a9f7fecf859f51 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 16:54:37 -0400 Subject: [PATCH 183/294] remove negative sign from sensible heat and add parentheses to rofliq calculation --- vic/drivers/cesm/src/cesm_put_data.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 0db0c0fe1..8d6d7807c 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -155,15 +155,15 @@ vic_cesm_put_data() l2x_vic[i].l2x_Fall_lat = out_data[i][OUT_LATENT][0]; // sensible heat, VIC: W/m2, CESM: W/m2 - l2x_vic[i].l2x_Fall_sen += -1 * out_data[i][OUT_SENSIBLE][0]; + l2x_vic[i].l2x_Fall_sen += out_data[i][OUT_SENSIBLE][0]; // evaporation, VIC: mm, CESM: kg m-2 s-1 l2x_vic[i].l2x_Fall_evap += out_data[i][OUT_EVAP][0] / global_param.dt; // lnd->rtm input fluxes - l2x_vic[i].l2x_Flrl_rofliq = out_data[i][OUT_RUNOFF][0] + - out_data[i][OUT_BASEFLOW][0] / + l2x_vic[i].l2x_Flrl_rofliq = (out_data[i][OUT_RUNOFF][0] + + out_data[i][OUT_BASEFLOW][0]) / global_param.dt; From 18823e28146aeff979ceb109bf57c629a418edfd Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 13:57:30 -0700 Subject: [PATCH 184/294] ran uncrustify --- vic/drivers/cesm/src/cesm_put_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 8d6d7807c..3b6ee94ef 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -163,7 +163,7 @@ vic_cesm_put_data() // lnd->rtm input fluxes l2x_vic[i].l2x_Flrl_rofliq = (out_data[i][OUT_RUNOFF][0] + - out_data[i][OUT_BASEFLOW][0]) / + out_data[i][OUT_BASEFLOW][0]) / global_param.dt; From 76dcc434136f3c280110530b903f985a75a7935f Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 15:14:00 -0700 Subject: [PATCH 185/294] add release notes entry --- docs/Development/ReleaseNotes.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index cb745599e..d7b287285 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -65,7 +65,11 @@ To check which release of VIC you are running: [GH#726] (https://github.com/UW-Hydro/VIC/pull/726) - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. + Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. + + [GH#732] (https://github.com/UW-Hydro/VIC/pull/732) + + Updates theh cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) From aea131333abffbd2cd798b0792fe5b8423245a17 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 15:14:59 -0700 Subject: [PATCH 186/294] fix typo --- docs/Development/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index d7b287285..63279f014 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -69,7 +69,7 @@ To check which release of VIC you are running: [GH#732] (https://github.com/UW-Hydro/VIC/pull/732) - Updates theh cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). + Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) From 5718c7e2cc59c384eeaeb458a40140246b9a21ab Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 18:22:54 -0400 Subject: [PATCH 187/294] update comment --- vic/drivers/cesm/src/vic_force.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index e7abd88ee..e194b4d30 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -129,6 +129,8 @@ vic_force(void) for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: Pa // VIC units: Pa + // Note: Image Driver uses kPa inputs and + // converts to Pa force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot; } } @@ -137,7 +139,7 @@ vic_force(void) for (j = 0; j < NF; j++) { for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: shum is specific humidity (g/g) - // VIC units: kPa inputs, uses Pa + // VIC units: Pa force[i].vp[j] = q_to_vp(x2l_vic[i].x2l_Sa_shum, force[i].pressure[j]); } From ed39820ba658bdaffdf4646aefd6d5234a4d514d Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 9 Aug 2017 15:26:43 -0700 Subject: [PATCH 188/294] ran uncrustify --- vic/drivers/cesm/src/vic_force.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/vic_force.c b/vic/drivers/cesm/src/vic_force.c index e194b4d30..6a368fe5c 100644 --- a/vic/drivers/cesm/src/vic_force.c +++ b/vic/drivers/cesm/src/vic_force.c @@ -129,7 +129,7 @@ vic_force(void) for (i = 0; i < local_domain.ncells_active; i++) { // CESM units: Pa // VIC units: Pa - // Note: Image Driver uses kPa inputs and + // Note: Image Driver uses kPa inputs and // converts to Pa force[i].pressure[j] = x2l_vic[i].x2l_Sa_pbot; } From de1cc53ab91a8971a304e63b1c9107e1b2e8ea3e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 18 Aug 2017 15:02:41 -0700 Subject: [PATCH 189/294] Feature/fix remaining coupler fields (#734) * fix signs and leave ram1 field empty in accordance with VIC 4 implementation in RASM --- docs/Development/ReleaseNotes.md | 6 +++++- vic/drivers/cesm/src/cesm_put_data.c | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 63279f014..7f9d2e372 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -69,7 +69,11 @@ To check which release of VIC you are running: [GH#732] (https://github.com/UW-Hydro/VIC/pull/732) - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). + Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). + + [GH#734] (https://github.com/UW-Hydro/VIC/pull/734) + + Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 3b6ee94ef..b64c5f2aa 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -151,14 +151,16 @@ vic_cesm_put_data() out_data[i][OUT_LWNET][0]); // turbulent heat fluxes + // Note: both are the opposite sign from image driver + // in accordance with the sign convention for coupled models // latent heat, VIC: W/m2, CESM: W/m2 - l2x_vic[i].l2x_Fall_lat = out_data[i][OUT_LATENT][0]; + l2x_vic[i].l2x_Fall_lat = -1 * out_data[i][OUT_LATENT][0]; // sensible heat, VIC: W/m2, CESM: W/m2 - l2x_vic[i].l2x_Fall_sen += out_data[i][OUT_SENSIBLE][0]; + l2x_vic[i].l2x_Fall_sen += -1 * out_data[i][OUT_SENSIBLE][0]; // evaporation, VIC: mm, CESM: kg m-2 s-1 - l2x_vic[i].l2x_Fall_evap += out_data[i][OUT_EVAP][0] / + l2x_vic[i].l2x_Fall_evap += -1 * out_data[i][OUT_EVAP][0] / global_param.dt; // lnd->rtm input fluxes @@ -210,8 +212,6 @@ vic_cesm_put_data() aero_resist = param.HUGE_RESIST; } - l2x_vic[i].l2x_Sl_ram1 += AreaFactor * aero_resist; - // log z0 // CESM units: m if (snow.snow) { From abf9e93a655248de223f212356c1bc78af45caf9 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 18 Aug 2017 17:35:46 -0600 Subject: [PATCH 190/294] fix to makefile --- vic/drivers/image/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index e70b9223b..8d7bf2517 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -75,7 +75,7 @@ INCLUDES = -I ${DRIVERPATH}/include \ # Uncomment to include debugging information CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ - - fopenmp \ + -fopenmp \ -DLOG_LVL=$(LOG_LVL) \ -DGIT_VERSION=\"$(GIT_VERSION)\" \ -DUSERNAME=\"$(USER)\" \ From 349b7ed1e43ac320c394b8f5203675b65ef32ca3 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Tue, 22 Aug 2017 11:38:15 -0700 Subject: [PATCH 191/294] update timing table for openmp, release note --- docs/Development/ReleaseNotes.md | 11 +++++++---- vic/drivers/shared_image/src/vic_image_timing.c | 12 ++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 681534b39..79ea64209 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -53,16 +53,15 @@ To check which release of VIC you are running: [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) - Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. + Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. [GH#716] (https://github.com/UW-Hydro/VIC/pull/716) - Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. + Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. [GH#718] (https://github.com/UW-Hydro/VIC/pull/718) - Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. - + Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) @@ -76,6 +75,10 @@ To check which release of VIC you are running: This is for use in the CESM driver for VIC to pass to WRF, but has been implemented in the core structure of VIC (in vic_run) for consistency with the classic and image drivers. Running VIC from a cold start now also includes calculation of gridcell-averaged albedo. +6. Added thread parallelization using OPENMP ([GH#712](https://github.com/UW-Hydro/VIC/pull/712)) + + The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. + ## VIC 5.0.1 **Release date: (February 1, 2017)** diff --git a/vic/drivers/shared_image/src/vic_image_timing.c b/vic/drivers/shared_image/src/vic_image_timing.c index d5f0d41c6..e9b8a94a2 100644 --- a/vic/drivers/shared_image/src/vic_image_timing.c +++ b/vic/drivers/shared_image/src/vic_image_timing.c @@ -46,6 +46,8 @@ write_vic_timing_table(timer_struct *timers, struct passwd *pw; double ndays; double nyears; + int nprocs; + int nthreads; // datestr curr_date_time = time(NULL); @@ -70,6 +72,10 @@ write_vic_timing_table(timer_struct *timers, strcpy(user, "unknown"); } + // mpi/openmp + nthreads = omp_get_max_threads(); + nprocs = mpi_size * nthreads; + // calculate run length ndays = global_param.dt * global_param.nrecs / SEC_PER_DAY; nyears = ndays / DAYS_PER_YEAR; @@ -107,7 +113,9 @@ write_vic_timing_table(timer_struct *timers, global_param.atmos_dt); fprintf(LOG_DEST, "\n"); - fprintf(LOG_DEST, " Total pes active : %d\n", mpi_size); + fprintf(LOG_DEST, " MPI Processes : %d\n", mpi_size); + fprintf(LOG_DEST, " OPENMP Threads : %d\n", nthreads); + fprintf(LOG_DEST, " Total pes active : %d\n", nprocs); fprintf(LOG_DEST, " pes per node : %ld\n", sysconf(_SC_NPROCESSORS_ONLN)); @@ -116,7 +124,7 @@ write_vic_timing_table(timer_struct *timers, fprintf(LOG_DEST, " Overall Metrics\n"); fprintf(LOG_DEST, " ---------------\n"); fprintf(LOG_DEST, " Model Cost : %g pe-hrs/simulated_year\n", - mpi_size * timers[TIMER_VIC_ALL].delta_wall / SEC_PER_HOUR / + nprocs * timers[TIMER_VIC_ALL].delta_wall / SEC_PER_HOUR / nyears); fprintf(LOG_DEST, " Model Throughput : %g simulated_years/day\n", nyears / (timers[TIMER_VIC_ALL].delta_wall / SEC_PER_DAY)); From 656511d3e0544266b27b554c3a9947d6c21c6fca Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 22 Aug 2017 14:11:50 -0700 Subject: [PATCH 192/294] Feature/fix compiler warnings (#736) * remove unused variables * ran uncrustify --- .../shared_all/src/generate_default_state.c | 2 -- vic/vic_run/src/calc_gridcell_avg_albedo.c | 17 ++++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/vic/drivers/shared_all/src/generate_default_state.c b/vic/drivers/shared_all/src/generate_default_state.c index 5c5cb7ef5..cfcda7dc7 100644 --- a/vic/drivers/shared_all/src/generate_default_state.c +++ b/vic/drivers/shared_all/src/generate_default_state.c @@ -64,11 +64,9 @@ generate_default_state(all_vars_struct *all_vars, cell_data_struct **cell; energy_bal_struct **energy; - veg_var_struct **veg_var; cell = all_vars->cell; energy = all_vars->energy; - veg_var = all_vars->veg_var; Nveg = veg_con[0].vegetat_type_num; // allocate memory for tmpT and tmpZ diff --git a/vic/vic_run/src/calc_gridcell_avg_albedo.c b/vic/vic_run/src/calc_gridcell_avg_albedo.c index 4d400d965..e2ff2f2cc 100644 --- a/vic/vic_run/src/calc_gridcell_avg_albedo.c +++ b/vic/vic_run/src/calc_gridcell_avg_albedo.c @@ -42,15 +42,14 @@ calc_gridcell_avg_albedo(double *albedo, veg_con_struct *veg_con, soil_con_struct *soil_con) { - extern option_struct options; - extern parameters_struct param; - size_t veg; - size_t band; - double Cv; - double AreaFactor; - double TreeAdjustFactor = 1.; - double lakefactor = 1; - double swnet; + extern option_struct options; + size_t veg; + size_t band; + double Cv; + double AreaFactor; + double TreeAdjustFactor = 1.; + double lakefactor = 1; + double swnet; swnet = 0; *albedo = 0; From 5721f91f71956b4e050e7a24db117903a79869ce Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Tue, 22 Aug 2017 14:43:42 -0700 Subject: [PATCH 193/294] default shared and threadprivate global --- vic/drivers/shared_image/src/vic_image_run.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index c419afa98..637185ce6 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#pragma omp threadprivate(vic_run_ref_str) /****************************************************************************** * @brief Run VIC for one timestep and store output data @@ -55,7 +56,7 @@ vic_image_run(dmy_struct *dmy_current) sprint_dmy(dmy_str, dmy_current); debug("Running timestep %zu: %s", current, dmy_str); - #pragma omp parallel for private(i,vic_run_ref_str) + #pragma omp parallel for default(shared) private(i, timer) for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) sprintf(vic_run_ref_str, "Gridcell io_idx: %zu, timestep info: %s", From 3c23b8589be39a1e00ba19fdf5bc2749f3bcd2ee Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 23 Aug 2017 14:37:40 -0700 Subject: [PATCH 194/294] threadsafe static variables in vic_run and update docs for OpenMP --- docs/Documentation/Drivers/Image/RunVIC.md | 16 ++++++++++++++-- tests/test_restart.py | 4 ++-- vic/vic_run/src/CalcBlowingSnow.c | 1 + vic/vic_run/src/frozen_soil.c | 8 ++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index a8847ee4a..288485f80 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -48,11 +48,23 @@ At the command prompt, type: where `global_parameter_filename` = name of the global parameter file corresponding to your project. -To run VIC image driver using multiple processors, type the following instead: +The VIC image driver can be run using parallel processing using MPI and/or OpenMP. + +!!! Note + Users are encouraged to consult their system administrator for assistance in configuring the VIC image driver for parallel processing applications. + +To run VIC image driver using multiple processors using MPI, type the following instead: mpiexec -np $n_proc ./vic_image.exe -g global_parameter_filename.txt -where `n_proc` = number of processors to be used +where `n_proc` = number of processors to be used. *Note that different MPI implementations may use different names for the MPI executable such as: `mpirun`, `mpiexec_mpt`, or `mpiexec.hydra`*. + +To run the VIC image driver using multiple processors using OpenMP (threads), set the environment variable `OMP_NUM_THREADS`: + + export OMP_NUM_THREADS=8 + ./vic_image.exe -g global_parameter_filename.txt + +These two parallelization methods may also be combined using a Hybrid OpenMP/MPI approach. However, that configuration is usually machine, compiler, or scheduler dependent. ## Other Command Line Options diff --git a/tests/test_restart.py b/tests/test_restart.py index 89dfbf84a..934d60f5e 100644 --- a/tests/test_restart.py +++ b/tests/test_restart.py @@ -260,7 +260,7 @@ def check_exact_restart_fluxes(result_basedir, driver, run_periods): for var in ds_full_run.data_vars: np.testing.assert_array_equal( ds[var].values, ds_full_run_split_period[var].values, - err_msg='Fluxes are not an exact match') + err_msg='Fluxes are not an exact match %s' % var) def check_exact_restart_states(state_basedir, driver, run_periods, @@ -365,7 +365,7 @@ def check_exact_restart_states(state_basedir, driver, run_periods, np.testing.assert_array_equal(ds_states[var].values, ds_states_full_run[var].values, err_msg='states are not an ' - 'exact match') + 'exact match for %s' % var) def read_ascii_state(state_fname): diff --git a/vic/vic_run/src/CalcBlowingSnow.c b/vic/vic_run/src/CalcBlowingSnow.c index 7d3f458f7..80717e74e 100644 --- a/vic/vic_run/src/CalcBlowingSnow.c +++ b/vic/vic_run/src/CalcBlowingSnow.c @@ -379,6 +379,7 @@ trapzd(double (*funcd)(), { double x, tnm, sum, del; static double s; + #pragma omp threadprivate(s) int it, j; if (n == 1) { diff --git a/vic/vic_run/src/frozen_soil.c b/vic/vic_run/src/frozen_soil.c index 1fc113bc4..67f69311c 100644 --- a/vic/vic_run/src/frozen_soil.c +++ b/vic/vic_run/src/frozen_soil.c @@ -175,6 +175,7 @@ solve_T_profile(double *T, static double C[MAX_NODES]; static double D[MAX_NODES]; static double E[MAX_NODES]; + #pragma omp threadprivate(A,B,C,D,E) double *aa, *bb, *cc, *dd, *ee, Bexp; @@ -681,6 +682,13 @@ fda_heat_eqn(double T_2[], static double DT[MAX_NODES], DT_down[MAX_NODES], DT_up[MAX_NODES]; static double Dkappa[MAX_NODES]; static double Bexp; + #pragma omp threadprivate(deltat, NOFLUX, EXP_TRANS, T0, moist, ice, \ + kappa, Cs, max_moist, bubble, expt, alpha, beta, \ + gamma, Zsum, Dp, bulk_dens_min, soil_dens_min, \ + quartz, bulk_density, soil_density, organic, \ + depth, Nlayers, Ts, Tb, ice_new, Cs_new, \ + kappa_new, DT, DT_down, DT_up, Dkappa, Bexp) + char PAST_BOTTOM; double storage_term, flux_term, phase_term, flux_term1, flux_term2; double Lsum; From c00d36f84c158c066413f63b730ffbec8ec40630 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 23 Aug 2017 14:43:11 -0700 Subject: [PATCH 195/294] run uncrustify --- vic/vic_run/src/CalcBlowingSnow.c | 50 +++++++++++++++---------------- vic/vic_run/src/frozen_soil.c | 26 ++++++++-------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/vic/vic_run/src/CalcBlowingSnow.c b/vic/vic_run/src/CalcBlowingSnow.c index 80717e74e..612062f0f 100644 --- a/vic/vic_run/src/CalcBlowingSnow.c +++ b/vic/vic_run/src/CalcBlowingSnow.c @@ -271,18 +271,18 @@ CalcBlowingSnow(double Dt, *****************************************************************************/ double qromb(double (*funcd)(), - double es, - double Wind, - double AirDens, - double ZO, - double EactAir, - double F, - double hsalt, - double phi_r, - double ushear, - double Zrh, - double a, - double b) + double es, + double Wind, + double AirDens, + double ZO, + double EactAir, + double F, + double hsalt, + double phi_r, + double ushear, + double Zrh, + double a, + double b) { extern parameters_struct param; @@ -363,19 +363,19 @@ polint(double xa[], *****************************************************************************/ double trapzd(double (*funcd)(), - double es, - double Wind, - double AirDens, - double ZO, - double EactAir, - double F, - double hsalt, - double phi_r, - double ushear, - double Zrh, - double a, - double b, - int n) + double es, + double Wind, + double AirDens, + double ZO, + double EactAir, + double F, + double hsalt, + double phi_r, + double ushear, + double Zrh, + double a, + double b, + int n) { double x, tnm, sum, del; static double s; diff --git a/vic/vic_run/src/frozen_soil.c b/vic/vic_run/src/frozen_soil.c index 67f69311c..15535a292 100644 --- a/vic/vic_run/src/frozen_soil.c +++ b/vic/vic_run/src/frozen_soil.c @@ -683,21 +683,21 @@ fda_heat_eqn(double T_2[], static double Dkappa[MAX_NODES]; static double Bexp; #pragma omp threadprivate(deltat, NOFLUX, EXP_TRANS, T0, moist, ice, \ - kappa, Cs, max_moist, bubble, expt, alpha, beta, \ - gamma, Zsum, Dp, bulk_dens_min, soil_dens_min, \ - quartz, bulk_density, soil_density, organic, \ - depth, Nlayers, Ts, Tb, ice_new, Cs_new, \ - kappa_new, DT, DT_down, DT_up, Dkappa, Bexp) - - char PAST_BOTTOM; - double storage_term, flux_term, phase_term, flux_term1, flux_term2; - double Lsum; - int i; - size_t lidx; - int focus, left, right; + kappa, Cs, max_moist, bubble, expt, alpha, beta, \ + gamma, Zsum, Dp, bulk_dens_min, soil_dens_min, \ + quartz, bulk_density, soil_density, organic, \ + depth, Nlayers, Ts, Tb, ice_new, Cs_new, \ + kappa_new, DT, DT_down, DT_up, Dkappa, Bexp) + + char PAST_BOTTOM; + double storage_term, flux_term, phase_term, flux_term1, flux_term2; + double Lsum; + int i; + size_t lidx; + int focus, left, right; // argument list handling - va_list arg_addr; + va_list arg_addr; // initialize variables if init==1 if (init == 1) { From b767886f015f96923a43e75683ce4be323af5413 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 23 Aug 2017 14:51:48 -0700 Subject: [PATCH 196/294] uncrustify with some manual edits --- vic/vic_run/src/CalcBlowingSnow.c | 6 +++++- vic/vic_run/src/frozen_soil.c | 35 ++++++++++++++++++------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/vic/vic_run/src/CalcBlowingSnow.c b/vic/vic_run/src/CalcBlowingSnow.c index 612062f0f..9a312e701 100644 --- a/vic/vic_run/src/CalcBlowingSnow.c +++ b/vic/vic_run/src/CalcBlowingSnow.c @@ -379,9 +379,13 @@ trapzd(double (*funcd)(), { double x, tnm, sum, del; static double s; - #pragma omp threadprivate(s) + int it, j; + // TODO: remove use of static variables (see GH #735), for now: + // make static variables thread safe + #pragma omp threadprivate(s) + if (n == 1) { return (s = 0.5 * (b - diff --git a/vic/vic_run/src/frozen_soil.c b/vic/vic_run/src/frozen_soil.c index 15535a292..a6ac7c6f1 100644 --- a/vic/vic_run/src/frozen_soil.c +++ b/vic/vic_run/src/frozen_soil.c @@ -175,13 +175,16 @@ solve_T_profile(double *T, static double C[MAX_NODES]; static double D[MAX_NODES]; static double E[MAX_NODES]; - #pragma omp threadprivate(A,B,C,D,E) double *aa, *bb, *cc, *dd, *ee, Bexp; int Error; int j; + // TODO: remove use of static variables (see GH #735), for now: + // make static variables thread safe + #pragma omp threadprivate(A,B,C,D,E) + if (FIRST_SOLN[0]) { if (EXP_TRANS) { Bexp = logf(Dp + 1.) / (double) (Nnodes - 1); @@ -682,22 +685,24 @@ fda_heat_eqn(double T_2[], static double DT[MAX_NODES], DT_down[MAX_NODES], DT_up[MAX_NODES]; static double Dkappa[MAX_NODES]; static double Bexp; - #pragma omp threadprivate(deltat, NOFLUX, EXP_TRANS, T0, moist, ice, \ - kappa, Cs, max_moist, bubble, expt, alpha, beta, \ - gamma, Zsum, Dp, bulk_dens_min, soil_dens_min, \ - quartz, bulk_density, soil_density, organic, \ - depth, Nlayers, Ts, Tb, ice_new, Cs_new, \ - kappa_new, DT, DT_down, DT_up, Dkappa, Bexp) - - char PAST_BOTTOM; - double storage_term, flux_term, phase_term, flux_term1, flux_term2; - double Lsum; - int i; - size_t lidx; - int focus, left, right; + + char PAST_BOTTOM; + double storage_term, flux_term, phase_term, flux_term1, flux_term2; + double Lsum; + int i; + size_t lidx; + int focus, left, right; // argument list handling - va_list arg_addr; + va_list arg_addr; + + // TODO: remove use of static variables (see GH #735), for now: + // make static variables thread safe + #pragma omp threadprivate(deltat, NOFLUX, EXP_TRANS, T0, moist, ice, \ + kappa, Cs, max_moist, bubble, expt, alpha, beta, gamma, Zsum, Dp, \ + bulk_dens_min, soil_dens_min, quartz, bulk_density, soil_density, organic, \ + depth, Nlayers, Ts, Tb, ice_new, Cs_new, kappa_new, DT, DT_down, DT_up, \ + Dkappa, Bexp) // initialize variables if init==1 if (init == 1) { From 955f3ffc266f0531693fd769766bb826d8c3e6a8 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 23 Aug 2017 14:56:12 -0700 Subject: [PATCH 197/294] set omp threads to 4 on travis rather than using all available processors --- ci/image.travis | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/image.travis b/ci/image.travis index c0d022fe2..c6a046035 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -81,6 +81,8 @@ function vic_script { $DRIVER_EXE -v $DRIVER_EXE -o + export OMP_NUM_THREADS=4 + # Run test package ./tests/run_tests.py unit examples system \ --image=${DRIVER_EXE} \ From 02cbdd831c56d60bdb45a34c2a80294f7812bf47 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Wed, 23 Aug 2017 15:08:11 -0700 Subject: [PATCH 198/294] move vic_run_ref_str to private thread level --- vic/drivers/shared_image/src/vic_image_run.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index 637185ce6..bb960cfcf 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -25,7 +25,6 @@ *****************************************************************************/ #include -#pragma omp threadprivate(vic_run_ref_str) /****************************************************************************** * @brief Run VIC for one timestep and store output data @@ -56,7 +55,7 @@ vic_image_run(dmy_struct *dmy_current) sprint_dmy(dmy_str, dmy_current); debug("Running timestep %zu: %s", current, dmy_str); - #pragma omp parallel for default(shared) private(i, timer) + #pragma omp parallel for default(shared) private(i, timer, vic_run_ref_str) for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) sprintf(vic_run_ref_str, "Gridcell io_idx: %zu, timestep info: %s", From 7a613aec5e74e8eff3b0b9197e73635f58b28058 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 23 Aug 2017 18:32:09 -0400 Subject: [PATCH 199/294] add sqrt to fv and change signs for taux and tauy --- vic/drivers/cesm/src/cesm_put_data.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index b64c5f2aa..3f23a0b43 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -198,7 +198,6 @@ vic_cesm_put_data() AreaFactorSum += AreaFactor; // aerodynamical resistance, VIC: s/m, CESM: s/m - // TO-DO: update in future PR if (overstory) { aero_resist = cell.aero_resist[1]; } @@ -236,13 +235,13 @@ vic_cesm_put_data() // wind stress, zonal // CESM units: N m-2 - wind_stress_x = -1 * out_data[i][OUT_DENSITY][0] * + wind_stress_x = out_data[i][OUT_DENSITY][0] * x2l_vic[i].x2l_Sa_u / aero_resist; l2x_vic[i].l2x_Fall_taux += AreaFactor * wind_stress_x; // wind stress, meridional // CESM units: N m-2 - wind_stress_y = -1 * out_data[i][OUT_DENSITY][0] * + wind_stress_y = out_data[i][OUT_DENSITY][0] * x2l_vic[i].x2l_Sa_v / aero_resist; l2x_vic[i].l2x_Fall_tauy += AreaFactor * wind_stress_y; @@ -251,7 +250,7 @@ vic_cesm_put_data() wind_stress = sqrt(pow(wind_stress_x, 2) + pow(wind_stress_y, 2)); l2x_vic[i].l2x_Sl_fv += AreaFactor * - (wind_stress / + sqrt(wind_stress / out_data[i][OUT_DENSITY][0]); } } From 7d4228ad92dadda15149b67d00b27db7c4564bf7 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 23 Aug 2017 15:50:07 -0700 Subject: [PATCH 200/294] ran uncrustify --- vic/drivers/cesm/src/cesm_put_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/cesm_put_data.c b/vic/drivers/cesm/src/cesm_put_data.c index 3f23a0b43..efb37311f 100644 --- a/vic/drivers/cesm/src/cesm_put_data.c +++ b/vic/drivers/cesm/src/cesm_put_data.c @@ -251,7 +251,7 @@ vic_cesm_put_data() sqrt(pow(wind_stress_x, 2) + pow(wind_stress_y, 2)); l2x_vic[i].l2x_Sl_fv += AreaFactor * sqrt(wind_stress / - out_data[i][OUT_DENSITY][0]); + out_data[i][OUT_DENSITY][0]); } } From 9460b6b8b61b5c6164ef2866ec5d52d336533037 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 23 Aug 2017 16:04:46 -0700 Subject: [PATCH 201/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 7f9d2e372..ca7a05593 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -75,6 +75,10 @@ To check which release of VIC you are running: Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. + [GH#739] (https://github.com/UW-Hydro/VIC/pull/739) + + Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). + 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. From a3d8ebbf5a027b6b75c99ef90e48053e6184aa08 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 24 Aug 2017 15:26:06 -0700 Subject: [PATCH 202/294] respond to @bartnijssen's comments --- ci/image.travis | 2 + docs/Documentation/Drivers/Image/RunVIC.md | 3 ++ tests/test_restart.py | 2 +- vic/drivers/cesm/Makefile | 1 + vic/drivers/image/Makefile | 2 +- vic/drivers/shared_image/include/vic_mpi.h | 6 ++- vic/drivers/shared_image/src/vic_image_run.c | 1 + vic/vic_run/src/CalcBlowingSnow.c | 7 ++-- vic/vic_run/src/frozen_soil.c | 40 ++++++++++---------- 9 files changed, 36 insertions(+), 28 deletions(-) diff --git a/ci/image.travis b/ci/image.travis index c6a046035..37a92deea 100644 --- a/ci/image.travis +++ b/ci/image.travis @@ -81,6 +81,8 @@ function vic_script { $DRIVER_EXE -v $DRIVER_EXE -o + # Set the number of OpenMP threads to use + # https://docs.travis-ci.com/user/languages/c/#OpenMP-projects export OMP_NUM_THREADS=4 # Run test package diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 288485f80..946d7a79c 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -19,6 +19,9 @@ The Image Driver has three dependencies: 3. [netCDF4](http://www.unidata.ucar.edu/software/netcdf/) +!!! Note + Compiling the Image Driver may also be done with [OpenMP](http://www.openmp.org/). Nearly all [modern C compilers include the OpenMP standard](http://www.openmp.org/resources/openmp-compilers/) and users will need to ensure that the makefile has the appropriate compiler flag (usually `-openmp`). See the discussion below for how to control OpenMP parallelization. + ## Compiling In most cases, you will need to edit the `NETCDF_PATH` and `MPI_PATH` variables in the `Makefile`. diff --git a/tests/test_restart.py b/tests/test_restart.py index 934d60f5e..a66799157 100644 --- a/tests/test_restart.py +++ b/tests/test_restart.py @@ -260,7 +260,7 @@ def check_exact_restart_fluxes(result_basedir, driver, run_periods): for var in ds_full_run.data_vars: np.testing.assert_array_equal( ds[var].values, ds_full_run_split_period[var].values, - err_msg='Fluxes are not an exact match %s' % var) + err_msg='Fluxes are not an exact match for %s' % var) def check_exact_restart_states(state_basedir, driver, run_periods, diff --git a/vic/drivers/cesm/Makefile b/vic/drivers/cesm/Makefile index 41029ed94..700ae9e9a 100644 --- a/vic/drivers/cesm/Makefile +++ b/vic/drivers/cesm/Makefile @@ -88,6 +88,7 @@ LIBRARY = -lm -L${NETCDFPATH}/lib -lnetcdf # Set compiler flags CFLAGS = ${INCLUDES} -ggdb -O0 -Wall -Wextra -fPIC \ + -fopenmp \ -DLOG_LVL=$(LOG_LVL) \ -DGIT_VERSION=\"$(GIT_VERSION)\" \ -DUSERNAME=\"$(USER)\" \ diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 8d7bf2517..cbe40f6c2 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -74,7 +74,7 @@ INCLUDES = -I ${DRIVERPATH}/include \ -I ${SHAREDIMAGEPATH}/include # Uncomment to include debugging information -CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ +CFLAGS = ${INCLUDES} ${NC_CFLAGS} -ggdb -O0 -Wall -Wextra -std=c99 \ -fopenmp \ -DLOG_LVL=$(LOG_LVL) \ -DGIT_VERSION=\"$(GIT_VERSION)\" \ diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index 39ba06be1..c7366cb68 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -29,7 +29,11 @@ #include #include -#include +#ifdef _OPENMP + #include +#else + #define omp_get_max_threads() 1 +#endif #define VIC_MPI_ROOT 0 diff --git a/vic/drivers/shared_image/src/vic_image_run.c b/vic/drivers/shared_image/src/vic_image_run.c index bb960cfcf..532a607fa 100644 --- a/vic/drivers/shared_image/src/vic_image_run.c +++ b/vic/drivers/shared_image/src/vic_image_run.c @@ -55,6 +55,7 @@ vic_image_run(dmy_struct *dmy_current) sprint_dmy(dmy_str, dmy_current); debug("Running timestep %zu: %s", current, dmy_str); + // If running with OpenMP, run this for loop using multiple threads #pragma omp parallel for default(shared) private(i, timer, vic_run_ref_str) for (i = 0; i < local_domain.ncells_active; i++) { // Set global reference string (for debugging inside vic_run) diff --git a/vic/vic_run/src/CalcBlowingSnow.c b/vic/vic_run/src/CalcBlowingSnow.c index 9a312e701..16cfa6f97 100644 --- a/vic/vic_run/src/CalcBlowingSnow.c +++ b/vic/vic_run/src/CalcBlowingSnow.c @@ -377,13 +377,12 @@ trapzd(double (*funcd)(), double b, int n) { - double x, tnm, sum, del; - static double s; - - int it, j; + double x, tnm, sum, del; + int it, j; // TODO: remove use of static variables (see GH #735), for now: // make static variables thread safe + static double s; #pragma omp threadprivate(s) if (n == 1) { diff --git a/vic/vic_run/src/frozen_soil.c b/vic/vic_run/src/frozen_soil.c index a6ac7c6f1..90d6c09dc 100644 --- a/vic/vic_run/src/frozen_soil.c +++ b/vic/vic_run/src/frozen_soil.c @@ -170,20 +170,18 @@ solve_T_profile(double *T, int NOFLUX, int EXP_TRANS) { + double *aa, *bb, *cc, *dd, *ee, Bexp; + int Error; + int j; + + // TODO: remove use of static variables (see GH #735), for now: + // make static variables thread safe static double A[MAX_NODES]; static double B[MAX_NODES]; static double C[MAX_NODES]; static double D[MAX_NODES]; static double E[MAX_NODES]; - - double *aa, *bb, *cc, *dd, *ee, Bexp; - - int Error; - int j; - - // TODO: remove use of static variables (see GH #735), for now: - // make static variables thread safe - #pragma omp threadprivate(A,B,C,D,E) + #pragma omp threadprivate(A, B, C, D, E) if (FIRST_SOLN[0]) { if (EXP_TRANS) { @@ -650,6 +648,18 @@ fda_heat_eqn(double T_2[], int init, ...) { + char PAST_BOTTOM; + double storage_term, flux_term, phase_term, flux_term1, flux_term2; + double Lsum; + int i; + size_t lidx; + int focus, left, right; + + // argument list handling + va_list arg_addr; + + // TODO: remove use of static variables (see GH #735), for now: + // make static variables thread safe static double deltat; static int NOFLUX; static int EXP_TRANS; @@ -686,18 +696,6 @@ fda_heat_eqn(double T_2[], static double Dkappa[MAX_NODES]; static double Bexp; - char PAST_BOTTOM; - double storage_term, flux_term, phase_term, flux_term1, flux_term2; - double Lsum; - int i; - size_t lidx; - int focus, left, right; - - // argument list handling - va_list arg_addr; - - // TODO: remove use of static variables (see GH #735), for now: - // make static variables thread safe #pragma omp threadprivate(deltat, NOFLUX, EXP_TRANS, T0, moist, ice, \ kappa, Cs, max_moist, bubble, expt, alpha, beta, gamma, Zsum, Dp, \ bulk_dens_min, soil_dens_min, quartz, bulk_density, soil_density, organic, \ From 49b48d24f1cc1cf43b16731b518774c68b79f3b2 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 24 Aug 2017 16:23:10 -0700 Subject: [PATCH 203/294] uncrustify (#741) * uncrustify * fix uncrustify --- vic/drivers/shared_all/include/vic_driver_shared_all.h | 1 + vic/drivers/shared_image/src/vic_init.c | 2 +- vic/vic_run/src/func_canopy_energy_bal.c | 4 ++-- vic/vic_run/src/snow_intercept.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index e1464f49b..f447ec118 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -47,6 +47,7 @@ // Max counter for root distribution iteration #define MAX_ROOT_ITER 9999 + /****************************************************************************** * @brief File formats *****************************************************************************/ diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index fd0ca0233..83a7cf769 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1232,7 +1232,7 @@ vic_init(void) if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); log_warn("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", - Cv_sum[i], i, locstr); + Cv_sum[i], i, locstr); for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; veg_con[i][vidx].Cv /= Cv_sum[i]; diff --git a/vic/vic_run/src/func_canopy_energy_bal.c b/vic/vic_run/src/func_canopy_energy_bal.c index 5f5a9d066..030e3c796 100644 --- a/vic/vic_run/src/func_canopy_energy_bal.c +++ b/vic/vic_run/src/func_canopy_energy_bal.c @@ -217,7 +217,7 @@ func_canopy_energy_bal(double Tfoliage, /* Calculate the latent heat flux */ Ls = calc_latent_heat_of_sublimation(Tfoliage); - *LatentHeatSub = Ls * *VaporMassFlux * CONST_RHOFW; + *LatentHeatSub = Ls * (*VaporMassFlux) * CONST_RHOFW; *LatentHeat = 0; *Evap = 0; veg_var->throughfall = 0; @@ -246,7 +246,7 @@ func_canopy_energy_bal(double Tfoliage, root, dryFrac, shortwave, Catm, CanopLayerBnd); *Wdew /= MM_PER_M; - *LatentHeat = Le * *Evap * CONST_RHOFW; + *LatentHeat = Le * (*Evap) * CONST_RHOFW; *LatentHeatSub = 0; } diff --git a/vic/vic_run/src/snow_intercept.c b/vic/vic_run/src/snow_intercept.c index ebc13174b..b541cb4ab 100644 --- a/vic/vic_run/src/snow_intercept.c +++ b/vic/vic_run/src/snow_intercept.c @@ -518,7 +518,7 @@ snow_intercept(double Dt, /* Energy released by freezing of intercepted water is added to the MeltEnergy */ - *MeltEnergy += (CONST_LATICE * *IntRain * CONST_RHOFW) / (Dt); + *MeltEnergy += (CONST_LATICE * (*IntRain) * CONST_RHOFW) / (Dt); *IntRain = 0.0; } From 032a31831c26f667f853afd5bb7890ab191b00e2 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 24 Aug 2017 17:08:38 -0700 Subject: [PATCH 204/294] mods to image driver docs for openmp --- docs/Documentation/Drivers/Image/RunVIC.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 946d7a79c..21a397797 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -20,7 +20,7 @@ The Image Driver has three dependencies: 3. [netCDF4](http://www.unidata.ucar.edu/software/netcdf/) !!! Note - Compiling the Image Driver may also be done with [OpenMP](http://www.openmp.org/). Nearly all [modern C compilers include the OpenMP standard](http://www.openmp.org/resources/openmp-compilers/) and users will need to ensure that the makefile has the appropriate compiler flag (usually `-openmp`). See the discussion below for how to control OpenMP parallelization. + Compiling the Image Driver may also be done with [OpenMP](http://www.openmp.org/). Nearly all modern C compilers include the [OpenMP standard](http://www.openmp.org/resources/openmp-compilers/) and users will need to ensure that the makefile has the appropriate compiler flag (usually `-openmp`). See the discussion below for how to control OpenMP parallelization. ## Compiling In most cases, you will need to edit the `NETCDF_PATH` and `MPI_PATH` variables in the `Makefile`. @@ -51,7 +51,7 @@ At the command prompt, type: where `global_parameter_filename` = name of the global parameter file corresponding to your project. -The VIC image driver can be run using parallel processing using MPI and/or OpenMP. +The VIC image driver can be run using parallel processing with MPI and/or OpenMP. !!! Note Users are encouraged to consult their system administrator for assistance in configuring the VIC image driver for parallel processing applications. @@ -62,7 +62,7 @@ To run VIC image driver using multiple processors using MPI, type the following where `n_proc` = number of processors to be used. *Note that different MPI implementations may use different names for the MPI executable such as: `mpirun`, `mpiexec_mpt`, or `mpiexec.hydra`*. -To run the VIC image driver using multiple processors using OpenMP (threads), set the environment variable `OMP_NUM_THREADS`: +To run the VIC image driver using multiple processors with OpenMP (threads), set the environment variable `OMP_NUM_THREADS`: export OMP_NUM_THREADS=8 ./vic_image.exe -g global_parameter_filename.txt From 74dc13e77d613b811fa889e1b6339c8aa04a070e Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 25 Aug 2017 10:48:50 -0700 Subject: [PATCH 205/294] -fopenmp flag correction --- docs/Documentation/Drivers/Image/RunVIC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index 21a397797..3bc509ac0 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -20,7 +20,7 @@ The Image Driver has three dependencies: 3. [netCDF4](http://www.unidata.ucar.edu/software/netcdf/) !!! Note - Compiling the Image Driver may also be done with [OpenMP](http://www.openmp.org/). Nearly all modern C compilers include the [OpenMP standard](http://www.openmp.org/resources/openmp-compilers/) and users will need to ensure that the makefile has the appropriate compiler flag (usually `-openmp`). See the discussion below for how to control OpenMP parallelization. + Compiling the Image Driver may also be done with [OpenMP](http://www.openmp.org/). Nearly all modern C compilers include the [OpenMP standard](http://www.openmp.org/resources/openmp-compilers/) and users will need to ensure that the makefile has the appropriate compiler flag (usually `-fopenmp`). See the discussion below for how to control OpenMP parallelization. ## Compiling In most cases, you will need to edit the `NETCDF_PATH` and `MPI_PATH` variables in the `Makefile`. From bfdb4a6300c805b7505b8967adf0c951ba4e7c36 Mon Sep 17 00:00:00 2001 From: Bart Nijssen Date: Fri, 25 Aug 2017 16:34:42 -0600 Subject: [PATCH 206/294] Fix/issue673 (#742) * Added release not for fixing #673 * Renamed fcov to fcan per https://github.com/UW-Hydro/VIC/issues/673 * Fixed releasenotes in response to review by jhamman --- docs/Development/ReleaseNotes.md | 16 +++++++++++----- vic/drivers/image/src/vic_force.c | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 2d0c83abd..44333349d 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -68,16 +68,16 @@ To check which release of VIC you are running: Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. [GH#732] (https://github.com/UW-Hydro/VIC/pull/732) - - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). - [GH#734] (https://github.com/UW-Hydro/VIC/pull/734) + Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. + [GH#734] (https://github.com/UW-Hydro/VIC/pull/734) + + Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. [GH#739] (https://github.com/UW-Hydro/VIC/pull/739) - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). + Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) @@ -99,6 +99,12 @@ To check which release of VIC you are running: The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. +#### Bug Fixes: + +1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) + +------------------------------ + ## VIC 5.0.1 **Release date: (February 1, 2017)** diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 04a3aa05a..1209335e0 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -335,14 +335,14 @@ vic_force(void) } } - // Partial veg cover fraction: fcov + // Partial veg cover fraction: fcan if (options.FCAN_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "fcov", + get_scatter_nc_field_double(&(filenames.forcing[1]), "fcan", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; From 819cda94a2522ae4d839dc48091ce28ff1881cac Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 31 Aug 2017 15:53:39 -0700 Subject: [PATCH 207/294] fix and add missing timers in cesm_interface.c --- vic/drivers/cesm/src/cesm_interface_c.c | 12 ++++++++++-- vic/drivers/image/src/vic_image.c | 3 --- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index b9070968a..7d2f1a4c4 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -97,7 +97,9 @@ vic_cesm_init(vic_clock *vclock, vic_populate_model_state(trimstr(cmeta->starttype), &dmy_current); // initialize forcings + timer_start(&(global_timers[TIMER_VIC_FORCE])); vic_force(); + timer_stop(&(global_timers[TIMER_VIC_FORCE])); // initialize output structures vic_init_output(&dmy_current); @@ -142,7 +144,9 @@ vic_cesm_run(vic_clock *vclock) initialize_l2x_data(); // read forcing data + timer_continue(&(global_timers[TIMER_VIC_FORCE])); vic_force(); + timer_stop(&(global_timers[TIMER_VIC_FORCE])); // run vic over the domain vic_image_run(&dmy_current); @@ -151,7 +155,9 @@ vic_cesm_run(vic_clock *vclock) vic_cesm_put_data(); // Write history files + timer_continue(&(global_timers[TIMER_VIC_WRITE])); vic_write_output(&dmy_current); + timer_stop(&(global_timers[TIMER_VIC_WRITE])); // advance the clock advance_vic_time(); @@ -160,8 +166,10 @@ vic_cesm_run(vic_clock *vclock) // if save: if (vclock->state_flag) { // write state file + debug("writing state file for timestep %zu", current); vic_store(&dmy_current, state_filename); write_rpointer_file(state_filename); + debug("finished storing state file: %s", state_filename) } // reset x2l fields @@ -183,8 +191,8 @@ vic_cesm_final() { // continue vic all timer timer_continue(&(global_timers[TIMER_VIC_ALL])); - // start vic run timer - timer_start(&(global_timers[TIMER_VIC_RUN])); + // start vic final timer + timer_start(&(global_timers[TIMER_VIC_FINAL])); // clean up vic_cesm_finalize(); diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 9e0a87283..af5ab60d3 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -131,9 +131,6 @@ main(int argc, // start vic run timer timer_start(&(global_timers[TIMER_VIC_RUN])); - timer_init(&(global_timers[TIMER_VIC_FORCE])); - timer_init(&(global_timers[TIMER_VIC_WRITE])); - // loop over all timesteps for (current = 0; current < global_param.nrecs; current++) { // read forcing data From 2267799da7f31ab96ccb536bfac44e103da5a4b8 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Thu, 31 Aug 2017 15:55:45 -0700 Subject: [PATCH 208/294] only write timing table from mpi root --- vic/drivers/cesm/src/cesm_interface_c.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 7d2f1a4c4..98685d437 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -201,8 +201,10 @@ vic_cesm_final() timer_stop(&(global_timers[TIMER_VIC_FINAL])); // stop vic all timer timer_stop(&(global_timers[TIMER_VIC_ALL])); - // write timing info - write_vic_timing_table(global_timers, VIC_DRIVER); + if (mpi_rank == VIC_MPI_ROOT) { + // write timing info + write_vic_timing_table(global_timers, VIC_DRIVER); + } return EXIT_SUCCESS; } From 5cb05431d26635f4cb0a8b6a9c246c2b8e9a3ae6 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 1 Sep 2017 12:19:41 -0700 Subject: [PATCH 209/294] init/continue vic run timer in cesm driver --- vic/drivers/cesm/src/cesm_interface_c.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 98685d437..041bc155b 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -123,6 +123,8 @@ vic_cesm_init(vic_clock *vclock, timer_stop(&(global_timers[TIMER_VIC_INIT])); // stop vic all timer timer_stop(&(global_timers[TIMER_VIC_ALL])); + // init vic run timer + timer_init(&(global_timers[TIMER_VIC_RUN])); return EXIT_SUCCESS; } @@ -137,8 +139,8 @@ vic_cesm_run(vic_clock *vclock) // continue vic all timer timer_continue(&(global_timers[TIMER_VIC_ALL])); - // start vic run timer - timer_start(&(global_timers[TIMER_VIC_RUN])); + // continue vic run timer + timer_continue(&(global_timers[TIMER_VIC_RUN])); // reset l2x fields initialize_l2x_data(); From da9a62da14c5824c18741e1f3439e87b6ea6b00b Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 1 Sep 2017 14:27:13 -0700 Subject: [PATCH 210/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 44333349d..ce4cdcf84 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -79,6 +79,10 @@ To check which release of VIC you are running: Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). + [GH#744] (https://github.com/UW-Hydro/VIC/pull/744) + + Updates the cesm_interface_c.c routine to include missing timers and the VIC RUN timer in the CESM driver. + 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) These changes speed up image driver initialization, forcing reads, and history writes by only opening and closing each input netCDF file once. From 5317327fc80c24132e37f29928b6665e754360f1 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 5 Sep 2017 09:51:50 -0700 Subject: [PATCH 211/294] Feature/cesm timingtables secsday columns (#746) * populate nrecs, endyear, endmonth and endday in global_param struct for secs/day columns in timing tables for CESM driver * ran uncrustify * add release notes entry * update PR number in release notes entry --- docs/Development/ReleaseNotes.md | 8 ++++++-- vic/drivers/cesm/cpl_mct/lnd_comp_mct.F90 | 2 +- vic/drivers/cesm/include/vic_driver_cesm.h | 3 ++- vic/drivers/cesm/src/cesm_interface_c.c | 5 ++++- vic/drivers/cesm/src/cesm_interface_f.F90 | 3 ++- vic/drivers/cesm/src/vic_cesm_time.c | 16 ++++++++++++++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index ce4cdcf84..450c58742 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -79,9 +79,13 @@ To check which release of VIC you are running: Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). - [GH#744] (https://github.com/UW-Hydro/VIC/pull/744) + [GH#744](https://github.com/UW-Hydro/VIC/pull/744) - Updates the cesm_interface_c.c routine to include missing timers and the VIC RUN timer in the CESM driver. + Updates the cesm_interface_c.c routine to include missing timers and the VIC RUN timer in the CESM driver. + + [GH#746](https://github.com/UW-Hydro/VIC/pull/746) + + Updates the cesm_interface_c.c routine in the CESM driver to populate the nrecs, endyear, endmonth and endday fields in the global_param struct to make them available to vic_finalize for timing tables (specifically the secs/day columns). 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) diff --git a/vic/drivers/cesm/cpl_mct/lnd_comp_mct.F90 b/vic/drivers/cesm/cpl_mct/lnd_comp_mct.F90 index 7173aa594..22a889cd4 100644 --- a/vic/drivers/cesm/cpl_mct/lnd_comp_mct.F90 +++ b/vic/drivers/cesm/cpl_mct/lnd_comp_mct.F90 @@ -415,7 +415,7 @@ SUBROUTINE lnd_final_mct(EClock, cdata, x2l, l2x, cdata_s, x2s, s2x) CHARACTER(len=*), PARAMETER :: subname = '(lnd_final_mct)' !--- clean up - errno = vic_cesm_final() + errno = vic_cesm_final(vclock) IF (errno /= 0) THEN CALL shr_sys_abort(subname//' ERROR: vic_cesm_final returned a errno /= 0') diff --git a/vic/drivers/cesm/include/vic_driver_cesm.h b/vic/drivers/cesm/include/vic_driver_cesm.h index 6a55e3507..b883b3f79 100644 --- a/vic/drivers/cesm/include/vic_driver_cesm.h +++ b/vic/drivers/cesm/include/vic_driver_cesm.h @@ -159,6 +159,7 @@ typedef struct { void advance_vic_time(void); void assert_time_insync(vic_clock *vclock, dmy_struct *dmy); +void finalize_cesm_time(vic_clock *vclock); void get_global_param(FILE *); void initialize_cesm_time(void); void initialize_l2x_data(void); @@ -178,7 +179,7 @@ void validate_options(option_struct *options); void vic_cesm_alloc(void); int vic_cesm_init_mpi(int MPI_COMM_VIC_F); int vic_cesm_init(vic_clock *vclock, case_metadata *cmeta); -int vic_cesm_final(void); +int vic_cesm_final(vic_clock *vclock); void vic_cesm_finalize(void); int vic_cesm_run(vic_clock *vclock); void vic_force(void); diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index 041bc155b..df4f0336c 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -189,13 +189,16 @@ vic_cesm_run(vic_clock *vclock) * @brief Finalize function for CESM driver *****************************************************************************/ int -vic_cesm_final() +vic_cesm_final(vic_clock *vclock) { // continue vic all timer timer_continue(&(global_timers[TIMER_VIC_ALL])); // start vic final timer timer_start(&(global_timers[TIMER_VIC_FINAL])); + // finalize time + finalize_cesm_time(vclock); + // clean up vic_cesm_finalize(); diff --git a/vic/drivers/cesm/src/cesm_interface_f.F90 b/vic/drivers/cesm/src/cesm_interface_f.F90 index 4cf07718d..df510caa8 100644 --- a/vic/drivers/cesm/src/cesm_interface_f.F90 +++ b/vic/drivers/cesm/src/cesm_interface_f.F90 @@ -89,10 +89,11 @@ END FUNCTION vic_cesm_run !> @brief Finalize Interface !-------------------------------------------------------------------------- INTERFACE - INTEGER(C_INT) FUNCTION vic_cesm_final() BIND(C, name='vic_cesm_final') + INTEGER(C_INT) FUNCTION vic_cesm_final(vclock) BIND(C, name='vic_cesm_final') USE, INTRINSIC :: ISO_C_BINDING USE vic_cesm_def_mod IMPLICIT NONE + TYPE(vic_clock), INTENT(in) :: vclock END FUNCTION vic_cesm_final END INTERFACE diff --git a/vic/drivers/cesm/src/vic_cesm_time.c b/vic/drivers/cesm/src/vic_cesm_time.c index ec46bd8c4..d7083e51f 100644 --- a/vic/drivers/cesm/src/vic_cesm_time.c +++ b/vic/drivers/cesm/src/vic_cesm_time.c @@ -65,6 +65,22 @@ initialize_cesm_time(void) global_param.time_units, &dmy_current); } +/****************************************************************************** + * @brief Finalize cesm time + *****************************************************************************/ +void +finalize_cesm_time(vic_clock *vclock) +{ + extern size_t current; + extern global_param_struct global_param; + + // populate fields in global_param needed for timing tables + global_param.nrecs = current; + global_param.endyear = vclock->current_year; + global_param.endmonth = vclock->current_month; + global_param.endday = vclock->current_day; +} + /****************************************************************************** * @brief Advance one timestep *****************************************************************************/ From 990abf4c57985dbdc70c341efe84c3ebffab2934 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 5 Sep 2017 12:14:58 -0700 Subject: [PATCH 212/294] fix PR links in cesm documentation --- docs/Development/ReleaseNotes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 450c58742..629f5cfb0 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -47,35 +47,35 @@ To check which release of VIC you are running: Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. - [GH#702] (https://github.com/UW-Hydro/VIC/pull/702) + [GH#702](https://github.com/UW-Hydro/VIC/pull/702) Fixes Julian day for the first timestep in the dmy struct for the CESM driver. - [GH#710] (https://github.com/UW-Hydro/VIC/pull/710) + [GH#710](https://github.com/UW-Hydro/VIC/pull/710) Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. - [GH#716] (https://github.com/UW-Hydro/VIC/pull/716) + [GH#716](https://github.com/UW-Hydro/VIC/pull/716) Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. - [GH#718] (https://github.com/UW-Hydro/VIC/pull/718) + [GH#718](https://github.com/UW-Hydro/VIC/pull/718) Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. - [GH#726] (https://github.com/UW-Hydro/VIC/pull/726) + [GH#726](https://github.com/UW-Hydro/VIC/pull/726) Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. - [GH#732] (https://github.com/UW-Hydro/VIC/pull/732) + [GH#732](https://github.com/UW-Hydro/VIC/pull/732) Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). - [GH#734] (https://github.com/UW-Hydro/VIC/pull/734) + [GH#734](https://github.com/UW-Hydro/VIC/pull/734) Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. - [GH#739] (https://github.com/UW-Hydro/VIC/pull/739) + [GH#739](https://github.com/UW-Hydro/VIC/pull/739) Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). From f6a593fb30e9b8e888d1e6c899ebc4732cf1fc76 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Sep 2017 12:04:03 +0200 Subject: [PATCH 213/294] removed rout_ring for initstate file by moving vic_restore.c, vic_store.c, state_metadata.c and vic_driver_shared_all.h to the extensions folders: rvic and stub --- .../include/vic_driver_shared_all.h | 0 .../rout_rvic}/src/state_metadata.c | 0 .../rout_rvic}/src/vic_restore.c | 0 .../rout_rvic}/src/vic_store.c | 0 .../rout_stub/include/vic_driver_shared_all.h | 746 ++++++ vic/extensions/rout_stub/src/state_metadata.c | 710 ++++++ vic/extensions/rout_stub/src/vic_restore.c | 1119 +++++++++ vic/extensions/rout_stub/src/vic_store.c | 2171 +++++++++++++++++ 8 files changed, 4746 insertions(+) rename vic/{drivers/shared_all => extensions/rout_rvic}/include/vic_driver_shared_all.h (100%) rename vic/{drivers/shared_image => extensions/rout_rvic}/src/state_metadata.c (100%) rename vic/{drivers/shared_image => extensions/rout_rvic}/src/vic_restore.c (100%) rename vic/{drivers/shared_image => extensions/rout_rvic}/src/vic_store.c (100%) create mode 100644 vic/extensions/rout_stub/include/vic_driver_shared_all.h create mode 100644 vic/extensions/rout_stub/src/state_metadata.c create mode 100644 vic/extensions/rout_stub/src/vic_restore.c create mode 100644 vic/extensions/rout_stub/src/vic_store.c diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/extensions/rout_rvic/include/vic_driver_shared_all.h similarity index 100% rename from vic/drivers/shared_all/include/vic_driver_shared_all.h rename to vic/extensions/rout_rvic/include/vic_driver_shared_all.h diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/extensions/rout_rvic/src/state_metadata.c similarity index 100% rename from vic/drivers/shared_image/src/state_metadata.c rename to vic/extensions/rout_rvic/src/state_metadata.c diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/extensions/rout_rvic/src/vic_restore.c similarity index 100% rename from vic/drivers/shared_image/src/vic_restore.c rename to vic/extensions/rout_rvic/src/vic_restore.c diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/extensions/rout_rvic/src/vic_store.c similarity index 100% rename from vic/drivers/shared_image/src/vic_store.c rename to vic/extensions/rout_rvic/src/vic_store.c diff --git a/vic/extensions/rout_stub/include/vic_driver_shared_all.h b/vic/extensions/rout_stub/include/vic_driver_shared_all.h new file mode 100644 index 000000000..c042ecf50 --- /dev/null +++ b/vic/extensions/rout_stub/include/vic_driver_shared_all.h @@ -0,0 +1,746 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for vic_driver_shared_all routines + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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. + *****************************************************************************/ + +#ifndef VIC_DRIVER_SHARED_H +#define VIC_DRIVER_SHARED_H + +#include +#include + +// Define maximum array sizes for driver level objects +#define MAX_FORCE_FILES 2 +#define MAX_OUTPUT_STREAMS 20 + +// Output compression setting +#define COMPRESSION_LVL_UNSET -1 +#define COMPRESSION_LVL_DEFAULT 5 + +// Default ouput values +#define OUT_MULT_DEFAULT 0 // Why is this not 1? +#define OUT_ASCII_FORMAT_DEFAULT "%.4f" + +// Default snow band setting +#define SNOW_BAND_TRUE_BUT_UNSET 99999 + +// Max counter for root distribution iteration +#define MAX_ROOT_ITER 9999 + +/****************************************************************************** + * @brief File formats + *****************************************************************************/ +enum +{ + UNSET_FILE_FORMAT, + ASCII, + BINARY, + NETCDF3_CLASSIC, + NETCDF3_64BIT_OFFSET, + NETCDF4_CLASSIC, + NETCDF4 +}; + +/****************************************************************************** + * @brief endian flags + *****************************************************************************/ +enum +{ + LITTLE, /**< little-endian flag */ + BIG /**< big-endian flag */ +}; + +/****************************************************************************** + * @brief Veg param sources + *****************************************************************************/ +enum +{ + FROM_DEFAULT, + FROM_VEGLIB, + FROM_VEGPARAM, + FROM_VEGHIST +}; + +/****************************************************************************** + * @brief Forcing Variable Types + *****************************************************************************/ +enum +{ + AIR_TEMP, /**< air temperature per time step [C] */ + ALBEDO, /**< surface albedo [fraction] */ + CATM, /**< atmospheric CO2 concentration [ppm] */ + CHANNEL_IN, /**< incoming channel flow [m3] */ + FCANOPY, /**< fractional area covered by plant canopy [fraction] */ + FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ + LAI_IN, /**< leaf area index [m2/m2] */ + LWDOWN, /**< incoming longwave radiation [W/m2] */ + PAR, /**< incoming photosynthetically active radiation [W/m2] */ + PREC, /**< total precipitation (rain and snow) [mm] */ + PRESSURE, /**< atmospheric pressure [kPa] */ + VP, /**< vapor pressure [kPa] */ + SWDOWN, /**< incoming shortwave [W/m2] */ + WIND, /**< wind speed [m/s] */ + SKIP, /**< place holder for unused data columns */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_FORCING_TYPES /**< Number of forcing types */ +}; + + +/****************************************************************************** + * @brief Output Variable Types + *****************************************************************************/ +enum +{ + // Water Balance Terms - state variables + OUT_ASAT, /**< Saturated Area Fraction */ + OUT_LAKE_AREA_FRAC, /**< lake surface area as fraction of the grid cell area [fraction] */ + OUT_LAKE_DEPTH, /**< lake depth (distance between surface and deepest point) [m] */ + OUT_LAKE_ICE, /**< moisture stored as lake ice [mm over lake ice area] */ + OUT_LAKE_ICE_FRACT, /**< fractional coverage of lake ice [fraction] */ + OUT_LAKE_ICE_HEIGHT, /**< thickness of lake ice [cm] */ + OUT_LAKE_MOIST, /**< liquid water and ice stored in lake [mm over grid cell] */ + OUT_LAKE_SURF_AREA, /**< lake surface area [m2] */ + OUT_LAKE_SWE, /**< liquid water equivalent of snow on top of lake ice [m over lake ice area] */ + OUT_LAKE_SWE_V, /**< volumetric liquid water equivalent of snow on top of lake ice [m3] */ + OUT_LAKE_VOLUME, /**< lake volume [m3] */ + OUT_ROOTMOIST, /**< root zone soil moisture [mm] */ + OUT_SMFROZFRAC, /**< fraction of soil moisture (by mass) that is ice, for each soil layer */ + OUT_SMLIQFRAC, /**< fraction of soil moisture (by mass) that is liquid, for each soil layer */ + OUT_SNOW_CANOPY, /**< snow interception storage in canopy [mm] */ + OUT_SNOW_COVER, /**< fractional area of snow cover [fraction] */ + OUT_SNOW_DEPTH, /**< depth of snow pack [cm] */ + OUT_SOIL_ICE, /**< soil ice content [mm] for each soil layer */ + OUT_SOIL_LIQ, /**< soil liquid content [mm] for each soil layer */ + OUT_SOIL_ICE_FRAC, /**< soil ice content fraction of column volume [1] for each soil layer */ + OUT_SOIL_LIQ_FRAC, /**< soil liquid content fraction of column volume [1] for each soil layer */ + OUT_SOIL_MOIST, /**< soil total moisture content [mm] for each soil layer */ + OUT_SOIL_WET, /**< vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ + OUT_SURFSTOR, /**< storage of liquid water and ice (not snow) on surface (ponding) [mm] */ + OUT_SURF_FROST_FRAC, /**< fraction of soil surface that is frozen [fraction] */ + OUT_SWE, /**< snow water equivalent in snow pack (including vegetation-intercepted snow) [mm] */ + OUT_WDEW, /**< total moisture interception storage in canopy [mm] */ + OUT_ZWT, /**< water table position [cm] (zwt within lowest unsaturated layer) */ + OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ + // Water Balance Terms - fluxes + OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] */ + OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ + OUT_DELSOILMOIST, /**< change in soil water content [mm] */ + OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ + OUT_DELSWE, /**< change in snow water equivalent [mm] */ + OUT_DISCHARGE, /**< river discharge [m3 s-1]) */ + OUT_EVAP, /**< total net evaporation [mm] */ + OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ + OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ + OUT_INFLOW, /**< moisture that reaches top of soil column [mm] */ + OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] */ + OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] */ + OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] */ + OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] */ + OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] */ + OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] */ + OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] */ + OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] */ + OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] */ + OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ + OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] */ + OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] */ + OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] */ + OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] */ + OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] */ + OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] */ + OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] */ + OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] */ + OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] */ + OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] */ + OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] */ + OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] */ + OUT_PREC, /**< incoming precipitation [mm] */ + OUT_RAINF, /**< rainfall [mm] */ + OUT_REFREEZE, /**< refreezing of water in the snow [mm] */ + OUT_RUNOFF, /**< surface runoff [mm] */ + OUT_SNOW_MELT, /**< snow melt [mm] */ + OUT_SNOWF, /**< snowfall [mm] */ + OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] */ + OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] */ + OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] */ + OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] */ + OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] */ + OUT_WATER_ERROR, /**< water budget error [mm] */ + // Energy Balance Terms - state variables + OUT_ALBEDO, /**< average surface albedo [fraction] */ + OUT_BARESOILT, /**< bare soil surface temperature [C] */ + OUT_FDEPTH, /**< depth of freezing fronts [cm] */ + OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] */ + OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] */ + OUT_RAD_TEMP, /**< average radiative surface temperature [K] */ + OUT_SALBEDO, /**< snow pack albedo [fraction] */ + OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] */ + OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] */ + OUT_SNOWT_FBFLAG, /**< snow surface temperature fallback flag */ + OUT_SOIL_TEMP, /**< soil temperature [C] */ + OUT_SOIL_TNODE, /**< soil temperature [C] */ + OUT_SOIL_TNODE_WL, /**< soil temperature [C] */ + OUT_SOILT_FBFLAG, /**< soil temperature flag for each soil thermal node */ + OUT_SURF_TEMP, /**< average surface temperature [C] */ + OUT_SURFT_FBFLAG, /**< surface temperature flag */ + OUT_TCAN_FBFLAG, /**< Tcanopy flag */ + OUT_TDEPTH, /**< depth of thawing fronts [cm] */ + OUT_TFOL_FBFLAG, /**< Tfoliage flag */ + OUT_VEGT, /**< average vegetation canopy temperature [C] */ + // Energy Balance Terms - fluxes + OUT_ADV_SENS, /**< net sensible flux advected to snow pack [W/m2] */ + OUT_ADVECTION, /**< advected energy [W/m2] */ + OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] */ + OUT_DELTAH, /**< rate of change in heat storage [W/m2] */ + OUT_ENERGY_ERROR, /**< energy budget error [W/m2] */ + OUT_FUSION, /**< net energy used to melt/freeze soil moisture [W/m2] */ + OUT_GRND_FLUX, /**< net heat flux into ground [W/m2] */ + OUT_IN_LONG, /**< incoming longwave at ground surface (under veg) [W/m2] */ + OUT_LATENT, /**< net upward latent heat flux [W/m2] */ + OUT_LATENT_SUB, /**< net upward latent heat flux from sublimation [W/m2] */ + OUT_MELT_ENERGY, /**< energy of fusion (melting) in snowpack [W/m2] */ + OUT_LWNET, /**< net downward longwave flux [W/m2] */ + OUT_SWNET, /**< net downward shortwave flux [W/m2] */ + OUT_R_NET, /**< net downward radiation flux [W/m2] */ + OUT_RFRZ_ENERGY, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ + OUT_SENSIBLE, /**< net upward sensible heat flux [W/m2] */ + OUT_SNOW_FLUX, /**< energy flux through snow pack [W/m2] */ + // Miscellaneous Terms + OUT_AERO_COND, /**< "scene" aerodynamic conductance [m/s] (tiles with overstory contribute overstory conductance; others contribute surface conductance) */ + OUT_AERO_COND1, /**< surface aerodynamic conductance [m/s] */ + OUT_AERO_COND2, /**< overstory aerodynamic conductance [m/s] */ + OUT_AERO_RESIST, /**< "scene"canopy aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribute surface resistance)*/ + OUT_AERO_RESIST1, /**< surface aerodynamic resistance [s/m] */ + OUT_AERO_RESIST2, /**< overstory aerodynamic resistance [s/m] */ + OUT_AIR_TEMP, /**< air temperature [C] */ + OUT_CATM, /**< atmospheric CO2 concentrtaion [ppm]*/ + OUT_DENSITY, /**< near-surface atmospheric density [kg/m3]*/ + OUT_FCANOPY, /**< fractional area covered by plant canopy [fraction] */ + OUT_FDIR, /**< fraction of incoming shortwave that is direct [fraction]*/ + OUT_LAI, /**< leaf area index [m2/m2] */ + OUT_LWDOWN, /**< incoming longwave [W/m2] */ + OUT_PAR, /**< incoming photosynthetically active radiation [W/m2] */ + OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] */ + OUT_QAIR, /**< specific humidity [kg/kg] */ + OUT_REL_HUMID, /**< relative humidity [%]*/ + OUT_SWDOWN, /**< incoming shortwave [W/m2] */ + OUT_SURF_COND, /**< surface conductance [m/s] */ + OUT_VP, /**< near surface vapor pressure [kPa] */ + OUT_VPD, /**< near surface vapor pressure deficit [kPa] */ + OUT_WIND, /**< near surface wind speed [m/s] */ + // Band-specific quantities + OUT_ADV_SENS_BAND, /**< net sensible heat flux advected to snow pack [W/m2] */ + OUT_ADVECTION_BAND, /**< advected energy [W/m2] */ + OUT_ALBEDO_BAND, /**< average surface albedo [fraction] */ + OUT_DELTACC_BAND, /**< change in cold content in snow pack [W/m2] */ + OUT_GRND_FLUX_BAND, /**< net heat flux into ground [W/m2] */ + OUT_IN_LONG_BAND, /**< incoming longwave at ground surface (under veg) [W/m2] */ + OUT_LATENT_BAND, /**< net upward latent heat flux [W/m2] */ + OUT_LATENT_SUB_BAND, /**< net upward latent heat flux due to sublimation [W/m2] */ + OUT_MELT_ENERGY_BAND, /**< energy of fusion (melting) in snowpack [W/m2] */ + OUT_LWNET_BAND, /**< net downward longwave flux [W/m2] */ + OUT_SWNET_BAND, /**< net downward shortwave flux [W/m2] */ + OUT_RFRZ_ENERGY_BAND, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ + OUT_SENSIBLE_BAND, /**< net upward sensible heat flux [W/m2] */ + OUT_SNOW_CANOPY_BAND, /**< snow interception storage in canopy [mm] */ + OUT_SNOW_COVER_BAND, /**< fractional area of snow cover [fraction] */ + OUT_SNOW_DEPTH_BAND, /**< depth of snow pack [cm] */ + OUT_SNOW_FLUX_BAND, /**< energy flux through snow pack [W/m2] */ + OUT_SNOW_MELT_BAND, /**< snow melt [mm] */ + OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] */ + OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] */ + OUT_SWE_BAND, /**< snow water equivalent in snow pack [mm] */ + // Carbon-Cycling Terms + OUT_APAR, /**< absorbed PAR [W/m2] */ + OUT_GPP, /**< gross primary productivity [g C/m2d] */ + OUT_RAUT, /**< autotrophic respiration [g C/m2d] */ + OUT_NPP, /**< net primary productivity [g C/m2d] */ + OUT_LITTERFALL, /**< flux of carbon from living biomass into soil [g C/m2d] */ + OUT_RHET, /**< soil respiration (heterotrophic respiration) [g C/m2d] */ + OUT_NEE, /**< net ecosystem exchange (=NPP-RHET) [g C/m2d] */ + OUT_CLITTER, /**< Carbon density in litter pool [g C/m2] */ + OUT_CINTER, /**< Carbon density in intermediate pool [g C/m2] */ + OUT_CSLOW, /**< Carbon density in slow pool [g C/m2] */ + // Timing and Profiling Terms + OUT_TIME_VICRUN_WALL, /**< Wall time spent inside vic_run [seconds] */ + OUT_TIME_VICRUN_CPU, /**< Wall time spent inside vic_run [seconds] */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_OUTVAR_TYPES /**< used as a loop counter*/ +}; + +/****************************************************************************** + * @brief Output state variable. + *****************************************************************************/ +enum +{ + STATE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_SOIL_ICE, /**< ice content */ + STATE_CANOPY_WATER, /**< dew storage: tmpval = veg_var[veg][band].Wdew; */ + STATE_ANNUALNPP, /**< cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; */ + STATE_ANNUALNPPPREV, /**< previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; */ + STATE_CLITTER, /**< litter carbon: tmpval = cell[veg][band].CLitter; */ + STATE_CINTER, /**< intermediate carbon: tmpval = cell[veg][band].CInter; */ + STATE_CSLOW, /**< slow carbon: tmpval = cell[veg][band].CSlow; */ + STATE_SNOW_AGE, /**< snow age: snow[veg][band].last_snow */ + STATE_SNOW_MELT_STATE, /**< melting state: (int)snow[veg][band].MELTING */ + STATE_SNOW_COVERAGE, /**< snow covered fraction: snow[veg][band].coverage */ + STATE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: snow[veg][band].swq */ + STATE_SNOW_SURF_TEMP, /**< snow surface temperature: snow[veg][band].surf_temp */ + STATE_SNOW_SURF_WATER, /**< snow surface water: snow[veg][band].surf_water */ + STATE_SNOW_PACK_TEMP, /**< snow pack temperature: snow[veg][band].pack_temp */ + STATE_SNOW_PACK_WATER, /**< snow pack water: snow[veg][band].pack_water */ + STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ + STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ + STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ + STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ + STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ + STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ + STATE_ENERGY_SNOW_FLUX, /**< Thermal flux through the snow pack: energy[veg][band].snow_flux */ + STATE_LAKE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_LAKE_SOIL_ICE, /**< ice content */ + STATE_LAKE_CLITTER, /**< litter carbon: tmpval = lake_var.soil.CLitter; */ + STATE_LAKE_CINTER, /**< intermediate carbon: tmpval = lake_var.soil.CInter; */ + STATE_LAKE_CSLOW, /**< slow carbon: tmpval = lake_var.soil.CSlow; */ + STATE_LAKE_SNOW_AGE, /**< snow age: lake_var.snow.last_snow */ + STATE_LAKE_SNOW_MELT_STATE, /**< melting state: (int)lake_var.snow.MELTING */ + STATE_LAKE_SNOW_COVERAGE, /**< snow covered fraction: lake_var.snow.coverage */ + STATE_LAKE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: lake_var.snow.swq */ + STATE_LAKE_SNOW_SURF_TEMP, /**< snow surface temperature: lake_var.snow.surf_temp */ + STATE_LAKE_SNOW_SURF_WATER, /**< snow surface water: lake_var.snow.surf_water */ + STATE_LAKE_SNOW_PACK_TEMP, /**< snow pack temperature: lake_var.snow.pack_temp */ + STATE_LAKE_SNOW_PACK_WATER, /**< snow pack water: lake_var.snow.pack_water */ + STATE_LAKE_SNOW_DENSITY, /**< snow density: lake_var.snow.density */ + STATE_LAKE_SNOW_COLD_CONTENT, /**< snow cold content: lake_var.snow.coldcontent */ + STATE_LAKE_SNOW_CANOPY, /**< snow canopy storage: lake_var.snow.snow_canopy */ + STATE_LAKE_SOIL_NODE_TEMP, /**< soil node temperatures: lake_var.energy.T[nidx] */ + STATE_LAKE_ACTIVE_LAYERS, /**< lake active layers: lake_var.activenod */ + STATE_LAKE_LAYER_DZ, /**< lake layer thickness: lake_var.dz */ + STATE_LAKE_SURF_LAYER_DZ, /**< lake surface layer thickness: lake_var.surfdz */ + STATE_LAKE_DEPTH, /**< lake depth: lake_var.ldepth */ + STATE_LAKE_LAYER_SURF_AREA, /**< lake layer surface areas: lake_var.surface[ndix] */ + STATE_LAKE_SURF_AREA, /**< lake surface area: lake_var.sarea */ + STATE_LAKE_VOLUME, /**< lake volume: lake_var.volume */ + STATE_LAKE_LAYER_TEMP, /**< lake layer temperatures: lake_var.temp[nidx] */ + STATE_LAKE_AVERAGE_TEMP, /**< vertical average lake temperature: lake_var.tempavg */ + STATE_LAKE_ICE_AREA_FRAC, /**< lake ice area fraction: lake_var.areai */ + STATE_LAKE_ICE_AREA_FRAC_NEW, /**< new lake ice area fraction: lake_var.new_ice_area */ + STATE_LAKE_ICE_WATER_EQUIVALENT, /**< lake ice water equivalent: lake_var.ice_water_eq */ + STATE_LAKE_ICE_HEIGHT, /**< lake ice height: lake_var.hice */ + STATE_LAKE_ICE_TEMP, /**< lake ice temperature: lake_var.tempi */ + STATE_LAKE_ICE_SWE, /**< lake ice snow water equivalent: lake_var.swe */ + STATE_LAKE_ICE_SNOW_SURF_TEMP, /**< lake ice snow surface temperature: lake_var.surf_temp */ + STATE_LAKE_ICE_SNOW_PACK_TEMP, /**< lake ice snow pack temperature: lake_var.pack_temp */ + STATE_LAKE_ICE_SNOW_COLD_CONTENT, /**< lake ice snow coldcontent: lake_var.coldcontent */ + STATE_LAKE_ICE_SNOW_SURF_WATER, /**< lake ice snow surface water: lake_var.surf_water */ + STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ + STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ + STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ + STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gridcell_avg.avg_albedo */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_STATE_VARS /**< used as a loop counter*/ +}; + + +/****************************************************************************** + * @brief Output BINARY format types + *****************************************************************************/ +enum +{ + OUT_TYPE_DEFAULT, /**< Default data type */ + OUT_TYPE_CHAR, /**< char */ + OUT_TYPE_SINT, /**< short int */ + OUT_TYPE_USINT, /**< unsigned short int */ + OUT_TYPE_INT, /**< int */ + OUT_TYPE_FLOAT, /**< single-precision floating point */ + OUT_TYPE_DOUBLE /**< double-precision floating point */ +}; + +/****************************************************************************** + * @brief Output aggregation method types + *****************************************************************************/ +enum +{ + AGG_TYPE_DEFAULT, /**< Default aggregation type */ + AGG_TYPE_AVG, /**< average over agg interval */ + AGG_TYPE_BEG, /**< value at beginning of agg interval */ + AGG_TYPE_END, /**< value at end of agg interval */ + AGG_TYPE_MAX, /**< maximum value over agg interval */ + AGG_TYPE_MIN, /**< minimum value over agg interval */ + AGG_TYPE_SUM /**< sum over agg interval */ +}; + +/****************************************************************************** + * @brief Frequency flags for raising alarms/flags + *****************************************************************************/ +enum +{ + FREQ_NEVER, /**< Flag for never raising alarm */ + FREQ_NSTEPS, /**< Flag for raising alarm every nsteps */ + FREQ_NSECONDS, /**< Flag for raising alarm every nseconds */ + FREQ_NMINUTES, /**< Flag for raising alarm every nminutes */ + FREQ_NHOURS, /**< Flag for raising alarm every nhours */ + FREQ_NDAYS, /**< Flag for raising alarm every ndays */ + FREQ_NMONTHS, /**< Flag for raising alarm every nmonths */ + FREQ_NYEARS, /**< Flag for raising alarm every nyears */ + FREQ_DATE, /**< Flag for raising alarm on a specific date */ + FREQ_END /**< Flag for raising alarm at the end of a simulation */ +}; + +/****************************************************************************** + * @brief Codes for displaying version information + *****************************************************************************/ +enum +{ + DISP_VERSION, + DISP_COMPILE_TIME, + DISP_ALL +}; + +/****************************************************************************** + * @brief Codes for calendar option. + *****************************************************************************/ +enum calendars +{ + CALENDAR_STANDARD, + CALENDAR_GREGORIAN, + CALENDAR_PROLEPTIC_GREGORIAN, + CALENDAR_NOLEAP, + CALENDAR_365_DAY, + CALENDAR_360_DAY, + CALENDAR_JULIAN, + CALENDAR_ALL_LEAP, + CALENDAR_366_DAY +}; + +/****************************************************************************** + * @brief Codes for time units option. + *****************************************************************************/ +enum time_units +{ + TIME_UNITS_SECONDS, + TIME_UNITS_MINUTES, + TIME_UNITS_HOURS, + TIME_UNITS_DAYS +}; + +/****************************************************************************** + * @brief Codes for timers + *****************************************************************************/ +enum timers +{ + TIMER_VIC_ALL, + TIMER_VIC_INIT, + TIMER_VIC_RUN, + TIMER_VIC_FINAL, + TIMER_VIC_FORCE, + TIMER_VIC_WRITE, + N_TIMERS +}; + +/****************************************************************************** + * @brief Stores forcing file input information. + *****************************************************************************/ +typedef struct { + size_t N_ELEM; /**< number of elements per record; for LAI and ALBEDO, + 1 element per veg tile; for others N_ELEM = 1; */ + bool SIGNED; + bool SUPPLIED; + double multiplier; + char varname[MAXSTRING]; +} force_type_struct; + +/****************************************************************************** + * @brief This structure records the parameters set by the forcing file + input routines. Those filled, are used to estimate the paramters + needed for the model run in initialize_atmos.c. + *****************************************************************************/ +typedef struct { + force_type_struct TYPE[N_FORCING_TYPES]; + double FORCE_DT[2]; /**< forcing file time step */ + size_t force_steps_per_day[2]; /**< forcing file timesteps per day */ + unsigned short int FORCE_ENDIAN[2]; /**< endian-ness of input file, used for + DAILY_BINARY format */ + int FORCE_FORMAT[2]; /**< ASCII or BINARY */ + int FORCE_INDEX[2][N_FORCING_TYPES]; + size_t N_TYPES[2]; +} param_set_struct; + +/****************************************************************************** + * @brief This structure stores alarm information + *****************************************************************************/ +typedef struct { + unsigned int count; /**< current alarm count */ + dmy_struct next_dmy; /**< next dmy to raise alarm at */ + int next_count; /**< next count to raise alarm at */ + unsigned int freq; /**< enum value to describing alarm frequency */ + int n; /**< variable that provides additional information with respect to alarm_freq */ + bool is_subdaily; /**< flag denoting if alarm will be raised more than once per day */ +} alarm_struct; + +/****************************************************************************** + * @brief This structure stores output information for one output stream. + *****************************************************************************/ +typedef struct { + size_t nvars; /**< number of variables to store in the file */ + size_t ngridcells; /**< number of grid cells in aggdata */ + dmy_struct time_bounds[2]; /**< timestep bounds of stream */ + char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ + char filename[MAXSTRING]; /**< complete file name */ + FILE *fh; /**< filehandle */ + unsigned short int file_format; /**< output file format */ + short int compress; /**< Compress output files in stream*/ + unsigned short int *type; /**< type, when written to a binary file; + OUT_TYPE_USINT = unsigned short int + OUT_TYPE_SINT = short int + OUT_TYPE_FLOAT = single precision floating point + OUT_TYPE_DOUBLE = double precision floating point */ + double *mult; /**< multiplier, when written to a binary file [shape=(nvars, )] */ + char **format; /**< format, when written to disk [shape=(nvars, )] */ + unsigned int *varid; /**< id numbers of the variables to store in the file + (a variable's id number is its index in the out_data array). + The order of the id numbers in the varid array + is the order in which the variables will be written. */ + unsigned short int *aggtype; /**< type of aggregation to use [shape=(nvars, )] */ + double ****aggdata; /**< array of aggregated data values [shape=(ngridcells, nvars, nelem, nbins)] */ + alarm_struct agg_alarm; /**< alaram for stream aggregation */ + alarm_struct write_alarm; /**< alaram for controlling stream write */ +} stream_struct; + +/****************************************************************************** + * @brief This structure stores moisture state information for differencing + * with next time step. + *****************************************************************************/ +typedef struct { + double total_moist_storage; /**< total moisture storage [mm] */ + double total_soil_moist; /**< total column soil moisture [mm] */ + double surfstor; /**< surface water storage [mm] */ + double swe; /**< snow water equivalent [mm] */ + double wdew; /**< canopy interception [mm] */ +} save_data_struct; + +/****************************************************************************** + * @brief This structure stores metadata for individual variables + *****************************************************************************/ +typedef struct { + char varname[MAXSTRING]; /**< name of variable */ + char long_name[MAXSTRING]; /**< name of variable */ + char standard_name[MAXSTRING]; /**< cf long_name of variable */ + char units[MAXSTRING]; /**< units of variable */ + char description[MAXSTRING]; /**< descripition of variable */ + size_t nelem; /**< number of data values */ +} metadata_struct; + +/****************************************************************************** + * @brief This structure holds all variables needed for the error handling + * routines. + *****************************************************************************/ +typedef struct { + force_data_struct *force; + double dt; + energy_bal_struct *energy; + size_t rec; + double **out_data; + stream_struct *output_streams; + snow_data_struct *snow; + soil_con_struct soil_con; + veg_con_struct *veg_con; + veg_var_struct *veg_var; +} Error_struct; + +/****************************************************************************** + * @brief This structure holds timer information for profiling + *****************************************************************************/ +typedef struct { + double start_wall; + double start_cpu; + double stop_wall; + double stop_cpu; + double delta_wall; + double delta_cpu; +} timer_struct; + +double air_density(double t, double p); +void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, + double ***out_data); +double all_30_day_from_dmy(dmy_struct *dmy); +double all_leap_from_dmy(dmy_struct *dmy); +void alloc_aggdata(stream_struct *stream); +void alloc_out_data(size_t ngridcells, double ***out_data); +double average(double *ar, size_t n); +double calc_energy_balance_error(double, double, double, double, double); +void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); +double calc_water_balance_error(double, double, double, double); +bool cell_method_from_agg_type(unsigned short int aggtype, char cell_method[]); +bool check_write_flag(int rec); +void collect_eb_terms(energy_bal_struct, snow_data_struct, cell_data_struct, + double, double, double, bool, bool, double, bool, int, + double *, double, double **); +void collect_wb_terms(cell_data_struct, veg_var_struct, snow_data_struct, + double, double, double, bool, double, bool, double *, + double **); +void compute_derived_state_vars(all_vars_struct *, soil_con_struct *, + veg_con_struct *); +void compute_lake_params(lake_con_struct *, soil_con_struct); +void compute_treeline(force_data_struct *, dmy_struct *, double, double *, + bool *); +size_t count_force_vars(FILE *gp); +void count_nstreams_nvars(FILE *gp, size_t *nstreams, size_t nvars[]); +void cmd_proc(int argc, char **argv, char *globalfilename); +void compress_files(char string[], short int level); +stream_struct create_outstream(stream_struct *output_streams); +double get_cpu_time(); +void get_current_datetime(char *cdt); +double get_wall_time(); +double date2num(double origin, dmy_struct *date, double tzoffset, + unsigned short int calendar, unsigned short int time_units); +void dmy_all_30_day(double julian, dmy_struct *dmy); +void dmy_all_leap(double julian, dmy_struct *dmy); +bool dmy_equal(dmy_struct *a, dmy_struct *b); +void dmy_julian_day(double julian, unsigned short int calendar, + dmy_struct *dmy); +void dmy_no_leap_day(double julian, dmy_struct *dmy); +void dt_seconds_to_time_units(unsigned short int time_units, double dt_seconds, + double *dt_time_units); +void display_current_settings(int); +double fractional_day_from_dmy(dmy_struct *dmy); +void free_all_vars(all_vars_struct *all_vars, int Nveg); +void free_dmy(dmy_struct **dmy); +void free_out_data(size_t ngridcells, double ***out_data); +void free_streams(stream_struct **streams); +void free_vegcon(veg_con_struct **veg_con); +void generate_default_state(all_vars_struct *, soil_con_struct *, + veg_con_struct *, dmy_struct *); +void generate_default_lake_state(all_vars_struct *, soil_con_struct *, + lake_con_struct); +void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); +void get_parameters(FILE *paramfile); +void init_output_list(double **out_data, int write, char *format, int type, + double mult); +void initialize_energy(energy_bal_struct **energy, size_t nveg); +void initialize_global(void); +void initialize_options(void); +void initialize_parameters(void); +void initialize_save_data(all_vars_struct *all_vars, force_data_struct *force, + soil_con_struct *soil_con, veg_con_struct *veg_con, + veg_lib_struct *veg_lib, lake_con_struct *lake_con, + double **out_data, save_data_struct *save_data, + timer_struct *timer); +void initialize_snow(snow_data_struct **snow, size_t veg_num); +void initialize_soil(cell_data_struct **cell, size_t veg_num); +void initialize_time(void); +void initialize_veg(veg_var_struct **veg_var, size_t nveg); +double julian_day_from_dmy(dmy_struct *dmy, unsigned short int calendar); +bool leap_year(unsigned short int year, unsigned short int calendar); +all_vars_struct make_all_vars(size_t nveg); +cell_data_struct **make_cell_data(size_t veg_type_num); +dmy_struct *make_dmy(global_param_struct *global); +energy_bal_struct **make_energy_bal(size_t nveg); +void make_lastday(unsigned short int calendar, unsigned short int year, + unsigned short int lastday[]); +snow_data_struct **make_snow_data(size_t nveg); +veg_var_struct **make_veg_var(size_t veg_type_num); +double no_leap_day_from_dmy(dmy_struct *dmy); +void num2date(double origin, double time_value, double tzoffset, + unsigned short int calendar, unsigned short int time_units, + dmy_struct *date); +FILE *open_file(char string[], char type[]); +void parse_nc_time_units(char *nc_unit_chars, unsigned short int *units, + dmy_struct *dmy); +void put_data(all_vars_struct *, force_data_struct *, soil_con_struct *, + veg_con_struct *, veg_lib_struct *veg_lib, lake_con_struct *, + double **out_data, save_data_struct *, timer_struct *timer); +void print_alarm(alarm_struct *alarm); +void print_cell_data(cell_data_struct *cell, size_t nlayers, size_t nfrost); +void print_dmy(dmy_struct *dmy); +void print_energy_bal(energy_bal_struct *eb, size_t nnodes, size_t nfronts); +void print_force_type(force_type_struct *force_type); +void print_global_param(global_param_struct *gp); +void print_lake_con(lake_con_struct *lcon, size_t nlnodes); +void print_lake_var(lake_var_struct *lvar, size_t nlnodes, size_t nfronts, + size_t nlayers, size_t nnodes, size_t nfrost); +void print_layer_data_states(layer_data_struct *ldata, size_t nfrost); +void print_layer_data_fluxes(layer_data_struct *ldata); +void print_license(void); +void print_option(option_struct *option); +void print_out_data(double **out_data, metadata_struct *metadata); +void print_out_metadata(metadata_struct *metadata, size_t nvars); +void print_output_streams(stream_struct *outf); +void print_param_set(param_set_struct *param_set); +void print_parameters(parameters_struct *param); +void print_save_data(save_data_struct *save); +void print_snow_data(snow_data_struct *snow); +void print_soil_con(soil_con_struct *scon, size_t nlayers, size_t nnodes, + size_t nfrost, size_t nbands, size_t nzwt); +void print_stream(stream_struct *stream, metadata_struct *metadata); +void print_veg_con(veg_con_struct *vcon, size_t nroots, char blowing, char lake, + char carbon, size_t ncanopy); +void print_veg_lib(veg_lib_struct *vlib, char carbon); +void print_veg_var(veg_var_struct *vvar, size_t ncanopy); +void print_version(char *); +void print_usage(char *); +double q_to_vp(double q, double p); +bool raise_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_stream(stream_struct *stream, dmy_struct *dmy_current); +void set_output_var(stream_struct *stream, char *varname, size_t varnum, + char *format, unsigned short int type, double mult, + unsigned short int aggtype); +unsigned int get_default_outvar_aggtype(unsigned int varid); +void set_alarm(dmy_struct *dmy_current, unsigned int freq, void *value, + alarm_struct *alarm); +void set_output_defaults(stream_struct **output_streams, + dmy_struct *dmy_current, + unsigned short default_file_format); +void set_output_met_data_info(); +void setup_stream(stream_struct *stream, size_t nvars, size_t ngridcells); +void soil_moisture_from_water_table(soil_con_struct *soil_con, size_t nlayers); +void sprint_dmy(char *str, dmy_struct *dmy); +void str_from_calendar(unsigned short int calendar, char *calendar_str); +void str_from_time_units(unsigned short int time_units, char *unit_str); +unsigned short int str_to_agg_type(char aggstr[]); +void str_to_ascii_format(char *format); +bool str_to_bool(char str[]); +unsigned short int str_to_calendar(char *cal_chars); +unsigned short int str_to_freq_flag(char freq[]); +double str_to_out_mult(char multstr[]); +unsigned short int str_to_out_type(char typestr[]); +unsigned short int str_to_timeunits(char units_chars[]); +void strpdmy(const char *s, const char *format, dmy_struct *dmy); +double time_delta(dmy_struct *dmy_current, unsigned short int freq, int n); +void timer_continue(timer_struct *t); +void timer_init(timer_struct *t); +void timer_start(timer_struct *t); +void timer_stop(timer_struct *t); +int update_step_vars(all_vars_struct *, veg_con_struct *, veg_hist_struct *); +int invalid_date(unsigned short int calendar, dmy_struct *dmy); +void validate_parameters(void); +void validate_streams(stream_struct **stream); +char will_it_snow(double *t, double t_offset, double max_snow_temp, + double *prcp, size_t n); +void zero_output_list(double **); + +#endif diff --git a/vic/extensions/rout_stub/src/state_metadata.c b/vic/extensions/rout_stub/src/state_metadata.c new file mode 100644 index 000000000..5792160fe --- /dev/null +++ b/vic/extensions/rout_stub/src/state_metadata.c @@ -0,0 +1,710 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * This routine sets the metadata structure for VIC state variables + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Set output met data information + *****************************************************************************/ +void +set_state_meta_data_info() +{ + size_t v; + + extern option_struct options; + extern metadata_struct state_metadata[N_STATE_VARS]; + + // Build the list of state variables + + // Set missing and/or default values + for (v = 0; v < N_STATE_VARS; v++) { + // Set default string values + strcpy(state_metadata[v].varname, MISSING_S); + strcpy(state_metadata[v].long_name, MISSING_S); + strcpy(state_metadata[v].standard_name, MISSING_S); + strcpy(state_metadata[v].units, MISSING_S); + strcpy(state_metadata[v].description, MISSING_S); + // Set default number of elements + state_metadata[v].nelem = 1; + } + + // STATE_SOIL_MOISTURE + strcpy(state_metadata[STATE_SOIL_MOISTURE].varname, "STATE_SOIL_MOISTURE"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].long_name, "soil_moisture"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].standard_name, + "soil_layer_moisture"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].units, "mm"); + strcpy(state_metadata[STATE_SOIL_MOISTURE].description, + "soil total moisture contents including ice for each soil layer"); + + // STATE_SOIL_ICE + strcpy(state_metadata[STATE_SOIL_ICE].varname, "STATE_SOIL_ICE"); + strcpy(state_metadata[STATE_SOIL_ICE].long_name, "soil_ice"); + strcpy(state_metadata[STATE_SOIL_ICE].standard_name, + "soil_moisture_ice_depth"); + strcpy(state_metadata[STATE_SOIL_ICE].units, "mm"); + strcpy(state_metadata[STATE_SOIL_ICE].description, + "soil ice content for each soil layer"); + + // STATE_CANOPY_WATER + strcpy(state_metadata[STATE_CANOPY_WATER].varname, "STATE_CANOPY_WATER"); + strcpy(state_metadata[STATE_CANOPY_WATER].long_name, "canopy_water"); + strcpy(state_metadata[STATE_CANOPY_WATER].standard_name, "water_in_canopy"); + strcpy(state_metadata[STATE_CANOPY_WATER].units, "mm"); + strcpy(state_metadata[STATE_CANOPY_WATER].description, + "amount of water stored in the vegetation canopy"); + + if (options.CARBON) { + // STATE_ANNUALNPP + strcpy(state_metadata[STATE_ANNUALNPP].varname, "STATE_ANNUALNPP"); + strcpy(state_metadata[STATE_ANNUALNPP].long_name, "annualnpp"); + strcpy(state_metadata[STATE_ANNUALNPP].standard_name, + "running_total_annual_NPP"); + strcpy(state_metadata[STATE_ANNUALNPP].units, "g m-2"); + strcpy(state_metadata[STATE_ANNUALNPP].description, + "running total annual NPP"); + + // STATE_ANNUALNPPPREV + strcpy(state_metadata[STATE_ANNUALNPPPREV].varname, + "STATE_ANNUALNPPPREV"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].long_name, "annualnppprev"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].standard_name, + "previous_year_total_annual_NPP"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].units, "g m-2"); + strcpy(state_metadata[STATE_ANNUALNPPPREV].description, + "total annual NPP from previous year"); + + // STATE_CLITTER + strcpy(state_metadata[STATE_CLITTER].varname, "STATE_CLITTER"); + strcpy(state_metadata[STATE_CLITTER].long_name, "clitter"); + strcpy(state_metadata[STATE_CLITTER].standard_name, + "carbon_in_litter_pool"); + strcpy(state_metadata[STATE_CLITTER].units, "g m-2"); + strcpy(state_metadata[STATE_CLITTER].description, + "carbon storage in litter pool"); + + // STATE_CINTER + strcpy(state_metadata[STATE_CINTER].varname, "STATE_CINTER"); + strcpy(state_metadata[STATE_CINTER].long_name, "cinter"); + strcpy(state_metadata[STATE_CINTER].standard_name, + "carbon_in_intermediate_pool"); + strcpy(state_metadata[STATE_CINTER].units, "g m-2"); + strcpy(state_metadata[STATE_CINTER].description, + "carbon storage in intermediate pool"); + + // STATE_CSLOW + strcpy(state_metadata[STATE_CSLOW].varname, "STATE_CSLOW"); + strcpy(state_metadata[STATE_CSLOW].long_name, "cslow"); + strcpy(state_metadata[STATE_CSLOW].standard_name, + "carbon_in_slow_pool"); + strcpy(state_metadata[STATE_CSLOW].units, "g m-2"); + strcpy(state_metadata[STATE_CSLOW].description, + "carbon storage in slow pool"); + } + // STATE_SNOW_AGE + strcpy(state_metadata[STATE_SNOW_AGE].varname, "STATE_SNOW_AGE"); + strcpy(state_metadata[STATE_SNOW_AGE].long_name, "snow_age"); + strcpy(state_metadata[STATE_SNOW_AGE].standard_name, + "age_since_last_new_snow"); + strcpy(state_metadata[STATE_SNOW_AGE].units, "model_time_step"); + strcpy(state_metadata[STATE_SNOW_AGE].description, + "number of model time steps since the last new snow"); + + // STATE_SNOW_MELT_STATE + strcpy(state_metadata[STATE_SNOW_MELT_STATE].varname, + "STATE_SNOW_MELT_STATE"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].long_name, "snow_melt_state"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].standard_name, + "snow_melting_phase"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].units, + "1 melting, 0 not melting"); + strcpy(state_metadata[STATE_SNOW_MELT_STATE].description, + "flag to indicate whether snowpack is in accumulation or melting phase"); + + // STATE_SNOW_COVERAGE + strcpy(state_metadata[STATE_SNOW_COVERAGE].varname, "STATE_SNOW_COVERAGE"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].long_name, "snow_coverage"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].standard_name, + "snow_coverage_fraction"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].units, "1"); + strcpy(state_metadata[STATE_SNOW_COVERAGE].description, + "fraction of grid cell area covered by snow"); + + // STATE_SNOW_WATER_EQUIVALENT + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].varname, + "STATE_SNOW_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].long_name, + "snow_water_equivalent"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].standard_name, + "snow_water_equivalent"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].units, "m"); + strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].description, + "snow water equivalent"); + + // STATE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].varname, + "STATE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].long_name, "snow_surf_temp"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].standard_name, + "snow_surface_temperature"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_SNOW_SURF_TEMP].description, + "snow surface layer temperature"); + + // STATE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_SNOW_SURF_WATER].varname, + "STATE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].long_name, "snow_surf_water"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].standard_name, + "snow_surface_liquid_water"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_SNOW_SURF_WATER].description, + "liquid water content of the snow surface layer"); + + // STATE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].varname, + "STATE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].long_name, "snow_pack_temp"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].standard_name, + "snow_pack_temperature"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_SNOW_PACK_TEMP].description, + "snow pack layer temperature"); + + // STATE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_SNOW_PACK_WATER].varname, + "STATE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].long_name, "snow_pack_water"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].standard_name, + "snow_pack_liquid_water"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_SNOW_PACK_WATER].description, + "liquid water content of the snow pack layer"); + + // STATE_SNOW_DENSITY + strcpy(state_metadata[STATE_SNOW_DENSITY].varname, "STATE_SNOW_DENSITY"); + strcpy(state_metadata[STATE_SNOW_DENSITY].long_name, "snow_density"); + strcpy(state_metadata[STATE_SNOW_DENSITY].standard_name, + "snowpack_density"); + strcpy(state_metadata[STATE_SNOW_DENSITY].units, "kg m-3"); + strcpy(state_metadata[STATE_SNOW_DENSITY].description, "snowpack density"); + + // STATE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].varname, + "STATE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].long_name, + "snow_cold_content"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].standard_name, + "snowpack_cold_content"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].description, + "snowpack cold content"); + + // STATE_SNOW_CANOPY + strcpy(state_metadata[STATE_SNOW_CANOPY].varname, "STATE_SNOW_CANOPY"); + strcpy(state_metadata[STATE_SNOW_CANOPY].long_name, "snow_canopy"); + strcpy(state_metadata[STATE_SNOW_CANOPY].standard_name, + "snow_water_equivalent_intercepted_in_canopy"); + strcpy(state_metadata[STATE_SNOW_CANOPY].units, "m"); + strcpy(state_metadata[STATE_SNOW_CANOPY].description, + "snow interception storage in canopy"); + + // STATE_SOIL_NODE_TEMP + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].varname, + "STATE_SOIL_NODE_TEMP"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].long_name, "soil_node_temp"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].standard_name, + "soil_node_temperature"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].units, "C"); + strcpy(state_metadata[STATE_SOIL_NODE_TEMP].description, + "soil temperature of each soil thermal node"); + + // STATE_FOLIAGE_TEMPERATURE + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, + "STATE_FOLIAGE_TEMPERATURE"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].long_name, + "foliage_temperature"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].standard_name, + "foliage_temperature"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].units, "C"); + strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].description, + "overstory vegetaion temperature"); + + // STATE_ENERGY_LONGUNDEROUT + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, + "STATE_ENERGY_LONGUNDEROUT"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].long_name, + "energy_longunderout"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].standard_name, + "longwave_out_from_understory"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].units, "W m-2"); + strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].description, + "outgoing longwave flux from understory vegetation"); + + // STATE_ENERGY_SNOW_FLUX + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].varname, + "STATE_ENERGY_SNOW_FLUX"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].long_name, + "energy_snow_flux"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].standard_name, + "snowpack_thermal_flux"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].units, "W m-2"); + strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].description, + "thermal flux through snowpack"); + + // STATE_GRIDCELL_AVG_ALBEDO + strcpy(state_metadata[STATE_AVG_ALBEDO].varname, + "STATE_AVG_ALBEDO"); + strcpy(state_metadata[STATE_AVG_ALBEDO].long_name, + "state_avg_albedo"); + strcpy(state_metadata[STATE_AVG_ALBEDO].standard_name, + "state_gridcell_avg_albedo"); + strcpy(state_metadata[STATE_AVG_ALBEDO].units, "fraction"); + strcpy(state_metadata[STATE_AVG_ALBEDO].description, + "gridcell averaged albedo"); + + if (options.LAKES) { + // STATE_LAKE_SOIL_MOISTURE + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, + "STATE_LAKE_SOIL_MOISTURE"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].long_name, + "lake_soil_moisture"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].standard_name, + "lake_soil_moisture"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].units, "mm"); + strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].description, + "soil moisture below lake"); + + // STATE_LAKE_SOIL_ICE + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].varname, + "STATE_LAKE_SOIL_ICE"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].long_name, "lake_soil_ice"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].standard_name, + "lake_soil_ice_content"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].units, "mm"); + strcpy(state_metadata[STATE_LAKE_SOIL_ICE].description, + "soil ice content below lake"); + + if (options.CARBON) { + // STATE_LAKE_CLITTER + strcpy(state_metadata[STATE_LAKE_CLITTER].varname, + "STATE_LAKE_CLITTER"); + strcpy(state_metadata[STATE_LAKE_CLITTER].long_name, + "lake_clitter"); + strcpy(state_metadata[STATE_LAKE_CLITTER].standard_name, + "lake_carbon_in_litter_pool"); + strcpy(state_metadata[STATE_LAKE_CLITTER].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CLITTER].description, + "carbon storage in litter pool below lake"); + + // STATE_LAKE_CINTER + strcpy(state_metadata[STATE_LAKE_CINTER].varname, + "STATE_LAKE_CINTER"); + strcpy(state_metadata[STATE_LAKE_CINTER].long_name, "lake_cinter"); + strcpy(state_metadata[STATE_LAKE_CINTER].standard_name, + "lake_carbon_in_intermediate_pool"); + strcpy(state_metadata[STATE_LAKE_CINTER].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CINTER].description, + "carbon storage in intermediate pool below lake"); + + // STATE_LAKE_CSLOW + strcpy(state_metadata[STATE_LAKE_CSLOW].varname, + "STATE_LAKE_CSLOW"); + strcpy(state_metadata[STATE_LAKE_CSLOW].long_name, "lake_cslow"); + strcpy(state_metadata[STATE_LAKE_CSLOW].standard_name, + "lake_carbon_in_slow_pool"); + strcpy(state_metadata[STATE_LAKE_CSLOW].units, "g m-2"); + strcpy(state_metadata[STATE_LAKE_CSLOW].description, + "carbon storage in slow pool below lake"); + } + + // STATE_LAKE_SNOW_AGE + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].varname, + "STATE_LAKE_SNOW_AGE"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].long_name, "lake_snow_age"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].standard_name, + "lake_age_since_last_new_snow"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].units, "model_time_step"); + strcpy(state_metadata[STATE_LAKE_SNOW_AGE].description, + "number of model time steps since the last new snow on lake ice"); + + // STATE_LAKE_SNOW_MELT_STATE + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, + "STATE_LAKE_SNOW_MELT_STATE"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].long_name, + "lake_snow_melt_state"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].standard_name, + "lake_snow_melting_phase"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].units, + "1 melting, 0 not melting"); + strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].description, + "flag to indicate whether snowpack is in accumulation or melting phase on lake ice"); + + // STATE_LAKE_SNOW_COVERAGE + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, + "STATE_LAKE_SNOW_COVERAGE"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].long_name, + "lake_snow_coverage"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].standard_name, + "lake_snow_coverage_fraction"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].units, "1"); + strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].description, + "fraction of grid cell area covered by snow on lake ice"); + + // STATE_LAKE_SNOW_WATER_EQUIVALENT + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, + "STATE_LAKE_SNOW_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].long_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].standard_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].description, + "lake snow water equivalent on lake ice"); + + // STATE_LAKE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, + "STATE_LAKE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].long_name, + "lake_snow_surf_temp"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].description, + "snow surface layer temperature on lake ice"); + + // STATE_LAKE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, + "STATE_LAKE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].long_name, + "lake_snow_surf_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].description, + "liquid water content of the snow surface layer on lake ice"); + + // STATE_LAKE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, + "STATE_LAKE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].long_name, + "lake_snow_pack_temp"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].standard_name, + "lake_snow_pack_temperature"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].description, + "snow pack layer temperature on lake ice"); + + // STATE_LAKE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, + "STATE_LAKE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].long_name, + "lake_snow_pack_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].standard_name, + "lake_snow_surface_liquid_water"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].description, + "liquid water content of the snow surface layer on lake ice"); + + // STATE_LAKE_SNOW_DENSITY + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].varname, + "STATE_LAKE_SNOW_DENSITY"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].long_name, + "lake_snow_density"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].standard_name, + "lake_snowpack_density"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].units, "kg m-3"); + strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].description, + "snowpack density on lake ice"); + + // STATE_LAKE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, + "STATE_LAKE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].long_name, + "lake_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].standard_name, + "lake_snowpack_cold_content"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].description, + "snowpack cold content on lake ice"); + + // STATE_LAKE_SNOW_CANOPY + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].varname, + "STATE_LAKE_SNOW_CANOPY"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].long_name, + "lake_snow_canopy"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].standard_name, + "lake_snow_water_equivalent_intercepted_in_canopy"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].units, "m"); + strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].description, + "snow interception storage in canopy on lake ice"); + + // STATE_LAKE_SOIL_NODE_TEMP + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, + "STATE_LAKE_SOIL_NODE_TEMP"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].long_name, + "lake_soil_node_temp"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].standard_name, + "lake_soil_node_temperature"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].description, + "soil temperature of each soil thermal node below lake"); + + // STATE_LAKE_ACTIVE_LAYERS + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, + "STATE_LAKE_ACTIVE_LAYERS"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].long_name, + "lake_active_layers"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].standard_name, + "lake_active_layers"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].units, "-"); + strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].description, + "number of nodes whose corresponding layers currently contain water"); + + // STATE_LAKE_LAYER_DZ + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].varname, + "STATE_LAKE_LAYER_DZ"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].long_name, "lake_layer_dz"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].standard_name, + "lake_thickness_layer_below_surface"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].units, "m"); + strcpy(state_metadata[STATE_LAKE_LAYER_DZ].description, + "vertical thickness of all horizontal lake water layers below the surface layer"); + + // STATE_LAKE_SURF_LAYER_DZ + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, + "STATE_LAKE_SURF_LAYER_DZ"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].long_name, + "lake_surf_layer_dz"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].standard_name, + "lake_thickness_surface_layer"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].units, "m"); + strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].description, + "vertical thickness of surface water layer in lake"); + + // STATE_LAKE_DEPTH + strcpy(state_metadata[STATE_LAKE_DEPTH].varname, "STATE_LAKE_DEPTH"); + strcpy(state_metadata[STATE_LAKE_DEPTH].long_name, "lake_depth"); + strcpy(state_metadata[STATE_LAKE_DEPTH].standard_name, + "lake_liquid_water_depth"); + strcpy(state_metadata[STATE_LAKE_DEPTH].units, "m"); + strcpy(state_metadata[STATE_LAKE_DEPTH].description, + "distance from surface to deepest point in lake"); + + // STATE_LAKE_LAYER_SURF_AREA + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].varname, + "STATE_LAKE_LAYER_SURF_AREA"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].long_name, + "lake_layer_surf_area"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].standard_name, + "lake_node_surface_area"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].units, "m2"); + strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].description, + "surface area of liquid water in lake at each node"); + + // STATE_LAKE_SURF_AREA + strcpy(state_metadata[STATE_LAKE_SURF_AREA].varname, + "STATE_LAKE_SURF_AREA"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].long_name, + "lake_surf_area"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].standard_name, + "lake_surface_area"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].units, "m2"); + strcpy(state_metadata[STATE_LAKE_SURF_AREA].description, + "surface area of liquid plus ice water on lake surface"); + + // STATE_LAKE_VOLUME + strcpy(state_metadata[STATE_LAKE_VOLUME].varname, "STATE_LAKE_VOLUME"); + strcpy(state_metadata[STATE_LAKE_VOLUME].long_name, "lake_volume"); + strcpy(state_metadata[STATE_LAKE_VOLUME].standard_name, "lake_volume"); + strcpy(state_metadata[STATE_LAKE_VOLUME].units, "m3"); + strcpy(state_metadata[STATE_LAKE_VOLUME].description, + "lake total volume including liquid water equivalent of lake ice"); + + // STATE_LAKE_LAYER_TEMP + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].varname, + "STATE_LAKE_LAYER_TEMP"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].long_name, + "lake_layer_temp"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].standard_name, + "lake_layer_temp"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].description, + "lake water temperature at each node"); + + // STATE_LAKE_AVERAGE_TEMP + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, + "STATE_LAKE_AVERAGE_TEMP"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].long_name, + "lake_average_temp"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].standard_name, + "lake_average_temperature"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].description, + "average liquid water temperature of entire lake"); + + // STATE_LAKE_ICE_AREA_FRAC + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, + "STATE_LAKE_ICE_AREA"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].long_name, + "lake_ice_area"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].standard_name, + "lake_ice_coverage"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].units, "m2"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].description, + "area of ice coverage on lake at beginning of time step"); + + // STATE_LAKE_ICE_AREA_FRAC_NEW + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, + "STATE_LAKE_ICE_AREA_NEW"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].long_name, + "lake_ice_area_new"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].standard_name, + "lake_ice_area_new"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].units, "m2"); + strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].description, + "area of ice coverage on lake at end of time step"); + + // STATE_LAKE_ICE_WATER_EQUIVALENT + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].varname, + "STATE_LAKE_ICE_WATER_EQUIVALENT"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].long_name, + "lake_ice_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].standard_name, + "lake_ice_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].units, "m3"); + strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].description, + "liquid water equivalent volume of lake ice"); + + // STATE_LAKE_ICE_HEIGHT + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].varname, + "STATE_LAKE_ICE_HEIGHT"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].long_name, + "lake_ice_height"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].standard_name, + "lake_ice_height_thickest"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].description, + "lake ice height at ghickest point"); + + // STATE_LAKE_ICE_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].varname, + "STATE_LAKE_ICE_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].long_name, "lake_ice_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].standard_name, + "lake_ice_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_TEMP].description, + "lake ice temperature"); + + // STATE_LAKE_ICE_SWE + strcpy(state_metadata[STATE_LAKE_ICE_SWE].varname, + "STATE_LAKE_ICE_SWE"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].long_name, "lake_ice_swe"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].standard_name, + "lake_snow_water_equivalent"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SWE].description, + "liquid water equivalent depth of lake snow"); + + // STATE_LAKE_ICE_SNOW_SURF_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, + "STATE_LAKE_ICE_SNOW_SURF_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].long_name, + "lake_ice_snow_surf_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].standard_name, + "lake_snow_surface_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].description, + "temperature of snow surface layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_PACK_TEMP + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, + "STATE_LAKE_ICE_SNOW_PACK_TEMP"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].long_name, + "lake_ice_snow_pack_temp"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].standard_name, + "lake_ice_snow_pack_temperature"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].units, "C"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].description, + "temperature of snow pack layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_COLD_CONTENT + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, + "STATE_LAKE_ICE_SNOW_COLD_CONTENT"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].long_name, + "lake_ice_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].standard_name, + "lake_ice_snow_cold_content"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].units, "J m-2"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].description, + "snowpack cold content of snow lake"); + + // STATE_LAKE_ICE_SNOW_SURF_WATER + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].varname, + "STATE_LAKE_ICE_SNOW_SURF_WATER"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].long_name, + "lake_ice_snow_surf_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].standard_name, + "lake_ice_snow_surface_liquid_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].description, + "liquid water content of surface snow layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_PACK_WATER + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].varname, + "STATE_LAKE_ICE_SNOW_PACK_WATER"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].long_name, + "lake_ice_snow_pack_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].standard_name, + "lake_ice_snow_pack_liquid_water"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].description, + "liquid water content of pack snow layer of lake snow"); + + // STATE_LAKE_ICE_SNOW_ALBEDO + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, + "STATE_LAKE_ICE_SNOW_ALBEDO"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].long_name, + "lake_ice_snow_albedo"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].standard_name, + "lake_ice_snow_albedo"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].units, "1"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].description, + "albedo of lake snow"); + + // STATE_LAKE_ICE_SNOW_DEPTH + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, + "STATE_LAKE_ICE_SNOW_DEPTH"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].long_name, + "lake_ice_snow_depth"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].standard_name, + "lake_ice_snow_depth"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].units, "m"); + strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].description, + "depth of snow on lake ice"); + } +} diff --git a/vic/extensions/rout_stub/src/vic_restore.c b/vic/extensions/rout_stub/src/vic_restore.c new file mode 100644 index 000000000..5210edeb5 --- /dev/null +++ b/vic/extensions/rout_stub/src/vic_restore.c @@ -0,0 +1,1119 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Read initial model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Read initial model state. + *****************************************************************************/ +void +vic_restore(void) +{ + extern int mpi_rank; + extern all_vars_struct *all_vars; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern option_struct options; + extern veg_con_map_struct *veg_con_map; + extern filenames_struct filenames; + extern metadata_struct state_metadata[N_STATE_VARS]; + extern int mpi_rank; + + int v; + size_t i; + size_t j; + size_t k; + size_t m; + size_t p; + int *ivar = NULL; + int status; + double *dvar = NULL; + size_t d2count[2]; + size_t d2start[2]; + size_t d3count[3]; + size_t d3start[3]; + size_t d4count[4]; + size_t d4start[4]; + size_t d5count[5]; + size_t d5start[5]; + size_t d6count[6]; + size_t d6start[6]; + + if (mpi_rank == VIC_MPI_ROOT) { + // open initial state file + status = nc_open(filenames.init_state.nc_filename, NC_NOWRITE, + &(filenames.init_state.nc_id)); + check_nc_status(status, "Error opening %s", + filenames.init_state.nc_filename); + } + + // validate state file dimensions and coordinate variables + check_init_state_file(); + // read state variables + + // allocate memory for variables to be stored + ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + // initialize starts and counts + d2start[0] = 0; + d2start[1] = 0; + d2count[0] = global_domain.n_ny; + d2count[1] = global_domain.n_nx; + + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = 1; + d3count[1] = global_domain.n_ny; + d3count[2] = global_domain.n_nx; + + d4start[0] = 0; + d4start[1] = 0; + d4start[2] = 0; + d4start[3] = 0; + d4count[0] = 1; + d4count[1] = 1; + d4count[2] = global_domain.n_ny; + d4count[3] = global_domain.n_nx; + + d5start[0] = 0; + d5start[1] = 0; + d5start[2] = 0; + d5start[3] = 0; + d5start[4] = 0; + d5count[0] = 1; + d5count[1] = 1; + d5count[2] = 1; + d5count[3] = global_domain.n_ny; + d5count[4] = global_domain.n_nx; + + d6start[0] = 0; + d6start[1] = 0; + d6start[2] = 0; + d6start[3] = 0; + d6start[4] = 0; + d6start[5] = 0; + d6count[0] = 1; + d6count[1] = 1; + d6count[2] = 1; + d6count[3] = 1; + d6count[4] = global_domain.n_ny; + d6count[5] = global_domain.n_nx; + + // total soil moisture + for (m = 0; m < options.NVEGTYPES; m++) { + d5start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d5start[1] = k; + for (j = 0; j < options.Nlayer; j++) { + d5start[2] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SOIL_MOISTURE].varname, + d5start, d5count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].cell[v][k].layer[j].moist = dvar[i]; + } + } + } + } + } + + // ice content + for (m = 0; m < options.NVEGTYPES; m++) { + d6start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d6start[1] = k; + for (j = 0; j < options.Nlayer; j++) { + d6start[2] = j; + for (p = 0; p < options.Nfrost; p++) { + d6start[3] = p; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SOIL_ICE].varname, + d6start, d6count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].cell[v][k].layer[j].ice[p] = dvar[i]; + } + } + } + } + } + } + + // dew storage: tmpval = veg_var[veg][band].Wdew; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_CANOPY_WATER].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].veg_var[v][k].Wdew = dvar[i]; + } + } + } + } + + if (options.CARBON) { + // cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_ANNUALNPP].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].veg_var[v][k].AnnualNPP = dvar[i]; + } + } + } + } + + // previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_ANNUALNPPPREV].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].veg_var[v][k].AnnualNPPPrev = dvar[i]; + } + } + } + } + + // litter carbon: tmpval = cell[veg][band].CLitter; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_CLITTER].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].cell[v][k].CLitter = dvar[i]; + } + } + } + } + + // intermediate carbon: tmpval = cell[veg][band].CInter; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_CINTER].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].cell[v][k].CInter = dvar[i]; + } + } + } + } + + // slow carbon: tmpval = cell[veg][band].CSlow; + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_CSLOW].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].cell[v][k].CSlow = dvar[i]; + } + } + } + } + } + + // snow age: snow[veg][band].last_snow + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_int(&(filenames.init_state), + state_metadata[STATE_SNOW_AGE].varname, + d4start, d4count, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].last_snow = ivar[i]; + } + } + } + } + + // melting state: (int)snow[veg][band].MELTING + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_int(&(filenames.init_state), + state_metadata[STATE_SNOW_MELT_STATE].varname, + d4start, d4count, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].MELTING = ivar[i]; + } + } + } + } + + // snow covered fraction: snow[veg][band].coverage + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_COVERAGE].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].coverage = dvar[i]; + } + } + } + } + + // snow water equivalent: snow[veg][band].swq + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_SNOW_WATER_EQUIVALENT].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].swq = dvar[i]; + } + } + } + } + + // snow surface temperature: snow[veg][band].surf_temp + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_SURF_TEMP].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].surf_temp = dvar[i]; + } + } + } + } + + // snow surface water: snow[veg][band].surf_water + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_SURF_WATER].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].surf_water = dvar[i]; + } + } + } + } + + // snow pack temperature: snow[veg][band].pack_temp + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_PACK_TEMP].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].pack_temp = dvar[i]; + } + } + } + } + + // snow pack water: snow[veg][band].pack_water + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_PACK_WATER].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].pack_water = dvar[i]; + } + } + } + } + + // snow density: snow[veg][band].density + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_DENSITY].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].density = dvar[i]; + } + } + } + } + + // snow cold content: snow[veg][band].coldcontent + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_COLD_CONTENT].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].coldcontent = dvar[i]; + } + } + } + } + + // snow canopy storage: snow[veg][band].snow_canopy + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SNOW_CANOPY].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].snow[v][k].snow_canopy = dvar[i]; + } + } + } + } + + // grid cell-averaged albedo: gridcell_avg.avg_albedo + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_AVG_ALBEDO].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].gridcell_avg.avg_albedo = dvar[i]; + } + + // soil node temperatures: energy[veg][band].T[nidx] + for (m = 0; m < options.NVEGTYPES; m++) { + d5start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d5start[1] = k; + for (j = 0; j < options.Nnode; j++) { + d5start[2] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_SOIL_NODE_TEMP].varname, + d5start, d5count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].energy[v][k].T[j] = dvar[i]; + } + } + } + } + } + + // Foliage temperature: energy[veg][band].Tfoliage + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].energy[v][k].Tfoliage = dvar[i]; + } + } + } + } + + // Outgoing longwave from understory: energy[veg][band].LongUnderOut + // This is a flux. Saving it to state file is a temporary solution!! + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].energy[v][k].LongUnderOut = dvar[i]; + } + } + } + } + + // Thermal flux through the snow pack: energy[veg][band].snow_flux + // This is a flux. Saving it to state file is a temporary solution!! + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_ENERGY_SNOW_FLUX].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + all_vars[i].energy[v][k].snow_flux = dvar[i]; + } + } + } + } + + if (options.LAKES) { + // total soil moisture + for (j = 0; j < options.Nlayer; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; + } + } + + // ice content + for (j = 0; j < options.Nlayer; j++) { + d4start[0] = j; + for (p = 0; p < options.Nfrost; p++) { + d4start[1] = p; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SOIL_ICE].varname, + d4start, d4count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.layer[j].ice[p] = dvar[i]; + } + } + } + + if (options.CARBON) { + // litter carbon: tmpval = lake_var.soil.CLitter; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_CLITTER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.CLitter = dvar[i]; + } + + // intermediate carbon: tmpval = lake_var.soil.CInter; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_CINTER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.CInter = dvar[i]; + } + + // slow carbon: tmpval = lake_var.soil.CSlow; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_CSLOW].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.CSlow = dvar[i]; + } + } + + // snow age: lake_var.snow.last_snow + get_scatter_nc_field_int(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_AGE].varname, + d2start, d2count, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.last_snow = ivar[i]; + } + + // melting state: (int)lake_var.snow.MELTING + get_scatter_nc_field_int(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, + d2start, d2count, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.MELTING = ivar[i]; + } + + // snow covered fraction: lake_var.snow.coverage + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.coverage = dvar[i]; + } + + // snow water equivalent: lake_var.snow.swq + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.swq = dvar[i]; + } + + // snow surface temperature: lake_var.snow.surf_temp + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.surf_temp = dvar[i]; + } + + // snow surface water: lake_var.snow.surf_water + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.surf_water = dvar[i]; + } + + // snow pack temperature: lake_var.snow.pack_temp + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.pack_temp = dvar[i]; + } + + // snow pack water: lake_var.snow.pack_water + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.pack_water = dvar[i]; + } + + // snow density: lake_var.snow.density + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.density = dvar[i]; + } + + // snow cold content: lake_var.snow.coldcontent + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.coldcontent = dvar[i]; + } + + // snow canopy storage: lake_var.snow.snow_canopy + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SNOW_CANOPY].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.snow.snow_canopy = dvar[i]; + } + + // soil node temperatures: lake_var.energy.T[nidx] + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; + } + } + + // lake active layers: lake_var.activenod + get_scatter_nc_field_int(&(filenames.init_state), + state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, + d2start, d2count, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.activenod = ivar[i]; + } + + // lake layer thickness: lake_var.dz + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_LAYER_DZ].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.dz = dvar[i]; + } + + // lake surface layer thickness: lake_var.surfdz + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.surfdz = dvar[i]; + } + + // lake depth: lake_var.ldepth + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_DEPTH].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.ldepth = dvar[i]; + } + + // lake layer surface areas: lake_var.surface[ndix] + for (j = 0; j < options.NLAKENODES; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_LAYER_SURF_AREA].varname, + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.surface[j] = dvar[i]; + } + } + + // lake surface area: lake_var.sarea + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_SURF_AREA].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.sarea = dvar[i]; + } + + // lake volume: lake_var.volume + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_VOLUME].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.volume = dvar[i]; + } + + // lake layer temperatures: lake_var.temp[nidx] + for (j = 0; j < options.NLAKENODES; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_LAYER_TEMP].varname, + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.temp[j] = dvar[i]; + } + } + + // vertical average lake temperature: lake_var.tempavg + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.tempavg = dvar[i]; + } + + // lake ice area fraction: lake_var.areai + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.areai = dvar[i]; + } + + // new lake ice area fraction: lake_var.new_ice_area + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.new_ice_area = dvar[i]; + } + + // lake ice water equivalent: lake_var.ice_water_eq + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_ICE_WATER_EQUIVALENT].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.ice_water_eq = dvar[i]; + } + + // lake ice height: lake_var.hice + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_HEIGHT].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.hice = dvar[i]; + } + + // lake ice temperature: lake_var.tempi + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.tempi = dvar[i]; + } + + // lake ice snow water equivalent: lake_var.swe + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_SWE].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.swe = dvar[i]; + } + + // lake ice snow surface temperature: lake_var.surf_temp + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.surf_temp = dvar[i]; + } + + // lake ice snow pack temperature: lake_var.pack_temp + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.pack_temp = dvar[i]; + } + + // lake ice snow coldcontent: lake_var.coldcontent + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.coldcontent = dvar[i]; + } + + // lake ice snow surface water: lake_var.surf_water + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_ICE_SNOW_SURF_WATER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.surf_water = dvar[i]; + } + + // lake ice snow pack water: lake_var.pack_water + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[ + STATE_LAKE_ICE_SNOW_PACK_WATER].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.pack_water = dvar[i]; + } + + // lake ice snow albedo: lake_var.SAlbedo + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.SAlbedo = dvar[i]; + } + + // lake ice snow depth: lake_var.sdepth + get_scatter_nc_field_double(&(filenames.init_state), + state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, + d2start, d2count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + all_vars[i].lake_var.sdepth = dvar[i]; + } + } + + free(ivar); + free(dvar); + + // close initial state file + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_close(filenames.init_state.nc_id); + check_nc_status(status, "Error closing %s", + filenames.init_state.nc_filename); + } +} + +/****************************************************************************** + * @brief Check that the initial state file matches the global parameter + settings + *****************************************************************************/ +void +check_init_state_file(void) +{ + extern filenames_struct filenames; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern option_struct options; + extern soil_con_struct *soil_con; + extern int mpi_rank; + + int status; + size_t dimlen; + size_t i; + size_t j; + size_t d1count[1]; + size_t d1start[1]; + size_t d2count[2]; + size_t d2start[2]; + size_t d3count[3]; + size_t d3start[3]; + int lon_var_id; + int lat_var_id; + double *dvar; + double rtol = 0.0; // maybe move this to a .h file + double abs_tol = 0.0001; // maybe move this to a .h file + + // read and validate dimension lengths + if (mpi_rank == VIC_MPI_ROOT) { + dimlen = get_nc_dimension(&(filenames.init_state), + global_domain.info.x_dim); + if (dimlen != global_domain.n_nx) { + log_err("Number of grid columns in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), + global_domain.info.y_dim); + if (dimlen != global_domain.n_ny) { + log_err("Number of grid rows in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), "veg_class"); + if (dimlen != options.NVEGTYPES) { + log_err("Number of veg classes in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), "snow_band"); + if (dimlen != options.SNOW_BAND) { + log_err("Number of snow bands in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), "nlayer"); + if (dimlen != options.Nlayer) { + log_err("Number of soil layers in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), "frost_area"); + if (dimlen != options.Nfrost) { + log_err("Number of frost areas in state file does not " + "match parameter file"); + } + dimlen = get_nc_dimension(&(filenames.init_state), "soil_node"); + if (dimlen != options.Nnode) { + log_err("Number of soil nodes in state file does not " + "match parameter file"); + } + if (options.LAKES) { + dimlen = get_nc_dimension(&(filenames.init_state), "lake_node"); + if (dimlen != options.NLAKENODES) { + log_err("Number of lake nodes in state file does not " + "match parameter file"); + } + } + } + + // read dimension variables + + // lat/lon + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_inq_varid(filenames.init_state.nc_id, + global_domain.info.lon_var, &lon_var_id); + check_nc_status(status, "Unable to find variable \"%s\" in %s", + global_domain.info.lon_var, + filenames.init_state.nc_filename); + status = nc_inq_varid(filenames.init_state.nc_id, + global_domain.info.lat_var, &lat_var_id); + check_nc_status(status, "Unable to find variable \"%s\" in %s", + global_domain.info.lat_var, + filenames.init_state.nc_filename); + if (global_domain.info.n_coord_dims == 1) { + d1start[0] = 0; + dvar = calloc(global_domain.n_nx, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d1count[0] = global_domain.n_nx; + status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, + d1start, d1count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, + filenames.init_state.nc_filename); + // implicitly nested loop over ni and nj with j set to 0 + for (i = 0; i < global_domain.n_nx; i++) { + if (!assert_close_double(dvar[i], + global_domain.locations[i].longitude, + rtol, + abs_tol)) { + log_err("Longitudes in initial state file do not " + "match parameter file"); + } + } + free(dvar); + + dvar = calloc(global_domain.n_ny, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d1count[0] = global_domain.n_ny; + status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, + d1start, d1count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, + filenames.init_state.nc_filename); + // implicitly nested loop over ni and nj with i set to 0; + // j stride = n_nx + for (j = 0; j < global_domain.n_ny; j++) { + if (!assert_close_double(dvar[j], + global_domain.locations[j * + global_domain. + n_nx] + .latitude, rtol, + abs_tol)) { + log_err("Latitudes in initial state file do not " + "match parameter file"); + } + } + free(dvar); + } + else if (global_domain.info.n_coord_dims == 2) { + d2start[0] = 0; + d2start[1] = 0; + dvar = + calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + d2count[0] = global_domain.n_ny; + d2count[1] = global_domain.n_nx; + status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, + d2start, d2count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lon_var, + filenames.init_state.nc_filename); + for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { + if (dvar[i] != (double) global_domain.locations[i].longitude) { + log_err("Longitudes in initial state file do not " + "match parameter file"); + } + } + status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, + d2start, d2count, dvar); + check_nc_status(status, "Error reading data from \"%s\" in %s", + global_domain.info.lat_var, + filenames.init_state.nc_filename); + for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { + if (dvar[i] != (double) global_domain.locations[i].latitude) { + log_err("Latitudes in initial state file do not " + "match parameter file"); + } + } + free(dvar); + } + else { + log_err("global_domain.info.n_coord_dims should be 1 or 2"); + } + } + + // initialize dvar for soil thermal node deltas and depths + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + // soil thermal node deltas (dimension: node, lat, lon) + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = 1; + d3count[1] = global_domain.n_ny; + d3count[2] = global_domain.n_nx; + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + "dz_node", + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + if (dvar[i] != soil_con[i].dz_node[j]) { + log_err("Soil node intervals in state file do not match " + "those computed by VIC"); + } + } + } + + // soil thermal node depths + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + d3count[0] = 1; + d3count[1] = global_domain.n_ny; + d3count[2] = global_domain.n_nx; + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + get_scatter_nc_field_double(&(filenames.init_state), + "node_depth", + d3start, d3count, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + if (dvar[i] != soil_con[i].Zsum_node[j]) { + log_err("Soil node depths in state file do not match " + "those computed by VIC"); + } + } + } + free(dvar); +} diff --git a/vic/extensions/rout_stub/src/vic_store.c b/vic/extensions/rout_stub/src/vic_store.c new file mode 100644 index 000000000..7e3334cf5 --- /dev/null +++ b/vic/extensions/rout_stub/src/vic_store.c @@ -0,0 +1,2171 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +vic_store(dmy_struct *dmy_state, + char *filename) +{ + extern filenames_struct filenames; + extern all_vars_struct *all_vars; + extern domain_struct local_domain; + extern option_struct options; + extern veg_con_map_struct *veg_con_map; + extern int mpi_rank; + + int status; + int v; + size_t i; + size_t j; + size_t k; + size_t m; + size_t p; + int *ivar = NULL; + double *dvar = NULL; + size_t d2start[2]; + size_t d3start[3]; + size_t d4start[4]; + size_t d5start[5]; + size_t d6start[6]; + nc_file_struct nc_state_file; + nc_var_struct *nc_var; + + set_nc_state_file_info(&nc_state_file); + + // create netcdf file for storing model state + sprintf(filename, "%s.%04i%02i%02i_%05u.nc", + filenames.statefile, dmy_state->year, + dmy_state->month, dmy_state->day, + dmy_state->dayseconds); + + initialize_state_file(filename, &nc_state_file, dmy_state); + + if (mpi_rank == VIC_MPI_ROOT) { + debug("writing state file: %s", filename); + } + + // write state variables + + // allocate memory for variables to be stored + ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + + // initialize starts and counts + d2start[0] = 0; + d2start[1] = 0; + + d3start[0] = 0; + d3start[1] = 0; + d3start[2] = 0; + + d4start[0] = 0; + d4start[1] = 0; + d4start[2] = 0; + d4start[3] = 0; + + d5start[0] = 0; + d5start[1] = 0; + d5start[2] = 0; + d5start[3] = 0; + d5start[4] = 0; + + d6start[0] = 0; + d6start[1] = 0; + d6start[2] = 0; + d6start[3] = 0; + d6start[4] = 0; + d6start[5] = 0; + + // set missing values + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + dvar[i] = nc_state_file.d_fillvalue; + } + + // total soil moisture + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d5start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d5start[1] = k; + for (j = 0; j < options.Nlayer; j++) { + d5start[2] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = + (double) all_vars[i].cell[v][k].layer[j].moist; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d5start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + } + + // ice content + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_ICE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d6start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d6start[1] = k; + for (j = 0; j < options.Nlayer; j++) { + d6start[2] = j; + for (p = 0; p < options.Nfrost; p++) { + d6start[3] = p; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = + (double) all_vars[i].cell[v][k].layer[j].ice[p]; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d6start, nc_var->nc_counts, + dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + } + } + + + // dew storage: tmpval = veg_var[veg][band].Wdew; + nc_var = &(nc_state_file.nc_vars[STATE_CANOPY_WATER]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].veg_var[v][k].Wdew; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + if (options.CARBON) { + // cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; + nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPP]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].veg_var[v][k].AnnualNPP; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + // previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; + nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPPPREV]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = + (double) all_vars[i].veg_var[v][k].AnnualNPPPrev; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + // litter carbon: tmpval = cell[veg][band].CLitter; + nc_var = &(nc_state_file.nc_vars[STATE_CLITTER]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].cell[v][k].CLitter; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + // intermediate carbon: tmpval = tmpval = cell[veg][band].CInter; + nc_var = &(nc_state_file.nc_vars[STATE_CINTER]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].cell[v][k].CInter; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + // slow carbon: tmpval = cell[veg][band].CSlow; + nc_var = &(nc_state_file.nc_vars[STATE_CSLOW]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].cell[v][k].CSlow; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + } + + // snow age: snow[veg][band].last_snow + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_AGE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + ivar[i] = (int) all_vars[i].snow[v][k].last_snow; + } + else { + ivar[i] = nc_state_file.i_fillvalue; + } + } + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.i_fillvalue, + d4start, nc_var->nc_counts, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + } + } + } + + + // melting state: (int)snow[veg][band].MELTING + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_MELT_STATE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + ivar[i] = (int) all_vars[i].snow[v][k].MELTING; + } + else { + ivar[i] = nc_state_file.i_fillvalue; + } + } + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.i_fillvalue, + d4start, nc_var->nc_counts, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + } + } + } + + + // snow covered fraction: snow[veg][band].coverage + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COVERAGE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].coverage; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow water equivalent: snow[veg][band].swq + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_WATER_EQUIVALENT]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].swq; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow surface temperature: snow[veg][band].surf_temp + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_TEMP]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].surf_temp; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow surface water: snow[veg][band].surf_water + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_WATER]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].surf_water; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow pack temperature: snow[veg][band].pack_temp + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_TEMP]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].pack_temp; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow pack water: snow[veg][band].pack_water + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_WATER]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].pack_water; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow density: snow[veg][band].density + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_DENSITY]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].density; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow cold content: snow[veg][band].coldcontent + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COLD_CONTENT]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].coldcontent; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // snow canopy storage: snow[veg][band].snow_canopy + nc_var = &(nc_state_file.nc_vars[STATE_SNOW_CANOPY]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].snow[v][k].snow_canopy; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // soil node temperatures: energy[veg][band].T[nidx] + nc_var = &(nc_state_file.nc_vars[STATE_SOIL_NODE_TEMP]); + for (m = 0; m < options.NVEGTYPES; m++) { + d5start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d5start[1] = k; + for (j = 0; j < options.Nnode; j++) { + d5start[2] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].energy[v][k].T[j]; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d5start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + } + + + // Foliage temperature: energy[veg][band].Tfoliage + nc_var = &(nc_state_file.nc_vars[STATE_FOLIAGE_TEMPERATURE]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].energy[v][k].Tfoliage; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // Outgoing longwave from understory: energy[veg][band].LongUnderOut + // This is a flux, and saving it to state file is a temporary solution!! + nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_LONGUNDEROUT]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].energy[v][k].LongUnderOut; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + + // Thermal flux through the snow pack: energy[veg][band].snow_flux + // This is a flux, and saving it to state file is a temporary solution!! + nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_SNOW_FLUX]); + for (m = 0; m < options.NVEGTYPES; m++) { + d4start[0] = m; + for (k = 0; k < options.SNOW_BAND; k++) { + d4start[1] = k; + for (i = 0; i < local_domain.ncells_active; i++) { + v = veg_con_map[i].vidx[m]; + if (v >= 0) { + dvar[i] = (double) all_vars[i].energy[v][k].snow_flux; + } + else { + dvar[i] = nc_state_file.d_fillvalue; + } + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + // Grid cell averaged albedo + nc_var = &(nc_state_file.nc_vars[STATE_AVG_ALBEDO]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].gridcell_avg.avg_albedo; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + + if (options.LAKES) { + // total soil moisture + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_MOISTURE]); + for (j = 0; j < options.Nlayer; j++) { + d3start[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d3start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // ice content + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_ICE]); + for (j = 0; j < options.Nlayer; j++) { + d4start[0] = j; + for (p = 0; p < options.Nfrost; p++) { + d4start[1] = p; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = + (double) all_vars[i].lake_var.soil.layer[j].ice[p]; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d4start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + } + + if (options.CARBON) { + // litter carbon: tmpval = lake_var.soil.CLitter; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CLITTER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.soil.CLitter; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // intermediate carbon: tmpval = lake_var.soil.CInter; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CINTER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.soil.CInter; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // slow carbon: tmpval = lake_var.soil.CSlow; + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CSLOW]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.soil.CSlow; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // snow age: lake_var.snow.last_snow + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_AGE]); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = (int) all_vars[i].lake_var.snow.last_snow; + } + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.i_fillvalue, + d2start, nc_var->nc_counts, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + } + + // melting state: (int)lake_var.snow.MELTING + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_MELT_STATE]); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = (int) all_vars[i].lake_var.snow.MELTING; + } + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.i_fillvalue, + d2start, nc_var->nc_counts, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + } + + // snow covered fraction: lake_var.snow.coverage + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COVERAGE]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.coverage; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow water equivalent: lake_var.snow.swq + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_WATER_EQUIVALENT]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.swq; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow surface temperature: lake_var.snow.surf_temp + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.surf_temp; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow surface water: lake_var.snow.surf_water + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_WATER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.surf_water; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow pack temperature: lake_var.snow.pack_temp + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.pack_temp; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow pack water: lake_var.snow.pack_water + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_WATER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.pack_water; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow density: lake_var.snow.density + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_DENSITY]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.density; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow cold content: lake_var.snow.coldcontent + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COLD_CONTENT]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.coldcontent; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // snow canopy storage: lake_var.snow.snow_canopy + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_CANOPY]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.snow.snow_canopy; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // soil node temperatures: lake_var.energy.T[nidx] + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_NODE_TEMP]); + for (j = 0; j < options.Nnode; j++) { + d3start[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // lake active layers: lake_var.activenod + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ACTIVE_LAYERS]); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = (int) all_vars[i].lake_var.activenod; + } + gather_put_nc_field_int(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.i_fillvalue, + d2start, nc_var->nc_counts, ivar); + for (i = 0; i < local_domain.ncells_active; i++) { + ivar[i] = nc_state_file.i_fillvalue; + } + + // lake layer thickness: lake_var.dz + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_DZ]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.dz; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake surface layer thickness: lake_var.surfdz + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_LAYER_DZ]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.surfdz; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake depth: lake_var.ldepth + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_DEPTH]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.ldepth; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake layer surface areas: lake_var.surface[ndix] + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_SURF_AREA]); + for (j = 0; j < options.NLAKENODES; j++) { + d3start[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.surface[j]; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d3start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // lake surface area: lake_var.sarea + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_AREA]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.sarea; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake volume: lake_var.volume + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_VOLUME]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.volume; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake layer temperatures: lake_var.temp[nidx] + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_TEMP]); + for (j = 0; j < options.NLAKENODES; j++) { + d3start[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.temp[j]; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // vertical average lake temperature: lake_var.tempavg + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_AVERAGE_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.tempavg; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice area fraction: lake_var.areai + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.areai; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // new lake ice area fraction: lake_var.new_ice_area + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC_NEW]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.new_ice_area; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice water equivalent: lake_var.ice_water_eq + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_WATER_EQUIVALENT]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.ice_water_eq; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice height: lake_var.hice + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_HEIGHT]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.hice; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice temperature: lake_var.tempi + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.tempi; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow water equivalent: lake_var.swe + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SWE]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.swe; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow surface temperature: lake_var.surf_temp + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.surf_temp; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow pack temperature: lake_var.pack_temp + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_TEMP]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.pack_temp; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow coldcontent: lake_var.coldcontent + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_COLD_CONTENT]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.coldcontent; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow surface water: lake_var.surf_water + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_WATER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.surf_water; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow pack water: lake_var.pack_water + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_WATER]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.pack_water; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow albedo: lake_var.SAlbedo + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_ALBEDO]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.SAlbedo; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + + // lake ice snow depth: lake_var.sdepth + nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_DEPTH]); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = (double) all_vars[i].lake_var.sdepth; + } + gather_put_nc_field_double(nc_state_file.nc_id, + nc_var->nc_varid, + nc_state_file.d_fillvalue, + d2start, nc_var->nc_counts, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file.d_fillvalue; + } + } + + // close the netcdf file if it is still open + if (mpi_rank == VIC_MPI_ROOT) { + if (nc_state_file.open == true) { + status = nc_close(nc_state_file.nc_id); + check_nc_status(status, "Error closing %s", filename); + } + } + + free(ivar); + free(dvar); + free(nc_state_file.nc_vars); +} + +/****************************************************************************** + * @brief Setup state file netcdf structure + *****************************************************************************/ +void +set_nc_state_file_info(nc_file_struct *nc_state_file) +{ + extern option_struct options; + extern domain_struct global_domain; + + // Set fill values + nc_state_file->c_fillvalue = NC_FILL_CHAR; + nc_state_file->s_fillvalue = NC_FILL_SHORT; + nc_state_file->i_fillvalue = NC_FILL_INT; + nc_state_file->d_fillvalue = NC_FILL_DOUBLE; + nc_state_file->f_fillvalue = NC_FILL_FLOAT; + + // set ids to MISSING + nc_state_file->nc_id = MISSING; + nc_state_file->band_dimid = MISSING; + nc_state_file->front_dimid = MISSING; + nc_state_file->frost_dimid = MISSING; + nc_state_file->lake_node_dimid = MISSING; + nc_state_file->layer_dimid = MISSING; + nc_state_file->ni_dimid = MISSING; + nc_state_file->nj_dimid = MISSING; + nc_state_file->node_dimid = MISSING; + nc_state_file->outlet_dimid = MISSING; + nc_state_file->root_zone_dimid = MISSING; + nc_state_file->time_dimid = MISSING; + nc_state_file->veg_dimid = MISSING; + + // Set dimension sizes + nc_state_file->band_size = options.SNOW_BAND; + nc_state_file->front_size = MAX_FRONTS; + nc_state_file->frost_size = options.Nfrost; + nc_state_file->layer_size = options.Nlayer; + nc_state_file->ni_size = global_domain.n_nx; + nc_state_file->nj_size = global_domain.n_ny; + nc_state_file->node_size = options.Nnode; + nc_state_file->root_zone_size = options.ROOT_ZONES; + nc_state_file->time_size = NC_UNLIMITED; + nc_state_file->veg_size = options.NVEGTYPES; + + // allocate memory for nc_vars + nc_state_file->nc_vars = + calloc(N_STATE_VARS, sizeof(*(nc_state_file->nc_vars))); + check_alloc_status(nc_state_file->nc_vars, "Memory allocation error"); +} + +/****************************************************************************** + * @brief Setup state variable dimensions, types, etc. + *****************************************************************************/ +void +set_nc_state_var_info(nc_file_struct *nc) +{ + size_t i; + size_t j; + + for (i = 0; i < N_STATE_VARS; i++) { + nc->nc_vars[i].nc_varid = i; + for (j = 0; j < MAXDIMS; j++) { + nc->nc_vars[i].nc_dimids[j] = -1; + nc->nc_vars[i].nc_counts[j] = 0; + } + nc->nc_vars[i].nc_dims = 0; + + switch (i) { + case STATE_SNOW_AGE: + case STATE_SNOW_MELT_STATE: + case STATE_LAKE_SNOW_AGE: + case STATE_LAKE_SNOW_MELT_STATE: + case STATE_LAKE_ACTIVE_LAYERS: + nc->nc_vars[i].nc_type = NC_INT; + break; + default: + nc->nc_vars[i].nc_type = NC_DOUBLE; + } + + // Set the number of dimensions and dimids for each state variable + switch (i) { + case STATE_SOIL_MOISTURE: + // 5d vars [veg, band, layer, j, i] + nc->nc_vars[i].nc_dims = 5; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = nc->nj_size; + nc->nc_vars[i].nc_counts[4] = nc->ni_size; + break; + case STATE_SOIL_ICE: + // 6d vars [veg, band, layer, frost, j, i] + nc->nc_vars[i].nc_dims = 6; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->frost_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[5] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = 1; + nc->nc_vars[i].nc_counts[4] = nc->nj_size; + nc->nc_vars[i].nc_counts[5] = nc->ni_size; + break; + case STATE_CANOPY_WATER: + case STATE_ANNUALNPP: + case STATE_ANNUALNPPPREV: + case STATE_CLITTER: + case STATE_CINTER: + case STATE_CSLOW: + case STATE_SNOW_AGE: + case STATE_SNOW_MELT_STATE: + case STATE_SNOW_COVERAGE: + case STATE_SNOW_WATER_EQUIVALENT: + case STATE_SNOW_SURF_TEMP: + case STATE_SNOW_SURF_WATER: + case STATE_SNOW_PACK_TEMP: + case STATE_SNOW_PACK_WATER: + case STATE_SNOW_DENSITY: + case STATE_SNOW_COLD_CONTENT: + case STATE_SNOW_CANOPY: + case STATE_FOLIAGE_TEMPERATURE: + case STATE_ENERGY_LONGUNDEROUT: + case STATE_ENERGY_SNOW_FLUX: + // 4d vars [veg, band, j, i] + nc->nc_vars[i].nc_dims = 4; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = nc->nj_size; + nc->nc_vars[i].nc_counts[3] = nc->ni_size; + break; + case STATE_SOIL_NODE_TEMP: + // 5d vars [veg, band, node, j, i] + nc->nc_vars[i].nc_dims = 5; + nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->node_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = 1; + nc->nc_vars[i].nc_counts[3] = nc->nj_size; + nc->nc_vars[i].nc_counts[4] = nc->ni_size; + break; + case STATE_AVG_ALBEDO: + // 2d vars [j, i] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = nc->nj_size; + nc->nc_vars[i].nc_counts[1] = nc->ni_size; + break; + + case STATE_LAKE_SOIL_MOISTURE: + // 3d vars [layer, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + break; + case STATE_LAKE_SOIL_ICE: + // 4d vars [layer, frost, j, i] + nc->nc_vars[i].nc_dims = 4; + nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->frost_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = 1; + nc->nc_vars[i].nc_counts[2] = nc->nj_size; + nc->nc_vars[i].nc_counts[3] = nc->ni_size; + break; + case STATE_LAKE_CLITTER: + case STATE_LAKE_CINTER: + case STATE_LAKE_CSLOW: + case STATE_LAKE_SNOW_AGE: + case STATE_LAKE_SNOW_MELT_STATE: + case STATE_LAKE_SNOW_COVERAGE: + case STATE_LAKE_SNOW_WATER_EQUIVALENT: + case STATE_LAKE_SNOW_SURF_TEMP: + case STATE_LAKE_SNOW_SURF_WATER: + case STATE_LAKE_SNOW_PACK_TEMP: + case STATE_LAKE_SNOW_PACK_WATER: + case STATE_LAKE_SNOW_DENSITY: + case STATE_LAKE_SNOW_COLD_CONTENT: + case STATE_LAKE_SNOW_CANOPY: + case STATE_LAKE_ACTIVE_LAYERS: + case STATE_LAKE_LAYER_DZ: + case STATE_LAKE_SURF_LAYER_DZ: + case STATE_LAKE_DEPTH: + case STATE_LAKE_SURF_AREA: + case STATE_LAKE_VOLUME: + case STATE_LAKE_AVERAGE_TEMP: + case STATE_LAKE_ICE_AREA_FRAC: + case STATE_LAKE_ICE_AREA_FRAC_NEW: + case STATE_LAKE_ICE_WATER_EQUIVALENT: + case STATE_LAKE_ICE_HEIGHT: + case STATE_LAKE_ICE_TEMP: + case STATE_LAKE_ICE_SWE: + case STATE_LAKE_ICE_SNOW_SURF_TEMP: + case STATE_LAKE_ICE_SNOW_PACK_TEMP: + case STATE_LAKE_ICE_SNOW_COLD_CONTENT: + case STATE_LAKE_ICE_SNOW_SURF_WATER: + case STATE_LAKE_ICE_SNOW_PACK_WATER: + case STATE_LAKE_ICE_SNOW_ALBEDO: + case STATE_LAKE_ICE_SNOW_DEPTH: + // 2d vars [j, i] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = nc->nj_size; + nc->nc_vars[i].nc_counts[1] = nc->ni_size; + break; + case STATE_LAKE_SOIL_NODE_TEMP: + // 3d vars [node, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->node_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = nc->nj_size; + nc->nc_vars[i].nc_counts[2] = nc->ni_size; + break; + case STATE_LAKE_LAYER_SURF_AREA: + case STATE_LAKE_LAYER_TEMP: + // 3d vars [lake_node, j, i] + nc->nc_vars[i].nc_dims = 3; + nc->nc_vars[i].nc_dimids[0] = nc->lake_node_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; + nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; + nc->nc_vars[i].nc_counts[0] = 1; + nc->nc_vars[i].nc_counts[1] = nc->nj_size; + nc->nc_vars[i].nc_counts[2] = nc->ni_size; + break; + default: + log_err("state variable %zu not found when setting dimensions", i); + } + + if (nc->nc_vars[i].nc_dims > MAXDIMS) { + log_err("Too many dimensions specified in variable %zu", i); + } + } +} + +/****************************************************************************** + * @brief Initialize state file by creating dimensions, variables, + and adding metadata. + *****************************************************************************/ +void +initialize_state_file(char *filename, + nc_file_struct *nc_state_file, + dmy_struct *dmy_state) +{ + extern option_struct options; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern global_param_struct global_param; + extern metadata_struct state_metadata[N_STATE_VARS]; + extern soil_con_struct *soil_con; + extern int mpi_rank; + + int status; + int dimids[MAXDIMS]; + int old_fill_mode; + size_t i; + size_t j; + size_t dcount[MAXDIMS]; + size_t dstart[MAXDIMS]; + int lon_var_id; + int lat_var_id; + int veg_var_id; + int snow_band_var_id; + int layer_var_id; + int frost_area_var_id; + int dz_node_var_id; + int node_depth_var_id; + int lake_node_var_id; + char unit_str[MAXSTRING]; + char str[MAXSTRING]; + size_t ndims; + double dtime; + double *dvar = NULL; + int *ivar = NULL; + + // open the netcdf file + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), + &(nc_state_file->nc_id)); + check_nc_status(status, "Error creating %s", filename); + nc_state_file->open = true; + } + + if (mpi_rank == VIC_MPI_ROOT) { + // Set netcdf file global attributes + set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); + + // set the NC_FILL attribute + status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); + check_nc_status(status, "Error setting fill value in %s", filename); + + // define the time dimension + status = nc_def_dim(nc_state_file->nc_id, "time", + nc_state_file->time_size, + &(nc_state_file->time_dimid)); + check_nc_status(status, "Error defining time dimenension in %s", + filename); + + // define the variable time + status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, + &(nc_state_file->time_dimid), + &(nc_state_file->time_varid)); + check_nc_status(status, "Error defining time variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, + "standard_name", strlen("time"), "time"); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding units attribute to time variable + str_from_time_units(global_param.time_units, unit_str); + + sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); + + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, + "units", strlen(str), str); + check_nc_status(status, "Error adding attribute in %s", filename); + + // adding calendar attribute to time variable + str_from_calendar(global_param.calendar, str); + + status = nc_put_att_text(nc_state_file->nc_id, + nc_state_file->time_varid, + "calendar", strlen(str), str); + check_nc_status(status, "Error adding calendar attribute in %s", + filename); + + // define netcdf dimensions + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, + nc_state_file->ni_size, &(nc_state_file->ni_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.x_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, + nc_state_file->nj_size, &(nc_state_file->nj_dimid)); + check_nc_status(status, "Error defining \"%s\" in %s", + global_domain.info.y_dim, + filename); + + status = nc_def_dim(nc_state_file->nc_id, "veg_class", + nc_state_file->veg_size, + &(nc_state_file->veg_dimid)); + check_nc_status(status, "Error defining veg_class in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "snow_band", + nc_state_file->band_size, + &(nc_state_file->band_dimid)); + check_nc_status(status, "Error defining snow_band in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "nlayer", + nc_state_file->layer_size, + &(nc_state_file->layer_dimid)); + check_nc_status(status, "Error defining nlayer in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "frost_area", + nc_state_file->frost_size, + &(nc_state_file->frost_dimid)); + check_nc_status(status, "Error defining frost_area in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "soil_node", + nc_state_file->node_size, + &(nc_state_file->node_dimid)); + check_nc_status(status, "Error defining soil_node in %s", filename); + + if (options.LAKES) { + status = nc_def_dim(nc_state_file->nc_id, "lake_node", + nc_state_file->lake_node_size, + &(nc_state_file->lake_node_dimid)); + check_nc_status(status, "Error defining lake_node in %s", filename); + } + + set_nc_state_var_info(nc_state_file); + } + + // initialize dimids to invalid values + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // write dimension variables + + // Coordinate variables + if (mpi_rank == VIC_MPI_ROOT) { + ndims = global_domain.info.n_coord_dims; + dstart[0] = 0; + dstart[1] = 0; + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->ni_dimid; + dcount[0] = nc_state_file->ni_size; + } + else if (global_domain.info.n_coord_dims == 2) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + + dimids[1] = nc_state_file->ni_dimid; + dcount[1] = nc_state_file->ni_size; + } + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); + } + } + + // define the netcdf variable longitude + if (mpi_rank == VIC_MPI_ROOT) { + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, + NC_DOUBLE, ndims, dimids, &(lon_var_id)); + check_nc_status(status, "Error defining lon variable in %s", filename); + + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( + "degrees_east"), "degrees_east"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, + "standard_name", strlen( + "longitude"), "longitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + + if (global_domain.info.n_coord_dims == 1) { + dimids[0] = nc_state_file->nj_dimid; + dcount[0] = nc_state_file->nj_size; + } + + // define the netcdf variable latitude + status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, + NC_DOUBLE, ndims, dimids, &(lat_var_id)); + check_nc_status(status, "Error defining lat variable (%s) in %s", + global_domain.info.lat_var, filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( + "latitude"), "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( + "degrees_north"), "degrees_north"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, + "standard_name", strlen("latitude"), + "latitude"); + check_nc_status(status, "Error adding attribute in %s", filename); + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + + // veg_class + dimids[0] = nc_state_file->veg_dimid; + status = nc_def_var(nc_state_file->nc_id, "veg_class", + NC_INT, 1, dimids, &(veg_var_id)); + check_nc_status(status, "Error defining veg_class variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", + strlen("veg_class"), "veg_class"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, + "standard_name", + strlen("vegetation_class_number"), + "vegetation_class_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // snow_band + dimids[0] = nc_state_file->band_dimid; + status = nc_def_var(nc_state_file->nc_id, "snow_band", + NC_INT, 1, dimids, &(snow_band_var_id)); + check_nc_status(status, "Error defining snow_band variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, + "long_name", + strlen("snow_band"), "snow_band"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, + "standard_name", + strlen("snow_elevation_band_number"), + "snow_elevation_band_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // layer + dimids[0] = nc_state_file->layer_dimid; + status = + nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, + &(layer_var_id)); + check_nc_status(status, "Error defining layer variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, + "long_name", + strlen("layer"), "layer"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, + "standard_name", strlen("soil_layer_number"), + "soil_layer_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // frost_area + dimids[0] = nc_state_file->frost_dimid; + status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, + dimids, &(frost_area_var_id)); + check_nc_status(status, "Error defining frost_area variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "long_name", + strlen("frost_area"), "frost_area"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, + "standard_name", strlen("frost_area_number"), + "frost_area_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + + // dz_node (dimension: node, lat, lon) + dimids[0] = nc_state_file->node_dimid; + dimids[1] = nc_state_file->nj_dimid; + dimids[2] = nc_state_file->ni_dimid; + status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 3, + dimids, &(dz_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "long_name", + strlen("dz_node"), "dz_node"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "standard_name", strlen( + "soil_thermal_node_spacing"), + "soil_thermal_node_spacing"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "units", + strlen("m"), "m"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + dimids[1] = -1; + dimids[2] = -1; + + // node_depth (dimension: node, lat, lon) + dimids[0] = nc_state_file->node_dimid; + dimids[1] = nc_state_file->nj_dimid; + dimids[2] = nc_state_file->ni_dimid; + status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 3, + dimids, &(node_depth_var_id)); + check_nc_status(status, "Error defining node variable in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "long_name", + strlen("node_depth"), "node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "standard_name", + strlen("soil_thermal_node_depth"), + "soil_thermal_node_depth"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, + "units", + strlen("m"), "m"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + dimids[1] = -1; + dimids[2] = -1; + + if (options.LAKES) { + // lake_node + dimids[0] = nc_state_file->lake_node_dimid; + status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, + dimids, &(lake_node_var_id)); + check_nc_status(status, "Error defining node variable in %s", + filename); + status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, + "long_name", + strlen("lake_node"), "lake_node"); + check_nc_status(status, "Error adding attribute in %s", filename); + status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, + "standard_name", strlen( + "lake_node_number"), + "lake_node_number"); + check_nc_status(status, "Error adding attribute in %s", filename); + dimids[0] = -1; + } + } + + // Define state variables + if (mpi_rank == VIC_MPI_ROOT) { + for (i = 0; i < N_STATE_VARS; i++) { + if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { + // skip variables not set in set_state_meta_data_info + continue; + } + + // create the variable + status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, + nc_state_file->nc_vars[i].nc_type, + nc_state_file->nc_vars[i].nc_dims, + nc_state_file->nc_vars[i].nc_dimids, + &(nc_state_file->nc_vars[i].nc_varid)); + check_nc_status(status, "Error defining state variable %s in %s", + state_metadata[i].varname, filename); + + // set the fill value attribute + if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { + status = nc_put_att_double(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_DOUBLE, 1, + &(nc_state_file->d_fillvalue)); + } + else if (nc_state_file->nc_vars[i].nc_type == NC_INT) { + status = nc_put_att_int(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "_FillValue", NC_INT, 1, + &(nc_state_file->i_fillvalue)); + } + else { + log_err("NC_TYPE %d not supported at this time", + nc_state_file->nc_vars[i].nc_type); + } + check_nc_status(status, + "Error putting _FillValue attribute to %s in %s", + state_metadata[i].varname, filename); + + // Set string attributes + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "long_name", state_metadata[i].long_name); + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "standard_name", state_metadata[i].standard_name); + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "units", state_metadata[i].units); + put_nc_attr(nc_state_file->nc_id, + nc_state_file->nc_vars[i].nc_varid, + "description", state_metadata[i].description); + } + + // leave define mode + status = nc_enddef(nc_state_file->nc_id); + check_nc_status(status, "Error leaving define mode for %s", filename); + } + + // time variable + if (mpi_rank == VIC_MPI_ROOT) { + dtime = date2num(global_param.time_origin_num, dmy_state, 0, + global_param.calendar, global_param.time_units); + // put in netCDF file + dstart[0] = 0; + status = nc_put_var1_double(nc_state_file->nc_id, + nc_state_file->time_varid, + dstart, &dtime); + check_nc_status(status, "Error writing time variable"); + } + + // populate lat/lon + if (mpi_rank == VIC_MPI_ROOT) { + if (global_domain.info.n_coord_dims == 1) { + dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + + dcount[0] = nc_state_file->ni_size; + // implicitly nested loop over ni and nj with j set to 0 + for (i = 0; i < nc_state_file->ni_size; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, + dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + + dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + dcount[0] = nc_state_file->nj_size; + // implicitly nested loop over ni and nj with i set to 0; + // j stride = ni_size + for (j = 0; j < nc_state_file->nj_size; j++) { + dvar[j] = + (double) global_domain.locations[j * + nc_state_file->ni_size]. + latitude; + } + + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, + dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + free(dvar); + } + else if (global_domain.info.n_coord_dims == 2) { + dvar = calloc(global_domain.ncells_total, sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + dcount[0] = nc_state_file->nj_size; + dcount[1] = nc_state_file->ni_size; + + for (i = 0; i < global_domain.ncells_total; i++) { + dvar[i] = (double) global_domain.locations[i].longitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, + dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lon in %s", filename); + + for (i = 0; i < global_domain.ncells_total; + i++) { + dvar[i] = (double) global_domain.locations[i].latitude; + } + status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, + dstart, + dcount, dvar); + check_nc_status(status, "Error adding data to lat in %s", filename); + + free(dvar); + } + else { + log_err("COORD_DIMS_OUT should be 1 or 2"); + } + } + + // Variables for other dimensions (all 1-dimensional) + if (mpi_rank == VIC_MPI_ROOT) { + ndims = 1; + + // vegetation classes + dimids[0] = nc_state_file->veg_dimid; + dcount[0] = nc_state_file->veg_size; + ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->veg_size; j++) { + ivar[j] = (int) j + 1; + } + status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, + dcount, + ivar); + check_nc_status(status, "Error writing veg var id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // snow bands + dimids[0] = nc_state_file->band_dimid; + dcount[0] = nc_state_file->band_size; + ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->band_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, snow_band_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing snow band id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // soil layers + dimids[0] = nc_state_file->layer_dimid; + dcount[0] = nc_state_file->layer_size; + ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->layer_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, + dcount, + ivar); + check_nc_status(status, "Error writing layer id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + + // frost areas + dimids[0] = nc_state_file->frost_dimid; + dcount[0] = nc_state_file->frost_size; + ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->frost_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, + dstart, + dcount, ivar); + check_nc_status(status, "Error writing frost id"); + for (i = 0; i < ndims; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + } + + // initialize dvar for soil thermal node deltas and depths + dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error"); + // set missing values + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; + } + + // soil thermal node deltas (dimension: node, lat, lon) + dstart[0] = 0; + dstart[1] = 0; + dstart[2] = 0; + dcount[0] = 1; + dcount[1] = nc_state_file->nj_size; + dcount[2] = nc_state_file->ni_size; + for (j = 0; j < nc_state_file->node_size; j++) { + dstart[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = soil_con[i].dz_node[j]; + } + gather_put_nc_field_double(nc_state_file->nc_id, + dz_node_var_id, + nc_state_file->d_fillvalue, + dstart, dcount, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; + } + } + + // soil thermal node depths (dimension: node, lat, lon) + dstart[0] = 0; + dstart[1] = 0; + dstart[2] = 0; + dcount[0] = 1; + dcount[1] = nc_state_file->nj_size; + dcount[2] = nc_state_file->ni_size; + for (j = 0; j < nc_state_file->node_size; j++) { + dstart[0] = j; + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = soil_con[i].Zsum_node[j]; + } + gather_put_nc_field_double(nc_state_file->nc_id, + node_depth_var_id, + nc_state_file->d_fillvalue, + dstart, dcount, dvar); + for (i = 0; i < local_domain.ncells_active; i++) { + dvar[i] = nc_state_file->d_fillvalue; + } + } + free(dvar); + + if (options.LAKES) { + // lake nodes + dimids[0] = nc_state_file->lake_node_dimid; + dcount[0] = nc_state_file->lake_node_size; + ivar = malloc(nc_state_file->lake_node_size * sizeof(*ivar)); + check_alloc_status(ivar, "Memory allocation error"); + + for (j = 0; j < nc_state_file->lake_node_size; j++) { + ivar[j] = (int) j; + } + status = nc_put_vara_int(nc_state_file->nc_id, lake_node_var_id, dstart, + dcount, ivar); + check_nc_status(status, "Error writing lake nodes"); + + for (i = 0; i < MAXDIMS; i++) { + dimids[i] = -1; + dcount[i] = 0; + } + free(ivar); + } +} From 461796c6dde77441a546b2af1453339eac44ad0a Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Sep 2017 13:19:43 +0200 Subject: [PATCH 214/294] added empty vic_driver_shared_all.h to shared_all folder --- .../include/vic_driver_shared_all.h | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 vic/drivers/shared_all/include/vic_driver_shared_all.h diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h new file mode 100644 index 000000000..c32e4c028 --- /dev/null +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for vic_driver_shared_all routines + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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. + *****************************************************************************/ From adf31aa45cd132914788e7c4ff7fae73c45a34b1 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Sep 2017 14:28:09 +0200 Subject: [PATCH 215/294] test travis --- .../include/vic_driver_shared_all.h | 722 +++++++++++++++++ .../rout_rvic/include/vic_driver_shared_all.h | 747 ------------------ .../rout_stub/include/vic_driver_shared_all.h | 746 ----------------- 3 files changed, 722 insertions(+), 1493 deletions(-) delete mode 100644 vic/extensions/rout_rvic/include/vic_driver_shared_all.h delete mode 100644 vic/extensions/rout_stub/include/vic_driver_shared_all.h diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index c32e4c028..4c3823980 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -23,3 +23,725 @@ * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ + +#ifndef VIC_DRIVER_SHARED_H +#define VIC_DRIVER_SHARED_H + +#include +#include + +// Define maximum array sizes for driver level objects +#define MAX_FORCE_FILES 2 +#define MAX_OUTPUT_STREAMS 20 + +// Output compression setting +#define COMPRESSION_LVL_UNSET -1 +#define COMPRESSION_LVL_DEFAULT 5 + +// Default ouput values +#define OUT_MULT_DEFAULT 0 // Why is this not 1? +#define OUT_ASCII_FORMAT_DEFAULT "%.4f" + +// Default snow band setting +#define SNOW_BAND_TRUE_BUT_UNSET 99999 + +// Max counter for root distribution iteration +#define MAX_ROOT_ITER 9999 + +/****************************************************************************** + * @brief File formats + *****************************************************************************/ +enum +{ + UNSET_FILE_FORMAT, + ASCII, + BINARY, + NETCDF3_CLASSIC, + NETCDF3_64BIT_OFFSET, + NETCDF4_CLASSIC, + NETCDF4 +}; + +/****************************************************************************** + * @brief endian flags + *****************************************************************************/ +enum +{ + LITTLE, /**< little-endian flag */ + BIG /**< big-endian flag */ +}; + +/****************************************************************************** + * @brief Veg param sources + *****************************************************************************/ +enum +{ + FROM_DEFAULT, + FROM_VEGLIB, + FROM_VEGPARAM, + FROM_VEGHIST +}; + +/****************************************************************************** + * @brief Forcing Variable Types + *****************************************************************************/ +enum +{ + AIR_TEMP, /**< air temperature per time step [C] */ + ALBEDO, /**< surface albedo [fraction] */ + CATM, /**< atmospheric CO2 concentration [ppm] */ + CHANNEL_IN, /**< incoming channel flow [m3] */ + FCANOPY, /**< fractional area covered by plant canopy [fraction] */ + FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ + LAI_IN, /**< leaf area index [m2/m2] */ + LWDOWN, /**< incoming longwave radiation [W/m2] */ + PAR, /**< incoming photosynthetically active radiation [W/m2] */ + PREC, /**< total precipitation (rain and snow) [mm] */ + PRESSURE, /**< atmospheric pressure [kPa] */ + VP, /**< vapor pressure [kPa] */ + SWDOWN, /**< incoming shortwave [W/m2] */ + WIND, /**< wind speed [m/s] */ + SKIP, /**< place holder for unused data columns */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_FORCING_TYPES /**< Number of forcing types */ +}; + + +/****************************************************************************** + * @brief Output Variable Types + *****************************************************************************/ +enum +{ + // Water Balance Terms - state variables + OUT_ASAT, /**< Saturated Area Fraction */ + OUT_LAKE_AREA_FRAC, /**< lake surface area as fraction of the grid cell area [fraction] */ + OUT_LAKE_DEPTH, /**< lake depth (distance between surface and deepest point) [m] */ + OUT_LAKE_ICE, /**< moisture stored as lake ice [mm over lake ice area] */ + OUT_LAKE_ICE_FRACT, /**< fractional coverage of lake ice [fraction] */ + OUT_LAKE_ICE_HEIGHT, /**< thickness of lake ice [cm] */ + OUT_LAKE_MOIST, /**< liquid water and ice stored in lake [mm over grid cell] */ + OUT_LAKE_SURF_AREA, /**< lake surface area [m2] */ + OUT_LAKE_SWE, /**< liquid water equivalent of snow on top of lake ice [m over lake ice area] */ + OUT_LAKE_SWE_V, /**< volumetric liquid water equivalent of snow on top of lake ice [m3] */ + OUT_LAKE_VOLUME, /**< lake volume [m3] */ + OUT_ROOTMOIST, /**< root zone soil moisture [mm] */ + OUT_SMFROZFRAC, /**< fraction of soil moisture (by mass) that is ice, for each soil layer */ + OUT_SMLIQFRAC, /**< fraction of soil moisture (by mass) that is liquid, for each soil layer */ + OUT_SNOW_CANOPY, /**< snow interception storage in canopy [mm] */ + OUT_SNOW_COVER, /**< fractional area of snow cover [fraction] */ + OUT_SNOW_DEPTH, /**< depth of snow pack [cm] */ + OUT_SOIL_ICE, /**< soil ice content [mm] for each soil layer */ + OUT_SOIL_LIQ, /**< soil liquid content [mm] for each soil layer */ + OUT_SOIL_ICE_FRAC, /**< soil ice content fraction of column volume [1] for each soil layer */ + OUT_SOIL_LIQ_FRAC, /**< soil liquid content fraction of column volume [1] for each soil layer */ + OUT_SOIL_MOIST, /**< soil total moisture content [mm] for each soil layer */ + OUT_SOIL_WET, /**< vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ + OUT_SURFSTOR, /**< storage of liquid water and ice (not snow) on surface (ponding) [mm] */ + OUT_SURF_FROST_FRAC, /**< fraction of soil surface that is frozen [fraction] */ + OUT_SWE, /**< snow water equivalent in snow pack (including vegetation-intercepted snow) [mm] */ + OUT_WDEW, /**< total moisture interception storage in canopy [mm] */ + OUT_ZWT, /**< water table position [cm] (zwt within lowest unsaturated layer) */ + OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ + // Water Balance Terms - fluxes + OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] */ + OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ + OUT_DELSOILMOIST, /**< change in soil water content [mm] */ + OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ + OUT_DELSWE, /**< change in snow water equivalent [mm] */ + OUT_DISCHARGE, /**< river discharge [m3 s-1]) */ + OUT_EVAP, /**< total net evaporation [mm] */ + OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ + OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ + OUT_INFLOW, /**< moisture that reaches top of soil column [mm] */ + OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] */ + OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] */ + OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] */ + OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] */ + OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] */ + OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] */ + OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] */ + OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] */ + OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] */ + OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ + OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] */ + OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] */ + OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] */ + OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] */ + OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] */ + OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] */ + OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] */ + OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] */ + OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] */ + OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] */ + OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] */ + OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] */ + OUT_PREC, /**< incoming precipitation [mm] */ + OUT_RAINF, /**< rainfall [mm] */ + OUT_REFREEZE, /**< refreezing of water in the snow [mm] */ + OUT_RUNOFF, /**< surface runoff [mm] */ + OUT_SNOW_MELT, /**< snow melt [mm] */ + OUT_SNOWF, /**< snowfall [mm] */ + OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] */ + OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] */ + OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] */ + OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] */ + OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] */ + OUT_WATER_ERROR, /**< water budget error [mm] */ + // Energy Balance Terms - state variables + OUT_ALBEDO, /**< average surface albedo [fraction] */ + OUT_BARESOILT, /**< bare soil surface temperature [C] */ + OUT_FDEPTH, /**< depth of freezing fronts [cm] */ + OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] */ + OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] */ + OUT_RAD_TEMP, /**< average radiative surface temperature [K] */ + OUT_SALBEDO, /**< snow pack albedo [fraction] */ + OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] */ + OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] */ + OUT_SNOWT_FBFLAG, /**< snow surface temperature fallback flag */ + OUT_SOIL_TEMP, /**< soil temperature [C] */ + OUT_SOIL_TNODE, /**< soil temperature [C] */ + OUT_SOIL_TNODE_WL, /**< soil temperature [C] */ + OUT_SOILT_FBFLAG, /**< soil temperature flag for each soil thermal node */ + OUT_SURF_TEMP, /**< average surface temperature [C] */ + OUT_SURFT_FBFLAG, /**< surface temperature flag */ + OUT_TCAN_FBFLAG, /**< Tcanopy flag */ + OUT_TDEPTH, /**< depth of thawing fronts [cm] */ + OUT_TFOL_FBFLAG, /**< Tfoliage flag */ + OUT_VEGT, /**< average vegetation canopy temperature [C] */ + // Energy Balance Terms - fluxes + OUT_ADV_SENS, /**< net sensible flux advected to snow pack [W/m2] */ + OUT_ADVECTION, /**< advected energy [W/m2] */ + OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] */ + OUT_DELTAH, /**< rate of change in heat storage [W/m2] */ + OUT_ENERGY_ERROR, /**< energy budget error [W/m2] */ + OUT_FUSION, /**< net energy used to melt/freeze soil moisture [W/m2] */ + OUT_GRND_FLUX, /**< net heat flux into ground [W/m2] */ + OUT_IN_LONG, /**< incoming longwave at ground surface (under veg) [W/m2] */ + OUT_LATENT, /**< net upward latent heat flux [W/m2] */ + OUT_LATENT_SUB, /**< net upward latent heat flux from sublimation [W/m2] */ + OUT_MELT_ENERGY, /**< energy of fusion (melting) in snowpack [W/m2] */ + OUT_LWNET, /**< net downward longwave flux [W/m2] */ + OUT_SWNET, /**< net downward shortwave flux [W/m2] */ + OUT_R_NET, /**< net downward radiation flux [W/m2] */ + OUT_RFRZ_ENERGY, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ + OUT_SENSIBLE, /**< net upward sensible heat flux [W/m2] */ + OUT_SNOW_FLUX, /**< energy flux through snow pack [W/m2] */ + // Miscellaneous Terms + OUT_AERO_COND, /**< "scene" aerodynamic conductance [m/s] (tiles with overstory contribute overstory conductance; others contribute surface conductance) */ + OUT_AERO_COND1, /**< surface aerodynamic conductance [m/s] */ + OUT_AERO_COND2, /**< overstory aerodynamic conductance [m/s] */ + OUT_AERO_RESIST, /**< "scene"canopy aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribute surface resistance)*/ + OUT_AERO_RESIST1, /**< surface aerodynamic resistance [s/m] */ + OUT_AERO_RESIST2, /**< overstory aerodynamic resistance [s/m] */ + OUT_AIR_TEMP, /**< air temperature [C] */ + OUT_CATM, /**< atmospheric CO2 concentrtaion [ppm]*/ + OUT_DENSITY, /**< near-surface atmospheric density [kg/m3]*/ + OUT_FCANOPY, /**< fractional area covered by plant canopy [fraction] */ + OUT_FDIR, /**< fraction of incoming shortwave that is direct [fraction]*/ + OUT_LAI, /**< leaf area index [m2/m2] */ + OUT_LWDOWN, /**< incoming longwave [W/m2] */ + OUT_PAR, /**< incoming photosynthetically active radiation [W/m2] */ + OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] */ + OUT_QAIR, /**< specific humidity [kg/kg] */ + OUT_REL_HUMID, /**< relative humidity [%]*/ + OUT_SWDOWN, /**< incoming shortwave [W/m2] */ + OUT_SURF_COND, /**< surface conductance [m/s] */ + OUT_VP, /**< near surface vapor pressure [kPa] */ + OUT_VPD, /**< near surface vapor pressure deficit [kPa] */ + OUT_WIND, /**< near surface wind speed [m/s] */ + // Band-specific quantities + OUT_ADV_SENS_BAND, /**< net sensible heat flux advected to snow pack [W/m2] */ + OUT_ADVECTION_BAND, /**< advected energy [W/m2] */ + OUT_ALBEDO_BAND, /**< average surface albedo [fraction] */ + OUT_DELTACC_BAND, /**< change in cold content in snow pack [W/m2] */ + OUT_GRND_FLUX_BAND, /**< net heat flux into ground [W/m2] */ + OUT_IN_LONG_BAND, /**< incoming longwave at ground surface (under veg) [W/m2] */ + OUT_LATENT_BAND, /**< net upward latent heat flux [W/m2] */ + OUT_LATENT_SUB_BAND, /**< net upward latent heat flux due to sublimation [W/m2] */ + OUT_MELT_ENERGY_BAND, /**< energy of fusion (melting) in snowpack [W/m2] */ + OUT_LWNET_BAND, /**< net downward longwave flux [W/m2] */ + OUT_SWNET_BAND, /**< net downward shortwave flux [W/m2] */ + OUT_RFRZ_ENERGY_BAND, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ + OUT_SENSIBLE_BAND, /**< net upward sensible heat flux [W/m2] */ + OUT_SNOW_CANOPY_BAND, /**< snow interception storage in canopy [mm] */ + OUT_SNOW_COVER_BAND, /**< fractional area of snow cover [fraction] */ + OUT_SNOW_DEPTH_BAND, /**< depth of snow pack [cm] */ + OUT_SNOW_FLUX_BAND, /**< energy flux through snow pack [W/m2] */ + OUT_SNOW_MELT_BAND, /**< snow melt [mm] */ + OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] */ + OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] */ + OUT_SWE_BAND, /**< snow water equivalent in snow pack [mm] */ + // Carbon-Cycling Terms + OUT_APAR, /**< absorbed PAR [W/m2] */ + OUT_GPP, /**< gross primary productivity [g C/m2d] */ + OUT_RAUT, /**< autotrophic respiration [g C/m2d] */ + OUT_NPP, /**< net primary productivity [g C/m2d] */ + OUT_LITTERFALL, /**< flux of carbon from living biomass into soil [g C/m2d] */ + OUT_RHET, /**< soil respiration (heterotrophic respiration) [g C/m2d] */ + OUT_NEE, /**< net ecosystem exchange (=NPP-RHET) [g C/m2d] */ + OUT_CLITTER, /**< Carbon density in litter pool [g C/m2] */ + OUT_CINTER, /**< Carbon density in intermediate pool [g C/m2] */ + OUT_CSLOW, /**< Carbon density in slow pool [g C/m2] */ + // Timing and Profiling Terms + OUT_TIME_VICRUN_WALL, /**< Wall time spent inside vic_run [seconds] */ + OUT_TIME_VICRUN_CPU, /**< Wall time spent inside vic_run [seconds] */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_OUTVAR_TYPES /**< used as a loop counter*/ +}; + +/****************************************************************************** + * @brief Output state variable. + *****************************************************************************/ +enum +{ + STATE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_SOIL_ICE, /**< ice content */ + STATE_CANOPY_WATER, /**< dew storage: tmpval = veg_var[veg][band].Wdew; */ + STATE_ANNUALNPP, /**< cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; */ + STATE_ANNUALNPPPREV, /**< previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; */ + STATE_CLITTER, /**< litter carbon: tmpval = cell[veg][band].CLitter; */ + STATE_CINTER, /**< intermediate carbon: tmpval = cell[veg][band].CInter; */ + STATE_CSLOW, /**< slow carbon: tmpval = cell[veg][band].CSlow; */ + STATE_SNOW_AGE, /**< snow age: snow[veg][band].last_snow */ + STATE_SNOW_MELT_STATE, /**< melting state: (int)snow[veg][band].MELTING */ + STATE_SNOW_COVERAGE, /**< snow covered fraction: snow[veg][band].coverage */ + STATE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: snow[veg][band].swq */ + STATE_SNOW_SURF_TEMP, /**< snow surface temperature: snow[veg][band].surf_temp */ + STATE_SNOW_SURF_WATER, /**< snow surface water: snow[veg][band].surf_water */ + STATE_SNOW_PACK_TEMP, /**< snow pack temperature: snow[veg][band].pack_temp */ + STATE_SNOW_PACK_WATER, /**< snow pack water: snow[veg][band].pack_water */ + STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ + STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ + STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ + STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ + STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ + STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ + STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ + STATE_ENERGY_SNOW_FLUX, /**< Thermal flux through the snow pack: energy[veg][band].snow_flux */ + STATE_LAKE_SOIL_MOISTURE, /**< total soil moisture */ + STATE_LAKE_SOIL_ICE, /**< ice content */ + STATE_LAKE_CLITTER, /**< litter carbon: tmpval = lake_var.soil.CLitter; */ + STATE_LAKE_CINTER, /**< intermediate carbon: tmpval = lake_var.soil.CInter; */ + STATE_LAKE_CSLOW, /**< slow carbon: tmpval = lake_var.soil.CSlow; */ + STATE_LAKE_SNOW_AGE, /**< snow age: lake_var.snow.last_snow */ + STATE_LAKE_SNOW_MELT_STATE, /**< melting state: (int)lake_var.snow.MELTING */ + STATE_LAKE_SNOW_COVERAGE, /**< snow covered fraction: lake_var.snow.coverage */ + STATE_LAKE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: lake_var.snow.swq */ + STATE_LAKE_SNOW_SURF_TEMP, /**< snow surface temperature: lake_var.snow.surf_temp */ + STATE_LAKE_SNOW_SURF_WATER, /**< snow surface water: lake_var.snow.surf_water */ + STATE_LAKE_SNOW_PACK_TEMP, /**< snow pack temperature: lake_var.snow.pack_temp */ + STATE_LAKE_SNOW_PACK_WATER, /**< snow pack water: lake_var.snow.pack_water */ + STATE_LAKE_SNOW_DENSITY, /**< snow density: lake_var.snow.density */ + STATE_LAKE_SNOW_COLD_CONTENT, /**< snow cold content: lake_var.snow.coldcontent */ + STATE_LAKE_SNOW_CANOPY, /**< snow canopy storage: lake_var.snow.snow_canopy */ + STATE_LAKE_SOIL_NODE_TEMP, /**< soil node temperatures: lake_var.energy.T[nidx] */ + STATE_LAKE_ACTIVE_LAYERS, /**< lake active layers: lake_var.activenod */ + STATE_LAKE_LAYER_DZ, /**< lake layer thickness: lake_var.dz */ + STATE_LAKE_SURF_LAYER_DZ, /**< lake surface layer thickness: lake_var.surfdz */ + STATE_LAKE_DEPTH, /**< lake depth: lake_var.ldepth */ + STATE_LAKE_LAYER_SURF_AREA, /**< lake layer surface areas: lake_var.surface[ndix] */ + STATE_LAKE_SURF_AREA, /**< lake surface area: lake_var.sarea */ + STATE_LAKE_VOLUME, /**< lake volume: lake_var.volume */ + STATE_LAKE_LAYER_TEMP, /**< lake layer temperatures: lake_var.temp[nidx] */ + STATE_LAKE_AVERAGE_TEMP, /**< vertical average lake temperature: lake_var.tempavg */ + STATE_LAKE_ICE_AREA_FRAC, /**< lake ice area fraction: lake_var.areai */ + STATE_LAKE_ICE_AREA_FRAC_NEW, /**< new lake ice area fraction: lake_var.new_ice_area */ + STATE_LAKE_ICE_WATER_EQUIVALENT, /**< lake ice water equivalent: lake_var.ice_water_eq */ + STATE_LAKE_ICE_HEIGHT, /**< lake ice height: lake_var.hice */ + STATE_LAKE_ICE_TEMP, /**< lake ice temperature: lake_var.tempi */ + STATE_LAKE_ICE_SWE, /**< lake ice snow water equivalent: lake_var.swe */ + STATE_LAKE_ICE_SNOW_SURF_TEMP, /**< lake ice snow surface temperature: lake_var.surf_temp */ + STATE_LAKE_ICE_SNOW_PACK_TEMP, /**< lake ice snow pack temperature: lake_var.pack_temp */ + STATE_LAKE_ICE_SNOW_COLD_CONTENT, /**< lake ice snow coldcontent: lake_var.coldcontent */ + STATE_LAKE_ICE_SNOW_SURF_WATER, /**< lake ice snow surface water: lake_var.surf_water */ + STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ + STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ + STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ + STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gridcell_avg.avg_albedo */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_STATE_VARS /**< used as a loop counter*/ +}; + + +/****************************************************************************** + * @brief Output BINARY format types + *****************************************************************************/ +enum +{ + OUT_TYPE_DEFAULT, /**< Default data type */ + OUT_TYPE_CHAR, /**< char */ + OUT_TYPE_SINT, /**< short int */ + OUT_TYPE_USINT, /**< unsigned short int */ + OUT_TYPE_INT, /**< int */ + OUT_TYPE_FLOAT, /**< single-precision floating point */ + OUT_TYPE_DOUBLE /**< double-precision floating point */ +}; + +/****************************************************************************** + * @brief Output aggregation method types + *****************************************************************************/ +enum +{ + AGG_TYPE_DEFAULT, /**< Default aggregation type */ + AGG_TYPE_AVG, /**< average over agg interval */ + AGG_TYPE_BEG, /**< value at beginning of agg interval */ + AGG_TYPE_END, /**< value at end of agg interval */ + AGG_TYPE_MAX, /**< maximum value over agg interval */ + AGG_TYPE_MIN, /**< minimum value over agg interval */ + AGG_TYPE_SUM /**< sum over agg interval */ +}; + +/****************************************************************************** + * @brief Frequency flags for raising alarms/flags + *****************************************************************************/ +enum +{ + FREQ_NEVER, /**< Flag for never raising alarm */ + FREQ_NSTEPS, /**< Flag for raising alarm every nsteps */ + FREQ_NSECONDS, /**< Flag for raising alarm every nseconds */ + FREQ_NMINUTES, /**< Flag for raising alarm every nminutes */ + FREQ_NHOURS, /**< Flag for raising alarm every nhours */ + FREQ_NDAYS, /**< Flag for raising alarm every ndays */ + FREQ_NMONTHS, /**< Flag for raising alarm every nmonths */ + FREQ_NYEARS, /**< Flag for raising alarm every nyears */ + FREQ_DATE, /**< Flag for raising alarm on a specific date */ + FREQ_END /**< Flag for raising alarm at the end of a simulation */ +}; + +/****************************************************************************** + * @brief Codes for displaying version information + *****************************************************************************/ +enum +{ + DISP_VERSION, + DISP_COMPILE_TIME, + DISP_ALL +}; + +/****************************************************************************** + * @brief Codes for calendar option. + *****************************************************************************/ +enum calendars +{ + CALENDAR_STANDARD, + CALENDAR_GREGORIAN, + CALENDAR_PROLEPTIC_GREGORIAN, + CALENDAR_NOLEAP, + CALENDAR_365_DAY, + CALENDAR_360_DAY, + CALENDAR_JULIAN, + CALENDAR_ALL_LEAP, + CALENDAR_366_DAY +}; + +/****************************************************************************** + * @brief Codes for time units option. + *****************************************************************************/ +enum time_units +{ + TIME_UNITS_SECONDS, + TIME_UNITS_MINUTES, + TIME_UNITS_HOURS, + TIME_UNITS_DAYS +}; + +/****************************************************************************** + * @brief Codes for timers + *****************************************************************************/ +enum timers +{ + TIMER_VIC_ALL, + TIMER_VIC_INIT, + TIMER_VIC_RUN, + TIMER_VIC_FINAL, + TIMER_VIC_FORCE, + TIMER_VIC_WRITE, + N_TIMERS +}; + +/****************************************************************************** + * @brief Stores forcing file input information. + *****************************************************************************/ +typedef struct { + size_t N_ELEM; /**< number of elements per record; for LAI and ALBEDO, + 1 element per veg tile; for others N_ELEM = 1; */ + bool SIGNED; + bool SUPPLIED; + double multiplier; + char varname[MAXSTRING]; +} force_type_struct; + +/****************************************************************************** + * @brief This structure records the parameters set by the forcing file + input routines. Those filled, are used to estimate the paramters + needed for the model run in initialize_atmos.c. + *****************************************************************************/ +typedef struct { + force_type_struct TYPE[N_FORCING_TYPES]; + double FORCE_DT[2]; /**< forcing file time step */ + size_t force_steps_per_day[2]; /**< forcing file timesteps per day */ + unsigned short int FORCE_ENDIAN[2]; /**< endian-ness of input file, used for + DAILY_BINARY format */ + int FORCE_FORMAT[2]; /**< ASCII or BINARY */ + int FORCE_INDEX[2][N_FORCING_TYPES]; + size_t N_TYPES[2]; +} param_set_struct; + +/****************************************************************************** + * @brief This structure stores alarm information + *****************************************************************************/ +typedef struct { + unsigned int count; /**< current alarm count */ + dmy_struct next_dmy; /**< next dmy to raise alarm at */ + int next_count; /**< next count to raise alarm at */ + unsigned int freq; /**< enum value to describing alarm frequency */ + int n; /**< variable that provides additional information with respect to alarm_freq */ + bool is_subdaily; /**< flag denoting if alarm will be raised more than once per day */ +} alarm_struct; + +/****************************************************************************** + * @brief This structure stores output information for one output stream. + *****************************************************************************/ +typedef struct { + size_t nvars; /**< number of variables to store in the file */ + size_t ngridcells; /**< number of grid cells in aggdata */ + dmy_struct time_bounds[2]; /**< timestep bounds of stream */ + char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ + char filename[MAXSTRING]; /**< complete file name */ + FILE *fh; /**< filehandle */ + unsigned short int file_format; /**< output file format */ + short int compress; /**< Compress output files in stream*/ + unsigned short int *type; /**< type, when written to a binary file; + OUT_TYPE_USINT = unsigned short int + OUT_TYPE_SINT = short int + OUT_TYPE_FLOAT = single precision floating point + OUT_TYPE_DOUBLE = double precision floating point */ + double *mult; /**< multiplier, when written to a binary file [shape=(nvars, )] */ + char **format; /**< format, when written to disk [shape=(nvars, )] */ + unsigned int *varid; /**< id numbers of the variables to store in the file + (a variable's id number is its index in the out_data array). + The order of the id numbers in the varid array + is the order in which the variables will be written. */ + unsigned short int *aggtype; /**< type of aggregation to use [shape=(nvars, )] */ + double ****aggdata; /**< array of aggregated data values [shape=(ngridcells, nvars, nelem, nbins)] */ + alarm_struct agg_alarm; /**< alaram for stream aggregation */ + alarm_struct write_alarm; /**< alaram for controlling stream write */ +} stream_struct; + +/****************************************************************************** + * @brief This structure stores moisture state information for differencing + * with next time step. + *****************************************************************************/ +typedef struct { + double total_moist_storage; /**< total moisture storage [mm] */ + double total_soil_moist; /**< total column soil moisture [mm] */ + double surfstor; /**< surface water storage [mm] */ + double swe; /**< snow water equivalent [mm] */ + double wdew; /**< canopy interception [mm] */ +} save_data_struct; + +/****************************************************************************** + * @brief This structure stores metadata for individual variables + *****************************************************************************/ +typedef struct { + char varname[MAXSTRING]; /**< name of variable */ + char long_name[MAXSTRING]; /**< name of variable */ + char standard_name[MAXSTRING]; /**< cf long_name of variable */ + char units[MAXSTRING]; /**< units of variable */ + char description[MAXSTRING]; /**< descripition of variable */ + size_t nelem; /**< number of data values */ +} metadata_struct; + +/****************************************************************************** + * @brief This structure holds all variables needed for the error handling + * routines. + *****************************************************************************/ +typedef struct { + force_data_struct *force; + double dt; + energy_bal_struct *energy; + size_t rec; + double **out_data; + stream_struct *output_streams; + snow_data_struct *snow; + soil_con_struct soil_con; + veg_con_struct *veg_con; + veg_var_struct *veg_var; +} Error_struct; + +/****************************************************************************** + * @brief This structure holds timer information for profiling + *****************************************************************************/ +typedef struct { + double start_wall; + double start_cpu; + double stop_wall; + double stop_cpu; + double delta_wall; + double delta_cpu; +} timer_struct; + +double air_density(double t, double p); +void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, + double ***out_data); +double all_30_day_from_dmy(dmy_struct *dmy); +double all_leap_from_dmy(dmy_struct *dmy); +void alloc_aggdata(stream_struct *stream); +void alloc_out_data(size_t ngridcells, double ***out_data); +double average(double *ar, size_t n); +double calc_energy_balance_error(double, double, double, double, double); +void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); +double calc_water_balance_error(double, double, double, double); +bool cell_method_from_agg_type(unsigned short int aggtype, char cell_method[]); +bool check_write_flag(int rec); +void collect_eb_terms(energy_bal_struct, snow_data_struct, cell_data_struct, + double, double, double, bool, bool, double, bool, int, + double *, double, double **); +void collect_wb_terms(cell_data_struct, veg_var_struct, snow_data_struct, + double, double, double, bool, double, bool, double *, + double **); +void compute_derived_state_vars(all_vars_struct *, soil_con_struct *, + veg_con_struct *); +void compute_lake_params(lake_con_struct *, soil_con_struct); +void compute_treeline(force_data_struct *, dmy_struct *, double, double *, + bool *); +size_t count_force_vars(FILE *gp); +void count_nstreams_nvars(FILE *gp, size_t *nstreams, size_t nvars[]); +void cmd_proc(int argc, char **argv, char *globalfilename); +void compress_files(char string[], short int level); +stream_struct create_outstream(stream_struct *output_streams); +double get_cpu_time(); +void get_current_datetime(char *cdt); +double get_wall_time(); +double date2num(double origin, dmy_struct *date, double tzoffset, + unsigned short int calendar, unsigned short int time_units); +void dmy_all_30_day(double julian, dmy_struct *dmy); +void dmy_all_leap(double julian, dmy_struct *dmy); +bool dmy_equal(dmy_struct *a, dmy_struct *b); +void dmy_julian_day(double julian, unsigned short int calendar, + dmy_struct *dmy); +void dmy_no_leap_day(double julian, dmy_struct *dmy); +void dt_seconds_to_time_units(unsigned short int time_units, double dt_seconds, + double *dt_time_units); +void display_current_settings(int); +double fractional_day_from_dmy(dmy_struct *dmy); +void free_all_vars(all_vars_struct *all_vars, int Nveg); +void free_dmy(dmy_struct **dmy); +void free_out_data(size_t ngridcells, double ***out_data); +void free_streams(stream_struct **streams); +void free_vegcon(veg_con_struct **veg_con); +void generate_default_state(all_vars_struct *, soil_con_struct *, + veg_con_struct *, dmy_struct *); +void generate_default_lake_state(all_vars_struct *, soil_con_struct *, + lake_con_struct); +void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); +void get_parameters(FILE *paramfile); +void init_output_list(double **out_data, int write, char *format, int type, + double mult); +void initialize_energy(energy_bal_struct **energy, size_t nveg); +void initialize_global(void); +void initialize_options(void); +void initialize_parameters(void); +void initialize_save_data(all_vars_struct *all_vars, force_data_struct *force, + soil_con_struct *soil_con, veg_con_struct *veg_con, + veg_lib_struct *veg_lib, lake_con_struct *lake_con, + double **out_data, save_data_struct *save_data, + timer_struct *timer); +void initialize_snow(snow_data_struct **snow, size_t veg_num); +void initialize_soil(cell_data_struct **cell, size_t veg_num); +void initialize_time(void); +void initialize_veg(veg_var_struct **veg_var, size_t nveg); +double julian_day_from_dmy(dmy_struct *dmy, unsigned short int calendar); +bool leap_year(unsigned short int year, unsigned short int calendar); +all_vars_struct make_all_vars(size_t nveg); +cell_data_struct **make_cell_data(size_t veg_type_num); +dmy_struct *make_dmy(global_param_struct *global); +energy_bal_struct **make_energy_bal(size_t nveg); +void make_lastday(unsigned short int calendar, unsigned short int year, + unsigned short int lastday[]); +snow_data_struct **make_snow_data(size_t nveg); +veg_var_struct **make_veg_var(size_t veg_type_num); +double no_leap_day_from_dmy(dmy_struct *dmy); +void num2date(double origin, double time_value, double tzoffset, + unsigned short int calendar, unsigned short int time_units, + dmy_struct *date); +FILE *open_file(char string[], char type[]); +void parse_nc_time_units(char *nc_unit_chars, unsigned short int *units, + dmy_struct *dmy); +void put_data(all_vars_struct *, force_data_struct *, soil_con_struct *, + veg_con_struct *, veg_lib_struct *veg_lib, lake_con_struct *, + double **out_data, save_data_struct *, timer_struct *timer); +void print_alarm(alarm_struct *alarm); +void print_cell_data(cell_data_struct *cell, size_t nlayers, size_t nfrost); +void print_dmy(dmy_struct *dmy); +void print_energy_bal(energy_bal_struct *eb, size_t nnodes, size_t nfronts); +void print_force_type(force_type_struct *force_type); +void print_global_param(global_param_struct *gp); +void print_lake_con(lake_con_struct *lcon, size_t nlnodes); +void print_lake_var(lake_var_struct *lvar, size_t nlnodes, size_t nfronts, + size_t nlayers, size_t nnodes, size_t nfrost); +void print_layer_data_states(layer_data_struct *ldata, size_t nfrost); +void print_layer_data_fluxes(layer_data_struct *ldata); +void print_license(void); +void print_option(option_struct *option); +void print_out_data(double **out_data, metadata_struct *metadata); +void print_out_metadata(metadata_struct *metadata, size_t nvars); +void print_output_streams(stream_struct *outf); +void print_param_set(param_set_struct *param_set); +void print_parameters(parameters_struct *param); +void print_save_data(save_data_struct *save); +void print_snow_data(snow_data_struct *snow); +void print_soil_con(soil_con_struct *scon, size_t nlayers, size_t nnodes, + size_t nfrost, size_t nbands, size_t nzwt); +void print_stream(stream_struct *stream, metadata_struct *metadata); +void print_veg_con(veg_con_struct *vcon, size_t nroots, char blowing, char lake, + char carbon, size_t ncanopy); +void print_veg_lib(veg_lib_struct *vlib, char carbon); +void print_veg_var(veg_var_struct *vvar, size_t ncanopy); +void print_version(char *); +void print_usage(char *); +double q_to_vp(double q, double p); +bool raise_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_alarm(alarm_struct *alarm, dmy_struct *dmy_current); +void reset_stream(stream_struct *stream, dmy_struct *dmy_current); +void set_output_var(stream_struct *stream, char *varname, size_t varnum, + char *format, unsigned short int type, double mult, + unsigned short int aggtype); +unsigned int get_default_outvar_aggtype(unsigned int varid); +void set_alarm(dmy_struct *dmy_current, unsigned int freq, void *value, + alarm_struct *alarm); +void set_output_defaults(stream_struct **output_streams, + dmy_struct *dmy_current, + unsigned short default_file_format); +void set_output_met_data_info(); +void setup_stream(stream_struct *stream, size_t nvars, size_t ngridcells); +void soil_moisture_from_water_table(soil_con_struct *soil_con, size_t nlayers); +void sprint_dmy(char *str, dmy_struct *dmy); +void str_from_calendar(unsigned short int calendar, char *calendar_str); +void str_from_time_units(unsigned short int time_units, char *unit_str); +unsigned short int str_to_agg_type(char aggstr[]); +void str_to_ascii_format(char *format); +bool str_to_bool(char str[]); +unsigned short int str_to_calendar(char *cal_chars); +unsigned short int str_to_freq_flag(char freq[]); +double str_to_out_mult(char multstr[]); +unsigned short int str_to_out_type(char typestr[]); +unsigned short int str_to_timeunits(char units_chars[]); +void strpdmy(const char *s, const char *format, dmy_struct *dmy); +double time_delta(dmy_struct *dmy_current, unsigned short int freq, int n); +void timer_continue(timer_struct *t); +void timer_init(timer_struct *t); +void timer_start(timer_struct *t); +void timer_stop(timer_struct *t); +int update_step_vars(all_vars_struct *, veg_con_struct *, veg_hist_struct *); +int invalid_date(unsigned short int calendar, dmy_struct *dmy); +void validate_parameters(void); +void validate_streams(stream_struct **stream); +char will_it_snow(double *t, double t_offset, double max_snow_temp, + double *prcp, size_t n); +void zero_output_list(double **); + +#endif diff --git a/vic/extensions/rout_rvic/include/vic_driver_shared_all.h b/vic/extensions/rout_rvic/include/vic_driver_shared_all.h deleted file mode 100644 index 4c3823980..000000000 --- a/vic/extensions/rout_rvic/include/vic_driver_shared_all.h +++ /dev/null @@ -1,747 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Header file for vic_driver_shared_all routines - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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. - *****************************************************************************/ - -#ifndef VIC_DRIVER_SHARED_H -#define VIC_DRIVER_SHARED_H - -#include -#include - -// Define maximum array sizes for driver level objects -#define MAX_FORCE_FILES 2 -#define MAX_OUTPUT_STREAMS 20 - -// Output compression setting -#define COMPRESSION_LVL_UNSET -1 -#define COMPRESSION_LVL_DEFAULT 5 - -// Default ouput values -#define OUT_MULT_DEFAULT 0 // Why is this not 1? -#define OUT_ASCII_FORMAT_DEFAULT "%.4f" - -// Default snow band setting -#define SNOW_BAND_TRUE_BUT_UNSET 99999 - -// Max counter for root distribution iteration -#define MAX_ROOT_ITER 9999 - -/****************************************************************************** - * @brief File formats - *****************************************************************************/ -enum -{ - UNSET_FILE_FORMAT, - ASCII, - BINARY, - NETCDF3_CLASSIC, - NETCDF3_64BIT_OFFSET, - NETCDF4_CLASSIC, - NETCDF4 -}; - -/****************************************************************************** - * @brief endian flags - *****************************************************************************/ -enum -{ - LITTLE, /**< little-endian flag */ - BIG /**< big-endian flag */ -}; - -/****************************************************************************** - * @brief Veg param sources - *****************************************************************************/ -enum -{ - FROM_DEFAULT, - FROM_VEGLIB, - FROM_VEGPARAM, - FROM_VEGHIST -}; - -/****************************************************************************** - * @brief Forcing Variable Types - *****************************************************************************/ -enum -{ - AIR_TEMP, /**< air temperature per time step [C] */ - ALBEDO, /**< surface albedo [fraction] */ - CATM, /**< atmospheric CO2 concentration [ppm] */ - CHANNEL_IN, /**< incoming channel flow [m3] */ - FCANOPY, /**< fractional area covered by plant canopy [fraction] */ - FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ - LAI_IN, /**< leaf area index [m2/m2] */ - LWDOWN, /**< incoming longwave radiation [W/m2] */ - PAR, /**< incoming photosynthetically active radiation [W/m2] */ - PREC, /**< total precipitation (rain and snow) [mm] */ - PRESSURE, /**< atmospheric pressure [kPa] */ - VP, /**< vapor pressure [kPa] */ - SWDOWN, /**< incoming shortwave [W/m2] */ - WIND, /**< wind speed [m/s] */ - SKIP, /**< place holder for unused data columns */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_FORCING_TYPES /**< Number of forcing types */ -}; - - -/****************************************************************************** - * @brief Output Variable Types - *****************************************************************************/ -enum -{ - // Water Balance Terms - state variables - OUT_ASAT, /**< Saturated Area Fraction */ - OUT_LAKE_AREA_FRAC, /**< lake surface area as fraction of the grid cell area [fraction] */ - OUT_LAKE_DEPTH, /**< lake depth (distance between surface and deepest point) [m] */ - OUT_LAKE_ICE, /**< moisture stored as lake ice [mm over lake ice area] */ - OUT_LAKE_ICE_FRACT, /**< fractional coverage of lake ice [fraction] */ - OUT_LAKE_ICE_HEIGHT, /**< thickness of lake ice [cm] */ - OUT_LAKE_MOIST, /**< liquid water and ice stored in lake [mm over grid cell] */ - OUT_LAKE_SURF_AREA, /**< lake surface area [m2] */ - OUT_LAKE_SWE, /**< liquid water equivalent of snow on top of lake ice [m over lake ice area] */ - OUT_LAKE_SWE_V, /**< volumetric liquid water equivalent of snow on top of lake ice [m3] */ - OUT_LAKE_VOLUME, /**< lake volume [m3] */ - OUT_ROOTMOIST, /**< root zone soil moisture [mm] */ - OUT_SMFROZFRAC, /**< fraction of soil moisture (by mass) that is ice, for each soil layer */ - OUT_SMLIQFRAC, /**< fraction of soil moisture (by mass) that is liquid, for each soil layer */ - OUT_SNOW_CANOPY, /**< snow interception storage in canopy [mm] */ - OUT_SNOW_COVER, /**< fractional area of snow cover [fraction] */ - OUT_SNOW_DEPTH, /**< depth of snow pack [cm] */ - OUT_SOIL_ICE, /**< soil ice content [mm] for each soil layer */ - OUT_SOIL_LIQ, /**< soil liquid content [mm] for each soil layer */ - OUT_SOIL_ICE_FRAC, /**< soil ice content fraction of column volume [1] for each soil layer */ - OUT_SOIL_LIQ_FRAC, /**< soil liquid content fraction of column volume [1] for each soil layer */ - OUT_SOIL_MOIST, /**< soil total moisture content [mm] for each soil layer */ - OUT_SOIL_WET, /**< vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ - OUT_SURFSTOR, /**< storage of liquid water and ice (not snow) on surface (ponding) [mm] */ - OUT_SURF_FROST_FRAC, /**< fraction of soil surface that is frozen [fraction] */ - OUT_SWE, /**< snow water equivalent in snow pack (including vegetation-intercepted snow) [mm] */ - OUT_WDEW, /**< total moisture interception storage in canopy [mm] */ - OUT_ZWT, /**< water table position [cm] (zwt within lowest unsaturated layer) */ - OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ - // Water Balance Terms - fluxes - OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] */ - OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ - OUT_DELSOILMOIST, /**< change in soil water content [mm] */ - OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ - OUT_DELSWE, /**< change in snow water equivalent [mm] */ - OUT_DISCHARGE, /**< river discharge [m3 s-1]) */ - OUT_EVAP, /**< total net evaporation [mm] */ - OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ - OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ - OUT_INFLOW, /**< moisture that reaches top of soil column [mm] */ - OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] */ - OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] */ - OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] */ - OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] */ - OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] */ - OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] */ - OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] */ - OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] */ - OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] */ - OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ - OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] */ - OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] */ - OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] */ - OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] */ - OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] */ - OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] */ - OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] */ - OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] */ - OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] */ - OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] */ - OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] */ - OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] */ - OUT_PREC, /**< incoming precipitation [mm] */ - OUT_RAINF, /**< rainfall [mm] */ - OUT_REFREEZE, /**< refreezing of water in the snow [mm] */ - OUT_RUNOFF, /**< surface runoff [mm] */ - OUT_SNOW_MELT, /**< snow melt [mm] */ - OUT_SNOWF, /**< snowfall [mm] */ - OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] */ - OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] */ - OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] */ - OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] */ - OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] */ - OUT_WATER_ERROR, /**< water budget error [mm] */ - // Energy Balance Terms - state variables - OUT_ALBEDO, /**< average surface albedo [fraction] */ - OUT_BARESOILT, /**< bare soil surface temperature [C] */ - OUT_FDEPTH, /**< depth of freezing fronts [cm] */ - OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] */ - OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] */ - OUT_RAD_TEMP, /**< average radiative surface temperature [K] */ - OUT_SALBEDO, /**< snow pack albedo [fraction] */ - OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] */ - OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] */ - OUT_SNOWT_FBFLAG, /**< snow surface temperature fallback flag */ - OUT_SOIL_TEMP, /**< soil temperature [C] */ - OUT_SOIL_TNODE, /**< soil temperature [C] */ - OUT_SOIL_TNODE_WL, /**< soil temperature [C] */ - OUT_SOILT_FBFLAG, /**< soil temperature flag for each soil thermal node */ - OUT_SURF_TEMP, /**< average surface temperature [C] */ - OUT_SURFT_FBFLAG, /**< surface temperature flag */ - OUT_TCAN_FBFLAG, /**< Tcanopy flag */ - OUT_TDEPTH, /**< depth of thawing fronts [cm] */ - OUT_TFOL_FBFLAG, /**< Tfoliage flag */ - OUT_VEGT, /**< average vegetation canopy temperature [C] */ - // Energy Balance Terms - fluxes - OUT_ADV_SENS, /**< net sensible flux advected to snow pack [W/m2] */ - OUT_ADVECTION, /**< advected energy [W/m2] */ - OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] */ - OUT_DELTAH, /**< rate of change in heat storage [W/m2] */ - OUT_ENERGY_ERROR, /**< energy budget error [W/m2] */ - OUT_FUSION, /**< net energy used to melt/freeze soil moisture [W/m2] */ - OUT_GRND_FLUX, /**< net heat flux into ground [W/m2] */ - OUT_IN_LONG, /**< incoming longwave at ground surface (under veg) [W/m2] */ - OUT_LATENT, /**< net upward latent heat flux [W/m2] */ - OUT_LATENT_SUB, /**< net upward latent heat flux from sublimation [W/m2] */ - OUT_MELT_ENERGY, /**< energy of fusion (melting) in snowpack [W/m2] */ - OUT_LWNET, /**< net downward longwave flux [W/m2] */ - OUT_SWNET, /**< net downward shortwave flux [W/m2] */ - OUT_R_NET, /**< net downward radiation flux [W/m2] */ - OUT_RFRZ_ENERGY, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ - OUT_SENSIBLE, /**< net upward sensible heat flux [W/m2] */ - OUT_SNOW_FLUX, /**< energy flux through snow pack [W/m2] */ - // Miscellaneous Terms - OUT_AERO_COND, /**< "scene" aerodynamic conductance [m/s] (tiles with overstory contribute overstory conductance; others contribute surface conductance) */ - OUT_AERO_COND1, /**< surface aerodynamic conductance [m/s] */ - OUT_AERO_COND2, /**< overstory aerodynamic conductance [m/s] */ - OUT_AERO_RESIST, /**< "scene"canopy aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribute surface resistance)*/ - OUT_AERO_RESIST1, /**< surface aerodynamic resistance [s/m] */ - OUT_AERO_RESIST2, /**< overstory aerodynamic resistance [s/m] */ - OUT_AIR_TEMP, /**< air temperature [C] */ - OUT_CATM, /**< atmospheric CO2 concentrtaion [ppm]*/ - OUT_DENSITY, /**< near-surface atmospheric density [kg/m3]*/ - OUT_FCANOPY, /**< fractional area covered by plant canopy [fraction] */ - OUT_FDIR, /**< fraction of incoming shortwave that is direct [fraction]*/ - OUT_LAI, /**< leaf area index [m2/m2] */ - OUT_LWDOWN, /**< incoming longwave [W/m2] */ - OUT_PAR, /**< incoming photosynthetically active radiation [W/m2] */ - OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] */ - OUT_QAIR, /**< specific humidity [kg/kg] */ - OUT_REL_HUMID, /**< relative humidity [%]*/ - OUT_SWDOWN, /**< incoming shortwave [W/m2] */ - OUT_SURF_COND, /**< surface conductance [m/s] */ - OUT_VP, /**< near surface vapor pressure [kPa] */ - OUT_VPD, /**< near surface vapor pressure deficit [kPa] */ - OUT_WIND, /**< near surface wind speed [m/s] */ - // Band-specific quantities - OUT_ADV_SENS_BAND, /**< net sensible heat flux advected to snow pack [W/m2] */ - OUT_ADVECTION_BAND, /**< advected energy [W/m2] */ - OUT_ALBEDO_BAND, /**< average surface albedo [fraction] */ - OUT_DELTACC_BAND, /**< change in cold content in snow pack [W/m2] */ - OUT_GRND_FLUX_BAND, /**< net heat flux into ground [W/m2] */ - OUT_IN_LONG_BAND, /**< incoming longwave at ground surface (under veg) [W/m2] */ - OUT_LATENT_BAND, /**< net upward latent heat flux [W/m2] */ - OUT_LATENT_SUB_BAND, /**< net upward latent heat flux due to sublimation [W/m2] */ - OUT_MELT_ENERGY_BAND, /**< energy of fusion (melting) in snowpack [W/m2] */ - OUT_LWNET_BAND, /**< net downward longwave flux [W/m2] */ - OUT_SWNET_BAND, /**< net downward shortwave flux [W/m2] */ - OUT_RFRZ_ENERGY_BAND, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ - OUT_SENSIBLE_BAND, /**< net upward sensible heat flux [W/m2] */ - OUT_SNOW_CANOPY_BAND, /**< snow interception storage in canopy [mm] */ - OUT_SNOW_COVER_BAND, /**< fractional area of snow cover [fraction] */ - OUT_SNOW_DEPTH_BAND, /**< depth of snow pack [cm] */ - OUT_SNOW_FLUX_BAND, /**< energy flux through snow pack [W/m2] */ - OUT_SNOW_MELT_BAND, /**< snow melt [mm] */ - OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] */ - OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] */ - OUT_SWE_BAND, /**< snow water equivalent in snow pack [mm] */ - // Carbon-Cycling Terms - OUT_APAR, /**< absorbed PAR [W/m2] */ - OUT_GPP, /**< gross primary productivity [g C/m2d] */ - OUT_RAUT, /**< autotrophic respiration [g C/m2d] */ - OUT_NPP, /**< net primary productivity [g C/m2d] */ - OUT_LITTERFALL, /**< flux of carbon from living biomass into soil [g C/m2d] */ - OUT_RHET, /**< soil respiration (heterotrophic respiration) [g C/m2d] */ - OUT_NEE, /**< net ecosystem exchange (=NPP-RHET) [g C/m2d] */ - OUT_CLITTER, /**< Carbon density in litter pool [g C/m2] */ - OUT_CINTER, /**< Carbon density in intermediate pool [g C/m2] */ - OUT_CSLOW, /**< Carbon density in slow pool [g C/m2] */ - // Timing and Profiling Terms - OUT_TIME_VICRUN_WALL, /**< Wall time spent inside vic_run [seconds] */ - OUT_TIME_VICRUN_CPU, /**< Wall time spent inside vic_run [seconds] */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_OUTVAR_TYPES /**< used as a loop counter*/ -}; - -/****************************************************************************** - * @brief Output state variable. - *****************************************************************************/ -enum -{ - STATE_SOIL_MOISTURE, /**< total soil moisture */ - STATE_SOIL_ICE, /**< ice content */ - STATE_CANOPY_WATER, /**< dew storage: tmpval = veg_var[veg][band].Wdew; */ - STATE_ANNUALNPP, /**< cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; */ - STATE_ANNUALNPPPREV, /**< previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; */ - STATE_CLITTER, /**< litter carbon: tmpval = cell[veg][band].CLitter; */ - STATE_CINTER, /**< intermediate carbon: tmpval = cell[veg][band].CInter; */ - STATE_CSLOW, /**< slow carbon: tmpval = cell[veg][band].CSlow; */ - STATE_SNOW_AGE, /**< snow age: snow[veg][band].last_snow */ - STATE_SNOW_MELT_STATE, /**< melting state: (int)snow[veg][band].MELTING */ - STATE_SNOW_COVERAGE, /**< snow covered fraction: snow[veg][band].coverage */ - STATE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: snow[veg][band].swq */ - STATE_SNOW_SURF_TEMP, /**< snow surface temperature: snow[veg][band].surf_temp */ - STATE_SNOW_SURF_WATER, /**< snow surface water: snow[veg][band].surf_water */ - STATE_SNOW_PACK_TEMP, /**< snow pack temperature: snow[veg][band].pack_temp */ - STATE_SNOW_PACK_WATER, /**< snow pack water: snow[veg][band].pack_water */ - STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ - STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ - STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ - STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ - STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ - STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ - STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ - STATE_ENERGY_SNOW_FLUX, /**< Thermal flux through the snow pack: energy[veg][band].snow_flux */ - STATE_LAKE_SOIL_MOISTURE, /**< total soil moisture */ - STATE_LAKE_SOIL_ICE, /**< ice content */ - STATE_LAKE_CLITTER, /**< litter carbon: tmpval = lake_var.soil.CLitter; */ - STATE_LAKE_CINTER, /**< intermediate carbon: tmpval = lake_var.soil.CInter; */ - STATE_LAKE_CSLOW, /**< slow carbon: tmpval = lake_var.soil.CSlow; */ - STATE_LAKE_SNOW_AGE, /**< snow age: lake_var.snow.last_snow */ - STATE_LAKE_SNOW_MELT_STATE, /**< melting state: (int)lake_var.snow.MELTING */ - STATE_LAKE_SNOW_COVERAGE, /**< snow covered fraction: lake_var.snow.coverage */ - STATE_LAKE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: lake_var.snow.swq */ - STATE_LAKE_SNOW_SURF_TEMP, /**< snow surface temperature: lake_var.snow.surf_temp */ - STATE_LAKE_SNOW_SURF_WATER, /**< snow surface water: lake_var.snow.surf_water */ - STATE_LAKE_SNOW_PACK_TEMP, /**< snow pack temperature: lake_var.snow.pack_temp */ - STATE_LAKE_SNOW_PACK_WATER, /**< snow pack water: lake_var.snow.pack_water */ - STATE_LAKE_SNOW_DENSITY, /**< snow density: lake_var.snow.density */ - STATE_LAKE_SNOW_COLD_CONTENT, /**< snow cold content: lake_var.snow.coldcontent */ - STATE_LAKE_SNOW_CANOPY, /**< snow canopy storage: lake_var.snow.snow_canopy */ - STATE_LAKE_SOIL_NODE_TEMP, /**< soil node temperatures: lake_var.energy.T[nidx] */ - STATE_LAKE_ACTIVE_LAYERS, /**< lake active layers: lake_var.activenod */ - STATE_LAKE_LAYER_DZ, /**< lake layer thickness: lake_var.dz */ - STATE_LAKE_SURF_LAYER_DZ, /**< lake surface layer thickness: lake_var.surfdz */ - STATE_LAKE_DEPTH, /**< lake depth: lake_var.ldepth */ - STATE_LAKE_LAYER_SURF_AREA, /**< lake layer surface areas: lake_var.surface[ndix] */ - STATE_LAKE_SURF_AREA, /**< lake surface area: lake_var.sarea */ - STATE_LAKE_VOLUME, /**< lake volume: lake_var.volume */ - STATE_LAKE_LAYER_TEMP, /**< lake layer temperatures: lake_var.temp[nidx] */ - STATE_LAKE_AVERAGE_TEMP, /**< vertical average lake temperature: lake_var.tempavg */ - STATE_LAKE_ICE_AREA_FRAC, /**< lake ice area fraction: lake_var.areai */ - STATE_LAKE_ICE_AREA_FRAC_NEW, /**< new lake ice area fraction: lake_var.new_ice_area */ - STATE_LAKE_ICE_WATER_EQUIVALENT, /**< lake ice water equivalent: lake_var.ice_water_eq */ - STATE_LAKE_ICE_HEIGHT, /**< lake ice height: lake_var.hice */ - STATE_LAKE_ICE_TEMP, /**< lake ice temperature: lake_var.tempi */ - STATE_LAKE_ICE_SWE, /**< lake ice snow water equivalent: lake_var.swe */ - STATE_LAKE_ICE_SNOW_SURF_TEMP, /**< lake ice snow surface temperature: lake_var.surf_temp */ - STATE_LAKE_ICE_SNOW_PACK_TEMP, /**< lake ice snow pack temperature: lake_var.pack_temp */ - STATE_LAKE_ICE_SNOW_COLD_CONTENT, /**< lake ice snow coldcontent: lake_var.coldcontent */ - STATE_LAKE_ICE_SNOW_SURF_WATER, /**< lake ice snow surface water: lake_var.surf_water */ - STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ - STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ - STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ - STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gridcell_avg.avg_albedo */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_STATE_VARS /**< used as a loop counter*/ -}; - - -/****************************************************************************** - * @brief Output BINARY format types - *****************************************************************************/ -enum -{ - OUT_TYPE_DEFAULT, /**< Default data type */ - OUT_TYPE_CHAR, /**< char */ - OUT_TYPE_SINT, /**< short int */ - OUT_TYPE_USINT, /**< unsigned short int */ - OUT_TYPE_INT, /**< int */ - OUT_TYPE_FLOAT, /**< single-precision floating point */ - OUT_TYPE_DOUBLE /**< double-precision floating point */ -}; - -/****************************************************************************** - * @brief Output aggregation method types - *****************************************************************************/ -enum -{ - AGG_TYPE_DEFAULT, /**< Default aggregation type */ - AGG_TYPE_AVG, /**< average over agg interval */ - AGG_TYPE_BEG, /**< value at beginning of agg interval */ - AGG_TYPE_END, /**< value at end of agg interval */ - AGG_TYPE_MAX, /**< maximum value over agg interval */ - AGG_TYPE_MIN, /**< minimum value over agg interval */ - AGG_TYPE_SUM /**< sum over agg interval */ -}; - -/****************************************************************************** - * @brief Frequency flags for raising alarms/flags - *****************************************************************************/ -enum -{ - FREQ_NEVER, /**< Flag for never raising alarm */ - FREQ_NSTEPS, /**< Flag for raising alarm every nsteps */ - FREQ_NSECONDS, /**< Flag for raising alarm every nseconds */ - FREQ_NMINUTES, /**< Flag for raising alarm every nminutes */ - FREQ_NHOURS, /**< Flag for raising alarm every nhours */ - FREQ_NDAYS, /**< Flag for raising alarm every ndays */ - FREQ_NMONTHS, /**< Flag for raising alarm every nmonths */ - FREQ_NYEARS, /**< Flag for raising alarm every nyears */ - FREQ_DATE, /**< Flag for raising alarm on a specific date */ - FREQ_END /**< Flag for raising alarm at the end of a simulation */ -}; - -/****************************************************************************** - * @brief Codes for displaying version information - *****************************************************************************/ -enum -{ - DISP_VERSION, - DISP_COMPILE_TIME, - DISP_ALL -}; - -/****************************************************************************** - * @brief Codes for calendar option. - *****************************************************************************/ -enum calendars -{ - CALENDAR_STANDARD, - CALENDAR_GREGORIAN, - CALENDAR_PROLEPTIC_GREGORIAN, - CALENDAR_NOLEAP, - CALENDAR_365_DAY, - CALENDAR_360_DAY, - CALENDAR_JULIAN, - CALENDAR_ALL_LEAP, - CALENDAR_366_DAY -}; - -/****************************************************************************** - * @brief Codes for time units option. - *****************************************************************************/ -enum time_units -{ - TIME_UNITS_SECONDS, - TIME_UNITS_MINUTES, - TIME_UNITS_HOURS, - TIME_UNITS_DAYS -}; - -/****************************************************************************** - * @brief Codes for timers - *****************************************************************************/ -enum timers -{ - TIMER_VIC_ALL, - TIMER_VIC_INIT, - TIMER_VIC_RUN, - TIMER_VIC_FINAL, - TIMER_VIC_FORCE, - TIMER_VIC_WRITE, - N_TIMERS -}; - -/****************************************************************************** - * @brief Stores forcing file input information. - *****************************************************************************/ -typedef struct { - size_t N_ELEM; /**< number of elements per record; for LAI and ALBEDO, - 1 element per veg tile; for others N_ELEM = 1; */ - bool SIGNED; - bool SUPPLIED; - double multiplier; - char varname[MAXSTRING]; -} force_type_struct; - -/****************************************************************************** - * @brief This structure records the parameters set by the forcing file - input routines. Those filled, are used to estimate the paramters - needed for the model run in initialize_atmos.c. - *****************************************************************************/ -typedef struct { - force_type_struct TYPE[N_FORCING_TYPES]; - double FORCE_DT[2]; /**< forcing file time step */ - size_t force_steps_per_day[2]; /**< forcing file timesteps per day */ - unsigned short int FORCE_ENDIAN[2]; /**< endian-ness of input file, used for - DAILY_BINARY format */ - int FORCE_FORMAT[2]; /**< ASCII or BINARY */ - int FORCE_INDEX[2][N_FORCING_TYPES]; - size_t N_TYPES[2]; -} param_set_struct; - -/****************************************************************************** - * @brief This structure stores alarm information - *****************************************************************************/ -typedef struct { - unsigned int count; /**< current alarm count */ - dmy_struct next_dmy; /**< next dmy to raise alarm at */ - int next_count; /**< next count to raise alarm at */ - unsigned int freq; /**< enum value to describing alarm frequency */ - int n; /**< variable that provides additional information with respect to alarm_freq */ - bool is_subdaily; /**< flag denoting if alarm will be raised more than once per day */ -} alarm_struct; - -/****************************************************************************** - * @brief This structure stores output information for one output stream. - *****************************************************************************/ -typedef struct { - size_t nvars; /**< number of variables to store in the file */ - size_t ngridcells; /**< number of grid cells in aggdata */ - dmy_struct time_bounds[2]; /**< timestep bounds of stream */ - char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ - char filename[MAXSTRING]; /**< complete file name */ - FILE *fh; /**< filehandle */ - unsigned short int file_format; /**< output file format */ - short int compress; /**< Compress output files in stream*/ - unsigned short int *type; /**< type, when written to a binary file; - OUT_TYPE_USINT = unsigned short int - OUT_TYPE_SINT = short int - OUT_TYPE_FLOAT = single precision floating point - OUT_TYPE_DOUBLE = double precision floating point */ - double *mult; /**< multiplier, when written to a binary file [shape=(nvars, )] */ - char **format; /**< format, when written to disk [shape=(nvars, )] */ - unsigned int *varid; /**< id numbers of the variables to store in the file - (a variable's id number is its index in the out_data array). - The order of the id numbers in the varid array - is the order in which the variables will be written. */ - unsigned short int *aggtype; /**< type of aggregation to use [shape=(nvars, )] */ - double ****aggdata; /**< array of aggregated data values [shape=(ngridcells, nvars, nelem, nbins)] */ - alarm_struct agg_alarm; /**< alaram for stream aggregation */ - alarm_struct write_alarm; /**< alaram for controlling stream write */ -} stream_struct; - -/****************************************************************************** - * @brief This structure stores moisture state information for differencing - * with next time step. - *****************************************************************************/ -typedef struct { - double total_moist_storage; /**< total moisture storage [mm] */ - double total_soil_moist; /**< total column soil moisture [mm] */ - double surfstor; /**< surface water storage [mm] */ - double swe; /**< snow water equivalent [mm] */ - double wdew; /**< canopy interception [mm] */ -} save_data_struct; - -/****************************************************************************** - * @brief This structure stores metadata for individual variables - *****************************************************************************/ -typedef struct { - char varname[MAXSTRING]; /**< name of variable */ - char long_name[MAXSTRING]; /**< name of variable */ - char standard_name[MAXSTRING]; /**< cf long_name of variable */ - char units[MAXSTRING]; /**< units of variable */ - char description[MAXSTRING]; /**< descripition of variable */ - size_t nelem; /**< number of data values */ -} metadata_struct; - -/****************************************************************************** - * @brief This structure holds all variables needed for the error handling - * routines. - *****************************************************************************/ -typedef struct { - force_data_struct *force; - double dt; - energy_bal_struct *energy; - size_t rec; - double **out_data; - stream_struct *output_streams; - snow_data_struct *snow; - soil_con_struct soil_con; - veg_con_struct *veg_con; - veg_var_struct *veg_var; -} Error_struct; - -/****************************************************************************** - * @brief This structure holds timer information for profiling - *****************************************************************************/ -typedef struct { - double start_wall; - double start_cpu; - double stop_wall; - double stop_cpu; - double delta_wall; - double delta_cpu; -} timer_struct; - -double air_density(double t, double p); -void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, - double ***out_data); -double all_30_day_from_dmy(dmy_struct *dmy); -double all_leap_from_dmy(dmy_struct *dmy); -void alloc_aggdata(stream_struct *stream); -void alloc_out_data(size_t ngridcells, double ***out_data); -double average(double *ar, size_t n); -double calc_energy_balance_error(double, double, double, double, double); -void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); -double calc_water_balance_error(double, double, double, double); -bool cell_method_from_agg_type(unsigned short int aggtype, char cell_method[]); -bool check_write_flag(int rec); -void collect_eb_terms(energy_bal_struct, snow_data_struct, cell_data_struct, - double, double, double, bool, bool, double, bool, int, - double *, double, double **); -void collect_wb_terms(cell_data_struct, veg_var_struct, snow_data_struct, - double, double, double, bool, double, bool, double *, - double **); -void compute_derived_state_vars(all_vars_struct *, soil_con_struct *, - veg_con_struct *); -void compute_lake_params(lake_con_struct *, soil_con_struct); -void compute_treeline(force_data_struct *, dmy_struct *, double, double *, - bool *); -size_t count_force_vars(FILE *gp); -void count_nstreams_nvars(FILE *gp, size_t *nstreams, size_t nvars[]); -void cmd_proc(int argc, char **argv, char *globalfilename); -void compress_files(char string[], short int level); -stream_struct create_outstream(stream_struct *output_streams); -double get_cpu_time(); -void get_current_datetime(char *cdt); -double get_wall_time(); -double date2num(double origin, dmy_struct *date, double tzoffset, - unsigned short int calendar, unsigned short int time_units); -void dmy_all_30_day(double julian, dmy_struct *dmy); -void dmy_all_leap(double julian, dmy_struct *dmy); -bool dmy_equal(dmy_struct *a, dmy_struct *b); -void dmy_julian_day(double julian, unsigned short int calendar, - dmy_struct *dmy); -void dmy_no_leap_day(double julian, dmy_struct *dmy); -void dt_seconds_to_time_units(unsigned short int time_units, double dt_seconds, - double *dt_time_units); -void display_current_settings(int); -double fractional_day_from_dmy(dmy_struct *dmy); -void free_all_vars(all_vars_struct *all_vars, int Nveg); -void free_dmy(dmy_struct **dmy); -void free_out_data(size_t ngridcells, double ***out_data); -void free_streams(stream_struct **streams); -void free_vegcon(veg_con_struct **veg_con); -void generate_default_state(all_vars_struct *, soil_con_struct *, - veg_con_struct *, dmy_struct *); -void generate_default_lake_state(all_vars_struct *, soil_con_struct *, - lake_con_struct); -void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); -void get_parameters(FILE *paramfile); -void init_output_list(double **out_data, int write, char *format, int type, - double mult); -void initialize_energy(energy_bal_struct **energy, size_t nveg); -void initialize_global(void); -void initialize_options(void); -void initialize_parameters(void); -void initialize_save_data(all_vars_struct *all_vars, force_data_struct *force, - soil_con_struct *soil_con, veg_con_struct *veg_con, - veg_lib_struct *veg_lib, lake_con_struct *lake_con, - double **out_data, save_data_struct *save_data, - timer_struct *timer); -void initialize_snow(snow_data_struct **snow, size_t veg_num); -void initialize_soil(cell_data_struct **cell, size_t veg_num); -void initialize_time(void); -void initialize_veg(veg_var_struct **veg_var, size_t nveg); -double julian_day_from_dmy(dmy_struct *dmy, unsigned short int calendar); -bool leap_year(unsigned short int year, unsigned short int calendar); -all_vars_struct make_all_vars(size_t nveg); -cell_data_struct **make_cell_data(size_t veg_type_num); -dmy_struct *make_dmy(global_param_struct *global); -energy_bal_struct **make_energy_bal(size_t nveg); -void make_lastday(unsigned short int calendar, unsigned short int year, - unsigned short int lastday[]); -snow_data_struct **make_snow_data(size_t nveg); -veg_var_struct **make_veg_var(size_t veg_type_num); -double no_leap_day_from_dmy(dmy_struct *dmy); -void num2date(double origin, double time_value, double tzoffset, - unsigned short int calendar, unsigned short int time_units, - dmy_struct *date); -FILE *open_file(char string[], char type[]); -void parse_nc_time_units(char *nc_unit_chars, unsigned short int *units, - dmy_struct *dmy); -void put_data(all_vars_struct *, force_data_struct *, soil_con_struct *, - veg_con_struct *, veg_lib_struct *veg_lib, lake_con_struct *, - double **out_data, save_data_struct *, timer_struct *timer); -void print_alarm(alarm_struct *alarm); -void print_cell_data(cell_data_struct *cell, size_t nlayers, size_t nfrost); -void print_dmy(dmy_struct *dmy); -void print_energy_bal(energy_bal_struct *eb, size_t nnodes, size_t nfronts); -void print_force_type(force_type_struct *force_type); -void print_global_param(global_param_struct *gp); -void print_lake_con(lake_con_struct *lcon, size_t nlnodes); -void print_lake_var(lake_var_struct *lvar, size_t nlnodes, size_t nfronts, - size_t nlayers, size_t nnodes, size_t nfrost); -void print_layer_data_states(layer_data_struct *ldata, size_t nfrost); -void print_layer_data_fluxes(layer_data_struct *ldata); -void print_license(void); -void print_option(option_struct *option); -void print_out_data(double **out_data, metadata_struct *metadata); -void print_out_metadata(metadata_struct *metadata, size_t nvars); -void print_output_streams(stream_struct *outf); -void print_param_set(param_set_struct *param_set); -void print_parameters(parameters_struct *param); -void print_save_data(save_data_struct *save); -void print_snow_data(snow_data_struct *snow); -void print_soil_con(soil_con_struct *scon, size_t nlayers, size_t nnodes, - size_t nfrost, size_t nbands, size_t nzwt); -void print_stream(stream_struct *stream, metadata_struct *metadata); -void print_veg_con(veg_con_struct *vcon, size_t nroots, char blowing, char lake, - char carbon, size_t ncanopy); -void print_veg_lib(veg_lib_struct *vlib, char carbon); -void print_veg_var(veg_var_struct *vvar, size_t ncanopy); -void print_version(char *); -void print_usage(char *); -double q_to_vp(double q, double p); -bool raise_alarm(alarm_struct *alarm, dmy_struct *dmy_current); -void reset_alarm(alarm_struct *alarm, dmy_struct *dmy_current); -void reset_stream(stream_struct *stream, dmy_struct *dmy_current); -void set_output_var(stream_struct *stream, char *varname, size_t varnum, - char *format, unsigned short int type, double mult, - unsigned short int aggtype); -unsigned int get_default_outvar_aggtype(unsigned int varid); -void set_alarm(dmy_struct *dmy_current, unsigned int freq, void *value, - alarm_struct *alarm); -void set_output_defaults(stream_struct **output_streams, - dmy_struct *dmy_current, - unsigned short default_file_format); -void set_output_met_data_info(); -void setup_stream(stream_struct *stream, size_t nvars, size_t ngridcells); -void soil_moisture_from_water_table(soil_con_struct *soil_con, size_t nlayers); -void sprint_dmy(char *str, dmy_struct *dmy); -void str_from_calendar(unsigned short int calendar, char *calendar_str); -void str_from_time_units(unsigned short int time_units, char *unit_str); -unsigned short int str_to_agg_type(char aggstr[]); -void str_to_ascii_format(char *format); -bool str_to_bool(char str[]); -unsigned short int str_to_calendar(char *cal_chars); -unsigned short int str_to_freq_flag(char freq[]); -double str_to_out_mult(char multstr[]); -unsigned short int str_to_out_type(char typestr[]); -unsigned short int str_to_timeunits(char units_chars[]); -void strpdmy(const char *s, const char *format, dmy_struct *dmy); -double time_delta(dmy_struct *dmy_current, unsigned short int freq, int n); -void timer_continue(timer_struct *t); -void timer_init(timer_struct *t); -void timer_start(timer_struct *t); -void timer_stop(timer_struct *t); -int update_step_vars(all_vars_struct *, veg_con_struct *, veg_hist_struct *); -int invalid_date(unsigned short int calendar, dmy_struct *dmy); -void validate_parameters(void); -void validate_streams(stream_struct **stream); -char will_it_snow(double *t, double t_offset, double max_snow_temp, - double *prcp, size_t n); -void zero_output_list(double **); - -#endif diff --git a/vic/extensions/rout_stub/include/vic_driver_shared_all.h b/vic/extensions/rout_stub/include/vic_driver_shared_all.h deleted file mode 100644 index c042ecf50..000000000 --- a/vic/extensions/rout_stub/include/vic_driver_shared_all.h +++ /dev/null @@ -1,746 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Header file for vic_driver_shared_all routines - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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. - *****************************************************************************/ - -#ifndef VIC_DRIVER_SHARED_H -#define VIC_DRIVER_SHARED_H - -#include -#include - -// Define maximum array sizes for driver level objects -#define MAX_FORCE_FILES 2 -#define MAX_OUTPUT_STREAMS 20 - -// Output compression setting -#define COMPRESSION_LVL_UNSET -1 -#define COMPRESSION_LVL_DEFAULT 5 - -// Default ouput values -#define OUT_MULT_DEFAULT 0 // Why is this not 1? -#define OUT_ASCII_FORMAT_DEFAULT "%.4f" - -// Default snow band setting -#define SNOW_BAND_TRUE_BUT_UNSET 99999 - -// Max counter for root distribution iteration -#define MAX_ROOT_ITER 9999 - -/****************************************************************************** - * @brief File formats - *****************************************************************************/ -enum -{ - UNSET_FILE_FORMAT, - ASCII, - BINARY, - NETCDF3_CLASSIC, - NETCDF3_64BIT_OFFSET, - NETCDF4_CLASSIC, - NETCDF4 -}; - -/****************************************************************************** - * @brief endian flags - *****************************************************************************/ -enum -{ - LITTLE, /**< little-endian flag */ - BIG /**< big-endian flag */ -}; - -/****************************************************************************** - * @brief Veg param sources - *****************************************************************************/ -enum -{ - FROM_DEFAULT, - FROM_VEGLIB, - FROM_VEGPARAM, - FROM_VEGHIST -}; - -/****************************************************************************** - * @brief Forcing Variable Types - *****************************************************************************/ -enum -{ - AIR_TEMP, /**< air temperature per time step [C] */ - ALBEDO, /**< surface albedo [fraction] */ - CATM, /**< atmospheric CO2 concentration [ppm] */ - CHANNEL_IN, /**< incoming channel flow [m3] */ - FCANOPY, /**< fractional area covered by plant canopy [fraction] */ - FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ - LAI_IN, /**< leaf area index [m2/m2] */ - LWDOWN, /**< incoming longwave radiation [W/m2] */ - PAR, /**< incoming photosynthetically active radiation [W/m2] */ - PREC, /**< total precipitation (rain and snow) [mm] */ - PRESSURE, /**< atmospheric pressure [kPa] */ - VP, /**< vapor pressure [kPa] */ - SWDOWN, /**< incoming shortwave [W/m2] */ - WIND, /**< wind speed [m/s] */ - SKIP, /**< place holder for unused data columns */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_FORCING_TYPES /**< Number of forcing types */ -}; - - -/****************************************************************************** - * @brief Output Variable Types - *****************************************************************************/ -enum -{ - // Water Balance Terms - state variables - OUT_ASAT, /**< Saturated Area Fraction */ - OUT_LAKE_AREA_FRAC, /**< lake surface area as fraction of the grid cell area [fraction] */ - OUT_LAKE_DEPTH, /**< lake depth (distance between surface and deepest point) [m] */ - OUT_LAKE_ICE, /**< moisture stored as lake ice [mm over lake ice area] */ - OUT_LAKE_ICE_FRACT, /**< fractional coverage of lake ice [fraction] */ - OUT_LAKE_ICE_HEIGHT, /**< thickness of lake ice [cm] */ - OUT_LAKE_MOIST, /**< liquid water and ice stored in lake [mm over grid cell] */ - OUT_LAKE_SURF_AREA, /**< lake surface area [m2] */ - OUT_LAKE_SWE, /**< liquid water equivalent of snow on top of lake ice [m over lake ice area] */ - OUT_LAKE_SWE_V, /**< volumetric liquid water equivalent of snow on top of lake ice [m3] */ - OUT_LAKE_VOLUME, /**< lake volume [m3] */ - OUT_ROOTMOIST, /**< root zone soil moisture [mm] */ - OUT_SMFROZFRAC, /**< fraction of soil moisture (by mass) that is ice, for each soil layer */ - OUT_SMLIQFRAC, /**< fraction of soil moisture (by mass) that is liquid, for each soil layer */ - OUT_SNOW_CANOPY, /**< snow interception storage in canopy [mm] */ - OUT_SNOW_COVER, /**< fractional area of snow cover [fraction] */ - OUT_SNOW_DEPTH, /**< depth of snow pack [cm] */ - OUT_SOIL_ICE, /**< soil ice content [mm] for each soil layer */ - OUT_SOIL_LIQ, /**< soil liquid content [mm] for each soil layer */ - OUT_SOIL_ICE_FRAC, /**< soil ice content fraction of column volume [1] for each soil layer */ - OUT_SOIL_LIQ_FRAC, /**< soil liquid content fraction of column volume [1] for each soil layer */ - OUT_SOIL_MOIST, /**< soil total moisture content [mm] for each soil layer */ - OUT_SOIL_WET, /**< vertical average of (soil moisture - wilting point)/(maximum soil moisture - wilting point) [mm/mm] */ - OUT_SURFSTOR, /**< storage of liquid water and ice (not snow) on surface (ponding) [mm] */ - OUT_SURF_FROST_FRAC, /**< fraction of soil surface that is frozen [fraction] */ - OUT_SWE, /**< snow water equivalent in snow pack (including vegetation-intercepted snow) [mm] */ - OUT_WDEW, /**< total moisture interception storage in canopy [mm] */ - OUT_ZWT, /**< water table position [cm] (zwt within lowest unsaturated layer) */ - OUT_ZWT_LUMPED, /**< lumped water table position [cm] (zwt of total moisture across all layers, lumped together) */ - // Water Balance Terms - fluxes - OUT_BASEFLOW, /**< baseflow out of the bottom layer [mm] */ - OUT_DELINTERCEPT, /**< change in canopy interception storage [mm] */ - OUT_DELSOILMOIST, /**< change in soil water content [mm] */ - OUT_DELSURFSTOR, /**< change in surface liquid water storage [mm] */ - OUT_DELSWE, /**< change in snow water equivalent [mm] */ - OUT_DISCHARGE, /**< river discharge [m3 s-1]) */ - OUT_EVAP, /**< total net evaporation [mm] */ - OUT_EVAP_BARE, /**< net evaporation from bare soil [mm] */ - OUT_EVAP_CANOP, /**< net evaporation from canopy interception [mm] */ - OUT_INFLOW, /**< moisture that reaches top of soil column [mm] */ - OUT_LAKE_BF_IN, /**< incoming baseflow from lake catchment [mm] */ - OUT_LAKE_BF_IN_V, /**< incoming volumetric baseflow from lake catchment [m3] */ - OUT_LAKE_BF_OUT, /**< outgoing baseflow from lake [mm] */ - OUT_LAKE_BF_OUT_V, /**< outgoing volumetric baseflow from lake [m3] */ - OUT_LAKE_CHAN_IN, /**< channel inflow into lake [mm] */ - OUT_LAKE_CHAN_IN_V, /**< volumetric channel inflow into lake [m3] */ - OUT_LAKE_CHAN_OUT, /**< channel outflow from lake [mm] */ - OUT_LAKE_CHAN_OUT_V, /**< volumetric channel outflow from lake [m3] */ - OUT_LAKE_DSTOR, /**< change in lake moisture storage (liquid plus ice cover) [mm] */ - OUT_LAKE_DSTOR_V, /**< volumetric change in lake moisture storage (liquid plus ice cover) [m3] */ - OUT_LAKE_DSWE, /**< change in swe on top of lake ice [mm] */ - OUT_LAKE_DSWE_V, /**< volumetric change in swe on top of lake ice [m3] */ - OUT_LAKE_EVAP, /**< net evaporation from lake surface [mm] */ - OUT_LAKE_EVAP_V, /**< net volumetric evaporation from lake surface [m3] */ - OUT_LAKE_PREC_V, /**< volumetric precipitation over lake surface [m3] */ - OUT_LAKE_RCHRG, /**< recharge from lake to surrounding wetland [mm] */ - OUT_LAKE_RCHRG_V, /**< volumetric recharge from lake to surrounding wetland [m3] */ - OUT_LAKE_RO_IN, /**< incoming runoff from lake catchment [mm] */ - OUT_LAKE_RO_IN_V, /**< incoming volumetric runoff from lake catchment [m3] */ - OUT_LAKE_VAPFLX, /**< outgoing sublimation from snow on top of lake ice [mm] */ - OUT_LAKE_VAPFLX_V, /**< outgoing volumetric sublimation from snow on top of lake ice [m3] */ - OUT_PET, /**< Potential evapotranspiration (= area-weighted sum of potential transpiration and potential soil evaporation). Potential transpiration is computed using the Penman-Monteith eqn with architectural resistance and LAI of the current veg cover. [mm] */ - OUT_PREC, /**< incoming precipitation [mm] */ - OUT_RAINF, /**< rainfall [mm] */ - OUT_REFREEZE, /**< refreezing of water in the snow [mm] */ - OUT_RUNOFF, /**< surface runoff [mm] */ - OUT_SNOW_MELT, /**< snow melt [mm] */ - OUT_SNOWF, /**< snowfall [mm] */ - OUT_SUB_BLOWING, /**< net sublimation of blowing snow [mm] */ - OUT_SUB_CANOP, /**< net sublimation from snow stored in canopy [mm] */ - OUT_SUB_SNOW, /**< total net sublimation from snow pack (surface and blowing) [mm] */ - OUT_SUB_SURFACE, /**< net sublimation from snow pack surface [mm] */ - OUT_TRANSP_VEG, /**< net transpiration from vegetation [mm] */ - OUT_WATER_ERROR, /**< water budget error [mm] */ - // Energy Balance Terms - state variables - OUT_ALBEDO, /**< average surface albedo [fraction] */ - OUT_BARESOILT, /**< bare soil surface temperature [C] */ - OUT_FDEPTH, /**< depth of freezing fronts [cm] */ - OUT_LAKE_ICE_TEMP, /**< temperature of lake ice [C] */ - OUT_LAKE_SURF_TEMP, /**< lake surface temperature [C] */ - OUT_RAD_TEMP, /**< average radiative surface temperature [K] */ - OUT_SALBEDO, /**< snow pack albedo [fraction] */ - OUT_SNOW_PACK_TEMP, /**< snow pack temperature [C] */ - OUT_SNOW_SURF_TEMP, /**< snow surface temperature [C] */ - OUT_SNOWT_FBFLAG, /**< snow surface temperature fallback flag */ - OUT_SOIL_TEMP, /**< soil temperature [C] */ - OUT_SOIL_TNODE, /**< soil temperature [C] */ - OUT_SOIL_TNODE_WL, /**< soil temperature [C] */ - OUT_SOILT_FBFLAG, /**< soil temperature flag for each soil thermal node */ - OUT_SURF_TEMP, /**< average surface temperature [C] */ - OUT_SURFT_FBFLAG, /**< surface temperature flag */ - OUT_TCAN_FBFLAG, /**< Tcanopy flag */ - OUT_TDEPTH, /**< depth of thawing fronts [cm] */ - OUT_TFOL_FBFLAG, /**< Tfoliage flag */ - OUT_VEGT, /**< average vegetation canopy temperature [C] */ - // Energy Balance Terms - fluxes - OUT_ADV_SENS, /**< net sensible flux advected to snow pack [W/m2] */ - OUT_ADVECTION, /**< advected energy [W/m2] */ - OUT_DELTACC, /**< rate of change in cold content in snow pack [W/m2] */ - OUT_DELTAH, /**< rate of change in heat storage [W/m2] */ - OUT_ENERGY_ERROR, /**< energy budget error [W/m2] */ - OUT_FUSION, /**< net energy used to melt/freeze soil moisture [W/m2] */ - OUT_GRND_FLUX, /**< net heat flux into ground [W/m2] */ - OUT_IN_LONG, /**< incoming longwave at ground surface (under veg) [W/m2] */ - OUT_LATENT, /**< net upward latent heat flux [W/m2] */ - OUT_LATENT_SUB, /**< net upward latent heat flux from sublimation [W/m2] */ - OUT_MELT_ENERGY, /**< energy of fusion (melting) in snowpack [W/m2] */ - OUT_LWNET, /**< net downward longwave flux [W/m2] */ - OUT_SWNET, /**< net downward shortwave flux [W/m2] */ - OUT_R_NET, /**< net downward radiation flux [W/m2] */ - OUT_RFRZ_ENERGY, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ - OUT_SENSIBLE, /**< net upward sensible heat flux [W/m2] */ - OUT_SNOW_FLUX, /**< energy flux through snow pack [W/m2] */ - // Miscellaneous Terms - OUT_AERO_COND, /**< "scene" aerodynamic conductance [m/s] (tiles with overstory contribute overstory conductance; others contribute surface conductance) */ - OUT_AERO_COND1, /**< surface aerodynamic conductance [m/s] */ - OUT_AERO_COND2, /**< overstory aerodynamic conductance [m/s] */ - OUT_AERO_RESIST, /**< "scene"canopy aerodynamic resistance [s/m] (tiles with overstory contribute overstory resistance; others contribute surface resistance)*/ - OUT_AERO_RESIST1, /**< surface aerodynamic resistance [s/m] */ - OUT_AERO_RESIST2, /**< overstory aerodynamic resistance [s/m] */ - OUT_AIR_TEMP, /**< air temperature [C] */ - OUT_CATM, /**< atmospheric CO2 concentrtaion [ppm]*/ - OUT_DENSITY, /**< near-surface atmospheric density [kg/m3]*/ - OUT_FCANOPY, /**< fractional area covered by plant canopy [fraction] */ - OUT_FDIR, /**< fraction of incoming shortwave that is direct [fraction]*/ - OUT_LAI, /**< leaf area index [m2/m2] */ - OUT_LWDOWN, /**< incoming longwave [W/m2] */ - OUT_PAR, /**< incoming photosynthetically active radiation [W/m2] */ - OUT_PRESSURE, /**< near surface atmospheric pressure [kPa] */ - OUT_QAIR, /**< specific humidity [kg/kg] */ - OUT_REL_HUMID, /**< relative humidity [%]*/ - OUT_SWDOWN, /**< incoming shortwave [W/m2] */ - OUT_SURF_COND, /**< surface conductance [m/s] */ - OUT_VP, /**< near surface vapor pressure [kPa] */ - OUT_VPD, /**< near surface vapor pressure deficit [kPa] */ - OUT_WIND, /**< near surface wind speed [m/s] */ - // Band-specific quantities - OUT_ADV_SENS_BAND, /**< net sensible heat flux advected to snow pack [W/m2] */ - OUT_ADVECTION_BAND, /**< advected energy [W/m2] */ - OUT_ALBEDO_BAND, /**< average surface albedo [fraction] */ - OUT_DELTACC_BAND, /**< change in cold content in snow pack [W/m2] */ - OUT_GRND_FLUX_BAND, /**< net heat flux into ground [W/m2] */ - OUT_IN_LONG_BAND, /**< incoming longwave at ground surface (under veg) [W/m2] */ - OUT_LATENT_BAND, /**< net upward latent heat flux [W/m2] */ - OUT_LATENT_SUB_BAND, /**< net upward latent heat flux due to sublimation [W/m2] */ - OUT_MELT_ENERGY_BAND, /**< energy of fusion (melting) in snowpack [W/m2] */ - OUT_LWNET_BAND, /**< net downward longwave flux [W/m2] */ - OUT_SWNET_BAND, /**< net downward shortwave flux [W/m2] */ - OUT_RFRZ_ENERGY_BAND, /**< net energy used to refreeze liquid water in snowpack [W/m2] */ - OUT_SENSIBLE_BAND, /**< net upward sensible heat flux [W/m2] */ - OUT_SNOW_CANOPY_BAND, /**< snow interception storage in canopy [mm] */ - OUT_SNOW_COVER_BAND, /**< fractional area of snow cover [fraction] */ - OUT_SNOW_DEPTH_BAND, /**< depth of snow pack [cm] */ - OUT_SNOW_FLUX_BAND, /**< energy flux through snow pack [W/m2] */ - OUT_SNOW_MELT_BAND, /**< snow melt [mm] */ - OUT_SNOW_PACKT_BAND, /**< snow pack temperature [C] */ - OUT_SNOW_SURFT_BAND, /**< snow surface temperature [C] */ - OUT_SWE_BAND, /**< snow water equivalent in snow pack [mm] */ - // Carbon-Cycling Terms - OUT_APAR, /**< absorbed PAR [W/m2] */ - OUT_GPP, /**< gross primary productivity [g C/m2d] */ - OUT_RAUT, /**< autotrophic respiration [g C/m2d] */ - OUT_NPP, /**< net primary productivity [g C/m2d] */ - OUT_LITTERFALL, /**< flux of carbon from living biomass into soil [g C/m2d] */ - OUT_RHET, /**< soil respiration (heterotrophic respiration) [g C/m2d] */ - OUT_NEE, /**< net ecosystem exchange (=NPP-RHET) [g C/m2d] */ - OUT_CLITTER, /**< Carbon density in litter pool [g C/m2] */ - OUT_CINTER, /**< Carbon density in intermediate pool [g C/m2] */ - OUT_CSLOW, /**< Carbon density in slow pool [g C/m2] */ - // Timing and Profiling Terms - OUT_TIME_VICRUN_WALL, /**< Wall time spent inside vic_run [seconds] */ - OUT_TIME_VICRUN_CPU, /**< Wall time spent inside vic_run [seconds] */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_OUTVAR_TYPES /**< used as a loop counter*/ -}; - -/****************************************************************************** - * @brief Output state variable. - *****************************************************************************/ -enum -{ - STATE_SOIL_MOISTURE, /**< total soil moisture */ - STATE_SOIL_ICE, /**< ice content */ - STATE_CANOPY_WATER, /**< dew storage: tmpval = veg_var[veg][band].Wdew; */ - STATE_ANNUALNPP, /**< cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; */ - STATE_ANNUALNPPPREV, /**< previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; */ - STATE_CLITTER, /**< litter carbon: tmpval = cell[veg][band].CLitter; */ - STATE_CINTER, /**< intermediate carbon: tmpval = cell[veg][band].CInter; */ - STATE_CSLOW, /**< slow carbon: tmpval = cell[veg][band].CSlow; */ - STATE_SNOW_AGE, /**< snow age: snow[veg][band].last_snow */ - STATE_SNOW_MELT_STATE, /**< melting state: (int)snow[veg][band].MELTING */ - STATE_SNOW_COVERAGE, /**< snow covered fraction: snow[veg][band].coverage */ - STATE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: snow[veg][band].swq */ - STATE_SNOW_SURF_TEMP, /**< snow surface temperature: snow[veg][band].surf_temp */ - STATE_SNOW_SURF_WATER, /**< snow surface water: snow[veg][band].surf_water */ - STATE_SNOW_PACK_TEMP, /**< snow pack temperature: snow[veg][band].pack_temp */ - STATE_SNOW_PACK_WATER, /**< snow pack water: snow[veg][band].pack_water */ - STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ - STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ - STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ - STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ - STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ - STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ - STATE_ENERGY_SNOW_FLUX, /**< Thermal flux through the snow pack: energy[veg][band].snow_flux */ - STATE_LAKE_SOIL_MOISTURE, /**< total soil moisture */ - STATE_LAKE_SOIL_ICE, /**< ice content */ - STATE_LAKE_CLITTER, /**< litter carbon: tmpval = lake_var.soil.CLitter; */ - STATE_LAKE_CINTER, /**< intermediate carbon: tmpval = lake_var.soil.CInter; */ - STATE_LAKE_CSLOW, /**< slow carbon: tmpval = lake_var.soil.CSlow; */ - STATE_LAKE_SNOW_AGE, /**< snow age: lake_var.snow.last_snow */ - STATE_LAKE_SNOW_MELT_STATE, /**< melting state: (int)lake_var.snow.MELTING */ - STATE_LAKE_SNOW_COVERAGE, /**< snow covered fraction: lake_var.snow.coverage */ - STATE_LAKE_SNOW_WATER_EQUIVALENT, /**< snow water equivalent: lake_var.snow.swq */ - STATE_LAKE_SNOW_SURF_TEMP, /**< snow surface temperature: lake_var.snow.surf_temp */ - STATE_LAKE_SNOW_SURF_WATER, /**< snow surface water: lake_var.snow.surf_water */ - STATE_LAKE_SNOW_PACK_TEMP, /**< snow pack temperature: lake_var.snow.pack_temp */ - STATE_LAKE_SNOW_PACK_WATER, /**< snow pack water: lake_var.snow.pack_water */ - STATE_LAKE_SNOW_DENSITY, /**< snow density: lake_var.snow.density */ - STATE_LAKE_SNOW_COLD_CONTENT, /**< snow cold content: lake_var.snow.coldcontent */ - STATE_LAKE_SNOW_CANOPY, /**< snow canopy storage: lake_var.snow.snow_canopy */ - STATE_LAKE_SOIL_NODE_TEMP, /**< soil node temperatures: lake_var.energy.T[nidx] */ - STATE_LAKE_ACTIVE_LAYERS, /**< lake active layers: lake_var.activenod */ - STATE_LAKE_LAYER_DZ, /**< lake layer thickness: lake_var.dz */ - STATE_LAKE_SURF_LAYER_DZ, /**< lake surface layer thickness: lake_var.surfdz */ - STATE_LAKE_DEPTH, /**< lake depth: lake_var.ldepth */ - STATE_LAKE_LAYER_SURF_AREA, /**< lake layer surface areas: lake_var.surface[ndix] */ - STATE_LAKE_SURF_AREA, /**< lake surface area: lake_var.sarea */ - STATE_LAKE_VOLUME, /**< lake volume: lake_var.volume */ - STATE_LAKE_LAYER_TEMP, /**< lake layer temperatures: lake_var.temp[nidx] */ - STATE_LAKE_AVERAGE_TEMP, /**< vertical average lake temperature: lake_var.tempavg */ - STATE_LAKE_ICE_AREA_FRAC, /**< lake ice area fraction: lake_var.areai */ - STATE_LAKE_ICE_AREA_FRAC_NEW, /**< new lake ice area fraction: lake_var.new_ice_area */ - STATE_LAKE_ICE_WATER_EQUIVALENT, /**< lake ice water equivalent: lake_var.ice_water_eq */ - STATE_LAKE_ICE_HEIGHT, /**< lake ice height: lake_var.hice */ - STATE_LAKE_ICE_TEMP, /**< lake ice temperature: lake_var.tempi */ - STATE_LAKE_ICE_SWE, /**< lake ice snow water equivalent: lake_var.swe */ - STATE_LAKE_ICE_SNOW_SURF_TEMP, /**< lake ice snow surface temperature: lake_var.surf_temp */ - STATE_LAKE_ICE_SNOW_PACK_TEMP, /**< lake ice snow pack temperature: lake_var.pack_temp */ - STATE_LAKE_ICE_SNOW_COLD_CONTENT, /**< lake ice snow coldcontent: lake_var.coldcontent */ - STATE_LAKE_ICE_SNOW_SURF_WATER, /**< lake ice snow surface water: lake_var.surf_water */ - STATE_LAKE_ICE_SNOW_PACK_WATER, /**< lake ice snow pack water: lake_var.pack_water */ - STATE_LAKE_ICE_SNOW_ALBEDO, /**< lake ice snow albedo: lake_var.SAlbedo */ - STATE_LAKE_ICE_SNOW_DEPTH, /**< lake ice snow depth: lake_var.sdepth */ - STATE_AVG_ALBEDO, /**< gridcell-averaged albedo: gridcell_avg.avg_albedo */ - // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! - // used as a loop counter and must be >= the largest value in this enum - N_STATE_VARS /**< used as a loop counter*/ -}; - - -/****************************************************************************** - * @brief Output BINARY format types - *****************************************************************************/ -enum -{ - OUT_TYPE_DEFAULT, /**< Default data type */ - OUT_TYPE_CHAR, /**< char */ - OUT_TYPE_SINT, /**< short int */ - OUT_TYPE_USINT, /**< unsigned short int */ - OUT_TYPE_INT, /**< int */ - OUT_TYPE_FLOAT, /**< single-precision floating point */ - OUT_TYPE_DOUBLE /**< double-precision floating point */ -}; - -/****************************************************************************** - * @brief Output aggregation method types - *****************************************************************************/ -enum -{ - AGG_TYPE_DEFAULT, /**< Default aggregation type */ - AGG_TYPE_AVG, /**< average over agg interval */ - AGG_TYPE_BEG, /**< value at beginning of agg interval */ - AGG_TYPE_END, /**< value at end of agg interval */ - AGG_TYPE_MAX, /**< maximum value over agg interval */ - AGG_TYPE_MIN, /**< minimum value over agg interval */ - AGG_TYPE_SUM /**< sum over agg interval */ -}; - -/****************************************************************************** - * @brief Frequency flags for raising alarms/flags - *****************************************************************************/ -enum -{ - FREQ_NEVER, /**< Flag for never raising alarm */ - FREQ_NSTEPS, /**< Flag for raising alarm every nsteps */ - FREQ_NSECONDS, /**< Flag for raising alarm every nseconds */ - FREQ_NMINUTES, /**< Flag for raising alarm every nminutes */ - FREQ_NHOURS, /**< Flag for raising alarm every nhours */ - FREQ_NDAYS, /**< Flag for raising alarm every ndays */ - FREQ_NMONTHS, /**< Flag for raising alarm every nmonths */ - FREQ_NYEARS, /**< Flag for raising alarm every nyears */ - FREQ_DATE, /**< Flag for raising alarm on a specific date */ - FREQ_END /**< Flag for raising alarm at the end of a simulation */ -}; - -/****************************************************************************** - * @brief Codes for displaying version information - *****************************************************************************/ -enum -{ - DISP_VERSION, - DISP_COMPILE_TIME, - DISP_ALL -}; - -/****************************************************************************** - * @brief Codes for calendar option. - *****************************************************************************/ -enum calendars -{ - CALENDAR_STANDARD, - CALENDAR_GREGORIAN, - CALENDAR_PROLEPTIC_GREGORIAN, - CALENDAR_NOLEAP, - CALENDAR_365_DAY, - CALENDAR_360_DAY, - CALENDAR_JULIAN, - CALENDAR_ALL_LEAP, - CALENDAR_366_DAY -}; - -/****************************************************************************** - * @brief Codes for time units option. - *****************************************************************************/ -enum time_units -{ - TIME_UNITS_SECONDS, - TIME_UNITS_MINUTES, - TIME_UNITS_HOURS, - TIME_UNITS_DAYS -}; - -/****************************************************************************** - * @brief Codes for timers - *****************************************************************************/ -enum timers -{ - TIMER_VIC_ALL, - TIMER_VIC_INIT, - TIMER_VIC_RUN, - TIMER_VIC_FINAL, - TIMER_VIC_FORCE, - TIMER_VIC_WRITE, - N_TIMERS -}; - -/****************************************************************************** - * @brief Stores forcing file input information. - *****************************************************************************/ -typedef struct { - size_t N_ELEM; /**< number of elements per record; for LAI and ALBEDO, - 1 element per veg tile; for others N_ELEM = 1; */ - bool SIGNED; - bool SUPPLIED; - double multiplier; - char varname[MAXSTRING]; -} force_type_struct; - -/****************************************************************************** - * @brief This structure records the parameters set by the forcing file - input routines. Those filled, are used to estimate the paramters - needed for the model run in initialize_atmos.c. - *****************************************************************************/ -typedef struct { - force_type_struct TYPE[N_FORCING_TYPES]; - double FORCE_DT[2]; /**< forcing file time step */ - size_t force_steps_per_day[2]; /**< forcing file timesteps per day */ - unsigned short int FORCE_ENDIAN[2]; /**< endian-ness of input file, used for - DAILY_BINARY format */ - int FORCE_FORMAT[2]; /**< ASCII or BINARY */ - int FORCE_INDEX[2][N_FORCING_TYPES]; - size_t N_TYPES[2]; -} param_set_struct; - -/****************************************************************************** - * @brief This structure stores alarm information - *****************************************************************************/ -typedef struct { - unsigned int count; /**< current alarm count */ - dmy_struct next_dmy; /**< next dmy to raise alarm at */ - int next_count; /**< next count to raise alarm at */ - unsigned int freq; /**< enum value to describing alarm frequency */ - int n; /**< variable that provides additional information with respect to alarm_freq */ - bool is_subdaily; /**< flag denoting if alarm will be raised more than once per day */ -} alarm_struct; - -/****************************************************************************** - * @brief This structure stores output information for one output stream. - *****************************************************************************/ -typedef struct { - size_t nvars; /**< number of variables to store in the file */ - size_t ngridcells; /**< number of grid cells in aggdata */ - dmy_struct time_bounds[2]; /**< timestep bounds of stream */ - char prefix[MAXSTRING]; /**< prefix of the file name, e.g. "fluxes" */ - char filename[MAXSTRING]; /**< complete file name */ - FILE *fh; /**< filehandle */ - unsigned short int file_format; /**< output file format */ - short int compress; /**< Compress output files in stream*/ - unsigned short int *type; /**< type, when written to a binary file; - OUT_TYPE_USINT = unsigned short int - OUT_TYPE_SINT = short int - OUT_TYPE_FLOAT = single precision floating point - OUT_TYPE_DOUBLE = double precision floating point */ - double *mult; /**< multiplier, when written to a binary file [shape=(nvars, )] */ - char **format; /**< format, when written to disk [shape=(nvars, )] */ - unsigned int *varid; /**< id numbers of the variables to store in the file - (a variable's id number is its index in the out_data array). - The order of the id numbers in the varid array - is the order in which the variables will be written. */ - unsigned short int *aggtype; /**< type of aggregation to use [shape=(nvars, )] */ - double ****aggdata; /**< array of aggregated data values [shape=(ngridcells, nvars, nelem, nbins)] */ - alarm_struct agg_alarm; /**< alaram for stream aggregation */ - alarm_struct write_alarm; /**< alaram for controlling stream write */ -} stream_struct; - -/****************************************************************************** - * @brief This structure stores moisture state information for differencing - * with next time step. - *****************************************************************************/ -typedef struct { - double total_moist_storage; /**< total moisture storage [mm] */ - double total_soil_moist; /**< total column soil moisture [mm] */ - double surfstor; /**< surface water storage [mm] */ - double swe; /**< snow water equivalent [mm] */ - double wdew; /**< canopy interception [mm] */ -} save_data_struct; - -/****************************************************************************** - * @brief This structure stores metadata for individual variables - *****************************************************************************/ -typedef struct { - char varname[MAXSTRING]; /**< name of variable */ - char long_name[MAXSTRING]; /**< name of variable */ - char standard_name[MAXSTRING]; /**< cf long_name of variable */ - char units[MAXSTRING]; /**< units of variable */ - char description[MAXSTRING]; /**< descripition of variable */ - size_t nelem; /**< number of data values */ -} metadata_struct; - -/****************************************************************************** - * @brief This structure holds all variables needed for the error handling - * routines. - *****************************************************************************/ -typedef struct { - force_data_struct *force; - double dt; - energy_bal_struct *energy; - size_t rec; - double **out_data; - stream_struct *output_streams; - snow_data_struct *snow; - soil_con_struct soil_con; - veg_con_struct *veg_con; - veg_var_struct *veg_var; -} Error_struct; - -/****************************************************************************** - * @brief This structure holds timer information for profiling - *****************************************************************************/ -typedef struct { - double start_wall; - double start_cpu; - double stop_wall; - double stop_cpu; - double delta_wall; - double delta_cpu; -} timer_struct; - -double air_density(double t, double p); -void agg_stream_data(stream_struct *stream, dmy_struct *dmy_current, - double ***out_data); -double all_30_day_from_dmy(dmy_struct *dmy); -double all_leap_from_dmy(dmy_struct *dmy); -void alloc_aggdata(stream_struct *stream); -void alloc_out_data(size_t ngridcells, double ***out_data); -double average(double *ar, size_t n); -double calc_energy_balance_error(double, double, double, double, double); -void calc_root_fractions(veg_con_struct *veg_con, soil_con_struct *soil_con); -double calc_water_balance_error(double, double, double, double); -bool cell_method_from_agg_type(unsigned short int aggtype, char cell_method[]); -bool check_write_flag(int rec); -void collect_eb_terms(energy_bal_struct, snow_data_struct, cell_data_struct, - double, double, double, bool, bool, double, bool, int, - double *, double, double **); -void collect_wb_terms(cell_data_struct, veg_var_struct, snow_data_struct, - double, double, double, bool, double, bool, double *, - double **); -void compute_derived_state_vars(all_vars_struct *, soil_con_struct *, - veg_con_struct *); -void compute_lake_params(lake_con_struct *, soil_con_struct); -void compute_treeline(force_data_struct *, dmy_struct *, double, double *, - bool *); -size_t count_force_vars(FILE *gp); -void count_nstreams_nvars(FILE *gp, size_t *nstreams, size_t nvars[]); -void cmd_proc(int argc, char **argv, char *globalfilename); -void compress_files(char string[], short int level); -stream_struct create_outstream(stream_struct *output_streams); -double get_cpu_time(); -void get_current_datetime(char *cdt); -double get_wall_time(); -double date2num(double origin, dmy_struct *date, double tzoffset, - unsigned short int calendar, unsigned short int time_units); -void dmy_all_30_day(double julian, dmy_struct *dmy); -void dmy_all_leap(double julian, dmy_struct *dmy); -bool dmy_equal(dmy_struct *a, dmy_struct *b); -void dmy_julian_day(double julian, unsigned short int calendar, - dmy_struct *dmy); -void dmy_no_leap_day(double julian, dmy_struct *dmy); -void dt_seconds_to_time_units(unsigned short int time_units, double dt_seconds, - double *dt_time_units); -void display_current_settings(int); -double fractional_day_from_dmy(dmy_struct *dmy); -void free_all_vars(all_vars_struct *all_vars, int Nveg); -void free_dmy(dmy_struct **dmy); -void free_out_data(size_t ngridcells, double ***out_data); -void free_streams(stream_struct **streams); -void free_vegcon(veg_con_struct **veg_con); -void generate_default_state(all_vars_struct *, soil_con_struct *, - veg_con_struct *, dmy_struct *); -void generate_default_lake_state(all_vars_struct *, soil_con_struct *, - lake_con_struct); -void get_default_nstreams_nvars(size_t *nstreams, size_t nvars[]); -void get_parameters(FILE *paramfile); -void init_output_list(double **out_data, int write, char *format, int type, - double mult); -void initialize_energy(energy_bal_struct **energy, size_t nveg); -void initialize_global(void); -void initialize_options(void); -void initialize_parameters(void); -void initialize_save_data(all_vars_struct *all_vars, force_data_struct *force, - soil_con_struct *soil_con, veg_con_struct *veg_con, - veg_lib_struct *veg_lib, lake_con_struct *lake_con, - double **out_data, save_data_struct *save_data, - timer_struct *timer); -void initialize_snow(snow_data_struct **snow, size_t veg_num); -void initialize_soil(cell_data_struct **cell, size_t veg_num); -void initialize_time(void); -void initialize_veg(veg_var_struct **veg_var, size_t nveg); -double julian_day_from_dmy(dmy_struct *dmy, unsigned short int calendar); -bool leap_year(unsigned short int year, unsigned short int calendar); -all_vars_struct make_all_vars(size_t nveg); -cell_data_struct **make_cell_data(size_t veg_type_num); -dmy_struct *make_dmy(global_param_struct *global); -energy_bal_struct **make_energy_bal(size_t nveg); -void make_lastday(unsigned short int calendar, unsigned short int year, - unsigned short int lastday[]); -snow_data_struct **make_snow_data(size_t nveg); -veg_var_struct **make_veg_var(size_t veg_type_num); -double no_leap_day_from_dmy(dmy_struct *dmy); -void num2date(double origin, double time_value, double tzoffset, - unsigned short int calendar, unsigned short int time_units, - dmy_struct *date); -FILE *open_file(char string[], char type[]); -void parse_nc_time_units(char *nc_unit_chars, unsigned short int *units, - dmy_struct *dmy); -void put_data(all_vars_struct *, force_data_struct *, soil_con_struct *, - veg_con_struct *, veg_lib_struct *veg_lib, lake_con_struct *, - double **out_data, save_data_struct *, timer_struct *timer); -void print_alarm(alarm_struct *alarm); -void print_cell_data(cell_data_struct *cell, size_t nlayers, size_t nfrost); -void print_dmy(dmy_struct *dmy); -void print_energy_bal(energy_bal_struct *eb, size_t nnodes, size_t nfronts); -void print_force_type(force_type_struct *force_type); -void print_global_param(global_param_struct *gp); -void print_lake_con(lake_con_struct *lcon, size_t nlnodes); -void print_lake_var(lake_var_struct *lvar, size_t nlnodes, size_t nfronts, - size_t nlayers, size_t nnodes, size_t nfrost); -void print_layer_data_states(layer_data_struct *ldata, size_t nfrost); -void print_layer_data_fluxes(layer_data_struct *ldata); -void print_license(void); -void print_option(option_struct *option); -void print_out_data(double **out_data, metadata_struct *metadata); -void print_out_metadata(metadata_struct *metadata, size_t nvars); -void print_output_streams(stream_struct *outf); -void print_param_set(param_set_struct *param_set); -void print_parameters(parameters_struct *param); -void print_save_data(save_data_struct *save); -void print_snow_data(snow_data_struct *snow); -void print_soil_con(soil_con_struct *scon, size_t nlayers, size_t nnodes, - size_t nfrost, size_t nbands, size_t nzwt); -void print_stream(stream_struct *stream, metadata_struct *metadata); -void print_veg_con(veg_con_struct *vcon, size_t nroots, char blowing, char lake, - char carbon, size_t ncanopy); -void print_veg_lib(veg_lib_struct *vlib, char carbon); -void print_veg_var(veg_var_struct *vvar, size_t ncanopy); -void print_version(char *); -void print_usage(char *); -double q_to_vp(double q, double p); -bool raise_alarm(alarm_struct *alarm, dmy_struct *dmy_current); -void reset_alarm(alarm_struct *alarm, dmy_struct *dmy_current); -void reset_stream(stream_struct *stream, dmy_struct *dmy_current); -void set_output_var(stream_struct *stream, char *varname, size_t varnum, - char *format, unsigned short int type, double mult, - unsigned short int aggtype); -unsigned int get_default_outvar_aggtype(unsigned int varid); -void set_alarm(dmy_struct *dmy_current, unsigned int freq, void *value, - alarm_struct *alarm); -void set_output_defaults(stream_struct **output_streams, - dmy_struct *dmy_current, - unsigned short default_file_format); -void set_output_met_data_info(); -void setup_stream(stream_struct *stream, size_t nvars, size_t ngridcells); -void soil_moisture_from_water_table(soil_con_struct *soil_con, size_t nlayers); -void sprint_dmy(char *str, dmy_struct *dmy); -void str_from_calendar(unsigned short int calendar, char *calendar_str); -void str_from_time_units(unsigned short int time_units, char *unit_str); -unsigned short int str_to_agg_type(char aggstr[]); -void str_to_ascii_format(char *format); -bool str_to_bool(char str[]); -unsigned short int str_to_calendar(char *cal_chars); -unsigned short int str_to_freq_flag(char freq[]); -double str_to_out_mult(char multstr[]); -unsigned short int str_to_out_type(char typestr[]); -unsigned short int str_to_timeunits(char units_chars[]); -void strpdmy(const char *s, const char *format, dmy_struct *dmy); -double time_delta(dmy_struct *dmy_current, unsigned short int freq, int n); -void timer_continue(timer_struct *t); -void timer_init(timer_struct *t); -void timer_start(timer_struct *t); -void timer_stop(timer_struct *t); -int update_step_vars(all_vars_struct *, veg_con_struct *, veg_hist_struct *); -int invalid_date(unsigned short int calendar, dmy_struct *dmy); -void validate_parameters(void); -void validate_streams(stream_struct **stream); -char will_it_snow(double *t, double t_offset, double max_snow_temp, - double *prcp, size_t n); -void zero_output_list(double **); - -#endif From 22b2775ccef68bc0e903fceac78a86128024995d Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 18 Sep 2017 15:47:33 +0200 Subject: [PATCH 216/294] new extension header included --- .../include/vic_driver_shared_all.h | 2 ++ .../include/vic_driver_shared_image.h | 1 + .../rout_rvic/include/image_extension_name.h | 26 +++++++++++++++++++ .../rout_stub/include/image_extension_name.h | 25 ++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 vic/extensions/rout_rvic/include/image_extension_name.h create mode 100644 vic/extensions/rout_stub/include/image_extension_name.h diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 4c3823980..50c4353dc 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -315,7 +315,9 @@ enum STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ +#ifdef EXTENSION_RVIC STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ +#endif STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 01ccfe603..47a8c90ec 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -27,6 +27,7 @@ #ifndef VIC_DRIVER_SHARED_IMAGE_H #define VIC_DRIVER_SHARED_IMAGE_H +#include #include #include #include diff --git a/vic/extensions/rout_rvic/include/image_extension_name.h b/vic/extensions/rout_rvic/include/image_extension_name.h new file mode 100644 index 000000000..df8698e3d --- /dev/null +++ b/vic/extensions/rout_rvic/include/image_extension_name.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for rvic routing routines + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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. + *****************************************************************************/ +#define EXTENSION_RVIC diff --git a/vic/extensions/rout_stub/include/image_extension_name.h b/vic/extensions/rout_stub/include/image_extension_name.h new file mode 100644 index 000000000..13ed9f6ae --- /dev/null +++ b/vic/extensions/rout_stub/include/image_extension_name.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Header file for stub + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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. + *****************************************************************************/ From cb8c7ce6975f9a7615327cadf7ad4f49871c5159 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Tue, 19 Sep 2017 11:29:55 +0200 Subject: [PATCH 217/294] Added changelog info and statefile info --- docs/Development/ReleaseNotes.md | 4 ++++ docs/Documentation/Drivers/Image/StateFile.md | 8 +++++++- vic/extensions/rout_stub/include/image_extension_name.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 450c58742..1b1c24710 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -107,6 +107,10 @@ To check which release of VIC you are running: The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. +8. Added routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) + + The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available. + #### Bug Fixes: 1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) diff --git a/docs/Documentation/Drivers/Image/StateFile.md b/docs/Documentation/Drivers/Image/StateFile.md index 17447e6bf..92af52a91 100644 --- a/docs/Documentation/Drivers/Image/StateFile.md +++ b/docs/Documentation/Drivers/Image/StateFile.md @@ -56,7 +56,7 @@ The following variables contain information about the storage of moisture and th | STATE_CANOPY_WATER | [veg_class, snow_band, nlayer, lat, lon] | double | Amount of water stored in the vegetation canopy [mm]. Not defined for bare soil | | STATE_SNOW_AGE | [veg_class, snow_band, nlayer, lat, lon] | model_time_step | Number of model time steps since the last new snow | | STATE_SNOW_MELT_STATE | [veg_class, snow_band, nlayer, lat, lon] | int | flag to indicate whether snowpack is in accumulation or melting phase (1 melting, 0 not melting) | -| STATE_SNOW_COVERAGE | [veg_class, snow_band, nlayer, lat, lon] | double | Fraction of grid cell area covered by snow [1] | +| STATE_SNOW_COVERAGE | [veg_class, snow_band, nlayer, lat, lon] | double | Fraction of grid cell area covered by snow [1] | | STATE_SNOW_WATER_EQUIVALENT | [veg_class, snow_band, nlayer, lat, lon] | double | Snow water equivalent [m] | | STATE_SNOW_SURF_TEMP | [veg_class, snow_band, nlayer, lat, lon] | double | Snow surface layer temperature [C] | | STATE_SNOW_SURF_WATER | [veg_class, snow_band, nlayer, lat, lon] | double | Liquid water content of the snow surface layer [m] | @@ -70,6 +70,12 @@ The following variables contain information about the storage of moisture and th | STATE_ENERGY_LONGUNDEROUT | [veg_class, snow_band, nlayer, lat, lon] | double | Outgoing longwave flux from understory vegetation [W/m2] (Note: this is a flux variable temporarily saved in state file to ensure exact restart) | | STATE_ENERGY_SNOW_FLUX | [veg_class, snow_band, nlayer, lat, lon] | double | Thermal flux through snowpack [W/m2] (Note: this is a flux variable temporarily saved in state file to ensure exact restart) | +## netCDF State File Variables - RVIC-Routing (only when RVIC extension is activated in the makefile before compiling) + +| State variable name | Dimension | Type | Description | +|-----------------------------|-------------------------------------------------------|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------| +| STATE_ROUT_RING | [routing_timestep, outlet] | double | Routing ring unit hydrographs in the routing ring | + * * * ## Carbon Information diff --git a/vic/extensions/rout_stub/include/image_extension_name.h b/vic/extensions/rout_stub/include/image_extension_name.h index 13ed9f6ae..10201513c 100644 --- a/vic/extensions/rout_stub/include/image_extension_name.h +++ b/vic/extensions/rout_stub/include/image_extension_name.h @@ -23,3 +23,4 @@ * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *****************************************************************************/ +#define EXTENSION_STUB From 54eabab910b0bf90bafbe29af36466a78142b962 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 25 Sep 2017 14:53:35 +0200 Subject: [PATCH 218/294] first attempt to move the vic_store.c file back to its original position --- vic/drivers/image/src/vic_image.c | 2 +- .../include/vic_driver_shared_all.h | 3 - .../shared_image}/src/vic_store.c | 23 +- vic/extensions/rout_rvic/include/rout.h | 15 + vic/extensions/rout_rvic/src/state_metadata.c | 15 +- vic/extensions/rout_rvic/src/vic_restore.c | 2 +- vic/extensions/rout_rvic/src/vic_store.c | 2209 ----------------- .../rout_rvic/src/vic_store_extension.c | 170 ++ vic/extensions/rout_stub/include/rout.h | 15 + .../rout_stub/src/vic_store_extension.c | 63 + 10 files changed, 290 insertions(+), 2227 deletions(-) rename vic/{extensions/rout_stub => drivers/shared_image}/src/vic_store.c (99%) delete mode 100644 vic/extensions/rout_rvic/src/vic_store.c create mode 100644 vic/extensions/rout_rvic/src/vic_store_extension.c create mode 100644 vic/extensions/rout_stub/src/vic_store_extension.c diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index 2de22ace0..ff6699cc4 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -60,7 +60,7 @@ veg_con_map_struct *veg_con_map = NULL; veg_con_struct **veg_con = NULL; veg_hist_struct **veg_hist = NULL; veg_lib_struct **veg_lib = NULL; -metadata_struct state_metadata[N_STATE_VARS]; +metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; metadata_struct out_metadata[N_OUTVAR_TYPES]; save_data_struct *save_data; // [ncells] double ***out_data = NULL; // [ncells, nvars, nelem] diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index 50c4353dc..c042ecf50 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -315,9 +315,6 @@ enum STATE_SNOW_DENSITY, /**< snow density: snow[veg][band].density */ STATE_SNOW_COLD_CONTENT, /**< snow cold content: snow[veg][band].coldcontent */ STATE_SNOW_CANOPY, /**< snow canopy storage: snow[veg][band].snow_canopy */ -#ifdef EXTENSION_RVIC - STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ -#endif STATE_SOIL_NODE_TEMP, /**< soil node temperatures: energy[veg][band].T[nidx] */ STATE_FOLIAGE_TEMPERATURE, /**< Foliage temperature: energy[veg][band].Tfoliage */ STATE_ENERGY_LONGUNDEROUT, /**< Outgoing longwave from understory: energy[veg][band].LongUnderOut */ diff --git a/vic/extensions/rout_stub/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c similarity index 99% rename from vic/extensions/rout_stub/src/vic_store.c rename to vic/drivers/shared_image/src/vic_store.c index 7e3334cf5..0060ec746 100644 --- a/vic/extensions/rout_stub/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Save model state. @@ -114,6 +115,9 @@ vic_store(dmy_struct *dmy_state, dvar[i] = nc_state_file.d_fillvalue; } + // store extension variables + vic_store_extension(dmy_state, filename); + // total soil moisture nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); for (m = 0; m < options.NVEGTYPES; m++) { @@ -1291,7 +1295,7 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) extern option_struct options; extern domain_struct global_domain; - // Set fill values + // set fill values nc_state_file->c_fillvalue = NC_FILL_CHAR; nc_state_file->s_fillvalue = NC_FILL_SHORT; nc_state_file->i_fillvalue = NC_FILL_INT; @@ -1308,12 +1312,11 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->ni_dimid = MISSING; nc_state_file->nj_dimid = MISSING; nc_state_file->node_dimid = MISSING; - nc_state_file->outlet_dimid = MISSING; nc_state_file->root_zone_dimid = MISSING; nc_state_file->time_dimid = MISSING; nc_state_file->veg_dimid = MISSING; - // Set dimension sizes + // set dimension sizes nc_state_file->band_size = options.SNOW_BAND; nc_state_file->front_size = MAX_FRONTS; nc_state_file->frost_size = options.Nfrost; @@ -1325,9 +1328,12 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->time_size = NC_UNLIMITED; nc_state_file->veg_size = options.NVEGTYPES; + // set ids and dimension sizes of the extension variables + set_nc_state_file_info_extension(nc_state_file); + // allocate memory for nc_vars nc_state_file->nc_vars = - calloc(N_STATE_VARS, sizeof(*(nc_state_file->nc_vars))); + calloc(N_STATE_VARS + N_STATE_VARS_EXT, sizeof(*(nc_state_file->nc_vars))); check_alloc_status(nc_state_file->nc_vars, "Memory allocation error"); } @@ -1535,6 +1541,7 @@ set_nc_state_var_info(nc_file_struct *nc) log_err("Too many dimensions specified in variable %zu", i); } } + set_nc_state_var_info_extension(nc); } /****************************************************************************** @@ -1550,7 +1557,7 @@ initialize_state_file(char *filename, extern domain_struct global_domain; extern domain_struct local_domain; extern global_param_struct global_param; - extern metadata_struct state_metadata[N_STATE_VARS]; + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; extern soil_con_struct *soil_con; extern int mpi_rank; @@ -1667,6 +1674,7 @@ initialize_state_file(char *filename, &(nc_state_file->node_dimid)); check_nc_status(status, "Error defining soil_node in %s", filename); + if (options.LAKES) { status = nc_def_dim(nc_state_file->nc_id, "lake_node", nc_state_file->lake_node_size, @@ -1674,6 +1682,9 @@ initialize_state_file(char *filename, check_nc_status(status, "Error defining lake_node in %s", filename); } + // add extension dimensions + initialize_state_file_extension(filename, nc_state_file); + set_nc_state_var_info(nc_state_file); } @@ -1884,7 +1895,7 @@ initialize_state_file(char *filename, // Define state variables if (mpi_rank == VIC_MPI_ROOT) { - for (i = 0; i < N_STATE_VARS; i++) { + for (i = 0; i < (N_STATE_VARS + N_STATE_VARS_EXT); i++) { if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { // skip variables not set in set_state_meta_data_info continue; diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index ccfbbbdbc..c5685b1b0 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -82,5 +82,20 @@ void gather_var_double(double *, double *); *****************************************************************************/ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); +void vic_store_extension(dmy_struct *, char *); +void set_nc_state_file_info_extension(nc_file_struct *); +void set_nc_state_var_info_extension(nc_file_struct *); +void initialize_state_file_extension(char *, nc_file_struct *); + +/****************************************************************************** + * @brief Output state variable. + *****************************************************************************/ +enum +{ + STATE_ROUT_RING, /**< routing ring: rout_ring[routing_timestep, outlet] */ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_STATE_VARS_EXT /**< used as a loop counter*/ +}; #endif diff --git a/vic/extensions/rout_rvic/src/state_metadata.c b/vic/extensions/rout_rvic/src/state_metadata.c index d235e681e..0e06009d4 100644 --- a/vic/extensions/rout_rvic/src/state_metadata.c +++ b/vic/extensions/rout_rvic/src/state_metadata.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Set output met data information @@ -35,12 +36,12 @@ set_state_meta_data_info() size_t v; extern option_struct options; - extern metadata_struct state_metadata[N_STATE_VARS]; + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; // Build the list of state variables // Set missing and/or default values - for (v = 0; v < N_STATE_VARS; v++) { + for (v = 0; v < (N_STATE_VARS + N_STATE_VARS_EXT); v++) { // Set default string values strcpy(state_metadata[v].varname, MISSING_S); strcpy(state_metadata[v].long_name, MISSING_S); @@ -233,13 +234,13 @@ set_state_meta_data_info() "snow interception storage in canopy"); // STATE_ROUT_RING - strcpy(state_metadata[STATE_ROUT_RING].varname, + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].varname, "STATE_ROUT_RING"); - strcpy(state_metadata[STATE_ROUT_RING].long_name, "routing_ring"); - strcpy(state_metadata[STATE_ROUT_RING].standard_name, + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].long_name, "routing_ring"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].standard_name, "routing_ring"); - strcpy(state_metadata[STATE_ROUT_RING].units, "-"); - strcpy(state_metadata[STATE_ROUT_RING].description, + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].units, "-"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].description, "unit hydrographs in the routing ring"); // STATE_SOIL_NODE_TEMP diff --git a/vic/extensions/rout_rvic/src/vic_restore.c b/vic/extensions/rout_rvic/src/vic_restore.c index f5e850f43..fc63c2891 100644 --- a/vic/extensions/rout_rvic/src/vic_restore.c +++ b/vic/extensions/rout_rvic/src/vic_restore.c @@ -40,7 +40,7 @@ vic_restore(void) extern option_struct options; extern veg_con_map_struct *veg_con_map; extern filenames_struct filenames; - extern metadata_struct state_metadata[N_STATE_VARS]; + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; extern int mpi_rank; extern rout_struct rout; diff --git a/vic/extensions/rout_rvic/src/vic_store.c b/vic/extensions/rout_rvic/src/vic_store.c deleted file mode 100644 index d4a25eab4..000000000 --- a/vic/extensions/rout_rvic/src/vic_store.c +++ /dev/null @@ -1,2209 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Save model state. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 -#include - -/****************************************************************************** - * @brief Save model state. - *****************************************************************************/ -void -vic_store(dmy_struct *dmy_state, - char *filename) -{ - extern filenames_struct filenames; - extern all_vars_struct *all_vars; - extern domain_struct local_domain; - extern option_struct options; - extern veg_con_map_struct *veg_con_map; - extern int mpi_rank; - extern rout_struct rout; - - int status; - int v; - size_t i; - size_t j; - size_t k; - size_t m; - size_t p; - int *ivar = NULL; - double *dvar = NULL; - size_t d2start[2]; - size_t d3start[3]; - size_t d4start[4]; - size_t d5start[5]; - size_t d6start[6]; - nc_file_struct nc_state_file; - nc_var_struct *nc_var; - - set_nc_state_file_info(&nc_state_file); - - // create netcdf file for storing model state - sprintf(filename, "%s.%04i%02i%02i_%05u.nc", - filenames.statefile, dmy_state->year, - dmy_state->month, dmy_state->day, - dmy_state->dayseconds); - - initialize_state_file(filename, &nc_state_file, dmy_state); - - if (mpi_rank == VIC_MPI_ROOT) { - debug("writing state file: %s", filename); - } - - // write state variables - - // allocate memory for variables to be stored - ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - - dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - - // initialize starts and counts - d2start[0] = 0; - d2start[1] = 0; - - d3start[0] = 0; - d3start[1] = 0; - d3start[2] = 0; - - d4start[0] = 0; - d4start[1] = 0; - d4start[2] = 0; - d4start[3] = 0; - - d5start[0] = 0; - d5start[1] = 0; - d5start[2] = 0; - d5start[3] = 0; - d5start[4] = 0; - - d6start[0] = 0; - d6start[1] = 0; - d6start[2] = 0; - d6start[3] = 0; - d6start[4] = 0; - d6start[5] = 0; - - // set missing values - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - dvar[i] = nc_state_file.d_fillvalue; - } - - // routing ring - if (mpi_rank == VIC_MPI_ROOT) { - d2start[0] = 0; - d2start[1] = 0; - nc_var = &(nc_state_file.nc_vars[STATE_ROUT_RING]); - - status = - nc_put_vara_double(nc_state_file.nc_id, nc_var->nc_varid, d2start, - nc_var->nc_counts, - rout.ring); - check_nc_status(status, "Error writing values."); - } - - // total soil moisture - nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d5start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d5start[1] = k; - for (j = 0; j < options.Nlayer; j++) { - d5start[2] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = - (double) all_vars[i].cell[v][k].layer[j].moist; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d5start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - } - - // ice content - nc_var = &(nc_state_file.nc_vars[STATE_SOIL_ICE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d6start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d6start[1] = k; - for (j = 0; j < options.Nlayer; j++) { - d6start[2] = j; - for (p = 0; p < options.Nfrost; p++) { - d6start[3] = p; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = - (double) all_vars[i].cell[v][k].layer[j].ice[p]; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d6start, nc_var->nc_counts, - dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - } - } - - - // dew storage: tmpval = veg_var[veg][band].Wdew; - nc_var = &(nc_state_file.nc_vars[STATE_CANOPY_WATER]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].veg_var[v][k].Wdew; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - if (options.CARBON) { - // cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; - nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPP]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].veg_var[v][k].AnnualNPP; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - // previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; - nc_var = &(nc_state_file.nc_vars[STATE_ANNUALNPPPREV]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = - (double) all_vars[i].veg_var[v][k].AnnualNPPPrev; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - // litter carbon: tmpval = cell[veg][band].CLitter; - nc_var = &(nc_state_file.nc_vars[STATE_CLITTER]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].cell[v][k].CLitter; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - // intermediate carbon: tmpval = tmpval = cell[veg][band].CInter; - nc_var = &(nc_state_file.nc_vars[STATE_CINTER]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].cell[v][k].CInter; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - // slow carbon: tmpval = cell[veg][band].CSlow; - nc_var = &(nc_state_file.nc_vars[STATE_CSLOW]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].cell[v][k].CSlow; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - } - - // snow age: snow[veg][band].last_snow - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_AGE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - ivar[i] = (int) all_vars[i].snow[v][k].last_snow; - } - else { - ivar[i] = nc_state_file.i_fillvalue; - } - } - gather_put_nc_field_int(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.i_fillvalue, - d4start, nc_var->nc_counts, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - } - } - } - - - // melting state: (int)snow[veg][band].MELTING - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_MELT_STATE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - ivar[i] = (int) all_vars[i].snow[v][k].MELTING; - } - else { - ivar[i] = nc_state_file.i_fillvalue; - } - } - gather_put_nc_field_int(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.i_fillvalue, - d4start, nc_var->nc_counts, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - } - } - } - - - // snow covered fraction: snow[veg][band].coverage - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COVERAGE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].coverage; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow water equivalent: snow[veg][band].swq - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_WATER_EQUIVALENT]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].swq; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow surface temperature: snow[veg][band].surf_temp - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_TEMP]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].surf_temp; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow surface water: snow[veg][band].surf_water - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_SURF_WATER]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].surf_water; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow pack temperature: snow[veg][band].pack_temp - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_TEMP]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].pack_temp; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow pack water: snow[veg][band].pack_water - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_PACK_WATER]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].pack_water; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow density: snow[veg][band].density - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_DENSITY]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].density; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow cold content: snow[veg][band].coldcontent - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_COLD_CONTENT]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].coldcontent; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // snow canopy storage: snow[veg][band].snow_canopy - nc_var = &(nc_state_file.nc_vars[STATE_SNOW_CANOPY]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].snow[v][k].snow_canopy; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // soil node temperatures: energy[veg][band].T[nidx] - nc_var = &(nc_state_file.nc_vars[STATE_SOIL_NODE_TEMP]); - for (m = 0; m < options.NVEGTYPES; m++) { - d5start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d5start[1] = k; - for (j = 0; j < options.Nnode; j++) { - d5start[2] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].energy[v][k].T[j]; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d5start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - } - - - // Foliage temperature: energy[veg][band].Tfoliage - nc_var = &(nc_state_file.nc_vars[STATE_FOLIAGE_TEMPERATURE]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].energy[v][k].Tfoliage; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // Outgoing longwave from understory: energy[veg][band].LongUnderOut - // This is a flux, and saving it to state file is a temporary solution!! - nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_LONGUNDEROUT]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].energy[v][k].LongUnderOut; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - - // Thermal flux through the snow pack: energy[veg][band].snow_flux - // This is a flux, and saving it to state file is a temporary solution!! - nc_var = &(nc_state_file.nc_vars[STATE_ENERGY_SNOW_FLUX]); - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - dvar[i] = (double) all_vars[i].energy[v][k].snow_flux; - } - else { - dvar[i] = nc_state_file.d_fillvalue; - } - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - // Grid cell averaged albedo - nc_var = &(nc_state_file.nc_vars[STATE_AVG_ALBEDO]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].gridcell_avg.avg_albedo; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - - if (options.LAKES) { - // total soil moisture - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_MOISTURE]); - for (j = 0; j < options.Nlayer; j++) { - d3start[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d3start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // ice content - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_ICE]); - for (j = 0; j < options.Nlayer; j++) { - d4start[0] = j; - for (p = 0; p < options.Nfrost; p++) { - d4start[1] = p; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = - (double) all_vars[i].lake_var.soil.layer[j].ice[p]; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d4start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - } - - if (options.CARBON) { - // litter carbon: tmpval = lake_var.soil.CLitter; - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CLITTER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.soil.CLitter; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // intermediate carbon: tmpval = lake_var.soil.CInter; - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CINTER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.soil.CInter; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // slow carbon: tmpval = lake_var.soil.CSlow; - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_CSLOW]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.soil.CSlow; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // snow age: lake_var.snow.last_snow - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_AGE]); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = (int) all_vars[i].lake_var.snow.last_snow; - } - gather_put_nc_field_int(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.i_fillvalue, - d2start, nc_var->nc_counts, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - } - - // melting state: (int)lake_var.snow.MELTING - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_MELT_STATE]); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = (int) all_vars[i].lake_var.snow.MELTING; - } - gather_put_nc_field_int(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.i_fillvalue, - d2start, nc_var->nc_counts, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - } - - // snow covered fraction: lake_var.snow.coverage - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COVERAGE]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.coverage; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow water equivalent: lake_var.snow.swq - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_WATER_EQUIVALENT]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.swq; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow surface temperature: lake_var.snow.surf_temp - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.surf_temp; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow surface water: lake_var.snow.surf_water - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_SURF_WATER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.surf_water; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow pack temperature: lake_var.snow.pack_temp - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.pack_temp; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow pack water: lake_var.snow.pack_water - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_PACK_WATER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.pack_water; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow density: lake_var.snow.density - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_DENSITY]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.density; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow cold content: lake_var.snow.coldcontent - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_COLD_CONTENT]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.coldcontent; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // snow canopy storage: lake_var.snow.snow_canopy - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SNOW_CANOPY]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.snow.snow_canopy; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // soil node temperatures: lake_var.energy.T[nidx] - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SOIL_NODE_TEMP]); - for (j = 0; j < options.Nnode; j++) { - d3start[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.soil.layer[j].moist; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // lake active layers: lake_var.activenod - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ACTIVE_LAYERS]); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = (int) all_vars[i].lake_var.activenod; - } - gather_put_nc_field_int(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.i_fillvalue, - d2start, nc_var->nc_counts, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - ivar[i] = nc_state_file.i_fillvalue; - } - - // lake layer thickness: lake_var.dz - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_DZ]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.dz; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake surface layer thickness: lake_var.surfdz - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_LAYER_DZ]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.surfdz; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake depth: lake_var.ldepth - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_DEPTH]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.ldepth; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake layer surface areas: lake_var.surface[ndix] - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_SURF_AREA]); - for (j = 0; j < options.NLAKENODES; j++) { - d3start[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.surface[j]; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d3start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // lake surface area: lake_var.sarea - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_SURF_AREA]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.sarea; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake volume: lake_var.volume - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_VOLUME]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.volume; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake layer temperatures: lake_var.temp[nidx] - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_LAYER_TEMP]); - for (j = 0; j < options.NLAKENODES; j++) { - d3start[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.temp[j]; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // vertical average lake temperature: lake_var.tempavg - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_AVERAGE_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.tempavg; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice area fraction: lake_var.areai - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.areai; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // new lake ice area fraction: lake_var.new_ice_area - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_AREA_FRAC_NEW]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.new_ice_area; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice water equivalent: lake_var.ice_water_eq - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_WATER_EQUIVALENT]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.ice_water_eq; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice height: lake_var.hice - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_HEIGHT]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.hice; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice temperature: lake_var.tempi - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.tempi; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow water equivalent: lake_var.swe - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SWE]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.swe; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow surface temperature: lake_var.surf_temp - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.surf_temp; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow pack temperature: lake_var.pack_temp - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_TEMP]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.pack_temp; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow coldcontent: lake_var.coldcontent - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_COLD_CONTENT]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.coldcontent; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow surface water: lake_var.surf_water - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_SURF_WATER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.surf_water; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow pack water: lake_var.pack_water - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_PACK_WATER]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.pack_water; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow albedo: lake_var.SAlbedo - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_ALBEDO]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.SAlbedo; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - - // lake ice snow depth: lake_var.sdepth - nc_var = &(nc_state_file.nc_vars[STATE_LAKE_ICE_SNOW_DEPTH]); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = (double) all_vars[i].lake_var.sdepth; - } - gather_put_nc_field_double(nc_state_file.nc_id, - nc_var->nc_varid, - nc_state_file.d_fillvalue, - d2start, nc_var->nc_counts, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file.d_fillvalue; - } - } - - // close the netcdf file if it is still open - if (mpi_rank == VIC_MPI_ROOT) { - if (nc_state_file.open == true) { - status = nc_close(nc_state_file.nc_id); - check_nc_status(status, "Error closing %s", filename); - } - } - - free(ivar); - free(dvar); - free(nc_state_file.nc_vars); -} - -/****************************************************************************** - * @brief Setup state file netcdf structure - *****************************************************************************/ -void -set_nc_state_file_info(nc_file_struct *nc_state_file) -{ - extern option_struct options; - extern domain_struct global_domain; - extern rout_struct rout; - - // Set fill values - nc_state_file->c_fillvalue = NC_FILL_CHAR; - nc_state_file->s_fillvalue = NC_FILL_SHORT; - nc_state_file->i_fillvalue = NC_FILL_INT; - nc_state_file->d_fillvalue = NC_FILL_DOUBLE; - nc_state_file->f_fillvalue = NC_FILL_FLOAT; - - // set ids to MISSING - nc_state_file->nc_id = MISSING; - nc_state_file->band_dimid = MISSING; - nc_state_file->front_dimid = MISSING; - nc_state_file->frost_dimid = MISSING; - nc_state_file->lake_node_dimid = MISSING; - nc_state_file->layer_dimid = MISSING; - nc_state_file->ni_dimid = MISSING; - nc_state_file->nj_dimid = MISSING; - nc_state_file->node_dimid = MISSING; - nc_state_file->outlet_dimid = MISSING; - nc_state_file->routing_timestep_dimid = MISSING; - nc_state_file->root_zone_dimid = MISSING; - nc_state_file->time_dimid = MISSING; - nc_state_file->veg_dimid = MISSING; - - // Set dimension sizes - nc_state_file->band_size = options.SNOW_BAND; - nc_state_file->front_size = MAX_FRONTS; - nc_state_file->frost_size = options.Nfrost; - nc_state_file->layer_size = options.Nlayer; - nc_state_file->ni_size = global_domain.n_nx; - nc_state_file->nj_size = global_domain.n_ny; - nc_state_file->node_size = options.Nnode; - nc_state_file->outlet_size = rout.rout_param.n_outlets; - nc_state_file->routing_timestep_size = rout.rout_param.full_time_length; - nc_state_file->root_zone_size = options.ROOT_ZONES; - nc_state_file->time_size = NC_UNLIMITED; - nc_state_file->veg_size = options.NVEGTYPES; - - // allocate memory for nc_vars - nc_state_file->nc_vars = - calloc(N_STATE_VARS, sizeof(*(nc_state_file->nc_vars))); - check_alloc_status(nc_state_file->nc_vars, "Memory allocation error"); -} - -/****************************************************************************** - * @brief Setup state variable dimensions, types, etc. - *****************************************************************************/ -void -set_nc_state_var_info(nc_file_struct *nc) -{ - size_t i; - size_t j; - - for (i = 0; i < N_STATE_VARS; i++) { - nc->nc_vars[i].nc_varid = i; - for (j = 0; j < MAXDIMS; j++) { - nc->nc_vars[i].nc_dimids[j] = -1; - nc->nc_vars[i].nc_counts[j] = 0; - } - nc->nc_vars[i].nc_dims = 0; - - switch (i) { - case STATE_SNOW_AGE: - case STATE_SNOW_MELT_STATE: - case STATE_LAKE_SNOW_AGE: - case STATE_LAKE_SNOW_MELT_STATE: - case STATE_LAKE_ACTIVE_LAYERS: - nc->nc_vars[i].nc_type = NC_INT; - break; - default: - nc->nc_vars[i].nc_type = NC_DOUBLE; - } - - // Set the number of dimensions and dimids for each state variable - switch (i) { - case STATE_SOIL_MOISTURE: - // 5d vars [veg, band, layer, j, i] - nc->nc_vars[i].nc_dims = 5; - nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; - nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = 1; - nc->nc_vars[i].nc_counts[2] = 1; - nc->nc_vars[i].nc_counts[3] = nc->nj_size; - nc->nc_vars[i].nc_counts[4] = nc->ni_size; - break; - case STATE_SOIL_ICE: - // 6d vars [veg, band, layer, frost, j, i] - nc->nc_vars[i].nc_dims = 6; - nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->layer_dimid; - nc->nc_vars[i].nc_dimids[3] = nc->frost_dimid; - nc->nc_vars[i].nc_dimids[4] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[5] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = 1; - nc->nc_vars[i].nc_counts[2] = 1; - nc->nc_vars[i].nc_counts[3] = 1; - nc->nc_vars[i].nc_counts[4] = nc->nj_size; - nc->nc_vars[i].nc_counts[5] = nc->ni_size; - break; - case STATE_CANOPY_WATER: - case STATE_ANNUALNPP: - case STATE_ANNUALNPPPREV: - case STATE_CLITTER: - case STATE_CINTER: - case STATE_CSLOW: - case STATE_SNOW_AGE: - case STATE_SNOW_MELT_STATE: - case STATE_SNOW_COVERAGE: - case STATE_SNOW_WATER_EQUIVALENT: - case STATE_SNOW_SURF_TEMP: - case STATE_SNOW_SURF_WATER: - case STATE_SNOW_PACK_TEMP: - case STATE_SNOW_PACK_WATER: - case STATE_SNOW_DENSITY: - case STATE_SNOW_COLD_CONTENT: - case STATE_SNOW_CANOPY: - case STATE_FOLIAGE_TEMPERATURE: - case STATE_ENERGY_LONGUNDEROUT: - case STATE_ENERGY_SNOW_FLUX: - // 4d vars [veg, band, j, i] - nc->nc_vars[i].nc_dims = 4; - nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = 1; - nc->nc_vars[i].nc_counts[2] = nc->nj_size; - nc->nc_vars[i].nc_counts[3] = nc->ni_size; - break; - case STATE_ROUT_RING: - // 2d vars [routing_timestep, outlet] - nc->nc_vars[i].nc_dims = 2; - nc->nc_vars[i].nc_dimids[0] = nc->routing_timestep_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->outlet_dimid; - nc->nc_vars[i].nc_counts[0] = nc->routing_timestep_size; - nc->nc_vars[i].nc_counts[1] = nc->outlet_size; - break; - case STATE_SOIL_NODE_TEMP: - // 5d vars [veg, band, node, j, i] - nc->nc_vars[i].nc_dims = 5; - nc->nc_vars[i].nc_dimids[0] = nc->veg_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->band_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->node_dimid; - nc->nc_vars[i].nc_dimids[3] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[4] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = 1; - nc->nc_vars[i].nc_counts[2] = 1; - nc->nc_vars[i].nc_counts[3] = nc->nj_size; - nc->nc_vars[i].nc_counts[4] = nc->ni_size; - break; - case STATE_AVG_ALBEDO: - // 2d vars [j, i] - nc->nc_vars[i].nc_dims = 2; - nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = nc->nj_size; - nc->nc_vars[i].nc_counts[1] = nc->ni_size; - break; - - case STATE_LAKE_SOIL_MOISTURE: - // 3d vars [layer, j, i] - nc->nc_vars[i].nc_dims = 3; - nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; - break; - case STATE_LAKE_SOIL_ICE: - // 4d vars [layer, frost, j, i] - nc->nc_vars[i].nc_dims = 4; - nc->nc_vars[i].nc_dimids[0] = nc->layer_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->frost_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[3] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = 1; - nc->nc_vars[i].nc_counts[2] = nc->nj_size; - nc->nc_vars[i].nc_counts[3] = nc->ni_size; - break; - case STATE_LAKE_CLITTER: - case STATE_LAKE_CINTER: - case STATE_LAKE_CSLOW: - case STATE_LAKE_SNOW_AGE: - case STATE_LAKE_SNOW_MELT_STATE: - case STATE_LAKE_SNOW_COVERAGE: - case STATE_LAKE_SNOW_WATER_EQUIVALENT: - case STATE_LAKE_SNOW_SURF_TEMP: - case STATE_LAKE_SNOW_SURF_WATER: - case STATE_LAKE_SNOW_PACK_TEMP: - case STATE_LAKE_SNOW_PACK_WATER: - case STATE_LAKE_SNOW_DENSITY: - case STATE_LAKE_SNOW_COLD_CONTENT: - case STATE_LAKE_SNOW_CANOPY: - case STATE_LAKE_ACTIVE_LAYERS: - case STATE_LAKE_LAYER_DZ: - case STATE_LAKE_SURF_LAYER_DZ: - case STATE_LAKE_DEPTH: - case STATE_LAKE_SURF_AREA: - case STATE_LAKE_VOLUME: - case STATE_LAKE_AVERAGE_TEMP: - case STATE_LAKE_ICE_AREA_FRAC: - case STATE_LAKE_ICE_AREA_FRAC_NEW: - case STATE_LAKE_ICE_WATER_EQUIVALENT: - case STATE_LAKE_ICE_HEIGHT: - case STATE_LAKE_ICE_TEMP: - case STATE_LAKE_ICE_SWE: - case STATE_LAKE_ICE_SNOW_SURF_TEMP: - case STATE_LAKE_ICE_SNOW_PACK_TEMP: - case STATE_LAKE_ICE_SNOW_COLD_CONTENT: - case STATE_LAKE_ICE_SNOW_SURF_WATER: - case STATE_LAKE_ICE_SNOW_PACK_WATER: - case STATE_LAKE_ICE_SNOW_ALBEDO: - case STATE_LAKE_ICE_SNOW_DEPTH: - // 2d vars [j, i] - nc->nc_vars[i].nc_dims = 2; - nc->nc_vars[i].nc_dimids[0] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = nc->nj_size; - nc->nc_vars[i].nc_counts[1] = nc->ni_size; - break; - case STATE_LAKE_SOIL_NODE_TEMP: - // 3d vars [node, j, i] - nc->nc_vars[i].nc_dims = 3; - nc->nc_vars[i].nc_dimids[0] = nc->node_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = nc->nj_size; - nc->nc_vars[i].nc_counts[2] = nc->ni_size; - break; - case STATE_LAKE_LAYER_SURF_AREA: - case STATE_LAKE_LAYER_TEMP: - // 3d vars [lake_node, j, i] - nc->nc_vars[i].nc_dims = 3; - nc->nc_vars[i].nc_dimids[0] = nc->lake_node_dimid; - nc->nc_vars[i].nc_dimids[1] = nc->nj_dimid; - nc->nc_vars[i].nc_dimids[2] = nc->ni_dimid; - nc->nc_vars[i].nc_counts[0] = 1; - nc->nc_vars[i].nc_counts[1] = nc->nj_size; - nc->nc_vars[i].nc_counts[2] = nc->ni_size; - break; - default: - log_err("state variable %zu not found when setting dimensions", i); - } - - if (nc->nc_vars[i].nc_dims > MAXDIMS) { - log_err("Too many dimensions specified in variable %zu", i); - } - } -} - -/****************************************************************************** - * @brief Initialize state file by creating dimensions, variables, - and adding metadata. - *****************************************************************************/ -void -initialize_state_file(char *filename, - nc_file_struct *nc_state_file, - dmy_struct *dmy_state) -{ - extern option_struct options; - extern domain_struct global_domain; - extern domain_struct local_domain; - extern global_param_struct global_param; - extern metadata_struct state_metadata[N_STATE_VARS]; - extern soil_con_struct *soil_con; - extern int mpi_rank; - - int status; - int dimids[MAXDIMS]; - int old_fill_mode; - size_t i; - size_t j; - size_t dcount[MAXDIMS]; - size_t dstart[MAXDIMS]; - int lon_var_id; - int lat_var_id; - int veg_var_id; - int snow_band_var_id; - int layer_var_id; - int frost_area_var_id; - int dz_node_var_id; - int node_depth_var_id; - int lake_node_var_id; - char unit_str[MAXSTRING]; - char str[MAXSTRING]; - size_t ndims; - double dtime; - double *dvar = NULL; - int *ivar = NULL; - - // open the netcdf file - if (mpi_rank == VIC_MPI_ROOT) { - status = nc_create(filename, get_nc_mode(options.STATE_FORMAT), - &(nc_state_file->nc_id)); - check_nc_status(status, "Error creating %s", filename); - nc_state_file->open = true; - } - - if (mpi_rank == VIC_MPI_ROOT) { - // Set netcdf file global attributes - set_global_nc_attributes(nc_state_file->nc_id, NC_STATE_FILE); - - // set the NC_FILL attribute - status = nc_set_fill(nc_state_file->nc_id, NC_FILL, &old_fill_mode); - check_nc_status(status, "Error setting fill value in %s", filename); - - // define the time dimension - status = nc_def_dim(nc_state_file->nc_id, "time", - nc_state_file->time_size, - &(nc_state_file->time_dimid)); - check_nc_status(status, "Error defining time dimenension in %s", - filename); - - // define the variable time - status = nc_def_var(nc_state_file->nc_id, "time", NC_DOUBLE, 1, - &(nc_state_file->time_dimid), - &(nc_state_file->time_varid)); - check_nc_status(status, "Error defining time variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, - nc_state_file->time_varid, - "standard_name", strlen("time"), "time"); - check_nc_status(status, "Error adding attribute in %s", filename); - - // adding units attribute to time variable - str_from_time_units(global_param.time_units, unit_str); - - sprintf(str, "%s since %s", unit_str, global_param.time_origin_str); - - status = nc_put_att_text(nc_state_file->nc_id, - nc_state_file->time_varid, - "units", strlen(str), str); - check_nc_status(status, "Error adding attribute in %s", filename); - - // adding calendar attribute to time variable - str_from_calendar(global_param.calendar, str); - - status = nc_put_att_text(nc_state_file->nc_id, - nc_state_file->time_varid, - "calendar", strlen(str), str); - check_nc_status(status, "Error adding calendar attribute in %s", - filename); - - // define netcdf dimensions - status = nc_def_dim(nc_state_file->nc_id, global_domain.info.x_dim, - nc_state_file->ni_size, &(nc_state_file->ni_dimid)); - check_nc_status(status, "Error defining \"%s\" in %s", - global_domain.info.x_dim, - filename); - - status = nc_def_dim(nc_state_file->nc_id, global_domain.info.y_dim, - nc_state_file->nj_size, &(nc_state_file->nj_dimid)); - check_nc_status(status, "Error defining \"%s\" in %s", - global_domain.info.y_dim, - filename); - - status = nc_def_dim(nc_state_file->nc_id, "veg_class", - nc_state_file->veg_size, - &(nc_state_file->veg_dimid)); - check_nc_status(status, "Error defining veg_class in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "snow_band", - nc_state_file->band_size, - &(nc_state_file->band_dimid)); - check_nc_status(status, "Error defining snow_band in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "nlayer", - nc_state_file->layer_size, - &(nc_state_file->layer_dimid)); - check_nc_status(status, "Error defining nlayer in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "frost_area", - nc_state_file->frost_size, - &(nc_state_file->frost_dimid)); - check_nc_status(status, "Error defining frost_area in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "soil_node", - nc_state_file->node_size, - &(nc_state_file->node_dimid)); - check_nc_status(status, "Error defining soil_node in %s", filename); - - // Add routing dimensions - status = nc_def_dim(nc_state_file->nc_id, "outlet", - nc_state_file->outlet_size, - &(nc_state_file->outlet_dimid)); - check_nc_status(status, "Error defining outlet in %s", filename); - - status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", - nc_state_file->routing_timestep_size, - &(nc_state_file->routing_timestep_dimid)); - check_nc_status(status, "Error defining routing_timestep in %s", filename); - - if (options.LAKES) { - status = nc_def_dim(nc_state_file->nc_id, "lake_node", - nc_state_file->lake_node_size, - &(nc_state_file->lake_node_dimid)); - check_nc_status(status, "Error defining lake_node in %s", filename); - } - - set_nc_state_var_info(nc_state_file); - } - - // initialize dimids to invalid values - for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - - // write dimension variables - - // Coordinate variables - if (mpi_rank == VIC_MPI_ROOT) { - ndims = global_domain.info.n_coord_dims; - dstart[0] = 0; - dstart[1] = 0; - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file->ni_dimid; - dcount[0] = nc_state_file->ni_size; - } - else if (global_domain.info.n_coord_dims == 2) { - dimids[0] = nc_state_file->nj_dimid; - dcount[0] = nc_state_file->nj_size; - - dimids[1] = nc_state_file->ni_dimid; - dcount[1] = nc_state_file->ni_size; - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); - } - } - - // define the netcdf variable longitude - if (mpi_rank == VIC_MPI_ROOT) { - status = nc_def_var(nc_state_file->nc_id, global_domain.info.lon_var, - NC_DOUBLE, ndims, dimids, &(lon_var_id)); - check_nc_status(status, "Error defining lon variable in %s", filename); - - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "long_name", strlen( - "longitude"), "longitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, "units", strlen( - "degrees_east"), "degrees_east"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lon_var_id, - "standard_name", strlen( - "longitude"), "longitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - - if (global_domain.info.n_coord_dims == 1) { - dimids[0] = nc_state_file->nj_dimid; - dcount[0] = nc_state_file->nj_size; - } - - // define the netcdf variable latitude - status = nc_def_var(nc_state_file->nc_id, global_domain.info.lat_var, - NC_DOUBLE, ndims, dimids, &(lat_var_id)); - check_nc_status(status, "Error defining lat variable (%s) in %s", - global_domain.info.lat_var, filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "long_name", strlen( - "latitude"), "latitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, "units", strlen( - "degrees_north"), "degrees_north"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, lat_var_id, - "standard_name", strlen("latitude"), - "latitude"); - check_nc_status(status, "Error adding attribute in %s", filename); - for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - - // veg_class - dimids[0] = nc_state_file->veg_dimid; - status = nc_def_var(nc_state_file->nc_id, "veg_class", - NC_INT, 1, dimids, &(veg_var_id)); - check_nc_status(status, "Error defining veg_class variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, "long_name", - strlen("veg_class"), "veg_class"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, veg_var_id, - "standard_name", - strlen("vegetation_class_number"), - "vegetation_class_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // snow_band - dimids[0] = nc_state_file->band_dimid; - status = nc_def_var(nc_state_file->nc_id, "snow_band", - NC_INT, 1, dimids, &(snow_band_var_id)); - check_nc_status(status, "Error defining snow_band variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, - "long_name", - strlen("snow_band"), "snow_band"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, snow_band_var_id, - "standard_name", - strlen("snow_elevation_band_number"), - "snow_elevation_band_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // layer - dimids[0] = nc_state_file->layer_dimid; - status = - nc_def_var(nc_state_file->nc_id, "layer", NC_INT, 1, dimids, - &(layer_var_id)); - check_nc_status(status, "Error defining layer variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, - "long_name", - strlen("layer"), "layer"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, layer_var_id, - "standard_name", strlen("soil_layer_number"), - "soil_layer_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // frost_area - dimids[0] = nc_state_file->frost_dimid; - status = nc_def_var(nc_state_file->nc_id, "frost_area", NC_INT, 1, - dimids, &(frost_area_var_id)); - check_nc_status(status, "Error defining frost_area variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, - "long_name", - strlen("frost_area"), "frost_area"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, frost_area_var_id, - "standard_name", strlen("frost_area_number"), - "frost_area_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - - // dz_node (dimension: node, lat, lon) - dimids[0] = nc_state_file->node_dimid; - dimids[1] = nc_state_file->nj_dimid; - dimids[2] = nc_state_file->ni_dimid; - status = nc_def_var(nc_state_file->nc_id, "dz_node", NC_DOUBLE, 3, - dimids, &(dz_node_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "long_name", - strlen("dz_node"), "dz_node"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "standard_name", strlen( - "soil_thermal_node_spacing"), - "soil_thermal_node_spacing"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, "units", - strlen("m"), "m"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - dimids[1] = -1; - dimids[2] = -1; - - // node_depth (dimension: node, lat, lon) - dimids[0] = nc_state_file->node_dimid; - dimids[1] = nc_state_file->nj_dimid; - dimids[2] = nc_state_file->ni_dimid; - status = nc_def_var(nc_state_file->nc_id, "node_depth", NC_DOUBLE, 3, - dimids, &(node_depth_var_id)); - check_nc_status(status, "Error defining node variable in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "long_name", - strlen("node_depth"), "node_depth"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "standard_name", - strlen("soil_thermal_node_depth"), - "soil_thermal_node_depth"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, node_depth_var_id, - "units", - strlen("m"), "m"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - dimids[1] = -1; - dimids[2] = -1; - - if (options.LAKES) { - // lake_node - dimids[0] = nc_state_file->lake_node_dimid; - status = nc_def_var(nc_state_file->nc_id, "lake_node", NC_INT, 1, - dimids, &(lake_node_var_id)); - check_nc_status(status, "Error defining node variable in %s", - filename); - status = nc_put_att_text(nc_state_file->nc_id, lake_node_var_id, - "long_name", - strlen("lake_node"), "lake_node"); - check_nc_status(status, "Error adding attribute in %s", filename); - status = nc_put_att_text(nc_state_file->nc_id, dz_node_var_id, - "standard_name", strlen( - "lake_node_number"), - "lake_node_number"); - check_nc_status(status, "Error adding attribute in %s", filename); - dimids[0] = -1; - } - } - - // Define state variables - if (mpi_rank == VIC_MPI_ROOT) { - for (i = 0; i < N_STATE_VARS; i++) { - if (strcasecmp(state_metadata[i].varname, MISSING_S) == 0) { - // skip variables not set in set_state_meta_data_info - continue; - } - - // create the variable - status = nc_def_var(nc_state_file->nc_id, state_metadata[i].varname, - nc_state_file->nc_vars[i].nc_type, - nc_state_file->nc_vars[i].nc_dims, - nc_state_file->nc_vars[i].nc_dimids, - &(nc_state_file->nc_vars[i].nc_varid)); - check_nc_status(status, "Error defining state variable %s in %s", - state_metadata[i].varname, filename); - - // set the fill value attribute - if (nc_state_file->nc_vars[i].nc_type == NC_DOUBLE) { - status = nc_put_att_double(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "_FillValue", NC_DOUBLE, 1, - &(nc_state_file->d_fillvalue)); - } - else if (nc_state_file->nc_vars[i].nc_type == NC_INT) { - status = nc_put_att_int(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "_FillValue", NC_INT, 1, - &(nc_state_file->i_fillvalue)); - } - else { - log_err("NC_TYPE %d not supported at this time", - nc_state_file->nc_vars[i].nc_type); - } - check_nc_status(status, - "Error putting _FillValue attribute to %s in %s", - state_metadata[i].varname, filename); - - // Set string attributes - put_nc_attr(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "long_name", state_metadata[i].long_name); - put_nc_attr(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "standard_name", state_metadata[i].standard_name); - put_nc_attr(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "units", state_metadata[i].units); - put_nc_attr(nc_state_file->nc_id, - nc_state_file->nc_vars[i].nc_varid, - "description", state_metadata[i].description); - } - - // leave define mode - status = nc_enddef(nc_state_file->nc_id); - check_nc_status(status, "Error leaving define mode for %s", filename); - } - - // time variable - if (mpi_rank == VIC_MPI_ROOT) { - dtime = date2num(global_param.time_origin_num, dmy_state, 0, - global_param.calendar, global_param.time_units); - // put in netCDF file - dstart[0] = 0; - status = nc_put_var1_double(nc_state_file->nc_id, - nc_state_file->time_varid, - dstart, &dtime); - check_nc_status(status, "Error writing time variable"); - } - - // populate lat/lon - if (mpi_rank == VIC_MPI_ROOT) { - if (global_domain.info.n_coord_dims == 1) { - dvar = calloc(nc_state_file->ni_size, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - dcount[0] = nc_state_file->ni_size; - // implicitly nested loop over ni and nj with j set to 0 - for (i = 0; i < nc_state_file->ni_size; i++) { - dvar[i] = (double) global_domain.locations[i].longitude; - } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, - dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - free(dvar); - - dvar = calloc(nc_state_file->nj_size, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - dcount[0] = nc_state_file->nj_size; - // implicitly nested loop over ni and nj with i set to 0; - // j stride = ni_size - for (j = 0; j < nc_state_file->nj_size; j++) { - dvar[j] = - (double) global_domain.locations[j * - nc_state_file->ni_size]. - latitude; - } - - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, - dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - free(dvar); - } - else if (global_domain.info.n_coord_dims == 2) { - dvar = calloc(global_domain.ncells_total, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - dcount[0] = nc_state_file->nj_size; - dcount[1] = nc_state_file->ni_size; - - for (i = 0; i < global_domain.ncells_total; i++) { - dvar[i] = (double) global_domain.locations[i].longitude; - } - status = nc_put_vara_double(nc_state_file->nc_id, lon_var_id, - dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lon in %s", filename); - - for (i = 0; i < global_domain.ncells_total; - i++) { - dvar[i] = (double) global_domain.locations[i].latitude; - } - status = nc_put_vara_double(nc_state_file->nc_id, lat_var_id, - dstart, - dcount, dvar); - check_nc_status(status, "Error adding data to lat in %s", filename); - - free(dvar); - } - else { - log_err("COORD_DIMS_OUT should be 1 or 2"); - } - } - - // Variables for other dimensions (all 1-dimensional) - if (mpi_rank == VIC_MPI_ROOT) { - ndims = 1; - - // vegetation classes - dimids[0] = nc_state_file->veg_dimid; - dcount[0] = nc_state_file->veg_size; - ivar = malloc(nc_state_file->veg_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->veg_size; j++) { - ivar[j] = (int) j + 1; - } - status = nc_put_vara_int(nc_state_file->nc_id, veg_var_id, dstart, - dcount, - ivar); - check_nc_status(status, "Error writing veg var id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - - // snow bands - dimids[0] = nc_state_file->band_dimid; - dcount[0] = nc_state_file->band_size; - ivar = malloc(nc_state_file->band_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->band_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, snow_band_var_id, dstart, - dcount, ivar); - check_nc_status(status, "Error writing snow band id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - - // soil layers - dimids[0] = nc_state_file->layer_dimid; - dcount[0] = nc_state_file->layer_size; - ivar = malloc(nc_state_file->layer_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->layer_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, layer_var_id, dstart, - dcount, - ivar); - check_nc_status(status, "Error writing layer id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - - // frost areas - dimids[0] = nc_state_file->frost_dimid; - dcount[0] = nc_state_file->frost_size; - ivar = malloc(nc_state_file->frost_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->frost_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, frost_area_var_id, - dstart, - dcount, ivar); - check_nc_status(status, "Error writing frost id"); - for (i = 0; i < ndims; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - } - - // initialize dvar for soil thermal node deltas and depths - dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - // set missing values - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file->d_fillvalue; - } - - // soil thermal node deltas (dimension: node, lat, lon) - dstart[0] = 0; - dstart[1] = 0; - dstart[2] = 0; - dcount[0] = 1; - dcount[1] = nc_state_file->nj_size; - dcount[2] = nc_state_file->ni_size; - for (j = 0; j < nc_state_file->node_size; j++) { - dstart[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = soil_con[i].dz_node[j]; - } - gather_put_nc_field_double(nc_state_file->nc_id, - dz_node_var_id, - nc_state_file->d_fillvalue, - dstart, dcount, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file->d_fillvalue; - } - } - - // soil thermal node depths (dimension: node, lat, lon) - dstart[0] = 0; - dstart[1] = 0; - dstart[2] = 0; - dcount[0] = 1; - dcount[1] = nc_state_file->nj_size; - dcount[2] = nc_state_file->ni_size; - for (j = 0; j < nc_state_file->node_size; j++) { - dstart[0] = j; - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = soil_con[i].Zsum_node[j]; - } - gather_put_nc_field_double(nc_state_file->nc_id, - node_depth_var_id, - nc_state_file->d_fillvalue, - dstart, dcount, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - dvar[i] = nc_state_file->d_fillvalue; - } - } - free(dvar); - - if (options.LAKES) { - // lake nodes - dimids[0] = nc_state_file->lake_node_dimid; - dcount[0] = nc_state_file->lake_node_size; - ivar = malloc(nc_state_file->lake_node_size * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - for (j = 0; j < nc_state_file->lake_node_size; j++) { - ivar[j] = (int) j; - } - status = nc_put_vara_int(nc_state_file->nc_id, lake_node_var_id, dstart, - dcount, ivar); - check_nc_status(status, "Error writing lake nodes"); - - for (i = 0; i < MAXDIMS; i++) { - dimids[i] = -1; - dcount[i] = 0; - } - free(ivar); - } -} diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c new file mode 100644 index 000000000..294d45f4b --- /dev/null +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -0,0 +1,170 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +vic_store_extension(dmy_struct *dmy_state, + char *filename) +{ + extern filenames_struct filenames; + extern int mpi_rank; + extern rout_struct rout; + + int status; + size_t d2start[2]; + nc_file_struct nc_state_file; + nc_var_struct *nc_var; + + set_nc_state_file_info(&nc_state_file); + + // create netcdf file for storing model state + sprintf(filename, "%s.%04i%02i%02i_%05u.nc", + filenames.statefile, dmy_state->year, + dmy_state->month, dmy_state->day, + dmy_state->dayseconds); + + initialize_state_file(filename, &nc_state_file, dmy_state); + + // open the netcdf file if it is closed + if (mpi_rank == VIC_MPI_ROOT) { + if (nc_state_file.open == false) { + status = nc_open(filename, NC_WRITE, + &(nc_state_file.nc_id)); + check_nc_status(status, "Error opening %s", + filename); + } + } + + // write state variables + + // routing ring + if (mpi_rank == VIC_MPI_ROOT) { + d2start[0] = 0; + d2start[1] = 0; + nc_var = &(nc_state_file.nc_vars[N_STATE_VARS + STATE_ROUT_RING]); + + status = + nc_put_vara_double(nc_state_file.nc_id, nc_var->nc_varid, d2start, + nc_var->nc_counts, + rout.ring); + check_nc_status(status, "Error writing values."); + } + + // close the netcdf file if it is still open + if (mpi_rank == VIC_MPI_ROOT) { + if (nc_state_file.open == true) { + status = nc_close(nc_state_file.nc_id); + check_nc_status(status, "Error closing %s", filename); + } + } + + free(nc_state_file.nc_vars); +} + +/****************************************************************************** + * @brief Setup state file netcdf structure + *****************************************************************************/ +void +set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +{ + extern rout_struct rout; + + // set ids to MISSING + nc_state_file->outlet_dimid = MISSING; + nc_state_file->routing_timestep_dimid = MISSING; + + // set dimension sizes + nc_state_file->outlet_size = rout.rout_param.n_outlets; + nc_state_file->routing_timestep_size = rout.rout_param.full_time_length; + +} + +/****************************************************************************** + * @brief Setup state variable dimensions, types, etc. + *****************************************************************************/ +void +set_nc_state_var_info_extension(nc_file_struct *nc) +{ + size_t i; + size_t j; + + for (i = N_STATE_VARS; i < (N_STATE_VARS + N_STATE_VARS_EXT); i++) { + nc->nc_vars[i].nc_varid = i; + for (j = 0; j < MAXDIMS; j++) { + nc->nc_vars[i].nc_dimids[j] = -1; + nc->nc_vars[i].nc_counts[j] = 0; + } + nc->nc_vars[i].nc_dims = 0; + nc->nc_vars[i].nc_type = NC_DOUBLE; + + // Set the number of dimensions and dimids for each state variable + switch (i) { + + case (N_STATE_VARS + STATE_ROUT_RING): + // 2d vars [routing_timestep, outlet] + nc->nc_vars[i].nc_dims = 2; + nc->nc_vars[i].nc_dimids[0] = nc->routing_timestep_dimid; + nc->nc_vars[i].nc_dimids[1] = nc->outlet_dimid; + nc->nc_vars[i].nc_counts[0] = nc->routing_timestep_size; + nc->nc_vars[i].nc_counts[1] = nc->outlet_size; + break; + default: + log_err("state variable %zu not found when setting dimensions", i); + } + + if (nc->nc_vars[i].nc_dims > MAXDIMS) { + log_err("Too many dimensions specified in variable %zu", i); + } + } +} + +/****************************************************************************** + * @brief Initialize state file by creating dimensions, variables, + and adding metadata. + *****************************************************************************/ +void +initialize_state_file_extension(char *filename, + nc_file_struct *nc_state_file) +{ + int status; + + // Add routing dimensions + status = nc_def_dim(nc_state_file->nc_id, "outlet", + nc_state_file->outlet_size, + &(nc_state_file->outlet_dimid)); + check_nc_status(status, "Error defining outlet in %s", filename); + + status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", + nc_state_file->routing_timestep_size, + &(nc_state_file->routing_timestep_dimid)); + check_nc_status(status, "Error defining routing_timestep in %s", filename); + +} diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index db757a5a9..aaacaa184 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -30,6 +30,7 @@ #define ROUT_EXT "rout_stub" #include +#include /****************************************************************************** * @brief Routing Structs @@ -54,4 +55,18 @@ void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing +void vic_store_extension(dmy_struct *, char *); +void set_nc_state_file_info_extension(nc_file_struct *); +void set_nc_state_var_info_extension(nc_file_struct *); +void initialize_state_file_extension(char *, nc_file_struct *); +/****************************************************************************** + * @brief Output state variable. + *****************************************************************************/ +enum +{ + // Last value of enum - DO NOT ADD ANYTHING BELOW THIS LINE!! + // used as a loop counter and must be >= the largest value in this enum + N_STATE_VARS_EXT /**< used as a loop counter*/ +}; + #endif diff --git a/vic/extensions/rout_stub/src/vic_store_extension.c b/vic/extensions/rout_stub/src/vic_store_extension.c new file mode 100644 index 000000000..feaea0bb7 --- /dev/null +++ b/vic/extensions/rout_stub/src/vic_store_extension.c @@ -0,0 +1,63 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +vic_store_extension(dmy_struct *dmy_state, + char *filename) +{ +} + +/****************************************************************************** + * @brief Setup state file netcdf structure + *****************************************************************************/ +void +set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +{ +} + +/****************************************************************************** + * @brief Setup state variable dimensions, types, etc. + *****************************************************************************/ +void +set_nc_state_var_info_extension(nc_file_struct *nc) +{ +} + +/****************************************************************************** + * @brief Initialize state file by creating dimensions, variables, + and adding metadata. + *****************************************************************************/ +void +initialize_state_file_extension(char *filename, + nc_file_struct *nc_state_file) +{ +} From 23cfe54f05a2a985929fb9483faa16b33c95500a Mon Sep 17 00:00:00 2001 From: ymao Date: Fri, 13 Oct 2017 12:02:05 -0700 Subject: [PATCH 219/294] Clean up vic_store.c and related extension --- vic/drivers/shared_image/src/vic_store.c | 7 ++-- vic/extensions/rout_rvic/include/rout.h | 2 +- .../rout_rvic/src/vic_store_extension.c | 39 ++----------------- vic/extensions/rout_stub/include/rout.h | 2 +- .../rout_stub/src/vic_store_extension.c | 3 +- 5 files changed, 10 insertions(+), 43 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 0060ec746..61ebbf12a 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -115,9 +115,6 @@ vic_store(dmy_struct *dmy_state, dvar[i] = nc_state_file.d_fillvalue; } - // store extension variables - vic_store_extension(dmy_state, filename); - // total soil moisture nc_var = &(nc_state_file.nc_vars[STATE_SOIL_MOISTURE]); for (m = 0; m < options.NVEGTYPES; m++) { @@ -1273,6 +1270,10 @@ vic_store(dmy_struct *dmy_state, } } + // store extension variables + vic_store_extension(&nc_state_file); + + // close the netcdf file if it is still open if (mpi_rank == VIC_MPI_ROOT) { if (nc_state_file.open == true) { diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index c5685b1b0..83e9e551a 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -82,7 +82,7 @@ void gather_var_double(double *, double *); *****************************************************************************/ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); -void vic_store_extension(dmy_struct *, char *); +void vic_store_extension(nc_file_struct *); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c index 294d45f4b..19842d64f 100644 --- a/vic/extensions/rout_rvic/src/vic_store_extension.c +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -31,62 +31,29 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(dmy_struct *dmy_state, - char *filename) +vic_store_extension(nc_file_struct *nc_state_file) { - extern filenames_struct filenames; extern int mpi_rank; extern rout_struct rout; int status; size_t d2start[2]; - nc_file_struct nc_state_file; nc_var_struct *nc_var; - set_nc_state_file_info(&nc_state_file); - - // create netcdf file for storing model state - sprintf(filename, "%s.%04i%02i%02i_%05u.nc", - filenames.statefile, dmy_state->year, - dmy_state->month, dmy_state->day, - dmy_state->dayseconds); - - initialize_state_file(filename, &nc_state_file, dmy_state); - - // open the netcdf file if it is closed - if (mpi_rank == VIC_MPI_ROOT) { - if (nc_state_file.open == false) { - status = nc_open(filename, NC_WRITE, - &(nc_state_file.nc_id)); - check_nc_status(status, "Error opening %s", - filename); - } - } - // write state variables // routing ring if (mpi_rank == VIC_MPI_ROOT) { d2start[0] = 0; d2start[1] = 0; - nc_var = &(nc_state_file.nc_vars[N_STATE_VARS + STATE_ROUT_RING]); + nc_var = &(nc_state_file->nc_vars[N_STATE_VARS + STATE_ROUT_RING]); status = - nc_put_vara_double(nc_state_file.nc_id, nc_var->nc_varid, d2start, + nc_put_vara_double(nc_state_file->nc_id, nc_var->nc_varid, d2start, nc_var->nc_counts, rout.ring); check_nc_status(status, "Error writing values."); } - - // close the netcdf file if it is still open - if (mpi_rank == VIC_MPI_ROOT) { - if (nc_state_file.open == true) { - status = nc_close(nc_state_file.nc_id); - check_nc_status(status, "Error closing %s", filename); - } - } - - free(nc_state_file.nc_vars); } /****************************************************************************** diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index aaacaa184..e78698991 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -55,7 +55,7 @@ void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing -void vic_store_extension(dmy_struct *, char *); +void vic_store_extension(nc_file_struct *); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_stub/src/vic_store_extension.c b/vic/extensions/rout_stub/src/vic_store_extension.c index feaea0bb7..e81105faa 100644 --- a/vic/extensions/rout_stub/src/vic_store_extension.c +++ b/vic/extensions/rout_stub/src/vic_store_extension.c @@ -31,8 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(dmy_struct *dmy_state, - char *filename) +vic_store_extension(nc_file_struct *nc_state_file) { } From 1ef2e9b80db3a3deb809c837fcc7b9496b8ca72b Mon Sep 17 00:00:00 2001 From: ymao Date: Fri, 13 Oct 2017 13:51:27 -0700 Subject: [PATCH 220/294] Moved vic_restore.c back to "shared_image/src" and cleaned up extension --- .../shared_image}/src/vic_restore.c | 11 +- vic/extensions/rout_rvic/include/rout.h | 1 + vic/extensions/rout_rvic/src/vic_restore.c | 1134 ----------------- .../rout_rvic/src/vic_restore_extension.c | 58 + vic/extensions/rout_stub/include/rout.h | 1 + .../rout_stub/src/vic_restore_extension.c | 38 + 6 files changed, 105 insertions(+), 1138 deletions(-) rename vic/{extensions/rout_stub => drivers/shared_image}/src/vic_restore.c (99%) delete mode 100644 vic/extensions/rout_rvic/src/vic_restore.c create mode 100644 vic/extensions/rout_rvic/src/vic_restore_extension.c create mode 100644 vic/extensions/rout_stub/src/vic_restore_extension.c diff --git a/vic/extensions/rout_stub/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c similarity index 99% rename from vic/extensions/rout_stub/src/vic_restore.c rename to vic/drivers/shared_image/src/vic_restore.c index 5210edeb5..58df905c7 100644 --- a/vic/extensions/rout_stub/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -40,9 +40,8 @@ vic_restore(void) extern option_struct options; extern veg_con_map_struct *veg_con_map; extern filenames_struct filenames; - extern metadata_struct state_metadata[N_STATE_VARS]; - extern int mpi_rank; - + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; + int v; size_t i; size_t j; @@ -884,6 +883,9 @@ vic_restore(void) } } + // routing ring + vic_restore_extension(&(filenames.init_state), &state_metadata); + free(ivar); free(dvar); @@ -908,7 +910,8 @@ check_init_state_file(void) extern option_struct options; extern soil_con_struct *soil_con; extern int mpi_rank; - + extern rout_struct rout; + int status; size_t dimlen; size_t i; diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 83e9e551a..7110d96eb 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -83,6 +83,7 @@ void gather_var_double(double *, double *); void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); void vic_store_extension(nc_file_struct *); +void vic_restore_extension(nameid_struct *, metadata_struct *); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_rvic/src/vic_restore.c b/vic/extensions/rout_rvic/src/vic_restore.c deleted file mode 100644 index fc63c2891..000000000 --- a/vic/extensions/rout_rvic/src/vic_restore.c +++ /dev/null @@ -1,1134 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * Read initial model state. - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 -#include - -/****************************************************************************** - * @brief Read initial model state. - *****************************************************************************/ -void -vic_restore(void) -{ - extern int mpi_rank; - extern all_vars_struct *all_vars; - extern domain_struct global_domain; - extern domain_struct local_domain; - extern option_struct options; - extern veg_con_map_struct *veg_con_map; - extern filenames_struct filenames; - extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; - extern int mpi_rank; - extern rout_struct rout; - - int v; - size_t i; - size_t j; - size_t k; - size_t m; - size_t p; - int *ivar = NULL; - int status; - double *dvar = NULL; - size_t d2count_rout[2]; - size_t d2count[2]; - size_t d2start[2]; - size_t d3count[3]; - size_t d3start[3]; - size_t d4count[4]; - size_t d4start[4]; - size_t d5count[5]; - size_t d5start[5]; - size_t d6count[6]; - size_t d6start[6]; - - if (mpi_rank == VIC_MPI_ROOT) { - // open initial state file - status = nc_open(filenames.init_state.nc_filename, NC_NOWRITE, - &(filenames.init_state.nc_id)); - check_nc_status(status, "Error opening %s", - filenames.init_state.nc_filename); - } - - // validate state file dimensions and coordinate variables - check_init_state_file(); - // read state variables - - // allocate memory for variables to be stored - ivar = malloc(local_domain.ncells_active * sizeof(*ivar)); - check_alloc_status(ivar, "Memory allocation error"); - - dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - // initialize starts and counts - d2start[0] = 0; - d2start[1] = 0; - d2count[0] = global_domain.n_ny; - d2count[1] = global_domain.n_nx; - - d3start[0] = 0; - d3start[1] = 0; - d3start[2] = 0; - d3count[0] = 1; - d3count[1] = global_domain.n_ny; - d3count[2] = global_domain.n_nx; - - d4start[0] = 0; - d4start[1] = 0; - d4start[2] = 0; - d4start[3] = 0; - d4count[0] = 1; - d4count[1] = 1; - d4count[2] = global_domain.n_ny; - d4count[3] = global_domain.n_nx; - - d5start[0] = 0; - d5start[1] = 0; - d5start[2] = 0; - d5start[3] = 0; - d5start[4] = 0; - d5count[0] = 1; - d5count[1] = 1; - d5count[2] = 1; - d5count[3] = global_domain.n_ny; - d5count[4] = global_domain.n_nx; - - d6start[0] = 0; - d6start[1] = 0; - d6start[2] = 0; - d6start[3] = 0; - d6start[4] = 0; - d6start[5] = 0; - d6count[0] = 1; - d6count[1] = 1; - d6count[2] = 1; - d6count[3] = 1; - d6count[4] = global_domain.n_ny; - d6count[5] = global_domain.n_nx; - - // routing ring - if (mpi_rank == VIC_MPI_ROOT) { - d2start[0] = 0; - d2start[1] = 0; - d2count_rout[0] = rout.rout_param.full_time_length; - d2count_rout[1] = rout.rout_param.n_outlets; - - get_nc_field_double(&(filenames.init_state), - state_metadata[STATE_ROUT_RING].varname, - d2start, d2count_rout, rout.ring); - } - - // total soil moisture - for (m = 0; m < options.NVEGTYPES; m++) { - d5start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d5start[1] = k; - for (j = 0; j < options.Nlayer; j++) { - d5start[2] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SOIL_MOISTURE].varname, - d5start, d5count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].cell[v][k].layer[j].moist = dvar[i]; - } - } - } - } - } - - // ice content - for (m = 0; m < options.NVEGTYPES; m++) { - d6start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d6start[1] = k; - for (j = 0; j < options.Nlayer; j++) { - d6start[2] = j; - for (p = 0; p < options.Nfrost; p++) { - d6start[3] = p; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SOIL_ICE].varname, - d6start, d6count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].cell[v][k].layer[j].ice[p] = dvar[i]; - } - } - } - } - } - } - - // dew storage: tmpval = veg_var[veg][band].Wdew; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_CANOPY_WATER].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].veg_var[v][k].Wdew = dvar[i]; - } - } - } - } - - if (options.CARBON) { - // cumulative NPP: tmpval = veg_var[veg][band].AnnualNPP; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_ANNUALNPP].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].veg_var[v][k].AnnualNPP = dvar[i]; - } - } - } - } - - // previous NPP: tmpval = veg_var[veg][band].AnnualNPPPrev; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_ANNUALNPPPREV].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].veg_var[v][k].AnnualNPPPrev = dvar[i]; - } - } - } - } - - // litter carbon: tmpval = cell[veg][band].CLitter; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_CLITTER].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].cell[v][k].CLitter = dvar[i]; - } - } - } - } - - // intermediate carbon: tmpval = cell[veg][band].CInter; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_CINTER].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].cell[v][k].CInter = dvar[i]; - } - } - } - } - - // slow carbon: tmpval = cell[veg][band].CSlow; - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_CSLOW].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].cell[v][k].CSlow = dvar[i]; - } - } - } - } - } - - // snow age: snow[veg][band].last_snow - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_int(&(filenames.init_state), - state_metadata[STATE_SNOW_AGE].varname, - d4start, d4count, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].last_snow = ivar[i]; - } - } - } - } - - // melting state: (int)snow[veg][band].MELTING - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_int(&(filenames.init_state), - state_metadata[STATE_SNOW_MELT_STATE].varname, - d4start, d4count, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].MELTING = ivar[i]; - } - } - } - } - - // snow covered fraction: snow[veg][band].coverage - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_COVERAGE].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].coverage = dvar[i]; - } - } - } - } - - // snow water equivalent: snow[veg][band].swq - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_SNOW_WATER_EQUIVALENT].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].swq = dvar[i]; - } - } - } - } - - // snow surface temperature: snow[veg][band].surf_temp - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_SURF_TEMP].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].surf_temp = dvar[i]; - } - } - } - } - - // snow surface water: snow[veg][band].surf_water - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_SURF_WATER].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].surf_water = dvar[i]; - } - } - } - } - - // snow pack temperature: snow[veg][band].pack_temp - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_PACK_TEMP].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].pack_temp = dvar[i]; - } - } - } - } - - // snow pack water: snow[veg][band].pack_water - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_PACK_WATER].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].pack_water = dvar[i]; - } - } - } - } - - // snow density: snow[veg][band].density - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_DENSITY].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].density = dvar[i]; - } - } - } - } - - // snow cold content: snow[veg][band].coldcontent - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_COLD_CONTENT].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].coldcontent = dvar[i]; - } - } - } - } - - // snow canopy storage: snow[veg][band].snow_canopy - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SNOW_CANOPY].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].snow[v][k].snow_canopy = dvar[i]; - } - } - } - } - - // grid cell-averaged albedo: gridcell_avg.avg_albedo - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_AVG_ALBEDO].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].gridcell_avg.avg_albedo = dvar[i]; - } - - // soil node temperatures: energy[veg][band].T[nidx] - for (m = 0; m < options.NVEGTYPES; m++) { - d5start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d5start[1] = k; - for (j = 0; j < options.Nnode; j++) { - d5start[2] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_SOIL_NODE_TEMP].varname, - d5start, d5count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].energy[v][k].T[j] = dvar[i]; - } - } - } - } - } - - // Foliage temperature: energy[veg][band].Tfoliage - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].energy[v][k].Tfoliage = dvar[i]; - } - } - } - } - - // Outgoing longwave from understory: energy[veg][band].LongUnderOut - // This is a flux. Saving it to state file is a temporary solution!! - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].energy[v][k].LongUnderOut = dvar[i]; - } - } - } - } - - // Thermal flux through the snow pack: energy[veg][band].snow_flux - // This is a flux. Saving it to state file is a temporary solution!! - for (m = 0; m < options.NVEGTYPES; m++) { - d4start[0] = m; - for (k = 0; k < options.SNOW_BAND; k++) { - d4start[1] = k; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_ENERGY_SNOW_FLUX].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - v = veg_con_map[i].vidx[m]; - if (v >= 0) { - all_vars[i].energy[v][k].snow_flux = dvar[i]; - } - } - } - } - - if (options.LAKES) { - // total soil moisture - for (j = 0; j < options.Nlayer; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; - } - } - - // ice content - for (j = 0; j < options.Nlayer; j++) { - d4start[0] = j; - for (p = 0; p < options.Nfrost; p++) { - d4start[1] = p; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SOIL_ICE].varname, - d4start, d4count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.layer[j].ice[p] = dvar[i]; - } - } - } - - if (options.CARBON) { - // litter carbon: tmpval = lake_var.soil.CLitter; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_CLITTER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.CLitter = dvar[i]; - } - - // intermediate carbon: tmpval = lake_var.soil.CInter; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_CINTER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.CInter = dvar[i]; - } - - // slow carbon: tmpval = lake_var.soil.CSlow; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_CSLOW].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.CSlow = dvar[i]; - } - } - - // snow age: lake_var.snow.last_snow - get_scatter_nc_field_int(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_AGE].varname, - d2start, d2count, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.last_snow = ivar[i]; - } - - // melting state: (int)lake_var.snow.MELTING - get_scatter_nc_field_int(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, - d2start, d2count, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.MELTING = ivar[i]; - } - - // snow covered fraction: lake_var.snow.coverage - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.coverage = dvar[i]; - } - - // snow water equivalent: lake_var.snow.swq - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.swq = dvar[i]; - } - - // snow surface temperature: lake_var.snow.surf_temp - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.surf_temp = dvar[i]; - } - - // snow surface water: lake_var.snow.surf_water - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.surf_water = dvar[i]; - } - - // snow pack temperature: lake_var.snow.pack_temp - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.pack_temp = dvar[i]; - } - - // snow pack water: lake_var.snow.pack_water - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.pack_water = dvar[i]; - } - - // snow density: lake_var.snow.density - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.density = dvar[i]; - } - - // snow cold content: lake_var.snow.coldcontent - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.coldcontent = dvar[i]; - } - - // snow canopy storage: lake_var.snow.snow_canopy - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SNOW_CANOPY].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.snow.snow_canopy = dvar[i]; - } - - // soil node temperatures: lake_var.energy.T[nidx] - for (j = 0; j < options.Nnode; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.soil.layer[j].moist = dvar[i]; - } - } - - // lake active layers: lake_var.activenod - get_scatter_nc_field_int(&(filenames.init_state), - state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, - d2start, d2count, ivar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.activenod = ivar[i]; - } - - // lake layer thickness: lake_var.dz - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_LAYER_DZ].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.dz = dvar[i]; - } - - // lake surface layer thickness: lake_var.surfdz - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.surfdz = dvar[i]; - } - - // lake depth: lake_var.ldepth - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_DEPTH].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.ldepth = dvar[i]; - } - - // lake layer surface areas: lake_var.surface[ndix] - for (j = 0; j < options.NLAKENODES; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_LAYER_SURF_AREA].varname, - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.surface[j] = dvar[i]; - } - } - - // lake surface area: lake_var.sarea - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_SURF_AREA].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.sarea = dvar[i]; - } - - // lake volume: lake_var.volume - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_VOLUME].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.volume = dvar[i]; - } - - // lake layer temperatures: lake_var.temp[nidx] - for (j = 0; j < options.NLAKENODES; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_LAYER_TEMP].varname, - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.temp[j] = dvar[i]; - } - } - - // vertical average lake temperature: lake_var.tempavg - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.tempavg = dvar[i]; - } - - // lake ice area fraction: lake_var.areai - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.areai = dvar[i]; - } - - // new lake ice area fraction: lake_var.new_ice_area - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.new_ice_area = dvar[i]; - } - - // lake ice water equivalent: lake_var.ice_water_eq - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_ICE_WATER_EQUIVALENT].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.ice_water_eq = dvar[i]; - } - - // lake ice height: lake_var.hice - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_HEIGHT].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.hice = dvar[i]; - } - - // lake ice temperature: lake_var.tempi - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.tempi = dvar[i]; - } - - // lake ice snow water equivalent: lake_var.swe - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_SWE].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.swe = dvar[i]; - } - - // lake ice snow surface temperature: lake_var.surf_temp - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.surf_temp = dvar[i]; - } - - // lake ice snow pack temperature: lake_var.pack_temp - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.pack_temp = dvar[i]; - } - - // lake ice snow coldcontent: lake_var.coldcontent - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.coldcontent = dvar[i]; - } - - // lake ice snow surface water: lake_var.surf_water - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_ICE_SNOW_SURF_WATER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.surf_water = dvar[i]; - } - - // lake ice snow pack water: lake_var.pack_water - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[ - STATE_LAKE_ICE_SNOW_PACK_WATER].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.pack_water = dvar[i]; - } - - // lake ice snow albedo: lake_var.SAlbedo - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.SAlbedo = dvar[i]; - } - - // lake ice snow depth: lake_var.sdepth - get_scatter_nc_field_double(&(filenames.init_state), - state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, - d2start, d2count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - all_vars[i].lake_var.sdepth = dvar[i]; - } - } - - free(ivar); - free(dvar); - - // close initial state file - if (mpi_rank == VIC_MPI_ROOT) { - status = nc_close(filenames.init_state.nc_id); - check_nc_status(status, "Error closing %s", - filenames.init_state.nc_filename); - } -} - -/****************************************************************************** - * @brief Check that the initial state file matches the global parameter - settings - *****************************************************************************/ -void -check_init_state_file(void) -{ - extern filenames_struct filenames; - extern domain_struct global_domain; - extern domain_struct local_domain; - extern option_struct options; - extern soil_con_struct *soil_con; - extern int mpi_rank; - extern rout_struct rout; - - int status; - size_t dimlen; - size_t i; - size_t j; - size_t d1count[1]; - size_t d1start[1]; - size_t d2count[2]; - size_t d2start[2]; - size_t d3count[3]; - size_t d3start[3]; - int lon_var_id; - int lat_var_id; - double *dvar; - double rtol = 0.0; // maybe move this to a .h file - double abs_tol = 0.0001; // maybe move this to a .h file - - // read and validate dimension lengths - if (mpi_rank == VIC_MPI_ROOT) { - dimlen = get_nc_dimension(&(filenames.init_state), - global_domain.info.x_dim); - if (dimlen != global_domain.n_nx) { - log_err("Number of grid columns in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), - global_domain.info.y_dim); - if (dimlen != global_domain.n_ny) { - log_err("Number of grid rows in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), "veg_class"); - if (dimlen != options.NVEGTYPES) { - log_err("Number of veg classes in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), "snow_band"); - if (dimlen != options.SNOW_BAND) { - log_err("Number of snow bands in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), "nlayer"); - if (dimlen != options.Nlayer) { - log_err("Number of soil layers in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), "frost_area"); - if (dimlen != options.Nfrost) { - log_err("Number of frost areas in state file does not " - "match parameter file"); - } - dimlen = get_nc_dimension(&(filenames.init_state), "soil_node"); - if (dimlen != options.Nnode) { - log_err("Number of soil nodes in state file does not " - "match parameter file"); - } - if (options.LAKES) { - dimlen = get_nc_dimension(&(filenames.init_state), "lake_node"); - if (dimlen != options.NLAKENODES) { - log_err("Number of lake nodes in state file does not " - "match parameter file"); - } - } - } - - // read dimension variables - - // lat/lon - if (mpi_rank == VIC_MPI_ROOT) { - status = nc_inq_varid(filenames.init_state.nc_id, - global_domain.info.lon_var, &lon_var_id); - check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lon_var, - filenames.init_state.nc_filename); - status = nc_inq_varid(filenames.init_state.nc_id, - global_domain.info.lat_var, &lat_var_id); - check_nc_status(status, "Unable to find variable \"%s\" in %s", - global_domain.info.lat_var, - filenames.init_state.nc_filename); - if (global_domain.info.n_coord_dims == 1) { - d1start[0] = 0; - dvar = calloc(global_domain.n_nx, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d1count[0] = global_domain.n_nx; - status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, - d1start, d1count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, - filenames.init_state.nc_filename); - // implicitly nested loop over ni and nj with j set to 0 - for (i = 0; i < global_domain.n_nx; i++) { - if (!assert_close_double(dvar[i], - global_domain.locations[i].longitude, - rtol, - abs_tol)) { - log_err("Longitudes in initial state file do not " - "match parameter file"); - } - } - free(dvar); - - dvar = calloc(global_domain.n_ny, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d1count[0] = global_domain.n_ny; - status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, - d1start, d1count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, - filenames.init_state.nc_filename); - // implicitly nested loop over ni and nj with i set to 0; - // j stride = n_nx - for (j = 0; j < global_domain.n_ny; j++) { - if (!assert_close_double(dvar[j], - global_domain.locations[j * - global_domain. - n_nx] - .latitude, rtol, - abs_tol)) { - log_err("Latitudes in initial state file do not " - "match parameter file"); - } - } - free(dvar); - } - else if (global_domain.info.n_coord_dims == 2) { - d2start[0] = 0; - d2start[1] = 0; - dvar = - calloc(global_domain.n_ny * global_domain.n_nx, sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - d2count[0] = global_domain.n_ny; - d2count[1] = global_domain.n_nx; - status = nc_get_vara_double(filenames.init_state.nc_id, lon_var_id, - d2start, d2count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lon_var, - filenames.init_state.nc_filename); - for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { - if (dvar[i] != (double) global_domain.locations[i].longitude) { - log_err("Longitudes in initial state file do not " - "match parameter file"); - } - } - status = nc_get_vara_double(filenames.init_state.nc_id, lat_var_id, - d2start, d2count, dvar); - check_nc_status(status, "Error reading data from \"%s\" in %s", - global_domain.info.lat_var, - filenames.init_state.nc_filename); - for (i = 0; i < global_domain.n_ny * global_domain.n_nx; i++) { - if (dvar[i] != (double) global_domain.locations[i].latitude) { - log_err("Latitudes in initial state file do not " - "match parameter file"); - } - } - free(dvar); - } - else { - log_err("global_domain.info.n_coord_dims should be 1 or 2"); - } - } - - // initialize dvar for soil thermal node deltas and depths - dvar = malloc(local_domain.ncells_active * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error"); - - // soil thermal node deltas (dimension: node, lat, lon) - d3start[0] = 0; - d3start[1] = 0; - d3start[2] = 0; - d3count[0] = 1; - d3count[1] = global_domain.n_ny; - d3count[2] = global_domain.n_nx; - for (j = 0; j < options.Nnode; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - "dz_node", - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - if (dvar[i] != soil_con[i].dz_node[j]) { - log_err("Soil node intervals in state file do not match " - "those computed by VIC"); - } - } - } - - // soil thermal node depths - d3start[0] = 0; - d3start[1] = 0; - d3start[2] = 0; - d3count[0] = 1; - d3count[1] = global_domain.n_ny; - d3count[2] = global_domain.n_nx; - for (j = 0; j < options.Nnode; j++) { - d3start[0] = j; - get_scatter_nc_field_double(&(filenames.init_state), - "node_depth", - d3start, d3count, dvar); - for (i = 0; i < local_domain.ncells_active; i++) { - if (dvar[i] != soil_con[i].Zsum_node[j]) { - log_err("Soil node depths in state file do not match " - "those computed by VIC"); - } - } - } - free(dvar); -} diff --git a/vic/extensions/rout_rvic/src/vic_restore_extension.c b/vic/extensions/rout_rvic/src/vic_restore_extension.c new file mode 100644 index 000000000..2e08c200b --- /dev/null +++ b/vic/extensions/rout_rvic/src/vic_restore_extension.c @@ -0,0 +1,58 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +vic_restore_extension(nameid_struct *init_state_file, + metadata_struct *state_metadata) +{ + extern int mpi_rank; + extern rout_struct rout; + + size_t d2start[2]; + size_t d2count[2]; + + // write state variables + + // routing ring + if (mpi_rank == VIC_MPI_ROOT) { + d2start[0] = 0; + d2start[1] = 0; + d2count[0] = rout.rout_param.full_time_length; + d2count[1] = rout.rout_param.n_outlets; + + get_nc_field_double( + init_state_file, + state_metadata[N_STATE_VARS + STATE_ROUT_RING].varname, + d2start, d2count, rout.ring); + } +} + diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index e78698991..551ee94fb 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -56,6 +56,7 @@ void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing void vic_store_extension(nc_file_struct *); +void vic_restore_extension(nameid_struct *, metadata_struct *); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_stub/src/vic_restore_extension.c b/vic/extensions/rout_stub/src/vic_restore_extension.c new file mode 100644 index 000000000..c07a07623 --- /dev/null +++ b/vic/extensions/rout_stub/src/vic_restore_extension.c @@ -0,0 +1,38 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +vic_restore_extension(nameid_struct *init_state_file, + metadata_struct *state_metadata) +{ +} + From 3eb5296254c276c90e2b050915ab25edd20a6e3f Mon Sep 17 00:00:00 2001 From: ymao Date: Fri, 13 Oct 2017 15:29:16 -0700 Subject: [PATCH 221/294] Moved state_metadata.c back to shared_image/src and cleaned up extension --- .../shared_image}/src/state_metadata.c | 8 +- vic/extensions/rout_rvic/include/rout.h | 1 + vic/extensions/rout_rvic/src/state_metadata.c | 721 ------------------ .../rout_rvic/src/state_metadata_extension.c | 49 ++ vic/extensions/rout_stub/include/rout.h | 1 + .../rout_stub/src/state_metadata_extension.c | 37 + 6 files changed, 94 insertions(+), 723 deletions(-) rename vic/{extensions/rout_stub => drivers/shared_image}/src/state_metadata.c (99%) delete mode 100644 vic/extensions/rout_rvic/src/state_metadata.c create mode 100644 vic/extensions/rout_rvic/src/state_metadata_extension.c create mode 100644 vic/extensions/rout_stub/src/state_metadata_extension.c diff --git a/vic/extensions/rout_stub/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c similarity index 99% rename from vic/extensions/rout_stub/src/state_metadata.c rename to vic/drivers/shared_image/src/state_metadata.c index 5792160fe..fb099b2be 100644 --- a/vic/extensions/rout_stub/src/state_metadata.c +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include +#include /****************************************************************************** * @brief Set output met data information @@ -35,12 +36,12 @@ set_state_meta_data_info() size_t v; extern option_struct options; - extern metadata_struct state_metadata[N_STATE_VARS]; + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; // Build the list of state variables // Set missing and/or default values - for (v = 0; v < N_STATE_VARS; v++) { + for (v = 0; v < (N_STATE_VARS + N_STATE_VARS_EXT); v++) { // Set default string values strcpy(state_metadata[v].varname, MISSING_S); strcpy(state_metadata[v].long_name, MISSING_S); @@ -707,4 +708,7 @@ set_state_meta_data_info() strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].description, "depth of snow on lake ice"); } + + // STATE_ROUT_RING + state_metadata_extension(); } diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 7110d96eb..189231d0d 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -84,6 +84,7 @@ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); void vic_store_extension(nc_file_struct *); void vic_restore_extension(nameid_struct *, metadata_struct *); +void state_metadata_extension(); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_rvic/src/state_metadata.c b/vic/extensions/rout_rvic/src/state_metadata.c deleted file mode 100644 index 0e06009d4..000000000 --- a/vic/extensions/rout_rvic/src/state_metadata.c +++ /dev/null @@ -1,721 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * This routine sets the metadata structure for VIC state variables - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 -#include - -/****************************************************************************** - * @brief Set output met data information - *****************************************************************************/ -void -set_state_meta_data_info() -{ - size_t v; - - extern option_struct options; - extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; - - // Build the list of state variables - - // Set missing and/or default values - for (v = 0; v < (N_STATE_VARS + N_STATE_VARS_EXT); v++) { - // Set default string values - strcpy(state_metadata[v].varname, MISSING_S); - strcpy(state_metadata[v].long_name, MISSING_S); - strcpy(state_metadata[v].standard_name, MISSING_S); - strcpy(state_metadata[v].units, MISSING_S); - strcpy(state_metadata[v].description, MISSING_S); - // Set default number of elements - state_metadata[v].nelem = 1; - } - - // STATE_SOIL_MOISTURE - strcpy(state_metadata[STATE_SOIL_MOISTURE].varname, "STATE_SOIL_MOISTURE"); - strcpy(state_metadata[STATE_SOIL_MOISTURE].long_name, "soil_moisture"); - strcpy(state_metadata[STATE_SOIL_MOISTURE].standard_name, - "soil_layer_moisture"); - strcpy(state_metadata[STATE_SOIL_MOISTURE].units, "mm"); - strcpy(state_metadata[STATE_SOIL_MOISTURE].description, - "soil total moisture contents including ice for each soil layer"); - - // STATE_SOIL_ICE - strcpy(state_metadata[STATE_SOIL_ICE].varname, "STATE_SOIL_ICE"); - strcpy(state_metadata[STATE_SOIL_ICE].long_name, "soil_ice"); - strcpy(state_metadata[STATE_SOIL_ICE].standard_name, - "soil_moisture_ice_depth"); - strcpy(state_metadata[STATE_SOIL_ICE].units, "mm"); - strcpy(state_metadata[STATE_SOIL_ICE].description, - "soil ice content for each soil layer"); - - // STATE_CANOPY_WATER - strcpy(state_metadata[STATE_CANOPY_WATER].varname, "STATE_CANOPY_WATER"); - strcpy(state_metadata[STATE_CANOPY_WATER].long_name, "canopy_water"); - strcpy(state_metadata[STATE_CANOPY_WATER].standard_name, "water_in_canopy"); - strcpy(state_metadata[STATE_CANOPY_WATER].units, "mm"); - strcpy(state_metadata[STATE_CANOPY_WATER].description, - "amount of water stored in the vegetation canopy"); - - if (options.CARBON) { - // STATE_ANNUALNPP - strcpy(state_metadata[STATE_ANNUALNPP].varname, "STATE_ANNUALNPP"); - strcpy(state_metadata[STATE_ANNUALNPP].long_name, "annualnpp"); - strcpy(state_metadata[STATE_ANNUALNPP].standard_name, - "running_total_annual_NPP"); - strcpy(state_metadata[STATE_ANNUALNPP].units, "g m-2"); - strcpy(state_metadata[STATE_ANNUALNPP].description, - "running total annual NPP"); - - // STATE_ANNUALNPPPREV - strcpy(state_metadata[STATE_ANNUALNPPPREV].varname, - "STATE_ANNUALNPPPREV"); - strcpy(state_metadata[STATE_ANNUALNPPPREV].long_name, "annualnppprev"); - strcpy(state_metadata[STATE_ANNUALNPPPREV].standard_name, - "previous_year_total_annual_NPP"); - strcpy(state_metadata[STATE_ANNUALNPPPREV].units, "g m-2"); - strcpy(state_metadata[STATE_ANNUALNPPPREV].description, - "total annual NPP from previous year"); - - // STATE_CLITTER - strcpy(state_metadata[STATE_CLITTER].varname, "STATE_CLITTER"); - strcpy(state_metadata[STATE_CLITTER].long_name, "clitter"); - strcpy(state_metadata[STATE_CLITTER].standard_name, - "carbon_in_litter_pool"); - strcpy(state_metadata[STATE_CLITTER].units, "g m-2"); - strcpy(state_metadata[STATE_CLITTER].description, - "carbon storage in litter pool"); - - // STATE_CINTER - strcpy(state_metadata[STATE_CINTER].varname, "STATE_CINTER"); - strcpy(state_metadata[STATE_CINTER].long_name, "cinter"); - strcpy(state_metadata[STATE_CINTER].standard_name, - "carbon_in_intermediate_pool"); - strcpy(state_metadata[STATE_CINTER].units, "g m-2"); - strcpy(state_metadata[STATE_CINTER].description, - "carbon storage in intermediate pool"); - - // STATE_CSLOW - strcpy(state_metadata[STATE_CSLOW].varname, "STATE_CSLOW"); - strcpy(state_metadata[STATE_CSLOW].long_name, "cslow"); - strcpy(state_metadata[STATE_CSLOW].standard_name, - "carbon_in_slow_pool"); - strcpy(state_metadata[STATE_CSLOW].units, "g m-2"); - strcpy(state_metadata[STATE_CSLOW].description, - "carbon storage in slow pool"); - } - // STATE_SNOW_AGE - strcpy(state_metadata[STATE_SNOW_AGE].varname, "STATE_SNOW_AGE"); - strcpy(state_metadata[STATE_SNOW_AGE].long_name, "snow_age"); - strcpy(state_metadata[STATE_SNOW_AGE].standard_name, - "age_since_last_new_snow"); - strcpy(state_metadata[STATE_SNOW_AGE].units, "model_time_step"); - strcpy(state_metadata[STATE_SNOW_AGE].description, - "number of model time steps since the last new snow"); - - // STATE_SNOW_MELT_STATE - strcpy(state_metadata[STATE_SNOW_MELT_STATE].varname, - "STATE_SNOW_MELT_STATE"); - strcpy(state_metadata[STATE_SNOW_MELT_STATE].long_name, "snow_melt_state"); - strcpy(state_metadata[STATE_SNOW_MELT_STATE].standard_name, - "snow_melting_phase"); - strcpy(state_metadata[STATE_SNOW_MELT_STATE].units, - "1 melting, 0 not melting"); - strcpy(state_metadata[STATE_SNOW_MELT_STATE].description, - "flag to indicate whether snowpack is in accumulation or melting phase"); - - // STATE_SNOW_COVERAGE - strcpy(state_metadata[STATE_SNOW_COVERAGE].varname, "STATE_SNOW_COVERAGE"); - strcpy(state_metadata[STATE_SNOW_COVERAGE].long_name, "snow_coverage"); - strcpy(state_metadata[STATE_SNOW_COVERAGE].standard_name, - "snow_coverage_fraction"); - strcpy(state_metadata[STATE_SNOW_COVERAGE].units, "1"); - strcpy(state_metadata[STATE_SNOW_COVERAGE].description, - "fraction of grid cell area covered by snow"); - - // STATE_SNOW_WATER_EQUIVALENT - strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].varname, - "STATE_SNOW_WATER_EQUIVALENT"); - strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].long_name, - "snow_water_equivalent"); - strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].standard_name, - "snow_water_equivalent"); - strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].units, "m"); - strcpy(state_metadata[STATE_SNOW_WATER_EQUIVALENT].description, - "snow water equivalent"); - - // STATE_SNOW_SURF_TEMP - strcpy(state_metadata[STATE_SNOW_SURF_TEMP].varname, - "STATE_SNOW_SURF_TEMP"); - strcpy(state_metadata[STATE_SNOW_SURF_TEMP].long_name, "snow_surf_temp"); - strcpy(state_metadata[STATE_SNOW_SURF_TEMP].standard_name, - "snow_surface_temperature"); - strcpy(state_metadata[STATE_SNOW_SURF_TEMP].units, "C"); - strcpy(state_metadata[STATE_SNOW_SURF_TEMP].description, - "snow surface layer temperature"); - - // STATE_SNOW_SURF_WATER - strcpy(state_metadata[STATE_SNOW_SURF_WATER].varname, - "STATE_SNOW_SURF_WATER"); - strcpy(state_metadata[STATE_SNOW_SURF_WATER].long_name, "snow_surf_water"); - strcpy(state_metadata[STATE_SNOW_SURF_WATER].standard_name, - "snow_surface_liquid_water"); - strcpy(state_metadata[STATE_SNOW_SURF_WATER].units, "m"); - strcpy(state_metadata[STATE_SNOW_SURF_WATER].description, - "liquid water content of the snow surface layer"); - - // STATE_SNOW_PACK_TEMP - strcpy(state_metadata[STATE_SNOW_PACK_TEMP].varname, - "STATE_SNOW_PACK_TEMP"); - strcpy(state_metadata[STATE_SNOW_PACK_TEMP].long_name, "snow_pack_temp"); - strcpy(state_metadata[STATE_SNOW_PACK_TEMP].standard_name, - "snow_pack_temperature"); - strcpy(state_metadata[STATE_SNOW_PACK_TEMP].units, "C"); - strcpy(state_metadata[STATE_SNOW_PACK_TEMP].description, - "snow pack layer temperature"); - - // STATE_SNOW_PACK_WATER - strcpy(state_metadata[STATE_SNOW_PACK_WATER].varname, - "STATE_SNOW_PACK_WATER"); - strcpy(state_metadata[STATE_SNOW_PACK_WATER].long_name, "snow_pack_water"); - strcpy(state_metadata[STATE_SNOW_PACK_WATER].standard_name, - "snow_pack_liquid_water"); - strcpy(state_metadata[STATE_SNOW_PACK_WATER].units, "m"); - strcpy(state_metadata[STATE_SNOW_PACK_WATER].description, - "liquid water content of the snow pack layer"); - - // STATE_SNOW_DENSITY - strcpy(state_metadata[STATE_SNOW_DENSITY].varname, "STATE_SNOW_DENSITY"); - strcpy(state_metadata[STATE_SNOW_DENSITY].long_name, "snow_density"); - strcpy(state_metadata[STATE_SNOW_DENSITY].standard_name, - "snowpack_density"); - strcpy(state_metadata[STATE_SNOW_DENSITY].units, "kg m-3"); - strcpy(state_metadata[STATE_SNOW_DENSITY].description, "snowpack density"); - - // STATE_SNOW_COLD_CONTENT - strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].varname, - "STATE_SNOW_COLD_CONTENT"); - strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].long_name, - "snow_cold_content"); - strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].standard_name, - "snowpack_cold_content"); - strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].units, "J m-2"); - strcpy(state_metadata[STATE_SNOW_COLD_CONTENT].description, - "snowpack cold content"); - - // STATE_SNOW_CANOPY - strcpy(state_metadata[STATE_SNOW_CANOPY].varname, "STATE_SNOW_CANOPY"); - strcpy(state_metadata[STATE_SNOW_CANOPY].long_name, "snow_canopy"); - strcpy(state_metadata[STATE_SNOW_CANOPY].standard_name, - "snow_water_equivalent_intercepted_in_canopy"); - strcpy(state_metadata[STATE_SNOW_CANOPY].units, "m"); - strcpy(state_metadata[STATE_SNOW_CANOPY].description, - "snow interception storage in canopy"); - - // STATE_ROUT_RING - strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].varname, - "STATE_ROUT_RING"); - strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].long_name, "routing_ring"); - strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].standard_name, - "routing_ring"); - strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].units, "-"); - strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].description, - "unit hydrographs in the routing ring"); - - // STATE_SOIL_NODE_TEMP - strcpy(state_metadata[STATE_SOIL_NODE_TEMP].varname, - "STATE_SOIL_NODE_TEMP"); - strcpy(state_metadata[STATE_SOIL_NODE_TEMP].long_name, "soil_node_temp"); - strcpy(state_metadata[STATE_SOIL_NODE_TEMP].standard_name, - "soil_node_temperature"); - strcpy(state_metadata[STATE_SOIL_NODE_TEMP].units, "C"); - strcpy(state_metadata[STATE_SOIL_NODE_TEMP].description, - "soil temperature of each soil thermal node"); - - // STATE_FOLIAGE_TEMPERATURE - strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].varname, - "STATE_FOLIAGE_TEMPERATURE"); - strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].long_name, - "foliage_temperature"); - strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].standard_name, - "foliage_temperature"); - strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].units, "C"); - strcpy(state_metadata[STATE_FOLIAGE_TEMPERATURE].description, - "overstory vegetaion temperature"); - - // STATE_ENERGY_LONGUNDEROUT - strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].varname, - "STATE_ENERGY_LONGUNDEROUT"); - strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].long_name, - "energy_longunderout"); - strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].standard_name, - "longwave_out_from_understory"); - strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].units, "W m-2"); - strcpy(state_metadata[STATE_ENERGY_LONGUNDEROUT].description, - "outgoing longwave flux from understory vegetation"); - - // STATE_ENERGY_SNOW_FLUX - strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].varname, - "STATE_ENERGY_SNOW_FLUX"); - strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].long_name, - "energy_snow_flux"); - strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].standard_name, - "snowpack_thermal_flux"); - strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].units, "W m-2"); - strcpy(state_metadata[STATE_ENERGY_SNOW_FLUX].description, - "thermal flux through snowpack"); - - // STATE_GRIDCELL_AVG_ALBEDO - strcpy(state_metadata[STATE_AVG_ALBEDO].varname, - "STATE_AVG_ALBEDO"); - strcpy(state_metadata[STATE_AVG_ALBEDO].long_name, - "state_avg_albedo"); - strcpy(state_metadata[STATE_AVG_ALBEDO].standard_name, - "state_gridcell_avg_albedo"); - strcpy(state_metadata[STATE_AVG_ALBEDO].units, "fraction"); - strcpy(state_metadata[STATE_AVG_ALBEDO].description, - "gridcell averaged albedo"); - - if (options.LAKES) { - // STATE_LAKE_SOIL_MOISTURE - strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].varname, - "STATE_LAKE_SOIL_MOISTURE"); - strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].long_name, - "lake_soil_moisture"); - strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].standard_name, - "lake_soil_moisture"); - strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].units, "mm"); - strcpy(state_metadata[STATE_LAKE_SOIL_MOISTURE].description, - "soil moisture below lake"); - - // STATE_LAKE_SOIL_ICE - strcpy(state_metadata[STATE_LAKE_SOIL_ICE].varname, - "STATE_LAKE_SOIL_ICE"); - strcpy(state_metadata[STATE_LAKE_SOIL_ICE].long_name, "lake_soil_ice"); - strcpy(state_metadata[STATE_LAKE_SOIL_ICE].standard_name, - "lake_soil_ice_content"); - strcpy(state_metadata[STATE_LAKE_SOIL_ICE].units, "mm"); - strcpy(state_metadata[STATE_LAKE_SOIL_ICE].description, - "soil ice content below lake"); - - if (options.CARBON) { - // STATE_LAKE_CLITTER - strcpy(state_metadata[STATE_LAKE_CLITTER].varname, - "STATE_LAKE_CLITTER"); - strcpy(state_metadata[STATE_LAKE_CLITTER].long_name, - "lake_clitter"); - strcpy(state_metadata[STATE_LAKE_CLITTER].standard_name, - "lake_carbon_in_litter_pool"); - strcpy(state_metadata[STATE_LAKE_CLITTER].units, "g m-2"); - strcpy(state_metadata[STATE_LAKE_CLITTER].description, - "carbon storage in litter pool below lake"); - - // STATE_LAKE_CINTER - strcpy(state_metadata[STATE_LAKE_CINTER].varname, - "STATE_LAKE_CINTER"); - strcpy(state_metadata[STATE_LAKE_CINTER].long_name, "lake_cinter"); - strcpy(state_metadata[STATE_LAKE_CINTER].standard_name, - "lake_carbon_in_intermediate_pool"); - strcpy(state_metadata[STATE_LAKE_CINTER].units, "g m-2"); - strcpy(state_metadata[STATE_LAKE_CINTER].description, - "carbon storage in intermediate pool below lake"); - - // STATE_LAKE_CSLOW - strcpy(state_metadata[STATE_LAKE_CSLOW].varname, - "STATE_LAKE_CSLOW"); - strcpy(state_metadata[STATE_LAKE_CSLOW].long_name, "lake_cslow"); - strcpy(state_metadata[STATE_LAKE_CSLOW].standard_name, - "lake_carbon_in_slow_pool"); - strcpy(state_metadata[STATE_LAKE_CSLOW].units, "g m-2"); - strcpy(state_metadata[STATE_LAKE_CSLOW].description, - "carbon storage in slow pool below lake"); - } - - // STATE_LAKE_SNOW_AGE - strcpy(state_metadata[STATE_LAKE_SNOW_AGE].varname, - "STATE_LAKE_SNOW_AGE"); - strcpy(state_metadata[STATE_LAKE_SNOW_AGE].long_name, "lake_snow_age"); - strcpy(state_metadata[STATE_LAKE_SNOW_AGE].standard_name, - "lake_age_since_last_new_snow"); - strcpy(state_metadata[STATE_LAKE_SNOW_AGE].units, "model_time_step"); - strcpy(state_metadata[STATE_LAKE_SNOW_AGE].description, - "number of model time steps since the last new snow on lake ice"); - - // STATE_LAKE_SNOW_MELT_STATE - strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].varname, - "STATE_LAKE_SNOW_MELT_STATE"); - strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].long_name, - "lake_snow_melt_state"); - strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].standard_name, - "lake_snow_melting_phase"); - strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].units, - "1 melting, 0 not melting"); - strcpy(state_metadata[STATE_LAKE_SNOW_MELT_STATE].description, - "flag to indicate whether snowpack is in accumulation or melting phase on lake ice"); - - // STATE_LAKE_SNOW_COVERAGE - strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].varname, - "STATE_LAKE_SNOW_COVERAGE"); - strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].long_name, - "lake_snow_coverage"); - strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].standard_name, - "lake_snow_coverage_fraction"); - strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].units, "1"); - strcpy(state_metadata[STATE_LAKE_SNOW_COVERAGE].description, - "fraction of grid cell area covered by snow on lake ice"); - - // STATE_LAKE_SNOW_WATER_EQUIVALENT - strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].varname, - "STATE_LAKE_SNOW_WATER_EQUIVALENT"); - strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].long_name, - "lake_snow_water_equivalent"); - strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].standard_name, - "lake_snow_water_equivalent"); - strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].units, "m"); - strcpy(state_metadata[STATE_LAKE_SNOW_WATER_EQUIVALENT].description, - "lake snow water equivalent on lake ice"); - - // STATE_LAKE_SNOW_SURF_TEMP - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].varname, - "STATE_LAKE_SNOW_SURF_TEMP"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].long_name, - "lake_snow_surf_temp"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].standard_name, - "lake_snow_surface_temperature"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_TEMP].description, - "snow surface layer temperature on lake ice"); - - // STATE_LAKE_SNOW_SURF_WATER - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].varname, - "STATE_LAKE_SNOW_SURF_WATER"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].long_name, - "lake_snow_surf_water"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].standard_name, - "lake_snow_surface_temperature"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].units, "m"); - strcpy(state_metadata[STATE_LAKE_SNOW_SURF_WATER].description, - "liquid water content of the snow surface layer on lake ice"); - - // STATE_LAKE_SNOW_PACK_TEMP - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].varname, - "STATE_LAKE_SNOW_PACK_TEMP"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].long_name, - "lake_snow_pack_temp"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].standard_name, - "lake_snow_pack_temperature"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_TEMP].description, - "snow pack layer temperature on lake ice"); - - // STATE_LAKE_SNOW_PACK_WATER - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].varname, - "STATE_LAKE_SNOW_PACK_WATER"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].long_name, - "lake_snow_pack_water"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].standard_name, - "lake_snow_surface_liquid_water"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].units, "m"); - strcpy(state_metadata[STATE_LAKE_SNOW_PACK_WATER].description, - "liquid water content of the snow surface layer on lake ice"); - - // STATE_LAKE_SNOW_DENSITY - strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].varname, - "STATE_LAKE_SNOW_DENSITY"); - strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].long_name, - "lake_snow_density"); - strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].standard_name, - "lake_snowpack_density"); - strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].units, "kg m-3"); - strcpy(state_metadata[STATE_LAKE_SNOW_DENSITY].description, - "snowpack density on lake ice"); - - // STATE_LAKE_SNOW_COLD_CONTENT - strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].varname, - "STATE_LAKE_SNOW_COLD_CONTENT"); - strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].long_name, - "lake_snow_cold_content"); - strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].standard_name, - "lake_snowpack_cold_content"); - strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].units, "J m-2"); - strcpy(state_metadata[STATE_LAKE_SNOW_COLD_CONTENT].description, - "snowpack cold content on lake ice"); - - // STATE_LAKE_SNOW_CANOPY - strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].varname, - "STATE_LAKE_SNOW_CANOPY"); - strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].long_name, - "lake_snow_canopy"); - strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].standard_name, - "lake_snow_water_equivalent_intercepted_in_canopy"); - strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].units, "m"); - strcpy(state_metadata[STATE_LAKE_SNOW_CANOPY].description, - "snow interception storage in canopy on lake ice"); - - // STATE_LAKE_SOIL_NODE_TEMP - strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].varname, - "STATE_LAKE_SOIL_NODE_TEMP"); - strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].long_name, - "lake_soil_node_temp"); - strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].standard_name, - "lake_soil_node_temperature"); - strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_SOIL_NODE_TEMP].description, - "soil temperature of each soil thermal node below lake"); - - // STATE_LAKE_ACTIVE_LAYERS - strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].varname, - "STATE_LAKE_ACTIVE_LAYERS"); - strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].long_name, - "lake_active_layers"); - strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].standard_name, - "lake_active_layers"); - strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].units, "-"); - strcpy(state_metadata[STATE_LAKE_ACTIVE_LAYERS].description, - "number of nodes whose corresponding layers currently contain water"); - - // STATE_LAKE_LAYER_DZ - strcpy(state_metadata[STATE_LAKE_LAYER_DZ].varname, - "STATE_LAKE_LAYER_DZ"); - strcpy(state_metadata[STATE_LAKE_LAYER_DZ].long_name, "lake_layer_dz"); - strcpy(state_metadata[STATE_LAKE_LAYER_DZ].standard_name, - "lake_thickness_layer_below_surface"); - strcpy(state_metadata[STATE_LAKE_LAYER_DZ].units, "m"); - strcpy(state_metadata[STATE_LAKE_LAYER_DZ].description, - "vertical thickness of all horizontal lake water layers below the surface layer"); - - // STATE_LAKE_SURF_LAYER_DZ - strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].varname, - "STATE_LAKE_SURF_LAYER_DZ"); - strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].long_name, - "lake_surf_layer_dz"); - strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].standard_name, - "lake_thickness_surface_layer"); - strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].units, "m"); - strcpy(state_metadata[STATE_LAKE_SURF_LAYER_DZ].description, - "vertical thickness of surface water layer in lake"); - - // STATE_LAKE_DEPTH - strcpy(state_metadata[STATE_LAKE_DEPTH].varname, "STATE_LAKE_DEPTH"); - strcpy(state_metadata[STATE_LAKE_DEPTH].long_name, "lake_depth"); - strcpy(state_metadata[STATE_LAKE_DEPTH].standard_name, - "lake_liquid_water_depth"); - strcpy(state_metadata[STATE_LAKE_DEPTH].units, "m"); - strcpy(state_metadata[STATE_LAKE_DEPTH].description, - "distance from surface to deepest point in lake"); - - // STATE_LAKE_LAYER_SURF_AREA - strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].varname, - "STATE_LAKE_LAYER_SURF_AREA"); - strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].long_name, - "lake_layer_surf_area"); - strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].standard_name, - "lake_node_surface_area"); - strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].units, "m2"); - strcpy(state_metadata[STATE_LAKE_LAYER_SURF_AREA].description, - "surface area of liquid water in lake at each node"); - - // STATE_LAKE_SURF_AREA - strcpy(state_metadata[STATE_LAKE_SURF_AREA].varname, - "STATE_LAKE_SURF_AREA"); - strcpy(state_metadata[STATE_LAKE_SURF_AREA].long_name, - "lake_surf_area"); - strcpy(state_metadata[STATE_LAKE_SURF_AREA].standard_name, - "lake_surface_area"); - strcpy(state_metadata[STATE_LAKE_SURF_AREA].units, "m2"); - strcpy(state_metadata[STATE_LAKE_SURF_AREA].description, - "surface area of liquid plus ice water on lake surface"); - - // STATE_LAKE_VOLUME - strcpy(state_metadata[STATE_LAKE_VOLUME].varname, "STATE_LAKE_VOLUME"); - strcpy(state_metadata[STATE_LAKE_VOLUME].long_name, "lake_volume"); - strcpy(state_metadata[STATE_LAKE_VOLUME].standard_name, "lake_volume"); - strcpy(state_metadata[STATE_LAKE_VOLUME].units, "m3"); - strcpy(state_metadata[STATE_LAKE_VOLUME].description, - "lake total volume including liquid water equivalent of lake ice"); - - // STATE_LAKE_LAYER_TEMP - strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].varname, - "STATE_LAKE_LAYER_TEMP"); - strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].long_name, - "lake_layer_temp"); - strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].standard_name, - "lake_layer_temp"); - strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_LAYER_TEMP].description, - "lake water temperature at each node"); - - // STATE_LAKE_AVERAGE_TEMP - strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].varname, - "STATE_LAKE_AVERAGE_TEMP"); - strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].long_name, - "lake_average_temp"); - strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].standard_name, - "lake_average_temperature"); - strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_AVERAGE_TEMP].description, - "average liquid water temperature of entire lake"); - - // STATE_LAKE_ICE_AREA_FRAC - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].varname, - "STATE_LAKE_ICE_AREA"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].long_name, - "lake_ice_area"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].standard_name, - "lake_ice_coverage"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].units, "m2"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC].description, - "area of ice coverage on lake at beginning of time step"); - - // STATE_LAKE_ICE_AREA_FRAC_NEW - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].varname, - "STATE_LAKE_ICE_AREA_NEW"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].long_name, - "lake_ice_area_new"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].standard_name, - "lake_ice_area_new"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].units, "m2"); - strcpy(state_metadata[STATE_LAKE_ICE_AREA_FRAC_NEW].description, - "area of ice coverage on lake at end of time step"); - - // STATE_LAKE_ICE_WATER_EQUIVALENT - strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].varname, - "STATE_LAKE_ICE_WATER_EQUIVALENT"); - strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].long_name, - "lake_ice_water_equivalent"); - strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].standard_name, - "lake_ice_water_equivalent"); - strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].units, "m3"); - strcpy(state_metadata[STATE_LAKE_ICE_WATER_EQUIVALENT].description, - "liquid water equivalent volume of lake ice"); - - // STATE_LAKE_ICE_HEIGHT - strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].varname, - "STATE_LAKE_ICE_HEIGHT"); - strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].long_name, - "lake_ice_height"); - strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].standard_name, - "lake_ice_height_thickest"); - strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].units, "m"); - strcpy(state_metadata[STATE_LAKE_ICE_HEIGHT].description, - "lake ice height at ghickest point"); - - // STATE_LAKE_ICE_TEMP - strcpy(state_metadata[STATE_LAKE_ICE_TEMP].varname, - "STATE_LAKE_ICE_TEMP"); - strcpy(state_metadata[STATE_LAKE_ICE_TEMP].long_name, "lake_ice_temp"); - strcpy(state_metadata[STATE_LAKE_ICE_TEMP].standard_name, - "lake_ice_temperature"); - strcpy(state_metadata[STATE_LAKE_ICE_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_ICE_TEMP].description, - "lake ice temperature"); - - // STATE_LAKE_ICE_SWE - strcpy(state_metadata[STATE_LAKE_ICE_SWE].varname, - "STATE_LAKE_ICE_SWE"); - strcpy(state_metadata[STATE_LAKE_ICE_SWE].long_name, "lake_ice_swe"); - strcpy(state_metadata[STATE_LAKE_ICE_SWE].standard_name, - "lake_snow_water_equivalent"); - strcpy(state_metadata[STATE_LAKE_ICE_SWE].units, "m"); - strcpy(state_metadata[STATE_LAKE_ICE_SWE].description, - "liquid water equivalent depth of lake snow"); - - // STATE_LAKE_ICE_SNOW_SURF_TEMP - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].varname, - "STATE_LAKE_ICE_SNOW_SURF_TEMP"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].long_name, - "lake_ice_snow_surf_temp"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].standard_name, - "lake_snow_surface_temperature"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_TEMP].description, - "temperature of snow surface layer of lake snow"); - - // STATE_LAKE_ICE_SNOW_PACK_TEMP - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].varname, - "STATE_LAKE_ICE_SNOW_PACK_TEMP"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].long_name, - "lake_ice_snow_pack_temp"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].standard_name, - "lake_ice_snow_pack_temperature"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].units, "C"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_TEMP].description, - "temperature of snow pack layer of lake snow"); - - // STATE_LAKE_ICE_SNOW_COLD_CONTENT - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].varname, - "STATE_LAKE_ICE_SNOW_COLD_CONTENT"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].long_name, - "lake_ice_snow_cold_content"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].standard_name, - "lake_ice_snow_cold_content"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].units, "J m-2"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_COLD_CONTENT].description, - "snowpack cold content of snow lake"); - - // STATE_LAKE_ICE_SNOW_SURF_WATER - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].varname, - "STATE_LAKE_ICE_SNOW_SURF_WATER"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].long_name, - "lake_ice_snow_surf_water"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].standard_name, - "lake_ice_snow_surface_liquid_water"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].units, "m"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_SURF_WATER].description, - "liquid water content of surface snow layer of lake snow"); - - // STATE_LAKE_ICE_SNOW_PACK_WATER - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].varname, - "STATE_LAKE_ICE_SNOW_PACK_WATER"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].long_name, - "lake_ice_snow_pack_water"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].standard_name, - "lake_ice_snow_pack_liquid_water"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].units, "m"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_PACK_WATER].description, - "liquid water content of pack snow layer of lake snow"); - - // STATE_LAKE_ICE_SNOW_ALBEDO - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].varname, - "STATE_LAKE_ICE_SNOW_ALBEDO"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].long_name, - "lake_ice_snow_albedo"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].standard_name, - "lake_ice_snow_albedo"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].units, "1"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_ALBEDO].description, - "albedo of lake snow"); - - // STATE_LAKE_ICE_SNOW_DEPTH - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].varname, - "STATE_LAKE_ICE_SNOW_DEPTH"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].long_name, - "lake_ice_snow_depth"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].standard_name, - "lake_ice_snow_depth"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].units, "m"); - strcpy(state_metadata[STATE_LAKE_ICE_SNOW_DEPTH].description, - "depth of snow on lake ice"); - } -} diff --git a/vic/extensions/rout_rvic/src/state_metadata_extension.c b/vic/extensions/rout_rvic/src/state_metadata_extension.c new file mode 100644 index 000000000..b52ff3324 --- /dev/null +++ b/vic/extensions/rout_rvic/src/state_metadata_extension.c @@ -0,0 +1,49 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +state_metadata_extension() +{ + extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; + + // STATE_ROUT_RING + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].varname, + "STATE_ROUT_RING"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].long_name, + "routing_ring"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].standard_name, + "routing_ring"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].units, "-"); + strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].description, + "unit hydrographs in the routing ring"); +} + diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 551ee94fb..c6ffd1dbd 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -57,6 +57,7 @@ void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing void vic_store_extension(nc_file_struct *); void vic_restore_extension(nameid_struct *, metadata_struct *); +void state_metadata_extension(); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); diff --git a/vic/extensions/rout_stub/src/state_metadata_extension.c b/vic/extensions/rout_stub/src/state_metadata_extension.c new file mode 100644 index 000000000..0fd194497 --- /dev/null +++ b/vic/extensions/rout_stub/src/state_metadata_extension.c @@ -0,0 +1,37 @@ +/****************************************************************************** + * @section DESCRIPTION + * + * Save model state. + * + * @section LICENSE + * + * The Variable Infiltration Capacity (VIC) macroscale hydrological model + * Copyright (C) 2016 The Computational 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 +#include + +/****************************************************************************** + * @brief Save model state. + *****************************************************************************/ +void +state_metadata_extension(nc_file_struct *nc_state_file) +{ +} + From 7b776c9867b983ec93674b54dc20110e96f22ee5 Mon Sep 17 00:00:00 2001 From: ymao Date: Fri, 13 Oct 2017 17:03:57 -0700 Subject: [PATCH 222/294] Update routing-related documentation --- docs/Development/ReleaseNotes.md | 2 +- docs/Documentation/Drivers/Image/Routing.md | 30 +++++++++------------ docs/Documentation/Drivers/Image/RunVIC.md | 2 +- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 1b1c24710..5c37620da 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -109,7 +109,7 @@ To check which release of VIC you are running: 8. Added routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) - The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available. + The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. #### Bug Fixes: diff --git a/docs/Documentation/Drivers/Image/Routing.md b/docs/Documentation/Drivers/Image/Routing.md index b50475f62..b23ba6c48 100644 --- a/docs/Documentation/Drivers/Image/Routing.md +++ b/docs/Documentation/Drivers/Image/Routing.md @@ -1,28 +1,22 @@ # Routing -There are two routing options available: rout_stub (default) and rout_rvic. +By default, river routing is not included in the VIC model. But the routing option can be turned on such that river routing is performed in real time when the VIC model is running, outputing routed river discharge. The routing scheme is identical to the RVIC routing model (http://rvic.readthedocs.io/en/latest/) and is tested with RVIC version 1.1.0. The steps to turn on the routing option are as follows. -## Option: rout_stub +## 1. Prepare routing-specific parameter file +To run routing in VIC, an extra parameter file that defines unit hydrograph information is needed. This parameter file contains information about unit hydrographs, which quantifies the reponse of a river outlet (whose dicharge is to be calculated) to an upstream runoff input. This parameter file can typically be generated using the RVIC model. Information on how to run RVIC and generate this file can be found at http://rvic.readthedocs.io/en/latest/. Note that the domain file (lat-lon information and mask) required by the RVIC model must match the one used for the VIC model. With this extra parameter file, VIC is able to convolve local runoff to calculate river discharge at downstream outlets. -Option rout_stub is the default option. During compilation the routing module is left empty: VIC can thus not be used for routing and consequently no discharge will be calculated. +## 2. Specify the routing-specific information in the VIC global file +The path of the routing-specific parameter file must be set in the [Global Parameter File](GlobalParam.md). For example: +`ROUT_PARAM ./RVIC_params.nc # Routing parameter path/file` -## Option: rout_rvic - -Option rout_rvic is optional. - -The routing process is done in two steps: Generation unit hydrograph and the convolution -* The unit hydrograph is generated separately with the RVIC streamflow routing model. This RVIC is a stand alone python program see: http://rvic.readthedocs.io/en/latest/. VIC is tested with RVIC version 1.1.0. -* Convolution is calculated in VIC itself (if routing is enabled in the makefile) and uses the RVIC-parameter file generated in the step mentioned above. +To output routed discharge results, an extra output variable has to be set in the [Global Parameter File](GlobalParam.md): +`OUTVAR OUT_DISCHARGE` -### Running: rout_rvic +## 3. Turn on the routing option when compiling VIC +There are two ways to turn on the routing option when compiling VIC: -This option can be enabled by adding the following commandline option to the `make`: +1) Add the following command line option to the `make` command when compiling VIC: `make ROUT=rout_rvic` -VIC needs the RVIC-parameter file. In formation how to generate this file can be found at http://rvic.readthedocs.io/en/latest/user-guide/parameters/. Note that the domain (lat-lon information and mask) of the RVIC-parameter file must match with the one of the VIC domain. +2) Change the value of `ROUT` in the Makefile to `rout_rvic`, i.e., `ROUT=rout_rvic`. This variable is by default `rout_stub`, which means running VIC without routing. -The RIVC-parameter file must be set in the [Global Parameter File](GlobalParam.md) e.g.: -`ROUT_PARAM RVIC_params.nc # Routing parameter path/file` - -An extra output has to be set in the [Global Parameter File](GlobalParam.md): -`OUTVAR OUT_DISCHARGE` diff --git a/docs/Documentation/Drivers/Image/RunVIC.md b/docs/Documentation/Drivers/Image/RunVIC.md index a0e2bd6f2..bb237292c 100644 --- a/docs/Documentation/Drivers/Image/RunVIC.md +++ b/docs/Documentation/Drivers/Image/RunVIC.md @@ -36,7 +36,7 @@ The flags and libraries required to compile VIC with netCDF are automatically de In some versions of the MPI library (e.g. OPEN-MPI with Intel), you may also need to set the environment variable `MX_RCACHE=2` prior to compiling. -To enable the routing extension, you must set the ROUT option. Valid options are rout_stub (default) and rout_rvic. For more information on what these options mean, see the [routing extension documentation](Routing.md). +To enable the river routing extension, you must set the ROUT option. This includes setting extension in the Makefile and adding routing-specific input parameter file. For more information on how to enable the routing extension, see the [routing extension documentation](Routing.md). - Change directory, `cd`, to the "Image Driver" source code directory and type `make` From ec7703113bf23fc25b7551cdcfc27336e1220760 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 10:45:56 -0700 Subject: [PATCH 223/294] Clean up and small bug fix for vic_restore.c --- vic/drivers/shared_image/src/vic_restore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index 58df905c7..db18e4347 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -884,7 +884,7 @@ vic_restore(void) } // routing ring - vic_restore_extension(&(filenames.init_state), &state_metadata); + vic_restore_extension(&(filenames.init_state), state_metadata); free(ivar); free(dvar); @@ -910,7 +910,6 @@ check_init_state_file(void) extern option_struct options; extern soil_con_struct *soil_con; extern int mpi_rank; - extern rout_struct rout; int status; size_t dimlen; From feae8eee6216a59886e8962c39dd14c91e49be8c Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 14:13:48 -0700 Subject: [PATCH 224/294] Moved gather_field_double() and scatter_field_double() to shared_image/src. This included some refactoring for gather_put_nc_field_double() and get_scatter_nc_field_double() --- vic/drivers/shared_image/include/vic_mpi.h | 2 + .../shared_image/src/vic_mpi_support.c | 109 +++++++++++++----- .../rout_rvic/src/rout_mpi_gather.c | 86 -------------- .../rout_rvic/src/rout_mpi_scatter.c | 78 ------------- vic/extensions/rout_rvic/src/rout_run.c | 5 +- 5 files changed, 85 insertions(+), 195 deletions(-) delete mode 100644 vic/extensions/rout_rvic/src/rout_mpi_gather.c delete mode 100644 vic/extensions/rout_rvic/src/rout_mpi_scatter.c diff --git a/vic/drivers/shared_image/include/vic_mpi.h b/vic/drivers/shared_image/include/vic_mpi.h index c7366cb68..39173995f 100644 --- a/vic/drivers/shared_image/include/vic_mpi.h +++ b/vic/drivers/shared_image/include/vic_mpi.h @@ -51,6 +51,7 @@ void create_MPI_location_struct_type(MPI_Datatype *mpi_type); void create_MPI_alarm_struct_type(MPI_Datatype *mpi_type); void create_MPI_option_struct_type(MPI_Datatype *mpi_type); void create_MPI_param_struct_type(MPI_Datatype *mpi_type); +void gather_field_double(double fillval, double *dvar, double *var); void gather_put_nc_field_double(int nc_id, int var_id, double fillval, size_t *start, size_t *count, double *var); void gather_put_nc_field_float(int nc_id, int var_id, float fillval, @@ -61,6 +62,7 @@ void gather_put_nc_field_short(int nc_id, int var_id, short int fillval, size_t *start, size_t *count, short int *var); void gather_put_nc_field_schar(int nc_id, int var_id, char fillval, size_t *start, size_t *count, char *var); +void scatter_field_double(double *dvar, double *var); void get_scatter_nc_field_double(nameid_struct *nc_nameid, char *var_name, size_t *start, size_t *count, double *var); void get_scatter_nc_field_float(nameid_struct *nc_nameid, char *var_name, diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 1cd8141f6..544b5ec35 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -1680,17 +1680,13 @@ mpi_map_decomp_domain(size_t ncells, } /****************************************************************************** - * @brief Gather and write double precision NetCDF field - * @details Values are gathered to the master node and then written from the - * master node + * @brief Gather double precision variable + * @details Values are gathered to the master node *****************************************************************************/ void -gather_put_nc_field_double(int nc_id, - int var_id, - double fillval, - size_t *start, - size_t *count, - double *var) +gather_field_double(double fillval, + double *dvar, + double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -1701,7 +1697,6 @@ gather_put_nc_field_double(int nc_id, extern size_t *filter_active_cells; extern size_t *mpi_map_mapping_array; int status; - double *dvar = NULL; double *dvar_gathered = NULL; double *dvar_remapped = NULL; size_t grid_size; @@ -1709,9 +1704,6 @@ gather_put_nc_field_double(int nc_id, if (mpi_rank == VIC_MPI_ROOT) { grid_size = global_domain.n_nx * global_domain.n_ny; - dvar = malloc(grid_size * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error."); - for (i = 0; i < grid_size; i++) { dvar[i] = fillval; } @@ -1737,13 +1729,47 @@ gather_put_nc_field_double(int nc_id, // expand to full grid size map(sizeof(double), global_domain.ncells_active, NULL, filter_active_cells, dvar_remapped, dvar); + // cleanup + free(dvar_gathered); + free(dvar_remapped); + } +} +/****************************************************************************** + * @brief Gather and write double precision NetCDF field + * @details Values are gathered to the master node and then written from the + * master node + *****************************************************************************/ +void +gather_put_nc_field_double(int nc_id, + int var_id, + double fillval, + size_t *start, + size_t *count, + double *var) +{ + extern int mpi_rank; + extern domain_struct global_domain; + int status; + size_t grid_size; + double *dvar = NULL; + + // Allocate memory + if (mpi_rank == VIC_MPI_ROOT) { + grid_size = global_domain.n_nx * global_domain.n_ny; + dvar = malloc(grid_size * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error."); + } + + // Gather results from the nodes + gather_field_double(fillval, dvar, var); + + // Write to netcdf + if (mpi_rank == VIC_MPI_ROOT) { status = nc_put_vara_double(nc_id, var_id, start, count, dvar); check_nc_status(status, "Error writing values."); // cleanup free(dvar); - free(dvar_gathered); - free(dvar_remapped); } } @@ -2037,16 +2063,11 @@ gather_put_nc_field_schar(int nc_id, } /****************************************************************************** - * @brief Read double precision NetCDF field from file and scatter - * @details Read happens on the master node and is then scattered to the local - * nodes + * @brief Scatter double precision variable + * @details values from master node are scattered to the local nodes *****************************************************************************/ void -get_scatter_nc_field_double(nameid_struct *nc_nameid, - char *var_name, - size_t *start, - size_t *count, - double *var) +scatter_field_double(double *dvar, double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; @@ -2057,14 +2078,10 @@ get_scatter_nc_field_double(nameid_struct *nc_nameid, extern size_t *filter_active_cells; extern size_t *mpi_map_mapping_array; int status; - double *dvar = NULL; double *dvar_filtered = NULL; double *dvar_mapped = NULL; if (mpi_rank == VIC_MPI_ROOT) { - dvar = malloc(global_domain.ncells_total * sizeof(*dvar)); - check_alloc_status(dvar, "Memory allocation error."); - dvar_filtered = malloc(global_domain.ncells_active * sizeof(*dvar_filtered)); check_alloc_status(dvar_filtered, "Memory allocation error."); @@ -2073,7 +2090,6 @@ get_scatter_nc_field_double(nameid_struct *nc_nameid, malloc(global_domain.ncells_active * sizeof(*dvar_mapped)); check_alloc_status(dvar_mapped, "Memory allocation error."); - get_nc_field_double(nc_nameid, var_name, start, count, dvar); // filter the active cells only map(sizeof(double), global_domain.ncells_active, filter_active_cells, NULL, dvar, dvar_filtered); @@ -2097,6 +2113,43 @@ get_scatter_nc_field_double(nameid_struct *nc_nameid, } } +/****************************************************************************** + * @brief Read double precision NetCDF field from file and scatter + * @details Read happens on the master node and is then scattered to the local + * nodes + *****************************************************************************/ +void +get_scatter_nc_field_double(nameid_struct *nc_nameid, + char *var_name, + size_t *start, + size_t *count, + double *var) +{ + extern MPI_Comm MPI_COMM_VIC; + extern domain_struct global_domain; + extern domain_struct local_domain; + extern int mpi_rank; + extern int *mpi_map_global_array_offsets; + extern int *mpi_map_local_array_sizes; + extern size_t *filter_active_cells; + extern size_t *mpi_map_mapping_array; + int status; + double *dvar = NULL; + double *dvar_filtered = NULL; + double *dvar_mapped = NULL; + + // Read variable from netcdf + if (mpi_rank == VIC_MPI_ROOT) { + dvar = malloc(global_domain.ncells_total * sizeof(*dvar)); + check_alloc_status(dvar, "Memory allocation error."); + + get_nc_field_double(nc_nameid, var_name, start, count, dvar); + } + + // Scatter results to nodes + scatter_field_double(dvar, var); +} + /****************************************************************************** * @brief Read single precision NetCDF field from file and scatter * @details Read happens on the master node and is then scattered to the local diff --git a/vic/extensions/rout_rvic/src/rout_mpi_gather.c b/vic/extensions/rout_rvic/src/rout_mpi_gather.c deleted file mode 100644 index 943075880..000000000 --- a/vic/extensions/rout_rvic/src/rout_mpi_gather.c +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * MPI support routines for Routing - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Gather double precision variable - * @details Values are gathered to the master node - *****************************************************************************/ -void -gather_var_double(double *dvar, - double *local_var) -{ - extern MPI_Comm MPI_COMM_VIC; - extern domain_struct global_domain; - extern domain_struct local_domain; - extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - int status; - double *dvar_gathered = NULL; - double *dvar_remapped = NULL; - size_t grid_size; - size_t i; - - if (mpi_rank == VIC_MPI_ROOT) { - grid_size = global_domain.n_nx * global_domain.n_ny; - for (i = 0; i < grid_size; i++) { - dvar[i] = 0; - } - - dvar_gathered = - malloc(global_domain.ncells_active * sizeof(*dvar_gathered)); - check_alloc_status(dvar_gathered, "Memory allocation error."); - - dvar_remapped = - malloc(global_domain.ncells_active * sizeof(*dvar_remapped)); - check_alloc_status(dvar_remapped, "Memory allocation error."); - } - - // Gather the results from the nodes, result for the local node is in the - // array *var (which is a function argument) - status = MPI_Gatherv(local_var, local_domain.ncells_active, MPI_DOUBLE, - dvar_gathered, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); - check_mpi_status(status, "MPI error."); - - if (mpi_rank == VIC_MPI_ROOT) { - // remap the array - map(sizeof(double), global_domain.ncells_active, NULL, - mpi_map_mapping_array, dvar_gathered, dvar_remapped); - // expand to full grid size - map(sizeof(double), global_domain.ncells_active, NULL, - filter_active_cells, dvar_remapped, dvar); - - // cleanup - free(dvar_gathered); - free(dvar_remapped); - } -} diff --git a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c b/vic/extensions/rout_rvic/src/rout_mpi_scatter.c deleted file mode 100644 index 6788c5901..000000000 --- a/vic/extensions/rout_rvic/src/rout_mpi_scatter.c +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - * @section DESCRIPTION - * - * MPI support routines for Routing - * - * @section LICENSE - * - * The Variable Infiltration Capacity (VIC) macroscale hydrological model - * Copyright (C) 2016 The Computational 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 - -/****************************************************************************** - * @brief Scatter double precision variable - * @details values from master node are scattered to the local nodes - *****************************************************************************/ -void -scatter_var_double(double *dvar, - double *local_var) -{ - extern MPI_Comm MPI_COMM_VIC; - extern domain_struct global_domain; - extern domain_struct local_domain; - extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - int status; - double *dvar_filtered = NULL; - double *dvar_mapped = NULL; - - if (mpi_rank == VIC_MPI_ROOT) { - dvar_filtered = - malloc(global_domain.ncells_active * sizeof(*dvar_filtered)); - check_alloc_status(dvar_filtered, "Memory allocation error."); - - dvar_mapped = - malloc(global_domain.ncells_active * sizeof(*dvar_mapped)); - check_alloc_status(dvar_mapped, "Memory allocation error."); - - // filter the active cells only - map(sizeof(double), global_domain.ncells_active, filter_active_cells, - NULL, dvar, dvar_filtered); - // map to prepare for MPI_Scatterv - map(sizeof(double), global_domain.ncells_active, mpi_map_mapping_array, - NULL, dvar_filtered, dvar_mapped); - free(dvar_filtered); - } - - // Scatter the results to the nodes, result for the local node is in the - // array *var (which is a function argument) - status = MPI_Scatterv(dvar_mapped, mpi_map_local_array_sizes, - mpi_map_global_array_offsets, MPI_DOUBLE, - local_var, local_domain.ncells_active, MPI_DOUBLE, - VIC_MPI_ROOT, MPI_COMM_VIC); - check_mpi_status(status, "MPI error."); - - if (mpi_rank == VIC_MPI_ROOT) { - free(dvar_mapped); - } -} diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 9fff1213b..199efd67a 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -76,7 +76,7 @@ rout_run(void) } // Gather the runoff for the local nodes - gather_var_double(var_domain_runoff, var_local_runoff); + gather_field_double(0.0, var_domain_runoff, var_local_runoff); // Run the convolution on the master node if (mpi_rank == VIC_MPI_ROOT) { @@ -84,7 +84,7 @@ rout_run(void) } // Scatter the discharge back to the local nodes - scatter_var_double(var_domain_discharge, var_local_discharge); + scatter_field_double(var_domain_discharge, var_local_discharge); // Write to output struct for (i = 0; i < local_domain.ncells_active; i++) { @@ -98,6 +98,5 @@ rout_run(void) // Free variables on the master node if (mpi_rank == VIC_MPI_ROOT) { free(var_domain_runoff); - free(var_domain_discharge); } } From 2549773c5aba4f9723daddd33be4e480fe9c35e7 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 14:39:41 -0700 Subject: [PATCH 225/294] Added routing extension outputs (state & discharge hist output) in the test suite --- tests/system/global.image.STEHE.allhistvars.txt | 1 + tests/system/global.image.STEHE.mpi.txt | 1 + tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt | 1 + tests/system/global.image.STEHE.restart.txt | 1 + tests/system/global.image.STEHE.txt | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/system/global.image.STEHE.allhistvars.txt b/tests/system/global.image.STEHE.allhistvars.txt index 7eb5fec49..cfe6e17b3 100644 --- a/tests/system/global.image.STEHE.allhistvars.txt +++ b/tests/system/global.image.STEHE.allhistvars.txt @@ -208,3 +208,4 @@ OUTVAR OUT_SNOW_SURFT_BAND OUTVAR OUT_SWE_BAND OUTVAR OUT_TIME_VICRUN_WALL OUTVAR OUT_TIME_VICRUN_CPU +OUTVAR OUT_DISCHARGE diff --git a/tests/system/global.image.STEHE.mpi.txt b/tests/system/global.image.STEHE.mpi.txt index 803186bd3..a93a3f1ba 100644 --- a/tests/system/global.image.STEHE.mpi.txt +++ b/tests/system/global.image.STEHE.mpi.txt @@ -71,3 +71,4 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_DISCHARGE diff --git a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt index ed4a1040b..46c6aeb45 100644 --- a/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt +++ b/tests/system/global.image.STEHE.restart.FROZEN_SOIL.txt @@ -70,3 +70,4 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_DISCHARGE diff --git a/tests/system/global.image.STEHE.restart.txt b/tests/system/global.image.STEHE.restart.txt index 49d6b9212..048fe9e0f 100644 --- a/tests/system/global.image.STEHE.restart.txt +++ b/tests/system/global.image.STEHE.restart.txt @@ -71,3 +71,4 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_DISCHARGE diff --git a/tests/system/global.image.STEHE.txt b/tests/system/global.image.STEHE.txt index e2907b766..d1ca7895d 100644 --- a/tests/system/global.image.STEHE.txt +++ b/tests/system/global.image.STEHE.txt @@ -72,3 +72,4 @@ OUTVAR OUT_SWE OUTVAR OUT_SOIL_MOIST OUTVAR OUT_ALBEDO OUTVAR OUT_SOIL_TEMP +OUTVAR OUT_DISCHARGE From 9580e78c3c9268bd7020835808a279e4878224b5 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 14:42:08 -0700 Subject: [PATCH 226/294] Minor updates for routing doc --- docs/Documentation/Drivers/Image/Routing.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/Documentation/Drivers/Image/Routing.md b/docs/Documentation/Drivers/Image/Routing.md index b23ba6c48..f0a633222 100644 --- a/docs/Documentation/Drivers/Image/Routing.md +++ b/docs/Documentation/Drivers/Image/Routing.md @@ -7,13 +7,18 @@ To run routing in VIC, an extra parameter file that defines unit hydrograph info ## 2. Specify the routing-specific information in the VIC global file The path of the routing-specific parameter file must be set in the [Global Parameter File](GlobalParam.md). For example: -`ROUT_PARAM ./RVIC_params.nc # Routing parameter path/file` +``` +ROUT_PARAM ./RVIC_params.nc # Routing parameter path/file +``` To output routed discharge results, an extra output variable has to be set in the [Global Parameter File](GlobalParam.md): -`OUTVAR OUT_DISCHARGE` +``` + +OUTVAR OUT_DISCHARGE +``` ## 3. Turn on the routing option when compiling VIC -There are two ways to turn on the routing option when compiling VIC: +You must turn on the routing option when you compile VIC. There are two ways to turn on the routing option when compiling VIC: 1) Add the following command line option to the `make` command when compiling VIC: `make ROUT=rout_rvic` From dd4f1afa4ddff66414b52a6db1fc30545893ec65 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 14:46:45 -0700 Subject: [PATCH 227/294] Ran uncrustify --- .../shared_image/include/vic_image_log.h | 2 +- .../shared_image/src/vic_mpi_support.c | 3 ++- vic/drivers/shared_image/src/vic_store.c | 7 ++--- vic/extensions/rout_rvic/src/rout_alloc.c | 19 ++++++------- .../rout_rvic/src/rout_convolution.c | 4 +-- vic/extensions/rout_rvic/src/rout_init.c | 12 ++++----- vic/extensions/rout_rvic/src/rout_run.c | 7 ++--- .../rout_rvic/src/state_metadata_extension.c | 1 - .../rout_rvic/src/vic_restore_extension.c | 9 +++---- .../rout_rvic/src/vic_store_extension.c | 27 +++++++++---------- vic/extensions/rout_stub/include/rout.h | 1 + .../rout_stub/src/state_metadata_extension.c | 1 - .../rout_stub/src/vic_restore_extension.c | 1 - .../rout_stub/src/vic_store_extension.c | 2 +- vic/vic_run/include/vic_log.h | 10 +++---- 15 files changed, 52 insertions(+), 54 deletions(-) diff --git a/vic/drivers/shared_image/include/vic_image_log.h b/vic/drivers/shared_image/include/vic_image_log.h index 2b650fbe8..151f2c191 100644 --- a/vic/drivers/shared_image/include/vic_image_log.h +++ b/vic/drivers/shared_image/include/vic_image_log.h @@ -66,7 +66,7 @@ #define check_nc_status(A, M, ...) if (A != NC_NOERR) {log_ncerr(A, M, \ ## __VA_ARGS__); \ errno = 0; exit( \ - EXIT_FAILURE);} + EXIT_FAILURE); } #define log_mpi_err(e, M, ...) print_trace(); \ print_mpi_error_str(e); fprintf(LOG_DEST, \ diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 544b5ec35..61ea0b2b8 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -2067,7 +2067,8 @@ gather_put_nc_field_schar(int nc_id, * @details values from master node are scattered to the local nodes *****************************************************************************/ void -scatter_field_double(double *dvar, double *var) +scatter_field_double(double *dvar, + double *var) { extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index 61ebbf12a..c35de6e06 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1334,7 +1334,8 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) // allocate memory for nc_vars nc_state_file->nc_vars = - calloc(N_STATE_VARS + N_STATE_VARS_EXT, sizeof(*(nc_state_file->nc_vars))); + calloc(N_STATE_VARS + N_STATE_VARS_EXT, + sizeof(*(nc_state_file->nc_vars))); check_alloc_status(nc_state_file->nc_vars, "Memory allocation error"); } @@ -1674,7 +1675,7 @@ initialize_state_file(char *filename, nc_state_file->node_size, &(nc_state_file->node_dimid)); check_nc_status(status, "Error defining soil_node in %s", filename); - + if (options.LAKES) { status = nc_def_dim(nc_state_file->nc_id, "lake_node", @@ -1685,7 +1686,7 @@ initialize_state_file(char *filename, // add extension dimensions initialize_state_file_extension(filename, nc_state_file); - + set_nc_state_var_info(nc_state_file); } diff --git a/vic/extensions/rout_rvic/src/rout_alloc.c b/vic/extensions/rout_rvic/src/rout_alloc.c index fa4c8994e..efda3bb57 100644 --- a/vic/extensions/rout_rvic/src/rout_alloc.c +++ b/vic/extensions/rout_rvic/src/rout_alloc.c @@ -34,20 +34,20 @@ rout_alloc(void) { extern int mpi_rank; if (mpi_rank == VIC_MPI_ROOT) { - extern domain_struct global_domain; - extern rout_struct rout; - int ivar; - size_t d1count[1]; - size_t d1start[1]; - extern filenames_struct filenames; - int status; + extern domain_struct global_domain; + extern rout_struct rout; + int ivar; + size_t d1count[1]; + size_t d1start[1]; + extern filenames_struct filenames; + int status; // open parameter file status = nc_open(filenames.rout_params.nc_filename, NC_NOWRITE, &(filenames.rout_params.nc_id)); check_nc_status(status, "Error opening %s", filenames.rout_params.nc_filename); - + d1count[0] = 0; d1start[0] = 1; @@ -130,7 +130,8 @@ rout_alloc(void) rout.rout_param.aggrunin = malloc( global_domain.ncells_total * sizeof(*rout.rout_param.aggrunin)); - check_alloc_status(rout.rout_param.aggrunin, "Memory allocation error."); + check_alloc_status(rout.rout_param.aggrunin, + "Memory allocation error."); rout.discharge = malloc(global_domain.ncells_total * sizeof(*rout.discharge)); diff --git a/vic/extensions/rout_rvic/src/rout_convolution.c b/vic/extensions/rout_rvic/src/rout_convolution.c index e10d30a3a..fdee6a3af 100644 --- a/vic/extensions/rout_rvic/src/rout_convolution.c +++ b/vic/extensions/rout_rvic/src/rout_convolution.c @@ -78,7 +78,7 @@ convolution(double *runoff, discharge[rout.rout_param.outlet_VIC_index[i_outlet]] = rout.ring[i_outlet] * global_domain.locations[rout.rout_param.outlet_VIC_index[i_outlet]] - .area - / (MM_PER_M * global_param.dt); + .area / + (MM_PER_M * global_param.dt); } } diff --git a/vic/extensions/rout_rvic/src/rout_init.c b/vic/extensions/rout_rvic/src/rout_init.c index 1ae161dac..4f33b6c22 100644 --- a/vic/extensions/rout_rvic/src/rout_init.c +++ b/vic/extensions/rout_rvic/src/rout_init.c @@ -32,12 +32,12 @@ void rout_init(void) { - extern int mpi_rank; - extern rout_struct rout; - extern domain_struct global_domain; - extern filenames_struct filenames; - int status; - + extern int mpi_rank; + extern rout_struct rout; + extern domain_struct global_domain; + extern filenames_struct filenames; + int status; + if (mpi_rank == VIC_MPI_ROOT) { int *ivar = NULL; double *dvar = NULL; diff --git a/vic/extensions/rout_rvic/src/rout_run.c b/vic/extensions/rout_rvic/src/rout_run.c index 199efd67a..1239fb728 100644 --- a/vic/extensions/rout_rvic/src/rout_run.c +++ b/vic/extensions/rout_rvic/src/rout_run.c @@ -56,16 +56,17 @@ rout_run(void) // Allocate memory for entire global_domain variables on the master node if (mpi_rank == VIC_MPI_ROOT) { - var_domain_runoff = malloc(global_domain.ncells_total * sizeof(*var_domain_runoff)); + var_domain_runoff = + malloc(global_domain.ncells_total * sizeof(*var_domain_runoff)); check_alloc_status(var_domain_runoff, "Memory allocation error."); var_domain_discharge = malloc(global_domain.ncells_total * sizeof(*var_domain_discharge)); check_alloc_status(var_domain_discharge, "Memory allocation error."); - + // Initialize discharge to zero for (i = 0; i < global_domain.ncells_total; i++) { - var_domain_discharge[i] = 0; + var_domain_discharge[i] = 0; } } diff --git a/vic/extensions/rout_rvic/src/state_metadata_extension.c b/vic/extensions/rout_rvic/src/state_metadata_extension.c index b52ff3324..92b3a536f 100644 --- a/vic/extensions/rout_rvic/src/state_metadata_extension.c +++ b/vic/extensions/rout_rvic/src/state_metadata_extension.c @@ -46,4 +46,3 @@ state_metadata_extension() strcpy(state_metadata[N_STATE_VARS + STATE_ROUT_RING].description, "unit hydrographs in the routing ring"); } - diff --git a/vic/extensions/rout_rvic/src/vic_restore_extension.c b/vic/extensions/rout_rvic/src/vic_restore_extension.c index 2e08c200b..0b5e1e236 100644 --- a/vic/extensions/rout_rvic/src/vic_restore_extension.c +++ b/vic/extensions/rout_rvic/src/vic_restore_extension.c @@ -34,11 +34,11 @@ void vic_restore_extension(nameid_struct *init_state_file, metadata_struct *state_metadata) { - extern int mpi_rank; - extern rout_struct rout; + extern int mpi_rank; + extern rout_struct rout; - size_t d2start[2]; - size_t d2count[2]; + size_t d2start[2]; + size_t d2count[2]; // write state variables @@ -55,4 +55,3 @@ vic_restore_extension(nameid_struct *init_state_file, d2start, d2count, rout.ring); } } - diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c index 19842d64f..30fe0b47e 100644 --- a/vic/extensions/rout_rvic/src/vic_store_extension.c +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -33,12 +33,12 @@ void vic_store_extension(nc_file_struct *nc_state_file) { - extern int mpi_rank; - extern rout_struct rout; + extern int mpi_rank; + extern rout_struct rout; - int status; - size_t d2start[2]; - nc_var_struct *nc_var; + int status; + size_t d2start[2]; + nc_var_struct *nc_var; // write state variables @@ -62,7 +62,7 @@ vic_store_extension(nc_file_struct *nc_state_file) void set_nc_state_file_info_extension(nc_file_struct *nc_state_file) { - extern rout_struct rout; + extern rout_struct rout; // set ids to MISSING nc_state_file->outlet_dimid = MISSING; @@ -71,7 +71,6 @@ set_nc_state_file_info_extension(nc_file_struct *nc_state_file) // set dimension sizes nc_state_file->outlet_size = rout.rout_param.n_outlets; nc_state_file->routing_timestep_size = rout.rout_param.full_time_length; - } /****************************************************************************** @@ -82,7 +81,7 @@ set_nc_state_var_info_extension(nc_file_struct *nc) { size_t i; size_t j; - + for (i = N_STATE_VARS; i < (N_STATE_VARS + N_STATE_VARS_EXT); i++) { nc->nc_vars[i].nc_varid = i; for (j = 0; j < MAXDIMS; j++) { @@ -94,7 +93,6 @@ set_nc_state_var_info_extension(nc_file_struct *nc) // Set the number of dimensions and dimids for each state variable switch (i) { - case (N_STATE_VARS + STATE_ROUT_RING): // 2d vars [routing_timestep, outlet] nc->nc_vars[i].nc_dims = 2; @@ -119,19 +117,18 @@ set_nc_state_var_info_extension(nc_file_struct *nc) *****************************************************************************/ void initialize_state_file_extension(char *filename, - nc_file_struct *nc_state_file) + nc_file_struct *nc_state_file) { int status; // Add routing dimensions status = nc_def_dim(nc_state_file->nc_id, "outlet", - nc_state_file->outlet_size, - &(nc_state_file->outlet_dimid)); + nc_state_file->outlet_size, + &(nc_state_file->outlet_dimid)); check_nc_status(status, "Error defining outlet in %s", filename); status = nc_def_dim(nc_state_file->nc_id, "routing_timestep", - nc_state_file->routing_timestep_size, - &(nc_state_file->routing_timestep_dimid)); + nc_state_file->routing_timestep_size, + &(nc_state_file->routing_timestep_dimid)); check_nc_status(status, "Error defining routing_timestep in %s", filename); - } diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index c6ffd1dbd..a176102cc 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -61,6 +61,7 @@ void state_metadata_extension(); void set_nc_state_file_info_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); void initialize_state_file_extension(char *, nc_file_struct *); + /****************************************************************************** * @brief Output state variable. *****************************************************************************/ diff --git a/vic/extensions/rout_stub/src/state_metadata_extension.c b/vic/extensions/rout_stub/src/state_metadata_extension.c index 0fd194497..3a67fc38d 100644 --- a/vic/extensions/rout_stub/src/state_metadata_extension.c +++ b/vic/extensions/rout_stub/src/state_metadata_extension.c @@ -34,4 +34,3 @@ void state_metadata_extension(nc_file_struct *nc_state_file) { } - diff --git a/vic/extensions/rout_stub/src/vic_restore_extension.c b/vic/extensions/rout_stub/src/vic_restore_extension.c index c07a07623..c65b97ca4 100644 --- a/vic/extensions/rout_stub/src/vic_restore_extension.c +++ b/vic/extensions/rout_stub/src/vic_restore_extension.c @@ -35,4 +35,3 @@ vic_restore_extension(nameid_struct *init_state_file, metadata_struct *state_metadata) { } - diff --git a/vic/extensions/rout_stub/src/vic_store_extension.c b/vic/extensions/rout_stub/src/vic_store_extension.c index e81105faa..f5d0e3dd3 100644 --- a/vic/extensions/rout_stub/src/vic_store_extension.c +++ b/vic/extensions/rout_stub/src/vic_store_extension.c @@ -57,6 +57,6 @@ set_nc_state_var_info_extension(nc_file_struct *nc) *****************************************************************************/ void initialize_state_file_extension(char *filename, - nc_file_struct *nc_state_file) + nc_file_struct *nc_state_file) { } diff --git a/vic/vic_run/include/vic_log.h b/vic/vic_run/include/vic_log.h index cfaf4a174..819e17457 100644 --- a/vic/vic_run/include/vic_log.h +++ b/vic/vic_run/include/vic_log.h @@ -126,17 +126,17 @@ void setup_logging(int id, char log_path[], FILE **logfile); // here means that it just doesn't print a message, it still does the // check. MKAY? #define check_debug(A, M, ...) if (!(A)) {debug(M, ## __VA_ARGS__); errno = 0; \ - exit(EXIT_FAILURE);} + exit(EXIT_FAILURE); } #define check(A, M, ...) if (!(A)) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ - EXIT_FAILURE);} + EXIT_FAILURE); } #define check_alloc_status(A, M, \ ...) if (A == NULL) {log_err(M, ## __VA_ARGS__); \ errno = 0; exit( \ - EXIT_FAILURE);} + EXIT_FAILURE); } #define sentinel(M, ...) {log_err(M, ## __VA_ARGS__); errno = 0; exit( \ - EXIT_FAILURE);} + EXIT_FAILURE); } #define check_mem(A) check((A), "Out of memory.") @@ -144,7 +144,7 @@ void setup_logging(int id, char log_path[], FILE **logfile); E), E, __FUNCTION__, __LINE__) #define error_response(F, C, M, ...) {Response_send_status(F, &HTTP_ ## C); \ - sentinel(M, ## __VA_ARGS__);} + sentinel(M, ## __VA_ARGS__); } #define error_unless(T, F, C, M, ...) if (!(T)) \ error_response(F, C, M, ## __VA_ARGS__) From f061e51802dfb055f2a5a50a15542c4079484873 Mon Sep 17 00:00:00 2001 From: ymao Date: Mon, 16 Oct 2017 14:55:09 -0700 Subject: [PATCH 228/294] Removed unused variables in vic_mpi_support.c --- vic/drivers/shared_image/src/vic_mpi_support.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 61ea0b2b8..ed92f10fc 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -2126,18 +2126,9 @@ get_scatter_nc_field_double(nameid_struct *nc_nameid, size_t *count, double *var) { - extern MPI_Comm MPI_COMM_VIC; extern domain_struct global_domain; - extern domain_struct local_domain; extern int mpi_rank; - extern int *mpi_map_global_array_offsets; - extern int *mpi_map_local_array_sizes; - extern size_t *filter_active_cells; - extern size_t *mpi_map_mapping_array; - int status; double *dvar = NULL; - double *dvar_filtered = NULL; - double *dvar_mapped = NULL; // Read variable from netcdf if (mpi_rank == VIC_MPI_ROOT) { From d3868d9aa0312bd6912713da5796fea2e404a1e2 Mon Sep 17 00:00:00 2001 From: ymao Date: Tue, 17 Oct 2017 15:17:54 -0700 Subject: [PATCH 229/294] Remove dependence of extension header file rout.h on image driver (it should only depend on shared_image) --- vic/extensions/rout_rvic/include/rout.h | 2 +- vic/extensions/rout_stub/include/rout.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 189231d0d..6230964fa 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -29,7 +29,7 @@ #define ROUT_EXT "rout_rvic" #include -#include +#include /****************************************************************************** * @brief Routing Structs diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index a176102cc..35e9e0dae 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -30,7 +30,7 @@ #define ROUT_EXT "rout_stub" #include -#include +#include /****************************************************************************** * @brief Routing Structs From ab6ea9c73765b8a70bef3bae8dada6c251d42831 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 20 Oct 2017 10:59:30 -0700 Subject: [PATCH 230/294] remove redundant definition of frozen soils iteration max number FROZEN_MAXITER (#747) --- vic/drivers/shared_all/src/initialize_parameters.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index d696b9d7a..1add5498d 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -227,7 +227,4 @@ initialize_parameters() param.ROOT_BRENT_MAXITER = 1000; param.ROOT_BRENT_TSTEP = 10; param.ROOT_BRENT_T = 1.0e-7; - - // Frozen Soil Parameters - param.FROZEN_MAXITER = 1000; } From bfb3e65f58860686d6b07b5c608a7aa7af95c040 Mon Sep 17 00:00:00 2001 From: ymao Date: Fri, 20 Oct 2017 16:55:58 -0700 Subject: [PATCH 231/294] Small final updates for the routing extension, including: - Minor docs update - Rename extension function to be routing-extension-specific --- docs/Development/ReleaseNotes.md | 2 +- .../shared_image/include/vic_driver_shared_image.h | 2 +- vic/drivers/shared_image/src/state_metadata.c | 2 +- vic/drivers/shared_image/src/vic_restore.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 8 ++++---- vic/extensions/rout_rvic/include/rout.h | 12 ++++++------ ...{image_extension_name.h => rout_extension_name.h} | 0 .../rout_rvic/src/state_metadata_extension.c | 2 +- vic/extensions/rout_rvic/src/vic_restore_extension.c | 4 ++-- vic/extensions/rout_rvic/src/vic_store_extension.c | 10 +++++----- vic/extensions/rout_stub/include/rout.h | 12 ++++++------ ...{image_extension_name.h => rout_extension_name.h} | 0 .../rout_stub/src/state_metadata_extension.c | 2 +- vic/extensions/rout_stub/src/vic_restore_extension.c | 4 ++-- vic/extensions/rout_stub/src/vic_store_extension.c | 10 +++++----- 15 files changed, 36 insertions(+), 36 deletions(-) rename vic/extensions/rout_rvic/include/{image_extension_name.h => rout_extension_name.h} (100%) rename vic/extensions/rout_stub/include/{image_extension_name.h => rout_extension_name.h} (100%) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index d1632e692..1824d489d 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -107,7 +107,7 @@ To check which release of VIC you are running: The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. -8. Added routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) +8. Added streamflow routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 47a8c90ec..97f486213 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -27,7 +27,7 @@ #ifndef VIC_DRIVER_SHARED_IMAGE_H #define VIC_DRIVER_SHARED_IMAGE_H -#include +#include #include #include #include diff --git a/vic/drivers/shared_image/src/state_metadata.c b/vic/drivers/shared_image/src/state_metadata.c index fb099b2be..4071f2470 100644 --- a/vic/drivers/shared_image/src/state_metadata.c +++ b/vic/drivers/shared_image/src/state_metadata.c @@ -710,5 +710,5 @@ set_state_meta_data_info() } // STATE_ROUT_RING - state_metadata_extension(); + state_metadata_rout_extension(); } diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index db18e4347..e08b6ee75 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -884,7 +884,7 @@ vic_restore(void) } // routing ring - vic_restore_extension(&(filenames.init_state), state_metadata); + vic_restore_rout_extension(&(filenames.init_state), state_metadata); free(ivar); free(dvar); diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index c35de6e06..005728d81 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1271,7 +1271,7 @@ vic_store(dmy_struct *dmy_state, } // store extension variables - vic_store_extension(&nc_state_file); + vic_store_rout_extension(&nc_state_file); // close the netcdf file if it is still open @@ -1330,7 +1330,7 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->veg_size = options.NVEGTYPES; // set ids and dimension sizes of the extension variables - set_nc_state_file_info_extension(nc_state_file); + set_nc_state_file_info_rout_extension(nc_state_file); // allocate memory for nc_vars nc_state_file->nc_vars = @@ -1543,7 +1543,7 @@ set_nc_state_var_info(nc_file_struct *nc) log_err("Too many dimensions specified in variable %zu", i); } } - set_nc_state_var_info_extension(nc); + set_nc_state_var_info_rout_extension(nc); } /****************************************************************************** @@ -1685,7 +1685,7 @@ initialize_state_file(char *filename, } // add extension dimensions - initialize_state_file_extension(filename, nc_state_file); + initialize_state_file_rout_extension(filename, nc_state_file); set_nc_state_var_info(nc_state_file); } diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 6230964fa..b770c1c51 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -82,12 +82,12 @@ void gather_var_double(double *, double *); *****************************************************************************/ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); -void vic_store_extension(nc_file_struct *); -void vic_restore_extension(nameid_struct *, metadata_struct *); -void state_metadata_extension(); -void set_nc_state_file_info_extension(nc_file_struct *); -void set_nc_state_var_info_extension(nc_file_struct *); -void initialize_state_file_extension(char *, nc_file_struct *); +void vic_store_rout_extension(nc_file_struct *); +void vic_restore_rout_extension(nameid_struct *, metadata_struct *); +void state_metadata_rout_extension(); +void set_nc_state_file_info_rout_extension(nc_file_struct *); +void set_nc_state_var_info_rout_extension(nc_file_struct *); +void initialize_state_file_rout_extension(char *, nc_file_struct *); /****************************************************************************** * @brief Output state variable. diff --git a/vic/extensions/rout_rvic/include/image_extension_name.h b/vic/extensions/rout_rvic/include/rout_extension_name.h similarity index 100% rename from vic/extensions/rout_rvic/include/image_extension_name.h rename to vic/extensions/rout_rvic/include/rout_extension_name.h diff --git a/vic/extensions/rout_rvic/src/state_metadata_extension.c b/vic/extensions/rout_rvic/src/state_metadata_extension.c index 92b3a536f..0e4ac875c 100644 --- a/vic/extensions/rout_rvic/src/state_metadata_extension.c +++ b/vic/extensions/rout_rvic/src/state_metadata_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -state_metadata_extension() +state_metadata_rout_extension() { extern metadata_struct state_metadata[N_STATE_VARS + N_STATE_VARS_EXT]; diff --git a/vic/extensions/rout_rvic/src/vic_restore_extension.c b/vic/extensions/rout_rvic/src/vic_restore_extension.c index 0b5e1e236..10cc9dca8 100644 --- a/vic/extensions/rout_rvic/src/vic_restore_extension.c +++ b/vic/extensions/rout_rvic/src/vic_restore_extension.c @@ -31,8 +31,8 @@ * @brief Save model state. *****************************************************************************/ void -vic_restore_extension(nameid_struct *init_state_file, - metadata_struct *state_metadata) +vic_restore_rout_extension(nameid_struct *init_state_file, + metadata_struct *state_metadata) { extern int mpi_rank; extern rout_struct rout; diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c index 30fe0b47e..6fed8c230 100644 --- a/vic/extensions/rout_rvic/src/vic_store_extension.c +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(nc_file_struct *nc_state_file) +vic_store_rout_extension(nc_file_struct *nc_state_file) { extern int mpi_rank; extern rout_struct rout; @@ -60,7 +60,7 @@ vic_store_extension(nc_file_struct *nc_state_file) * @brief Setup state file netcdf structure *****************************************************************************/ void -set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +set_nc_state_file_info_rout_extension(nc_file_struct *nc_state_file) { extern rout_struct rout; @@ -77,7 +77,7 @@ set_nc_state_file_info_extension(nc_file_struct *nc_state_file) * @brief Setup state variable dimensions, types, etc. *****************************************************************************/ void -set_nc_state_var_info_extension(nc_file_struct *nc) +set_nc_state_var_info_rout_extension(nc_file_struct *nc) { size_t i; size_t j; @@ -116,8 +116,8 @@ set_nc_state_var_info_extension(nc_file_struct *nc) and adding metadata. *****************************************************************************/ void -initialize_state_file_extension(char *filename, - nc_file_struct *nc_state_file) +initialize_state_file_rout_extension(char *filename, + nc_file_struct *nc_state_file) { int status; diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 35e9e0dae..436fa4e04 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -55,12 +55,12 @@ void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing -void vic_store_extension(nc_file_struct *); -void vic_restore_extension(nameid_struct *, metadata_struct *); -void state_metadata_extension(); -void set_nc_state_file_info_extension(nc_file_struct *); -void set_nc_state_var_info_extension(nc_file_struct *); -void initialize_state_file_extension(char *, nc_file_struct *); +void vic_store_rout_extension(nc_file_struct *); +void vic_restore_rout_extension(nameid_struct *, metadata_struct *); +void state_metadata_rout_extension(); +void set_nc_state_file_info_rout_extension(nc_file_struct *); +void set_nc_state_var_info_rout_extension(nc_file_struct *); +void initialize_state_file_rout_extension(char *, nc_file_struct *); /****************************************************************************** * @brief Output state variable. diff --git a/vic/extensions/rout_stub/include/image_extension_name.h b/vic/extensions/rout_stub/include/rout_extension_name.h similarity index 100% rename from vic/extensions/rout_stub/include/image_extension_name.h rename to vic/extensions/rout_stub/include/rout_extension_name.h diff --git a/vic/extensions/rout_stub/src/state_metadata_extension.c b/vic/extensions/rout_stub/src/state_metadata_extension.c index 3a67fc38d..f848ebb6f 100644 --- a/vic/extensions/rout_stub/src/state_metadata_extension.c +++ b/vic/extensions/rout_stub/src/state_metadata_extension.c @@ -31,6 +31,6 @@ * @brief Save model state. *****************************************************************************/ void -state_metadata_extension(nc_file_struct *nc_state_file) +state_metadata_rout_extension(nc_file_struct *nc_state_file) { } diff --git a/vic/extensions/rout_stub/src/vic_restore_extension.c b/vic/extensions/rout_stub/src/vic_restore_extension.c index c65b97ca4..99bde10cc 100644 --- a/vic/extensions/rout_stub/src/vic_restore_extension.c +++ b/vic/extensions/rout_stub/src/vic_restore_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_restore_extension(nameid_struct *init_state_file, - metadata_struct *state_metadata) +vic_restore_rout_extension(nameid_struct *init_state_file, + metadata_struct *state_metadata) { } diff --git a/vic/extensions/rout_stub/src/vic_store_extension.c b/vic/extensions/rout_stub/src/vic_store_extension.c index f5d0e3dd3..71dfb7782 100644 --- a/vic/extensions/rout_stub/src/vic_store_extension.c +++ b/vic/extensions/rout_stub/src/vic_store_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(nc_file_struct *nc_state_file) +vic_store_rout_extension(nc_file_struct *nc_state_file) { } @@ -39,7 +39,7 @@ vic_store_extension(nc_file_struct *nc_state_file) * @brief Setup state file netcdf structure *****************************************************************************/ void -set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +set_nc_state_file_info_rout_extension(nc_file_struct *nc_state_file) { } @@ -47,7 +47,7 @@ set_nc_state_file_info_extension(nc_file_struct *nc_state_file) * @brief Setup state variable dimensions, types, etc. *****************************************************************************/ void -set_nc_state_var_info_extension(nc_file_struct *nc) +set_nc_state_var_info_rout_extension(nc_file_struct *nc) { } @@ -56,7 +56,7 @@ set_nc_state_var_info_extension(nc_file_struct *nc) and adding metadata. *****************************************************************************/ void -initialize_state_file_extension(char *filename, - nc_file_struct *nc_state_file) +initialize_state_file_rout_extension(char *filename, + nc_file_struct *nc_state_file) { } From 8138db3b163022b968a9947ab24b97149f2006b3 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 23 Oct 2017 15:25:00 +0200 Subject: [PATCH 232/294] applied changes suggested by joe --- docs/Development/ReleaseNotes.md | 2 +- vic/drivers/image/Makefile | 2 +- .../shared_image/include/vic_driver_shared_image.h | 2 +- vic/drivers/shared_image/src/vic_restore.c | 2 +- vic/drivers/shared_image/src/vic_store.c | 6 +++--- vic/extensions/rout_rvic/include/rout.h | 8 ++++---- .../{image_extension_name.h => rout_extension_name.h} | 0 vic/extensions/rout_rvic/src/vic_restore_extension.c | 2 +- vic/extensions/rout_rvic/src/vic_store_extension.c | 6 +++--- vic/extensions/rout_stub/include/rout.h | 8 ++++---- .../{image_extension_name.h => rout_extension_name.h} | 0 vic/extensions/rout_stub/src/vic_restore_extension.c | 2 +- vic/extensions/rout_stub/src/vic_store_extension.c | 6 +++--- 13 files changed, 23 insertions(+), 23 deletions(-) rename vic/extensions/rout_rvic/include/{image_extension_name.h => rout_extension_name.h} (100%) rename vic/extensions/rout_stub/include/{image_extension_name.h => rout_extension_name.h} (100%) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index d1632e692..1824d489d 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -107,7 +107,7 @@ To check which release of VIC you are running: The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. -8. Added routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) +8. Added streamflow routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 1403f5b2a..53b4dd5e8 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -46,7 +46,7 @@ EXTPATH = ../../extensions # |---------- |--------------------------------- | # | rout_stub | Stub routing model (no routing) | # | rout_rvic | Use RVIC routing scheme | -ROUT=rout_stub +ROUT := rout_stub include ${EXTPATH}/${ROUT}/rout.mk diff --git a/vic/drivers/shared_image/include/vic_driver_shared_image.h b/vic/drivers/shared_image/include/vic_driver_shared_image.h index 47a8c90ec..97f486213 100644 --- a/vic/drivers/shared_image/include/vic_driver_shared_image.h +++ b/vic/drivers/shared_image/include/vic_driver_shared_image.h @@ -27,7 +27,7 @@ #ifndef VIC_DRIVER_SHARED_IMAGE_H #define VIC_DRIVER_SHARED_IMAGE_H -#include +#include #include #include #include diff --git a/vic/drivers/shared_image/src/vic_restore.c b/vic/drivers/shared_image/src/vic_restore.c index db18e4347..e08b6ee75 100644 --- a/vic/drivers/shared_image/src/vic_restore.c +++ b/vic/drivers/shared_image/src/vic_restore.c @@ -884,7 +884,7 @@ vic_restore(void) } // routing ring - vic_restore_extension(&(filenames.init_state), state_metadata); + vic_restore_rout_extension(&(filenames.init_state), state_metadata); free(ivar); free(dvar); diff --git a/vic/drivers/shared_image/src/vic_store.c b/vic/drivers/shared_image/src/vic_store.c index c35de6e06..f3611e134 100644 --- a/vic/drivers/shared_image/src/vic_store.c +++ b/vic/drivers/shared_image/src/vic_store.c @@ -1271,7 +1271,7 @@ vic_store(dmy_struct *dmy_state, } // store extension variables - vic_store_extension(&nc_state_file); + vic_store_rout_extension(&nc_state_file); // close the netcdf file if it is still open @@ -1330,7 +1330,7 @@ set_nc_state_file_info(nc_file_struct *nc_state_file) nc_state_file->veg_size = options.NVEGTYPES; // set ids and dimension sizes of the extension variables - set_nc_state_file_info_extension(nc_state_file); + set_nc_state_file_info_rout_extension(nc_state_file); // allocate memory for nc_vars nc_state_file->nc_vars = @@ -1685,7 +1685,7 @@ initialize_state_file(char *filename, } // add extension dimensions - initialize_state_file_extension(filename, nc_state_file); + initialize_state_file_rout_extension(filename, nc_state_file); set_nc_state_var_info(nc_state_file); } diff --git a/vic/extensions/rout_rvic/include/rout.h b/vic/extensions/rout_rvic/include/rout.h index 6230964fa..1738efba9 100644 --- a/vic/extensions/rout_rvic/include/rout.h +++ b/vic/extensions/rout_rvic/include/rout.h @@ -82,12 +82,12 @@ void gather_var_double(double *, double *); *****************************************************************************/ void get_global_param_rout(FILE *gp); void cshift(double *, int, int, int, int); -void vic_store_extension(nc_file_struct *); -void vic_restore_extension(nameid_struct *, metadata_struct *); +void vic_store_rout_extension(nc_file_struct *); +void vic_restore_rout_extension(nameid_struct *, metadata_struct *); void state_metadata_extension(); -void set_nc_state_file_info_extension(nc_file_struct *); +void set_nc_state_file_info_rout_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); -void initialize_state_file_extension(char *, nc_file_struct *); +void initialize_state_file_rout_extension(char *, nc_file_struct *); /****************************************************************************** * @brief Output state variable. diff --git a/vic/extensions/rout_rvic/include/image_extension_name.h b/vic/extensions/rout_rvic/include/rout_extension_name.h similarity index 100% rename from vic/extensions/rout_rvic/include/image_extension_name.h rename to vic/extensions/rout_rvic/include/rout_extension_name.h diff --git a/vic/extensions/rout_rvic/src/vic_restore_extension.c b/vic/extensions/rout_rvic/src/vic_restore_extension.c index 0b5e1e236..66639ee61 100644 --- a/vic/extensions/rout_rvic/src/vic_restore_extension.c +++ b/vic/extensions/rout_rvic/src/vic_restore_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_restore_extension(nameid_struct *init_state_file, +vic_restore_rout_extension(nameid_struct *init_state_file, metadata_struct *state_metadata) { extern int mpi_rank; diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c index 30fe0b47e..3855a2b23 100644 --- a/vic/extensions/rout_rvic/src/vic_store_extension.c +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(nc_file_struct *nc_state_file) +vic_store_rout_extension(nc_file_struct *nc_state_file) { extern int mpi_rank; extern rout_struct rout; @@ -60,7 +60,7 @@ vic_store_extension(nc_file_struct *nc_state_file) * @brief Setup state file netcdf structure *****************************************************************************/ void -set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +set_nc_state_file_info_rout_extension(nc_file_struct *nc_state_file) { extern rout_struct rout; @@ -116,7 +116,7 @@ set_nc_state_var_info_extension(nc_file_struct *nc) and adding metadata. *****************************************************************************/ void -initialize_state_file_extension(char *filename, +initialize_state_file_rout_extension(char *filename, nc_file_struct *nc_state_file) { int status; diff --git a/vic/extensions/rout_stub/include/rout.h b/vic/extensions/rout_stub/include/rout.h index 35e9e0dae..673e33947 100644 --- a/vic/extensions/rout_stub/include/rout.h +++ b/vic/extensions/rout_stub/include/rout.h @@ -55,12 +55,12 @@ void rout_alloc(void); // allocate memory void rout_init(void); // initialize model parameters from parameter files void rout_run(void); // run routing over the domain void rout_finalize(void); // clean up routine for routing -void vic_store_extension(nc_file_struct *); -void vic_restore_extension(nameid_struct *, metadata_struct *); +void vic_store_rout_extension(nc_file_struct *); +void vic_restore_rout_extension(nameid_struct *, metadata_struct *); void state_metadata_extension(); -void set_nc_state_file_info_extension(nc_file_struct *); +void set_nc_state_file_info_rout_extension(nc_file_struct *); void set_nc_state_var_info_extension(nc_file_struct *); -void initialize_state_file_extension(char *, nc_file_struct *); +void initialize_state_file_rout_extension(char *, nc_file_struct *); /****************************************************************************** * @brief Output state variable. diff --git a/vic/extensions/rout_stub/include/image_extension_name.h b/vic/extensions/rout_stub/include/rout_extension_name.h similarity index 100% rename from vic/extensions/rout_stub/include/image_extension_name.h rename to vic/extensions/rout_stub/include/rout_extension_name.h diff --git a/vic/extensions/rout_stub/src/vic_restore_extension.c b/vic/extensions/rout_stub/src/vic_restore_extension.c index c65b97ca4..f7c5895c4 100644 --- a/vic/extensions/rout_stub/src/vic_restore_extension.c +++ b/vic/extensions/rout_stub/src/vic_restore_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_restore_extension(nameid_struct *init_state_file, +vic_restore_rout_extension(nameid_struct *init_state_file, metadata_struct *state_metadata) { } diff --git a/vic/extensions/rout_stub/src/vic_store_extension.c b/vic/extensions/rout_stub/src/vic_store_extension.c index f5d0e3dd3..2305ed97a 100644 --- a/vic/extensions/rout_stub/src/vic_store_extension.c +++ b/vic/extensions/rout_stub/src/vic_store_extension.c @@ -31,7 +31,7 @@ * @brief Save model state. *****************************************************************************/ void -vic_store_extension(nc_file_struct *nc_state_file) +vic_store_rout_extension(nc_file_struct *nc_state_file) { } @@ -39,7 +39,7 @@ vic_store_extension(nc_file_struct *nc_state_file) * @brief Setup state file netcdf structure *****************************************************************************/ void -set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +set_nc_state_file_info_rout_extension(nc_file_struct *nc_state_file) { } @@ -56,7 +56,7 @@ set_nc_state_var_info_extension(nc_file_struct *nc) and adding metadata. *****************************************************************************/ void -initialize_state_file_extension(char *filename, +initialize_state_file_rout_extension(char *filename, nc_file_struct *nc_state_file) { } From 9270582f9d924a8fd4c5f7c04bb122ab480f458e Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 30 Oct 2017 10:39:59 +0100 Subject: [PATCH 233/294] minor changes --- vic/drivers/image/Makefile | 2 +- vic/extensions/rout_rvic/src/vic_store_extension.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vic/drivers/image/Makefile b/vic/drivers/image/Makefile index 53b4dd5e8..1403f5b2a 100644 --- a/vic/drivers/image/Makefile +++ b/vic/drivers/image/Makefile @@ -46,7 +46,7 @@ EXTPATH = ../../extensions # |---------- |--------------------------------- | # | rout_stub | Stub routing model (no routing) | # | rout_rvic | Use RVIC routing scheme | -ROUT := rout_stub +ROUT=rout_stub include ${EXTPATH}/${ROUT}/rout.mk diff --git a/vic/extensions/rout_rvic/src/vic_store_extension.c b/vic/extensions/rout_rvic/src/vic_store_extension.c index c881fb1b0..6fed8c230 100644 --- a/vic/extensions/rout_rvic/src/vic_store_extension.c +++ b/vic/extensions/rout_rvic/src/vic_store_extension.c @@ -60,7 +60,7 @@ vic_store_rout_extension(nc_file_struct *nc_state_file) * @brief Setup state file netcdf structure *****************************************************************************/ void -set_nc_state_file_info_extension(nc_file_struct *nc_state_file) +set_nc_state_file_info_rout_extension(nc_file_struct *nc_state_file) { extern rout_struct rout; @@ -77,7 +77,7 @@ set_nc_state_file_info_extension(nc_file_struct *nc_state_file) * @brief Setup state variable dimensions, types, etc. *****************************************************************************/ void -set_nc_state_var_info_extension(nc_file_struct *nc) +set_nc_state_var_info_rout_extension(nc_file_struct *nc) { size_t i; size_t j; @@ -116,8 +116,8 @@ set_nc_state_var_info_extension(nc_file_struct *nc) and adding metadata. *****************************************************************************/ void -initialize_state_file_extension(char *filename, - nc_file_struct *nc_state_file) +initialize_state_file_rout_extension(char *filename, + nc_file_struct *nc_state_file) { int status; From 8afe2bbbcd64096a25df8134eb99b307e47fab78 Mon Sep 17 00:00:00 2001 From: ted Date: Sat, 18 Nov 2017 18:52:15 -0700 Subject: [PATCH 234/294] Changed "fcan" to "fcanopy" in vic/drivers/image/src/vic_force.c to be consistent with vic_init.c --- vic/drivers/image/src/vic_force.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 1209335e0..436c81358 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -335,15 +335,16 @@ vic_force(void) } } - // Partial veg cover fraction: fcan + // Partial veg cover fraction: fcanopy if (options.FCAN_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "fcan", - d4start, d4count, dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), + "fcanopy", d4start, d4count, + dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { From 0d6f3f2bf4b52c481c56aecf6cd0faaa99333330 Mon Sep 17 00:00:00 2001 From: ted Date: Sun, 3 Dec 2017 13:55:55 -0700 Subject: [PATCH 235/294] Fixed typo. --- vic/drivers/shared_all/src/history_metadata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index e38a39c76..75746a94c 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -391,7 +391,7 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_BF_IN].standard_name, "infiltration_amount"); strcpy(out_metadata[OUT_LAKE_BF_IN].units, "mm"); strcpy(out_metadata[OUT_LAKE_BF_IN].description, - "oisture that reaches top of soil column"); + "incoming baseflow from lake catchment"); /* incoming volumetric baseflow from lake catchment [m3] */ strcpy(out_metadata[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); From 294b251de056efbb18e45b46d49f3e134bba6294 Mon Sep 17 00:00:00 2001 From: ted Date: Sun, 3 Dec 2017 14:38:19 -0700 Subject: [PATCH 236/294] Removing MAX_VEG and MAX_BAND... --- vic/drivers/classic/src/display_current_settings.c | 1 - vic/drivers/classic/src/read_vegparam.c | 6 ------ vic/drivers/image/src/display_current_settings.c | 1 - vic/vic_run/src/vic_run.c | 11 ++--------- 4 files changed, 2 insertions(+), 17 deletions(-) diff --git a/vic/drivers/classic/src/display_current_settings.c b/vic/drivers/classic/src/display_current_settings.c index ccd3a9e91..a0e4dd0f3 100644 --- a/vic/drivers/classic/src/display_current_settings.c +++ b/vic/drivers/classic/src/display_current_settings.c @@ -65,7 +65,6 @@ display_current_settings(int mode) fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/classic/src/read_vegparam.c b/vic/drivers/classic/src/read_vegparam.c index c322a0833..13ea80878 100644 --- a/vic/drivers/classic/src/read_vegparam.c +++ b/vic/drivers/classic/src/read_vegparam.c @@ -92,12 +92,6 @@ read_vegparam(FILE *vegparam, if (vegcel != gridcel) { log_err("Grid cell %d not found", gridcel); } - if (vegetat_type_num >= MAX_VEG) { - log_err("Vegetation parameter file wants more vegetation tiles in " - "grid cell %i (%i) than are allowed by MAX_VEG (%i) [NOTE: " - "bare soil class is assumed]. Edit vic_run/vic_def.h and " - "recompile.", gridcel, vegetat_type_num + 1, MAX_VEG); - } // Make sure to allocate extra memory for bare soil tile // and optionally an above-treeline veg tile diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 4bf4f71f6..75f156dba 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -67,7 +67,6 @@ display_current_settings(int mode) fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index df4508090..942146539 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -58,8 +58,8 @@ vic_run(force_data_struct *force, double out_rain[MAX_BANDS]; double out_snow[MAX_BANDS]; double dp; - double ice0[MAX_BANDS]; - double moist0[MAX_BANDS]; + double ice0; + double moist0; double surf_atten; double wind_h; double height; @@ -128,13 +128,6 @@ vic_run(force_data_struct *force, force->out_rain = 0; force->out_snow = 0; - /** initialize moist0 and ice0 **/ - // this could be removed if we make them scalars - for (band = 0; band < options.SNOW_BAND; band++) { - moist0[band] = 0; - ice0[band] = 0; - } - /************************************************** Solve Energy and/or Water Balance for Each Vegetation Tile From cf4755cac6ad9123b0eef318682b88767efea350 Mon Sep 17 00:00:00 2001 From: ted Date: Sun, 3 Dec 2017 15:22:30 -0700 Subject: [PATCH 237/294] Removed MAX_VEG and MAX_BAND. Replaced arrays that were statically allocated using these terms with dynamically allocated arrays. --- .../cesm/src/display_current_settings.c | 2 - vic/drivers/cesm/src/get_global_param.c | 9 +- .../classic/src/display_current_settings.c | 1 - vic/drivers/classic/src/get_global_param.c | 6 - vic/drivers/classic/src/parse_output_info.c | 1 - vic/drivers/classic/src/read_veglib.c | 1 + .../image/src/display_current_settings.c | 1 - .../python/src/display_current_settings.c | 2 - .../src/compute_derived_state_vars.c | 32 ++-- vic/drivers/shared_all/src/put_data.c | 6 +- vic/drivers/shared_image/src/vic_alloc.c | 2 +- vic/vic_run/include/vic_def.h | 8 +- vic/vic_run/src/vic_run.c | 178 +++++++++--------- 13 files changed, 125 insertions(+), 124 deletions(-) diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 029575613..85a0dc2d9 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -56,14 +56,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 89ab7c3c4..e43243633 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -562,14 +562,7 @@ validate_options(option_struct *options) } // Validate the elevation band file information - if (options->SNOW_BAND > 1) { - if (options->SNOW_BAND > MAX_BANDS) { - log_err("Global file wants more snow bands (%zu) than are " - "defined by MAX_BANDS (%d). Edit vicNl_def.h and " - "recompile.", options->SNOW_BAND, MAX_BANDS); - } - } - else if (options->SNOW_BAND <= 0) { + if (options->SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " "file (%zu). Number of bands must be >= 1.", options->SNOW_BAND); diff --git a/vic/drivers/classic/src/display_current_settings.c b/vic/drivers/classic/src/display_current_settings.c index a0e4dd0f3..f0c5d7c8f 100644 --- a/vic/drivers/classic/src/display_current_settings.c +++ b/vic/drivers/classic/src/display_current_settings.c @@ -58,7 +58,6 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 4a6534ab9..6ea2726a3 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -1170,12 +1170,6 @@ get_global_param(FILE *gp) "file on the line that begins with \"SNOW_BAND\" " "(after the number of bands).", options.SNOW_BAND); } - if (options.SNOW_BAND > MAX_BANDS) { - log_err("Global file wants more snow bands (%zu) than are " - "defined by MAX_BANDS (%d). Edit vic_run/include/vic_def.h " - "and recompile.", options.SNOW_BAND, - MAX_BANDS); - } } else if (options.SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " diff --git a/vic/drivers/classic/src/parse_output_info.c b/vic/drivers/classic/src/parse_output_info.c index 1641a406e..d661e1f6d 100644 --- a/vic/drivers/classic/src/parse_output_info.c +++ b/vic/drivers/classic/src/parse_output_info.c @@ -36,7 +36,6 @@ parse_output_info(FILE *gp, dmy_struct *dmy_current) { extern option_struct options; - extern global_param_struct global_param; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; diff --git a/vic/drivers/classic/src/read_veglib.c b/vic/drivers/classic/src/read_veglib.c index 703074a04..af7853846 100644 --- a/vic/drivers/classic/src/read_veglib.c +++ b/vic/drivers/classic/src/read_veglib.c @@ -62,6 +62,7 @@ read_veglib(FILE *veglib, // +1 for bare soil temp = calloc(Nveg_type + 1, sizeof(*temp)); + options.NVEGTYPES = Nveg_type + 1; fscanf(veglib, "%s", str); i = 0; diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 75f156dba..e02df18cf 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -60,7 +60,6 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); diff --git a/vic/drivers/python/src/display_current_settings.c b/vic/drivers/python/src/display_current_settings.c index 305ea4892..8764ab752 100644 --- a/vic/drivers/python/src/display_current_settings.c +++ b/vic/drivers/python/src/display_current_settings.c @@ -53,14 +53,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/shared_all/src/compute_derived_state_vars.c b/vic/drivers/shared_all/src/compute_derived_state_vars.c index c0a61cabb..bff4c87a7 100644 --- a/vic/drivers/shared_all/src/compute_derived_state_vars.c +++ b/vic/drivers/shared_all/src/compute_derived_state_vars.c @@ -46,6 +46,10 @@ compute_derived_state_vars(all_vars_struct *all_vars, size_t veg; size_t lidx; size_t band; + size_t tmpMshape[] = { + options.NVEGTYPES + 1, options.SNOW_BAND, + options.Nlayer + }; size_t tmpTshape[] = { options.Nlayer, options.Nnode, options.Nfrost + 1 @@ -55,9 +59,9 @@ compute_derived_state_vars(all_vars_struct *all_vars, }; int ErrorFlag; double Cv; - double moist[MAX_VEG][MAX_BANDS][MAX_LAYERS]; double dt_thresh; double tmp_runoff; + double ***tmpM; double ***tmpT; double **tmpZ; @@ -70,9 +74,12 @@ compute_derived_state_vars(all_vars_struct *all_vars, snow = all_vars->snow; Nveg = veg_con[0].vegetat_type_num; - // allocate memory for tmpT and tmpZ - malloc_3d_double(tmpTshape, &tmpT); - malloc_2d_double(tmpZshape, &tmpZ); + // allocate memory for tmp* arrays + malloc_3d_double(tmpMshape, &tmpM); + if (!options.QUICK_FLUX) { + malloc_3d_double(tmpTshape, &tmpT); + malloc_2d_double(tmpZshape, &tmpZ); + } /****************************************** Compute derived soil layer vars @@ -85,14 +92,14 @@ compute_derived_state_vars(all_vars_struct *all_vars, for (band = 0; band < options.SNOW_BAND; band++) { // Initialize soil for existing snow elevation bands if (soil_con->AreaFract[band] > 0.) { - // set up temporary moist arrays + // set up temporary moist array for (lidx = 0; lidx < options.Nlayer; lidx++) { - moist[veg][band][lidx] = + tmpM[veg][band][lidx] = cell[veg][band].layer[lidx].moist; } // compute saturated area and water table - compute_runoff_and_asat(soil_con, moist[veg][band], 0, + compute_runoff_and_asat(soil_con, tmpM[veg][band], 0, &(cell[veg][band].asat), &tmp_runoff); wrap_compute_zwt(soil_con, &(cell[veg][band])); @@ -152,7 +159,7 @@ compute_derived_state_vars(all_vars_struct *all_vars, soil_con->max_moist_node, soil_con->expt_node, soil_con->bubble_node, - moist[veg][band], + tmpM[veg][band], soil_con->depth, soil_con->soil_dens_min, soil_con->bulk_dens_min, @@ -248,7 +255,10 @@ compute_derived_state_vars(all_vars_struct *all_vars, } } } - // free memory for tmpT and tmpZ - free_3d_double(tmpTshape, tmpT); - free_2d_double(tmpZshape, tmpZ); + // free memory for tmp* arrays + free_3d_double(tmpMshape, tmpM); + if (!options.QUICK_FLUX) { + free_3d_double(tmpTshape, tmpT); + free_2d_double(tmpZshape, tmpZ); + } } diff --git a/vic/drivers/shared_all/src/put_data.c b/vic/drivers/shared_all/src/put_data.c index 700310480..90b163607 100644 --- a/vic/drivers/shared_all/src/put_data.c +++ b/vic/drivers/shared_all/src/put_data.c @@ -67,7 +67,7 @@ put_data(all_vars_struct *all_vars, double inflow; double outflow; double storage; - double TreeAdjustFactor[MAX_BANDS]; + double *TreeAdjustFactor; double ThisAreaFract; double ThisTreeAdjust; size_t i; @@ -93,6 +93,8 @@ put_data(all_vars_struct *all_vars, dt_sec = global_param.dt; // Compute treeline adjustment factors + TreeAdjustFactor = calloc(options.SNOW_BAND, sizeof(*TreeAdjustFactor)); + check_alloc_status(TreeAdjustFactor, "Memory allocation error."); for (band = 0; band < options.SNOW_BAND; band++) { if (AboveTreeLine[band]) { Cv = 0; @@ -569,6 +571,8 @@ put_data(all_vars_struct *all_vars, out_data[OUT_ENERGY_ERROR][0] = MISSING; } + free((char *) (TreeAdjustFactor)); + // vic_run run time out_data[OUT_TIME_VICRUN_WALL][0] = timer->delta_wall; out_data[OUT_TIME_VICRUN_CPU][0] = timer->delta_cpu; diff --git a/vic/drivers/shared_image/src/vic_alloc.c b/vic/drivers/shared_image/src/vic_alloc.c index 34ecfec9d..005089375 100644 --- a/vic/drivers/shared_image/src/vic_alloc.c +++ b/vic/drivers/shared_image/src/vic_alloc.c @@ -158,7 +158,7 @@ vic_alloc(void) veg_lib[i] = calloc(options.NVEGTYPES, sizeof(*(veg_lib[i]))); check_alloc_status(veg_lib[i], "Memory allocation error."); - all_vars[i] = make_all_vars(veg_con_map[i].nv_active); + all_vars[i] = make_all_vars(veg_con_map[i].nv_active - 1); // allocate memory for veg_hist veg_hist[i] = calloc(veg_con_map[i].nv_active, sizeof(*(veg_hist[i]))); diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 184ede176..5ec924243 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -59,10 +59,8 @@ #define ERROR -999 /**< Error Flag returned by subroutines */ /***** Define maximum array sizes for model source code *****/ -#define MAX_VEG 12 /**< maximum number of vegetation types per cell */ #define MAX_LAYERS 3 /**< maximum number of soil moisture layers */ #define MAX_NODES 50 /**< maximum number of soil thermal nodes */ -#define MAX_BANDS 10 /**< maximum number of snow bands */ #define MAX_FRONTS 3 /**< maximum number of freezing and thawing front depths to store */ #define MAX_FROST_AREAS 10 /**< maximum number of frost sub-areas */ #define MAX_LAKE_NODES 20 /**< maximum number of lake thermal nodes */ @@ -235,10 +233,8 @@ typedef struct { size_t Nnode; /**< Number of soil thermal nodes in the model */ bool NOFLUX; /**< TRUE = Use no flux lower bondary when computing soil thermal fluxes */ - size_t NVEGTYPES; /**< number of vegetation types in veg_param file - (used by image driver) */ - size_t NLAKENODES; /**< number of lake layers in lake_param file - (used by image driver) */ + size_t NVEGTYPES; /**< number of vegetation types in veg_param file */ + size_t NLAKENODES; /**< number of lake layers in lake_param file */ unsigned short int RC_MODE; /**< RC_JARVIS = compute canopy resistance via Jarvis formulation (default) RC_PHOTO = compute canopy resistance based on photosynthetic activity */ size_t ROOT_ZONES; /**< Number of root zones used in simulation */ diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 942146539..fd6988875 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -47,16 +47,16 @@ vic_run(force_data_struct *force, extern parameters_struct param; char overstory; - size_t lidx; + size_t l; unsigned short iveg; size_t Nveg; unsigned short veg_class; unsigned short band; size_t Nbands; int ErrorFlag; - double out_prec[MAX_BANDS]; - double out_rain[MAX_BANDS]; - double out_snow[MAX_BANDS]; + double *out_prec; + double *out_rain; + double *out_snow; double dp; double ice0; double moist0; @@ -69,9 +69,9 @@ vic_run(force_data_struct *force, double aero_resist[3]; double Cv; double Le; - double Melt[MAX_BANDS]; + double *Melt; double bare_albedo; - double snow_inflow[MAX_BANDS]; + double *snow_inflow; double rainonly; double sum_runoff; double sum_baseflow; @@ -88,10 +88,21 @@ vic_run(force_data_struct *force, double rainprec; size_t cidx; lake_var_struct *lake_var; - cell_data_struct **cell; - veg_var_struct **veg_var; - energy_bal_struct **energy; - snow_data_struct **snow; + cell_data_struct *cell; + veg_var_struct *veg_var; + energy_bal_struct *energy; + snow_data_struct *snow; + + out_prec = calloc(options.SNOW_BAND, sizeof(*out_prec)); + check_alloc_status(out_prec, "Memory allocation error."); + out_rain = calloc(options.SNOW_BAND, sizeof(*out_rain)); + check_alloc_status(out_rain, "Memory allocation error."); + out_snow = calloc(options.SNOW_BAND, sizeof(*out_snow)); + check_alloc_status(out_snow, "Memory allocation error."); + Melt = calloc(options.SNOW_BAND, sizeof(*Melt)); + check_alloc_status(Melt, "Memory allocation error."); + snow_inflow = calloc(options.SNOW_BAND, sizeof(*snow_inflow)); + check_alloc_status(snow_inflow, "Memory allocation error."); // assign vic_run_veg_lib to veg_lib, so that the veg_lib for the correct // grid cell is used within vic_run. For simplicity sake, use vic_run_veg_lib @@ -99,11 +110,7 @@ vic_run(force_data_struct *force, vic_run_veg_lib = veg_lib; /* set local pointers */ - cell = all_vars->cell; - energy = all_vars->energy; lake_var = &all_vars->lake_var; - snow = all_vars->snow; - veg_var = all_vars->veg_var; Nbands = options.SNOW_BAND; @@ -173,6 +180,9 @@ vic_run(force_data_struct *force, } } + /* local pointer to veg_var */ + veg_var = &(all_vars->veg_var[iveg][0]); + /** Assign wind_h **/ /** Note: this is ignored below **/ wind_h = vic_run_veg_lib[veg_class].wind_h; @@ -183,8 +193,8 @@ vic_run(force_data_struct *force, tmp_wind[2] = MISSING; /* Set surface descriptive variables */ - displacement[0] = veg_var[iveg][0].displacement; - roughness[0] = veg_var[iveg][0].roughness; + displacement[0] = veg_var->displacement; + roughness[0] = veg_var->roughness; if (roughness[0] == 0) { roughness[0] = soil_con->rough; } @@ -214,14 +224,14 @@ vic_run(force_data_struct *force, } /** Compute Surface Attenuation due to Vegetation Coverage **/ - surf_atten = (1 - veg_var[iveg][0].fcanopy) * 1.0 + - veg_var[iveg][0].fcanopy * + surf_atten = (1 - veg_var->fcanopy) * 1.0 + + veg_var->fcanopy * exp(-vic_run_veg_lib[veg_class].rad_atten * - veg_var[iveg][0].LAI); + veg_var->LAI); /** Compute Bare (free of snow) Albedo **/ if (iveg != Nveg) { - bare_albedo = veg_var[iveg][0].albedo; + bare_albedo = veg_var->albedo; } else { bare_albedo = param.ALBEDO_BARE_SOIL; @@ -233,67 +243,66 @@ vic_run(force_data_struct *force, for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { + + /* Set local pointers */ + cell = &(all_vars->cell[iveg][band]); + veg_var = &(all_vars->veg_var[iveg][band]); + snow = &(all_vars->snow[iveg][band]); + energy = &(all_vars->energy[iveg][band]); + /****************************************** Initialize Band-dependent Model Parameters ******************************************/ /* Initialize soil thermal properties for the top two layers */ - prepare_full_energy(&(cell[iveg][band]), - &(energy[iveg][band]), - soil_con, &(moist0[band]), - &(ice0[band])); + prepare_full_energy(cell, energy, soil_con, &moist0, &ice0); /* Initialize final aerodynamic resistance values */ - cell[iveg][band].aero_resist[0] = - aero_resist[0]; - cell[iveg][band].aero_resist[1] = - aero_resist[1]; + cell->aero_resist[0] = aero_resist[0]; + cell->aero_resist[1] = aero_resist[1]; /* Initialize pot_evap */ - cell[iveg][band].pot_evap = 0; + cell->pot_evap = 0; // Convert LAI from global to local - veg_var[iveg][band].LAI /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdew /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax = veg_var[iveg][band].LAI * - param.VEG_LAI_WATER_FACTOR; - snow[iveg][band].snow_canopy /= veg_var[iveg][band].fcanopy; + veg_var->LAI /= veg_var->fcanopy; + veg_var->Wdew /= veg_var->fcanopy; + veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; + snow->snow_canopy /= veg_var->fcanopy; /** Initialize other veg vars **/ if (iveg < Nveg) { - veg_var[iveg][band].rc = param.HUGE_RESIST; + veg_var->rc = param.HUGE_RESIST; /* Carbon-related variables */ if (options.CARBON) { for (cidx = 0; cidx < options.Ncanopy; cidx++) { - veg_var[iveg][band].rsLayer[cidx] = - param.HUGE_RESIST; + veg_var->rsLayer[cidx] = param.HUGE_RESIST; } - veg_var[iveg][band].aPAR = 0; + veg_var->aPAR = 0; calc_Nscale_factors( vic_run_veg_lib[veg_class].NscaleFlag, veg_con[iveg].CanopLayerBnd, - veg_var[iveg][band].LAI, + veg_var->LAI, force->coszen[NR], - veg_var[iveg][band].NscaleFactor); + veg_var->NscaleFactor); // TBD: move this outside of vic_run() if (dmy->day_in_year == 1) { - veg_var[iveg][band].AnnualNPPPrev = - veg_var[iveg][band].AnnualNPP; - veg_var[iveg][band].AnnualNPP = 0; + veg_var->AnnualNPPPrev = veg_var->AnnualNPP; + veg_var->AnnualNPP = 0; } } // if options.CARBON } // if iveg < Nveg /* Initialize energy balance variables */ - energy[iveg][band].shortwave = 0; - energy[iveg][band].longwave = 0.; + energy->shortwave = 0; + energy->longwave = 0.; /* Initialize snow variables */ - snow[iveg][band].vapor_flux = 0.; - snow[iveg][band].canopy_vapor_flux = 0.; + snow->vapor_flux = 0.; + snow->canopy_vapor_flux = 0.; snow_inflow[band] = 0.; Melt[band] = 0.; @@ -311,10 +320,8 @@ vic_run(force_data_struct *force, fetch = veg_con[iveg].fetch; ErrorFlag = surface_fluxes(overstory, bare_albedo, - ice0[band], moist0[band], - surf_atten, &(Melt[band]), - &Le, - aero_resist, + ice0, moist0, surf_atten, + &(Melt[band]), &Le, aero_resist, displacement, gauge_correction, &out_prec[band], &out_rain[band], @@ -324,11 +331,9 @@ vic_run(force_data_struct *force, tmp_wind, veg_con[iveg].root, options.Nlayer, Nveg, band, dp, iveg, veg_class, force, dmy, - &(energy[iveg][band]), gp, - &(cell[iveg][band]), - &(snow[iveg][band]), - soil_con, &(veg_var[iveg][band]), - lag_one, sigma_slope, fetch, + energy, gp, cell, snow, + soil_con, veg_var, lag_one, + sigma_slope, fetch, veg_con[iveg].CanopLayerBnd); if (ErrorFlag == ERROR) { @@ -345,24 +350,22 @@ vic_run(force_data_struct *force, /******************************************************** Compute soil wetness and root zone soil moisture ********************************************************/ - cell[iveg][band].rootmoist = 0; - cell[iveg][band].wetness = 0; - for (lidx = 0; lidx < options.Nlayer; lidx++) { - if (veg_con[iveg].root[lidx] > 0) { - cell[iveg][band].rootmoist += - cell[iveg][band].layer[lidx].moist; + cell->rootmoist = 0; + cell->wetness = 0; + for (l = 0; l < options.Nlayer; l++) { + if (veg_con[iveg].root[l] > 0) { + cell->rootmoist += cell->layer[l].moist; } - cell[iveg][band].wetness += - (cell[iveg][band].layer[lidx].moist - - soil_con->Wpwp[lidx]) / - (soil_con->porosity[lidx] * soil_con->depth[lidx] * - MM_PER_M - soil_con->Wpwp[lidx]); + cell->wetness += + (cell->layer[l].moist - soil_con->Wpwp[l]) / + (soil_con->porosity[l] * soil_con->depth[l] * + MM_PER_M - soil_con->Wpwp[l]); } - cell[iveg][band].wetness /= options.Nlayer; + cell->wetness /= options.Nlayer; /* Convert LAI back to global */ - veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; + veg_var->LAI *= veg_var->fcanopy; + veg_var->Wdmax *= veg_var->fcanopy; } /** End non-zero area band **/ } /** End Loop Through Elevation Bands **/ } /** end non-zero area veg tile **/ @@ -371,7 +374,8 @@ vic_run(force_data_struct *force, // Compute gridcell-averaged albedo calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, force->shortwave[NR], Nveg, overstory, - energy, snow, veg_con, soil_con); + all_vars->energy, all_vars->snow, veg_con, + soil_con); /**************************** Run Lake Model @@ -397,23 +401,23 @@ vic_run(force_data_struct *force, // Loop through snow elevation bands for (band = 0; band < Nbands; band++) { if (soil_con->AreaFract[band] > 0) { + /* Set local pointers */ + cell = &(all_vars->cell[iveg][band]); if (veg_con[iveg].LAKE) { - wetland_runoff += (cell[iveg][band].runoff * - Cv * soil_con->AreaFract[band]); - wetland_baseflow += (cell[iveg][band].baseflow * - Cv * + wetland_runoff += (cell->runoff * Cv * + soil_con->AreaFract[band]); + wetland_baseflow += (cell->baseflow * Cv * soil_con->AreaFract[band]); - cell[iveg][band].runoff = 0; - cell[iveg][band].baseflow = 0; + cell->runoff = 0; + cell->baseflow = 0; } else { - sum_runoff += (cell[iveg][band].runoff * - Cv * soil_con->AreaFract[band]); - sum_baseflow += (cell[iveg][band].baseflow * - Cv * soil_con->AreaFract[band]); - cell[iveg][band].runoff *= (1 - lake_con->rpercent); - cell[iveg][band].baseflow *= - (1 - lake_con->rpercent); + sum_runoff += (cell->runoff * Cv * + soil_con->AreaFract[band]); + sum_baseflow += (cell->baseflow * Cv * + soil_con->AreaFract[band]); + cell->runoff *= (1 - lake_con->rpercent); + cell->baseflow *= (1 - lake_con->rpercent); } } } @@ -474,5 +478,11 @@ vic_run(force_data_struct *force, } } // end if (options.LAKES && lake_con->lake_idx >= 0) + free((char *) (out_prec)); + free((char *) (out_rain)); + free((char *) (out_snow)); + free((char *) (Melt)); + free((char *) (snow_inflow)); + return (0); } From eded5aeed82f5451c0d67fc98b608244c4941213 Mon Sep 17 00:00:00 2001 From: ted Date: Sun, 3 Dec 2017 19:24:08 -0700 Subject: [PATCH 238/294] A few more fixes. --- vic/drivers/shared_image/src/vic_finalize.c | 2 +- vic/drivers/shared_image/src/vic_init.c | 57 +++++++++++---------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_finalize.c b/vic/drivers/shared_image/src/vic_finalize.c index cc643876f..26043e199 100644 --- a/vic/drivers/shared_image/src/vic_finalize.c +++ b/vic/drivers/shared_image/src/vic_finalize.c @@ -94,7 +94,7 @@ vic_finalize(void) } free_veg_hist(&(veg_hist[i][j])); } - free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active); + free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active - 1); free(veg_con_map[i].vidx); free(veg_con_map[i].Cv); free(veg_con[i]); diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 83a7cf769..a3cc56bcd 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -265,13 +265,14 @@ vic_init(void) if (options.FCAN_SRC == FROM_DEFAULT) { for (k = 0; k < MONTHS_PER_YEAR; k++) { for (i = 0; i < local_domain.ncells_active; i++) { - if (j < options.NVEGTYPES - 1) { - veg_lib[i][j].fcanopy[k] = 1.0; - } - // Assuming the last type is bare soil - else { - veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; - } +// if (j < options.NVEGTYPES - 1) { +// veg_lib[i][j].fcanopy[k] = 1.0; +// } +// // Assuming the last type is bare soil +// else { +// veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; +// } + veg_lib[i][j].fcanopy[k] = 1.0; } } } @@ -988,11 +989,18 @@ vic_init(void) } if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Sum of the snow band area fractions does not equal " - "1 (%f), dividing each fraction by the sum\n%s", - sum, locstr); - for (j = 0; j < options.SNOW_BAND; j++) { - soil_con[i].AreaFract[j] /= sum; + if (sum > 0) { + log_warn("Sum of the snow band area fractions does not " + "equal 1 (%f), dividing each fraction by the " + "sum\n%s", sum, locstr); + for (j = 0; j < options.SNOW_BAND; j++) { + soil_con[i].AreaFract[j] /= sum; + } + } + else { + log_warn("Sum of the snow band area fractions is 0, " + "setting first fraction to 1\n%s", locstr); + soil_con[i].AreaFract[0] = 1.; } } // check that the mean elevation from the snow bands matches the @@ -1170,9 +1178,10 @@ vic_init(void) // Run some checks and corrections for vegetation for (i = 0; i < local_domain.ncells_active; i++) { - // Only run to options.NVEGTYPES - 1, assuming bare soil - // is the last type - for (j = 0; j < options.NVEGTYPES - 1; j++) { +// // Only run to options.NVEGTYPES - 1, assuming bare soil +// // is the last type +// for (j = 0; j < options.NVEGTYPES - 1; j++) { + for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; if (vidx != NODATA_VEG) { sum = 0; @@ -1219,11 +1228,11 @@ vic_init(void) } } - // handle the bare soil portion of the tile - vidx = veg_con_map[i].vidx[options.NVEGTYPES - 1]; - if (vidx != NODATA_VEG) { - Cv_sum[i] += veg_con[i][vidx].Cv; - } +// // handle the bare soil portion of the tile +// vidx = veg_con_map[i].vidx[options.NVEGTYPES - 1]; +// if (vidx != NODATA_VEG) { +// Cv_sum[i] += veg_con[i][vidx].Cv; +// } // TODO: handle bare soil adjustment for compute treeline option @@ -1231,12 +1240,8 @@ vic_init(void) // throw an error if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", - Cv_sum[i], i, locstr); - for (j = 0; j < options.NVEGTYPES; j++) { - vidx = veg_con_map[i].vidx[j]; - veg_con[i][vidx].Cv /= Cv_sum[i]; - } + log_err("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", + Cv_sum[i], i, locstr); } } From 52f4df65011ab892517d5996233c8210e9fce40d Mon Sep 17 00:00:00 2001 From: ted Date: Tue, 5 Dec 2017 21:45:27 -0700 Subject: [PATCH 239/294] Backed out changes to validation of bare soil tile. --- vic/drivers/shared_image/src/vic_init.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index a3cc56bcd..079bb2490 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1178,10 +1178,9 @@ vic_init(void) // Run some checks and corrections for vegetation for (i = 0; i < local_domain.ncells_active; i++) { -// // Only run to options.NVEGTYPES - 1, assuming bare soil -// // is the last type -// for (j = 0; j < options.NVEGTYPES - 1; j++) { - for (j = 0; j < options.NVEGTYPES; j++) { + // Only run to options.NVEGTYPES - 1, assuming bare soil + // is the last type + for (j = 0; j < options.NVEGTYPES - 1; j++) { vidx = veg_con_map[i].vidx[j]; if (vidx != NODATA_VEG) { sum = 0; @@ -1228,11 +1227,11 @@ vic_init(void) } } -// // handle the bare soil portion of the tile -// vidx = veg_con_map[i].vidx[options.NVEGTYPES - 1]; -// if (vidx != NODATA_VEG) { -// Cv_sum[i] += veg_con[i][vidx].Cv; -// } + // handle the bare soil portion of the tile + vidx = veg_con_map[i].vidx[options.NVEGTYPES - 1]; + if (vidx != NODATA_VEG) { + Cv_sum[i] += veg_con[i][vidx].Cv; + } // TODO: handle bare soil adjustment for compute treeline option From 85a77c00edeec24ca437191110046ff62773c69d Mon Sep 17 00:00:00 2001 From: ted Date: Wed, 6 Dec 2017 15:55:50 -0700 Subject: [PATCH 240/294] Changed LAI_IN to LAI. --- vic/drivers/classic/src/get_force_type.c | 12 +++----- vic/drivers/classic/src/vic_force.c | 12 ++++---- .../include/vic_driver_shared_all.h | 2 +- vic/drivers/shared_image/src/set_force_type.c | 28 +++++++++---------- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/vic/drivers/classic/src/get_force_type.c b/vic/drivers/classic/src/get_force_type.c index 03e2fb984..15df28328 100644 --- a/vic/drivers/classic/src/get_force_type.c +++ b/vic/drivers/classic/src/get_force_type.c @@ -82,8 +82,8 @@ get_force_type(char *cmdstr, type = FDIR; } /* type 6: LAI [m2/m2] */ - else if (strcasecmp("LAI_IN", optstr) == 0) { - type = LAI_IN; + else if (strcasecmp("LAI", optstr) == 0) { + type = LAI; } /* type 7: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { @@ -109,15 +109,11 @@ get_force_type(char *cmdstr, else if (strcasecmp("SWDOWN", optstr) == 0) { type = SWDOWN; } - /* type 13: vegetation cover fraction */ - else if (strcasecmp("FCANOPY", optstr) == 0) { - type = FCANOPY; - } - /* type 14: wind speed [m/s] */ + /* type 13: wind speed [m/s] */ else if (strcasecmp("WIND", optstr) == 0) { type = WIND; } - /* type 15: unused (blank) data */ + /* type 14: unused (blank) data */ else if (strcasecmp("SKIP", optstr) == 0) { type = SKIP; } diff --git a/vic/drivers/classic/src/vic_force.c b/vic/drivers/classic/src/vic_force.c index 36c9f85a7..09f1fb770 100644 --- a/vic/drivers/classic/src/vic_force.c +++ b/vic/drivers/classic/src/vic_force.c @@ -95,8 +95,8 @@ vic_force(force_data_struct *force, if (param_set.TYPE[ALBEDO].SUPPLIED) { param_set.TYPE[ALBEDO].N_ELEM = veg_con[0].vegetat_type_num; } - if (param_set.TYPE[LAI_IN].SUPPLIED) { - param_set.TYPE[LAI_IN].N_ELEM = veg_con[0].vegetat_type_num; + if (param_set.TYPE[LAI].SUPPLIED) { + param_set.TYPE[LAI].N_ELEM = veg_con[0].vegetat_type_num; } if (param_set.TYPE[FCANOPY].SUPPLIED) { param_set.TYPE[FCANOPY].N_ELEM = veg_con[0].vegetat_type_num; @@ -246,11 +246,11 @@ vic_force(force_data_struct *force, veg_hist_data[ALBEDO][v][uidx]; } } - if (param_set.TYPE[LAI_IN].SUPPLIED && + if (param_set.TYPE[LAI].SUPPLIED && options.LAI_SRC == FROM_VEGHIST) { - if (veg_hist_data[LAI_IN][v][uidx] != NODATA_VH) { + if (veg_hist_data[LAI][v][uidx] != NODATA_VH) { veg_hist[rec][v].LAI[i] = - veg_hist_data[LAI_IN][v][uidx]; + veg_hist_data[LAI][v][uidx]; } } if (param_set.TYPE[FCANOPY].SUPPLIED && @@ -289,7 +289,7 @@ vic_force(force_data_struct *force, for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { + if (i != ALBEDO && i != LAI && i != FCANOPY) { free(forcing_data[i]); } else { diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index c042ecf50..b60a97808 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -93,7 +93,7 @@ enum CHANNEL_IN, /**< incoming channel flow [m3] */ FCANOPY, /**< fractional area covered by plant canopy [fraction] */ FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ - LAI_IN, /**< leaf area index [m2/m2] */ + LAI, /**< leaf area index [m2/m2] */ LWDOWN, /**< incoming longwave radiation [W/m2] */ PAR, /**< incoming photosynthetically active radiation [W/m2] */ PREC, /**< total precipitation (rain and snow) [mm] */ diff --git a/vic/drivers/shared_image/src/set_force_type.c b/vic/drivers/shared_image/src/set_force_type.c index 89cdbfe89..c4a523386 100644 --- a/vic/drivers/shared_image/src/set_force_type.c +++ b/vic/drivers/shared_image/src/set_force_type.c @@ -76,42 +76,42 @@ set_force_type(char *cmdstr, else if (strcasecmp("CHANNEL_IN", optstr) == 0) { type = CHANNEL_IN; } - /* type 4: direct fraction of shortwave [fraction] */ + /* type 4: vegetation cover fraction [fraction] */ + else if (strcasecmp("FCANOPY", optstr) == 0) { + type = FCANOPY; + } + /* type 5: direct fraction of shortwave [fraction] */ else if (strcasecmp("FDIR", optstr) == 0) { type = FDIR; } - /* type 5: LAI [m2/m2] */ - else if (strcasecmp("LAI_IN", optstr) == 0) { - type = LAI_IN; + /* type 6: LAI [m2/m2] */ + else if (strcasecmp("LAI", optstr) == 0) { + type = LAI; } - /* type 6: incoming longwave radiation [W/m2] */ + /* type 7: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { type = LWDOWN; } - /* type 7: photosynthetically active radiation [uE/m2s] */ + /* type 8: photosynthetically active radiation [uE/m2s] */ else if (strcasecmp("PAR", optstr) == 0) { type = PAR; } - /* type 8: precipitation [mm] */ + /* type 9: precipitation [mm] */ else if (strcasecmp("PREC", optstr) == 0) { type = PREC; } - /* type 9: air pressure [kPa] */ + /* type 10: air pressure [kPa] */ else if (strcasecmp("PRESSURE", optstr) == 0) { type = PRESSURE; } - /* type 10: vapor pressure [kPa] */ + /* type 11: vapor pressure [kPa] */ else if (strcasecmp("VP", optstr) == 0) { type = VP; } - /* type 11: incoming shortwave radiation [W/m2] */ + /* type 12: incoming shortwave radiation [W/m2] */ else if (strcasecmp("SWDOWN", optstr) == 0) { type = SWDOWN; } - /* type 12: vegetation cover fraction */ - else if (strcasecmp("FCANOPY", optstr) == 0) { - type = FCANOPY; - } /* type 13: wind speed [m/s] */ else if (strcasecmp("WIND", optstr) == 0) { type = WIND; From 2d5e8eaa55ff6856457c295d6ca4e3f0ab7dfa54 Mon Sep 17 00:00:00 2001 From: ted Date: Wed, 6 Dec 2017 16:46:38 -0700 Subject: [PATCH 241/294] Changed "lai" to "LAI" in vic_force.c for consistency with vic_init.c. --- vic/drivers/image/src/vic_force.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 436c81358..49ee0a8b3 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -316,14 +316,14 @@ vic_force(void) d4count[2] = global_domain.n_ny; d4count[3] = global_domain.n_nx; - // Leaf Area Index: lai + // Leaf Area Index: LAI if (options.LAI_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "lai", + get_scatter_nc_field_double(&(filenames.forcing[1]), "LAI", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; From 19afd14b77455bd36fd3d4ae48a9fe898370d5be Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 18 Dec 2017 15:27:59 -0700 Subject: [PATCH 242/294] Changed LAI_IN to LAI. Updated docs to use FCANOPY instead of VEGCOVER. Updated netcdf names of forcing variables from fcan and alb to fcanopy and albedo. --- docs/Documentation/Drivers/Classic/ForcingData.md | 4 ++-- docs/Documentation/Drivers/Classic/GlobalParam.md | 6 +++--- docs/Documentation/Drivers/Classic/VegLib.md | 2 +- docs/Documentation/Drivers/Classic/VegParam.md | 4 ++-- docs/Documentation/Drivers/Image/GlobalParam.md | 2 +- docs/Documentation/Drivers/Image/Params.md | 6 +++--- vic/drivers/classic/src/get_force_type.c | 8 ++++++-- vic/drivers/classic/src/get_global_param.c | 8 ++++---- vic/drivers/classic/src/read_atmos_data.c | 4 ++-- vic/drivers/classic/src/read_forcing_data.c | 2 +- vic/drivers/image/src/get_global_param.c | 9 --------- vic/drivers/image/src/vic_force.c | 7 ++++--- 12 files changed, 29 insertions(+), 33 deletions(-) diff --git a/docs/Documentation/Drivers/Classic/ForcingData.md b/docs/Documentation/Drivers/Classic/ForcingData.md index 49106ee14..98a875c73 100644 --- a/docs/Documentation/Drivers/Classic/ForcingData.md +++ b/docs/Documentation/Drivers/Classic/ForcingData.md @@ -19,8 +19,8 @@ The VIC Classic Driver requires subdaily forcings (meteorological or other). For | Variable | Description | Units | |------------|----------------------------------------------------------|---------------------------- | | ALBEDO | Surface Albedo | fraction (between 0 and 1) | -| LAI_IN | Leaf Area Index | m2/m2 | -| VEGCOVER | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | +| LAI | Leaf Area Index | m2/m2 | +| FCANOPY | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | #### Lake Forcings, Required when LAKES is TRUE: diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index 0b434d84f..1d6db19d2 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -148,8 +148,8 @@ All FORCING filenames are actually the pathname, and prefix for gridded data typ | FORCING2 | string | pathname and file prefix | Second forcing file name, or FALSE if only one file used.This must precede all other forcing parameters used to define the second forcing file, and follow those used to define the first forcing file. | | FORCE_FORMAT | string | BINARY or ASCII | Defines the format type for the forcing files. | | FORCE_ENDIAN | string | BIG or LITTLE | Identifies the architecture of the machine on which the binary forcing files were created:BIG = big-endian (e.g. SUN).LITTLE = little-endian (e.g. PC/linux). Model will identify the endian of the current machine, and swap bytes if necessary. Required for binary forcing file, not used for ASCII forcing file. | -| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI_IN, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI_IN, and FCANOPY each count as only 1 variable despite covering multiple columns. | -| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI_IN, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI_IN, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | +| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI, and FCANOPY each count as only 1 variable despite covering multiple columns. | +| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | | FORCE_STEPS_PER_DAY | integer | steps | Number of timesteps per day in forcing file (must be = SNOW_STPES_PER_DAY) | | FORCEYEAR | integer | year | Year meteorological forcing files start | | FORCEMONTH | integer | month | Month meteorological forcing files start | @@ -218,7 +218,7 @@ The following options describe the input parameter files. | VEGPARAM_ALB | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly ALBEDO values for each vegetation type for each grid cell. Default = FALSE. | | ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values:FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE.FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGPARAM_LAI | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly LAI values for each vegetation type for each grid cell. Default = FALSE. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values:FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values:FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGLIB_FCAN | string | TRUE or FALSE | If TRUE the vegetation library file contains monthly FCANOPY values for each vegetation type for each grid cell (between the LAI and ALBEDO values). Default = FALSE. | | VEGPARAM_FCAN | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly FCANOPY values for each vegetation type for each grid cell. Default = FALSE. | | FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | diff --git a/docs/Documentation/Drivers/Classic/VegLib.md b/docs/Documentation/Drivers/Classic/VegLib.md index 7491c0d03..218fccf40 100644 --- a/docs/Documentation/Drivers/Classic/VegLib.md +++ b/docs/Documentation/Drivers/Classic/VegLib.md @@ -11,7 +11,7 @@ Vegetation parameters needed for each vegetation type used in the VIC model are | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/docs/Documentation/Drivers/Classic/VegParam.md b/docs/Documentation/Drivers/Classic/VegParam.md index 9e40530b3..10ceea7c2 100644 --- a/docs/Documentation/Drivers/Classic/VegParam.md +++ b/docs/Documentation/Drivers/Classic/VegParam.md @@ -37,11 +37,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: +OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | +| FCANOPY | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index de2fa16d7..3516cfe8c 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -176,7 +176,7 @@ The following options describe the input parameter files. | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional variable in the parameter file (July_Tavg) to contain the grid cell's average July temperature. *NOTE*: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE.

    Default = FALSE. | | ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the parameter file contains extra variables: the organic fraction, and the bulk density and soil particle density of the organic matter in each soil layer. FALSE = the parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | | ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file.FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | string | TRUE or FALSE | Whether multiple snowband option is enables. If TRUE, snowband information is specified in the parameter netCDF file.

    Default = FALSE. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index 5be216247..ef05570c5 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -94,11 +94,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: +OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | +| FCANOPY | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there following parameters will also be included in the NetCDF parameter file: @@ -118,7 +118,7 @@ Vegetation parameters are given for different vegetation types. Below are a list | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/vic/drivers/classic/src/get_force_type.c b/vic/drivers/classic/src/get_force_type.c index 15df28328..98bde93f5 100644 --- a/vic/drivers/classic/src/get_force_type.c +++ b/vic/drivers/classic/src/get_force_type.c @@ -109,11 +109,15 @@ get_force_type(char *cmdstr, else if (strcasecmp("SWDOWN", optstr) == 0) { type = SWDOWN; } - /* type 13: wind speed [m/s] */ + /* type 13: vegetation cover fraction */ + else if (strcasecmp("FCANOPY", optstr) == 0) { + type = FCANOPY; + } + /* type 14: wind speed [m/s] */ else if (strcasecmp("WIND", optstr) == 0) { type = WIND; } - /* type 14: unused (blank) data */ + /* type 15: unused (blank) data */ else if (strcasecmp("SKIP", optstr) == 0) { type = SKIP; } diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 6ea2726a3..064c98c76 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -1038,13 +1038,13 @@ get_global_param(FILE *gp) log_err("ROOT_ZONES must be defined to a positive integer greater " "than 0, in the global control file."); } - if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI_IN].SUPPLIED) { + if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI].SUPPLIED) { log_err("\"LAI_SRC\" was specified as \"FROM_VEGHIST\", but " - "\"LAI_IN\" was not specified as an input forcing in the " + "\"LAI\" was not specified as an input forcing in the " "global parameter file. If you want VIC to read LAI " "values from the veg_hist file, you MUST make sure the veg " - "hist file contains Nveg columns of LAI_IN values, 1 for " - "each veg tile in the grid cell, AND specify LAI_IN as a " + "hist file contains Nveg columns of LAI values, 1 for " + "each veg tile in the grid cell, AND specify LAI as a " "forcing variable in the veg_hist forcing file in the " "global parameter file."); } diff --git a/vic/drivers/classic/src/read_atmos_data.c b/vic/drivers/classic/src/read_atmos_data.c index deab975e4..0930987b1 100644 --- a/vic/drivers/classic/src/read_atmos_data.c +++ b/vic/drivers/classic/src/read_atmos_data.c @@ -145,7 +145,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && + if (field_index[i] != ALBEDO && field_index[i] != LAI && field_index[i] != FCANOPY) { if (param_set.TYPE[field_index[i]].SIGNED) { fread(&stmp, sizeof(short int), 1, infile); @@ -226,7 +226,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && + if (field_index[i] != ALBEDO && field_index[i] != LAI && field_index[i] != FCANOPY) { fscanf(infile, "%lf", &forcing_data[field_index[i]][rec]); } diff --git a/vic/drivers/classic/src/read_forcing_data.c b/vic/drivers/classic/src/read_forcing_data.c index cfaec814c..71f4720f6 100644 --- a/vic/drivers/classic/src/read_forcing_data.c +++ b/vic/drivers/classic/src/read_forcing_data.c @@ -50,7 +50,7 @@ read_forcing_data(FILE **infile, check_alloc_status((*veg_hist_data), "Memory allocation error."); for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { + if (i != ALBEDO && i != LAI && i != FCANOPY) { forcing_data[i] = calloc(global_param.nrecs * NF, sizeof(*(forcing_data[i]))); check_alloc_status(forcing_data[i], "Memory allocation error."); diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 67344cdee..1957716c8 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -527,15 +527,6 @@ get_global_param(FILE *gp) else if (strcasecmp("OUT_FORMAT", optstr) == 0) { ; // do nothing } - // vegetation history not yet implemented in image mode - // TBD: feature in VIC 4.2 that has been ported to classic - // mode, but that does not exist in image mode (yet) - else if (strcasecmp("ALBEDO", optstr) == 0 || - strcasecmp("LAI_IN", optstr) == 0 || - strcasecmp("FCANOPY", optstr) == 0) { - log_err("Time-varying vegetation parameters not implemented " - "in image mode"); - } /************************************* Fail when classic driver specific options are used diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 49ee0a8b3..033a9f057 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -355,15 +355,16 @@ vic_force(void) } } - // Albedo: alb + // Albedo: albedo if (options.ALB_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "alb", - d4start, d4count, dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), + "albedo", d4start, d4count, + dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { From 1c59dbd5393b6cb306ddc17a214d16dcf558e47a Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 18 Dec 2017 16:13:16 -0700 Subject: [PATCH 243/294] Backed out changes made to bare soil and Cv sum logic. --- vic/drivers/shared_image/src/vic_init.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 079bb2490..bbaa56ca7 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -265,13 +265,13 @@ vic_init(void) if (options.FCAN_SRC == FROM_DEFAULT) { for (k = 0; k < MONTHS_PER_YEAR; k++) { for (i = 0; i < local_domain.ncells_active; i++) { -// if (j < options.NVEGTYPES - 1) { -// veg_lib[i][j].fcanopy[k] = 1.0; -// } -// // Assuming the last type is bare soil -// else { -// veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; -// } + if (j < options.NVEGTYPES - 1) { + veg_lib[i][j].fcanopy[k] = 1.0; + } + // Assuming the last type is bare soil + else { + veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; + } veg_lib[i][j].fcanopy[k] = 1.0; } } @@ -1236,11 +1236,15 @@ vic_init(void) // TODO: handle bare soil adjustment for compute treeline option // If the sum of the tile fractions is not within a tolerance, - // throw an error + // readjust Cvs to sum to 1.0 if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_err("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", - Cv_sum[i], i, locstr); + log_warn("Cv != 1.0 (%f) at grid cell %zd. Adjusting fractions " + "...\n%s", Cv_sum[i], i, locstr); + for (j = 0; j < options.NVEGTYPES; j++) { + vidx = veg_con_map[i].vidx[j]; + veg_con[i][vidx].Cv /= Cv_sum[i]; + } } } From 957bade3fd632144015fa5a7e4ce415196ce7fee Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 18 Dec 2017 16:25:22 -0700 Subject: [PATCH 244/294] Changed LAI_IN to LAI. --- vic/drivers/cesm/src/get_global_param.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index e43243633..ef0c6ff82 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -448,7 +448,7 @@ get_global_param(FILE *gp) // TBD: feature in VIC 4.2 that has been ported to classic // mode, but that does not exist in image mode (yet) else if (strcasecmp("ALBEDO", optstr) == 0 || - strcasecmp("LAI_IN", optstr) == 0 || + strcasecmp("LAI", optstr) == 0 || strcasecmp("FCANOPY", optstr) == 0) { log_err("Time-varying vegetation parameters not implemented " "in CESM driver"); From 7a0ea867791bad0385b2113fc24054ad3bb4848a Mon Sep 17 00:00:00 2001 From: ted Date: Tue, 19 Dec 2017 20:23:37 -0700 Subject: [PATCH 245/294] Fixed typos in docs and replaced warning with error in vic_init.c when snow band areas sum to 0. --- .../Documentation/Drivers/Classic/GlobalParam.md | 16 ++++++++-------- docs/Documentation/Drivers/Image/GlobalParam.md | 16 ++++++++-------- vic/drivers/shared_image/src/vic_init.c | 5 ++--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index 1d6db19d2..161f9ef55 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -75,7 +75,7 @@ Generally these default values do not need to be overridden. | BLOWING_SPATIAL_WIND | string | TRUE or FALSE | If TRUE, multiple wind speed ranges, calculated according to a probability distribution, are used to determine the sublimation flux from blowing snow. If FALSE, then a single wind speed is used. See Lu and Pomeroy (1997) for details.

    Default: TRUE. | | COMPUTE_TREELINE | string or integer | FALSE or veg class id | Options for handling above-treeline vegetation:FALSE = Do not compute treeline or replace vegetation above the treeline.CLASS_ID = Compute the treeline elevation based on average July temperatures; for those elevation bands with elevations above the treeline (or the entire grid cell if SNOW_BAND == 1 and the grid cell elevation is above the tree line), if they contain vegetation tiles having overstory, replace that vegetation with the vegetation having id CLASS_ID in the vegetation library. NOTE 1: You MUST supply VIC with a July average air temperature, in the optional July_Tavg field, AND set theJULY_TAVG_SUPPLIED option to TRUE so that VIC can read the soil parameter file correctly. NOTE 2: If LAKES=TRUE, COMPUTE_TREELINE MUST be FALSE.Default = FALSE. | | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -216,12 +216,12 @@ The following options describe the input parameter files. | VEGPARAM | string | path/filename | Vegetation parameter file name | | ROOT_ZONES | integer | N/A | Number of defined root zones defined for root distribution. | | VEGPARAM_ALB | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly ALBEDO values for each vegetation type for each grid cell. Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values:FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE.FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE. FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGPARAM_LAI | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly LAI values for each vegetation type for each grid cell. Default = FALSE. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values:FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGLIB_FCAN | string | TRUE or FALSE | If TRUE the vegetation library file contains monthly FCANOPY values for each vegetation type for each grid cell (between the LAI and ALBEDO values). Default = FALSE. | | VEGPARAM_FCAN | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly FCANOPY values for each vegetation type for each grid cell. Default = FALSE. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | integer[string] | N/A [path/filename] | Maximum number of snow elevation bands to use, and the name (with path) of the snow elevation band file. For example: SNOW_BAND 5 path/filename. To turn off this feature, set the number of snow bands to 1 and do not follow this with a snow elevation band file name. Default = 1. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index 3516cfe8c..a2ba06297 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -77,7 +77,7 @@ Generally these default values do not need to be overridden. | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | | MAX_SNOW_TEMP | float | deg C | Maximum temperature at which snow can fall. Default = 0.5 C. | | MIN_RAIN_TEMP | float | deg C | Minimum temperature at which rain can fall. Default = -0.5 C. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -175,9 +175,9 @@ The following options describe the input parameter files. | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file. Valid options: ARNO, NIJSSEN2001. See classic driver global parameter file for detail (../Classic/GlobalParam.md). | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional variable in the parameter file (July_Tavg) to contain the grid cell's average July temperature. *NOTE*: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE.

    Default = FALSE. | | ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the parameter file contains extra variables: the organic fraction, and the bulk density and soil particle density of the organic matter in each soil layer. FALSE = the parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file.FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | string | TRUE or FALSE | Whether multiple snowband option is enables. If TRUE, snowband information is specified in the parameter netCDF file.

    Default = FALSE. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index bbaa56ca7..5bd57d410 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -998,9 +998,8 @@ vic_init(void) } } else { - log_warn("Sum of the snow band area fractions is 0, " - "setting first fraction to 1\n%s", locstr); - soil_con[i].AreaFract[0] = 1.; + log_err("Sum of the snow band area fractions is 0\n%s", + locstr); } } // check that the mean elevation from the snow bands matches the From f9a9ccb6526b300b4d376ea08a69eba4c90fb542 Mon Sep 17 00:00:00 2001 From: ted Date: Tue, 19 Dec 2017 20:35:49 -0700 Subject: [PATCH 246/294] Fixed a couple more typos. --- docs/Documentation/Drivers/Classic/GlobalParam.md | 8 ++++---- docs/Documentation/Drivers/Image/GlobalParam.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index 161f9ef55..ab28f10a6 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -49,14 +49,14 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | | SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | @@ -211,7 +211,7 @@ The following options describe the input parameter files. | SOIL | string | path/filename | the Soil parameter file. | | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file:ARNO = fields 5-8 of the soil parameter file are the standard VIC baseflow parametersNIJSSEN2001 = fields 5-8 of the soil parameter file are the baseflow parameters from Nijssen et al (2001) Default = ARNO. | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional column (July_Tavg) in the soil parameter file to contain the grid cell's average July temperature. If your soil parameter file contains this optional column, you MUST set JULY_TAVG_SUPPLIED to TRUE so that VIC can read the soil parameter file correctly. NOTE: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE. Default = FALSE. | -| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer.FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | +| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer. FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | | VEGLIB | string | path/filename | Vegetation library file name | | VEGPARAM | string | path/filename | Vegetation parameter file name | | ROOT_ZONES | integer | N/A | Number of defined root zones defined for root distribution. | diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index a2ba06297..d080294ec 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -49,14 +49,14 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | | SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | From 66733862d905d3558b383fa379d0dc09e46be0c2 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 1 Jan 2018 21:24:16 -0800 Subject: [PATCH 247/294] Feature/fix routing extension mods cesm driver (#756) * initial mods to fix compiling error with extensions file paths * rout.c * Revert "rout.c" This reverts commit 429bf49000b6deef0688c5396dfef53569c9f405. * update rout.c to solve issue with compiling CESM driver * remove unneeded paths and set ROUT rather than rout_rvic --- vic/drivers/cesm/bld/vic.buildexe.csh | 4 ++++ vic/extensions/rout_stub/src/rout.c | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/vic/drivers/cesm/bld/vic.buildexe.csh b/vic/drivers/cesm/bld/vic.buildexe.csh index d00d6b153..238b8a330 100755 --- a/vic/drivers/cesm/bld/vic.buildexe.csh +++ b/vic/drivers/cesm/bld/vic.buildexe.csh @@ -3,6 +3,8 @@ cd $OBJROOT/lnd/obj set comp = 'unknown' +set ROUT = 'rout_stub' + if ($COMP_INTERFACE == 'MCT' ) set comp = mct if ($COMP_INTERFACE == 'ESMF') set comp = esmf @@ -18,6 +20,8 @@ $CODEROOT/lnd/vic/vic/drivers/shared_image/include $CODEROOT/lnd/vic/vic/drivers/cesm/src $CODEROOT/lnd/vic/vic/drivers/cesm/include $CODEROOT/lnd/vic/vic/drivers/cesm/cpl_$comp/ +$CODEROOT/lnd/vic/vic/extensions/rout_stub/src +$CODEROOT/lnd/vic/vic/extensions/rout_stub/include EOF set vicdefs = "" diff --git a/vic/extensions/rout_stub/src/rout.c b/vic/extensions/rout_stub/src/rout.c index 3130a485d..ca7585b6f 100644 --- a/vic/extensions/rout_stub/src/rout.c +++ b/vic/extensions/rout_stub/src/rout.c @@ -32,13 +32,6 @@ void rout_alloc(void) { - extern rout_struct rout; - - // We need to write at least something to the VIC state file (if enabled). - // Therefore we make the dimension size 1*1. - rout.rout_param.n_outlets = 1; - rout.rout_param.full_time_length = 1; - rout.ring[1] = 0; } /****************************************************************************** From 7e87209df6ca2ee64ba5989761a2cf9e72c1b563 Mon Sep 17 00:00:00 2001 From: ted Date: Wed, 10 Jan 2018 20:15:32 -0700 Subject: [PATCH 248/294] Added release notes entry. --- docs/Development/ReleaseNotes.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 1824d489d..2e269c24d 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -101,19 +101,31 @@ To check which release of VIC you are running: 6. Cleanup of the initialization sections of the ``image`` and ``cesm`` drivers ([GH#701](https://github.com/UW-Hydro/VIC/pull/701)) - Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. + Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. 7. Added thread parallelization using OPENMP ([GH#712](https://github.com/UW-Hydro/VIC/pull/712)) - The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. + The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. 8. Added streamflow routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. +9. Miscellaneous clean-up: + + [GH#723](https://github.com/UW-Hydro/VIC/pull/723) + + 1. Added support for veg_hist forcings (non-climatological) in image mode + 2. Fixed erroneous allocation of extra veg tile in image mode + 3. Simplified looping over veg tiles and bands in vic_run() and prepare_full_energy() + 4. Replaced lengthy data structures with local pointers in vic_run() + 5. Simplified out_prec, out_rain, and Melt arrays + 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. + #### Bug Fixes: -1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) +1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) ------------------------------ From f2b519ec2f9bd42f40d072d00b52e4abd9645f73 Mon Sep 17 00:00:00 2001 From: Ted Bohn Date: Thu, 11 Jan 2018 23:28:43 -0700 Subject: [PATCH 249/294] Clean up esoil (#766) * Cleanup after merging with develop, which seemed to have removed my changes. * Simplified prepare_full_energy() to operate on a single instance of cell_data and energy_bal structs (removed loop over bands). * Removed re-formatting from uncrustify. * Changed "fcan" to "fcanopy" in vic/drivers/image/src/vic_force.c to be consistent with vic_init.c * Fixed typo. * Removing MAX_VEG and MAX_BAND... * Removed MAX_VEG and MAX_BAND. Replaced arrays that were statically allocated using these terms with dynamically allocated arrays. * A few more fixes. * Backed out changes to validation of bare soil tile. * Changed LAI_IN to LAI. * Changed "lai" to "LAI" in vic_force.c for consistency with vic_init.c. * Changed LAI_IN to LAI. Updated docs to use FCANOPY instead of VEGCOVER. Updated netcdf names of forcing variables from fcan and alb to fcanopy and albedo. * Backed out changes made to bare soil and Cv sum logic. * Changed LAI_IN to LAI. * Fixed typos in docs and replaced warning with error in vic_init.c when snow band areas sum to 0. * Fixed a couple more typos. * Cleaned up esoil logic and changed default value of RARC_SOIL to 250. * Rolled back the change to SOIL_RARC. * Added release notes entry. * Added release notes entry. --- docs/Development/ReleaseNotes.md | 22 +- .../Drivers/Classic/ForcingData.md | 4 +- .../Drivers/Classic/GlobalParam.md | 22 +- docs/Documentation/Drivers/Classic/VegLib.md | 2 +- .../Documentation/Drivers/Classic/VegParam.md | 4 +- .../Drivers/Image/GlobalParam.md | 16 +- docs/Documentation/Drivers/Image/Params.md | 6 +- .../cesm/src/display_current_settings.c | 2 - vic/drivers/cesm/src/get_global_param.c | 11 +- .../classic/src/display_current_settings.c | 2 - vic/drivers/classic/src/get_force_type.c | 4 +- vic/drivers/classic/src/get_global_param.c | 14 +- vic/drivers/classic/src/parse_output_info.c | 1 - vic/drivers/classic/src/read_atmos_data.c | 4 +- vic/drivers/classic/src/read_forcing_data.c | 2 +- vic/drivers/classic/src/read_veglib.c | 1 + vic/drivers/classic/src/read_vegparam.c | 6 - vic/drivers/classic/src/vic_force.c | 12 +- .../image/src/display_current_settings.c | 2 - vic/drivers/image/src/get_global_param.c | 9 - vic/drivers/image/src/vic_force.c | 18 +- .../python/src/display_current_settings.c | 2 - .../include/vic_driver_shared_all.h | 2 +- .../src/compute_derived_state_vars.c | 32 +- vic/drivers/shared_all/src/history_metadata.c | 2 +- vic/drivers/shared_all/src/initialize_soil.c | 3 +- .../shared_all/src/print_library_shared.c | 3 +- vic/drivers/shared_all/src/put_data.c | 22 +- vic/drivers/shared_image/src/set_force_type.c | 28 +- vic/drivers/shared_image/src/vic_alloc.c | 2 +- vic/drivers/shared_image/src/vic_finalize.c | 2 +- vic/drivers/shared_image/src/vic_init.c | 23 +- vic/vic_run/include/vic_def.h | 11 +- vic/vic_run/include/vic_run.h | 4 +- vic/vic_run/src/arno_evap.c | 22 +- vic/vic_run/src/canopy_evap.c | 67 ++-- vic/vic_run/src/func_surf_energy_bal.c | 83 ++--- vic/vic_run/src/prepare_full_energy.c | 100 +++-- vic/vic_run/src/vic_run.c | 344 +++++++++--------- 39 files changed, 433 insertions(+), 483 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 1824d489d..2e6068ee5 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -101,19 +101,35 @@ To check which release of VIC you are running: 6. Cleanup of the initialization sections of the ``image`` and ``cesm`` drivers ([GH#701](https://github.com/UW-Hydro/VIC/pull/701)) - Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. + Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. 7. Added thread parallelization using OPENMP ([GH#712](https://github.com/UW-Hydro/VIC/pull/712)) - The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. + The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. 8. Added streamflow routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. +9. Miscellaneous clean-up: + + [GH#723](https://github.com/UW-Hydro/VIC/pull/723) + + 1. Added support for veg_hist forcings (non-climatological) in image mode + 2. Fixed erroneous allocation of extra veg tile in image mode + 3. Simplified looping over veg tiles and bands in vic_run() and prepare_full_energy() + 4. Replaced lengthy data structures with local pointers in vic_run() + 5. Simplified out_prec, out_rain, and Melt arrays + 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. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) +1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) ------------------------------ diff --git a/docs/Documentation/Drivers/Classic/ForcingData.md b/docs/Documentation/Drivers/Classic/ForcingData.md index 49106ee14..98a875c73 100644 --- a/docs/Documentation/Drivers/Classic/ForcingData.md +++ b/docs/Documentation/Drivers/Classic/ForcingData.md @@ -19,8 +19,8 @@ The VIC Classic Driver requires subdaily forcings (meteorological or other). For | Variable | Description | Units | |------------|----------------------------------------------------------|---------------------------- | | ALBEDO | Surface Albedo | fraction (between 0 and 1) | -| LAI_IN | Leaf Area Index | m2/m2 | -| VEGCOVER | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | +| LAI | Leaf Area Index | m2/m2 | +| FCANOPY | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | #### Lake Forcings, Required when LAKES is TRUE: diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index 0b434d84f..ab28f10a6 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -75,7 +75,7 @@ Generally these default values do not need to be overridden. | BLOWING_SPATIAL_WIND | string | TRUE or FALSE | If TRUE, multiple wind speed ranges, calculated according to a probability distribution, are used to determine the sublimation flux from blowing snow. If FALSE, then a single wind speed is used. See Lu and Pomeroy (1997) for details.

    Default: TRUE. | | COMPUTE_TREELINE | string or integer | FALSE or veg class id | Options for handling above-treeline vegetation:FALSE = Do not compute treeline or replace vegetation above the treeline.CLASS_ID = Compute the treeline elevation based on average July temperatures; for those elevation bands with elevations above the treeline (or the entire grid cell if SNOW_BAND == 1 and the grid cell elevation is above the tree line), if they contain vegetation tiles having overstory, replace that vegetation with the vegetation having id CLASS_ID in the vegetation library. NOTE 1: You MUST supply VIC with a July average air temperature, in the optional July_Tavg field, AND set theJULY_TAVG_SUPPLIED option to TRUE so that VIC can read the soil parameter file correctly. NOTE 2: If LAKES=TRUE, COMPUTE_TREELINE MUST be FALSE.Default = FALSE. | | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -148,8 +148,8 @@ All FORCING filenames are actually the pathname, and prefix for gridded data typ | FORCING2 | string | pathname and file prefix | Second forcing file name, or FALSE if only one file used.This must precede all other forcing parameters used to define the second forcing file, and follow those used to define the first forcing file. | | FORCE_FORMAT | string | BINARY or ASCII | Defines the format type for the forcing files. | | FORCE_ENDIAN | string | BIG or LITTLE | Identifies the architecture of the machine on which the binary forcing files were created:BIG = big-endian (e.g. SUN).LITTLE = little-endian (e.g. PC/linux). Model will identify the endian of the current machine, and swap bytes if necessary. Required for binary forcing file, not used for ASCII forcing file. | -| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI_IN, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI_IN, and FCANOPY each count as only 1 variable despite covering multiple columns. | -| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI_IN, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI_IN, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | +| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI, and FCANOPY each count as only 1 variable despite covering multiple columns. | +| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | | FORCE_STEPS_PER_DAY | integer | steps | Number of timesteps per day in forcing file (must be = SNOW_STPES_PER_DAY) | | FORCEYEAR | integer | year | Year meteorological forcing files start | | FORCEMONTH | integer | month | Month meteorological forcing files start | @@ -211,17 +211,17 @@ The following options describe the input parameter files. | SOIL | string | path/filename | the Soil parameter file. | | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file:ARNO = fields 5-8 of the soil parameter file are the standard VIC baseflow parametersNIJSSEN2001 = fields 5-8 of the soil parameter file are the baseflow parameters from Nijssen et al (2001) Default = ARNO. | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional column (July_Tavg) in the soil parameter file to contain the grid cell's average July temperature. If your soil parameter file contains this optional column, you MUST set JULY_TAVG_SUPPLIED to TRUE so that VIC can read the soil parameter file correctly. NOTE: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE. Default = FALSE. | -| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer.FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | +| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer. FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | | VEGLIB | string | path/filename | Vegetation library file name | | VEGPARAM | string | path/filename | Vegetation parameter file name | | ROOT_ZONES | integer | N/A | Number of defined root zones defined for root distribution. | | VEGPARAM_ALB | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly ALBEDO values for each vegetation type for each grid cell. Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values:FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE.FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE. FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGPARAM_LAI | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly LAI values for each vegetation type for each grid cell. Default = FALSE. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values:FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGLIB_FCAN | string | TRUE or FALSE | If TRUE the vegetation library file contains monthly FCANOPY values for each vegetation type for each grid cell (between the LAI and ALBEDO values). Default = FALSE. | | VEGPARAM_FCAN | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly FCANOPY values for each vegetation type for each grid cell. Default = FALSE. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | integer[string] | N/A [path/filename] | Maximum number of snow elevation bands to use, and the name (with path) of the snow elevation band file. For example: SNOW_BAND 5 path/filename. To turn off this feature, set the number of snow bands to 1 and do not follow this with a snow elevation band file name. Default = 1. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Classic/VegLib.md b/docs/Documentation/Drivers/Classic/VegLib.md index 7491c0d03..218fccf40 100644 --- a/docs/Documentation/Drivers/Classic/VegLib.md +++ b/docs/Documentation/Drivers/Classic/VegLib.md @@ -11,7 +11,7 @@ Vegetation parameters needed for each vegetation type used in the VIC model are | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/docs/Documentation/Drivers/Classic/VegParam.md b/docs/Documentation/Drivers/Classic/VegParam.md index 9e40530b3..10ceea7c2 100644 --- a/docs/Documentation/Drivers/Classic/VegParam.md +++ b/docs/Documentation/Drivers/Classic/VegParam.md @@ -37,11 +37,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: +OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | +| FCANOPY | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index de2fa16d7..d080294ec 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -77,7 +77,7 @@ Generally these default values do not need to be overridden. | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | | MAX_SNOW_TEMP | float | deg C | Maximum temperature at which snow can fall. Default = 0.5 C. | | MIN_RAIN_TEMP | float | deg C | Minimum temperature at which rain can fall. Default = -0.5 C. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -175,9 +175,9 @@ The following options describe the input parameter files. | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file. Valid options: ARNO, NIJSSEN2001. See classic driver global parameter file for detail (../Classic/GlobalParam.md). | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional variable in the parameter file (July_Tavg) to contain the grid cell's average July temperature. *NOTE*: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE.

    Default = FALSE. | | ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the parameter file contains extra variables: the organic fraction, and the bulk density and soil particle density of the organic matter in each soil layer. FALSE = the parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file.FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | string | TRUE or FALSE | Whether multiple snowband option is enables. If TRUE, snowband information is specified in the parameter netCDF file.

    Default = FALSE. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index 5be216247..ef05570c5 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -94,11 +94,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: +OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | +| FCANOPY | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there following parameters will also be included in the NetCDF parameter file: @@ -118,7 +118,7 @@ Vegetation parameters are given for different vegetation types. Below are a list | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 029575613..85a0dc2d9 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -56,14 +56,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index 89ab7c3c4..ef0c6ff82 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -448,7 +448,7 @@ get_global_param(FILE *gp) // TBD: feature in VIC 4.2 that has been ported to classic // mode, but that does not exist in image mode (yet) else if (strcasecmp("ALBEDO", optstr) == 0 || - strcasecmp("LAI_IN", optstr) == 0 || + strcasecmp("LAI", optstr) == 0 || strcasecmp("FCANOPY", optstr) == 0) { log_err("Time-varying vegetation parameters not implemented " "in CESM driver"); @@ -562,14 +562,7 @@ validate_options(option_struct *options) } // Validate the elevation band file information - if (options->SNOW_BAND > 1) { - if (options->SNOW_BAND > MAX_BANDS) { - log_err("Global file wants more snow bands (%zu) than are " - "defined by MAX_BANDS (%d). Edit vicNl_def.h and " - "recompile.", options->SNOW_BAND, MAX_BANDS); - } - } - else if (options->SNOW_BAND <= 0) { + if (options->SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " "file (%zu). Number of bands must be >= 1.", options->SNOW_BAND); diff --git a/vic/drivers/classic/src/display_current_settings.c b/vic/drivers/classic/src/display_current_settings.c index ccd3a9e91..f0c5d7c8f 100644 --- a/vic/drivers/classic/src/display_current_settings.c +++ b/vic/drivers/classic/src/display_current_settings.c @@ -58,14 +58,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/classic/src/get_force_type.c b/vic/drivers/classic/src/get_force_type.c index 03e2fb984..98bde93f5 100644 --- a/vic/drivers/classic/src/get_force_type.c +++ b/vic/drivers/classic/src/get_force_type.c @@ -82,8 +82,8 @@ get_force_type(char *cmdstr, type = FDIR; } /* type 6: LAI [m2/m2] */ - else if (strcasecmp("LAI_IN", optstr) == 0) { - type = LAI_IN; + else if (strcasecmp("LAI", optstr) == 0) { + type = LAI; } /* type 7: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 4a6534ab9..064c98c76 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -1038,13 +1038,13 @@ get_global_param(FILE *gp) log_err("ROOT_ZONES must be defined to a positive integer greater " "than 0, in the global control file."); } - if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI_IN].SUPPLIED) { + if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI].SUPPLIED) { log_err("\"LAI_SRC\" was specified as \"FROM_VEGHIST\", but " - "\"LAI_IN\" was not specified as an input forcing in the " + "\"LAI\" was not specified as an input forcing in the " "global parameter file. If you want VIC to read LAI " "values from the veg_hist file, you MUST make sure the veg " - "hist file contains Nveg columns of LAI_IN values, 1 for " - "each veg tile in the grid cell, AND specify LAI_IN as a " + "hist file contains Nveg columns of LAI values, 1 for " + "each veg tile in the grid cell, AND specify LAI as a " "forcing variable in the veg_hist forcing file in the " "global parameter file."); } @@ -1170,12 +1170,6 @@ get_global_param(FILE *gp) "file on the line that begins with \"SNOW_BAND\" " "(after the number of bands).", options.SNOW_BAND); } - if (options.SNOW_BAND > MAX_BANDS) { - log_err("Global file wants more snow bands (%zu) than are " - "defined by MAX_BANDS (%d). Edit vic_run/include/vic_def.h " - "and recompile.", options.SNOW_BAND, - MAX_BANDS); - } } else if (options.SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " diff --git a/vic/drivers/classic/src/parse_output_info.c b/vic/drivers/classic/src/parse_output_info.c index 1641a406e..d661e1f6d 100644 --- a/vic/drivers/classic/src/parse_output_info.c +++ b/vic/drivers/classic/src/parse_output_info.c @@ -36,7 +36,6 @@ parse_output_info(FILE *gp, dmy_struct *dmy_current) { extern option_struct options; - extern global_param_struct global_param; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; diff --git a/vic/drivers/classic/src/read_atmos_data.c b/vic/drivers/classic/src/read_atmos_data.c index deab975e4..0930987b1 100644 --- a/vic/drivers/classic/src/read_atmos_data.c +++ b/vic/drivers/classic/src/read_atmos_data.c @@ -145,7 +145,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && + if (field_index[i] != ALBEDO && field_index[i] != LAI && field_index[i] != FCANOPY) { if (param_set.TYPE[field_index[i]].SIGNED) { fread(&stmp, sizeof(short int), 1, infile); @@ -226,7 +226,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && + if (field_index[i] != ALBEDO && field_index[i] != LAI && field_index[i] != FCANOPY) { fscanf(infile, "%lf", &forcing_data[field_index[i]][rec]); } diff --git a/vic/drivers/classic/src/read_forcing_data.c b/vic/drivers/classic/src/read_forcing_data.c index cfaec814c..71f4720f6 100644 --- a/vic/drivers/classic/src/read_forcing_data.c +++ b/vic/drivers/classic/src/read_forcing_data.c @@ -50,7 +50,7 @@ read_forcing_data(FILE **infile, check_alloc_status((*veg_hist_data), "Memory allocation error."); for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { + if (i != ALBEDO && i != LAI && i != FCANOPY) { forcing_data[i] = calloc(global_param.nrecs * NF, sizeof(*(forcing_data[i]))); check_alloc_status(forcing_data[i], "Memory allocation error."); diff --git a/vic/drivers/classic/src/read_veglib.c b/vic/drivers/classic/src/read_veglib.c index 703074a04..af7853846 100644 --- a/vic/drivers/classic/src/read_veglib.c +++ b/vic/drivers/classic/src/read_veglib.c @@ -62,6 +62,7 @@ read_veglib(FILE *veglib, // +1 for bare soil temp = calloc(Nveg_type + 1, sizeof(*temp)); + options.NVEGTYPES = Nveg_type + 1; fscanf(veglib, "%s", str); i = 0; diff --git a/vic/drivers/classic/src/read_vegparam.c b/vic/drivers/classic/src/read_vegparam.c index c322a0833..13ea80878 100644 --- a/vic/drivers/classic/src/read_vegparam.c +++ b/vic/drivers/classic/src/read_vegparam.c @@ -92,12 +92,6 @@ read_vegparam(FILE *vegparam, if (vegcel != gridcel) { log_err("Grid cell %d not found", gridcel); } - if (vegetat_type_num >= MAX_VEG) { - log_err("Vegetation parameter file wants more vegetation tiles in " - "grid cell %i (%i) than are allowed by MAX_VEG (%i) [NOTE: " - "bare soil class is assumed]. Edit vic_run/vic_def.h and " - "recompile.", gridcel, vegetat_type_num + 1, MAX_VEG); - } // Make sure to allocate extra memory for bare soil tile // and optionally an above-treeline veg tile diff --git a/vic/drivers/classic/src/vic_force.c b/vic/drivers/classic/src/vic_force.c index 36c9f85a7..09f1fb770 100644 --- a/vic/drivers/classic/src/vic_force.c +++ b/vic/drivers/classic/src/vic_force.c @@ -95,8 +95,8 @@ vic_force(force_data_struct *force, if (param_set.TYPE[ALBEDO].SUPPLIED) { param_set.TYPE[ALBEDO].N_ELEM = veg_con[0].vegetat_type_num; } - if (param_set.TYPE[LAI_IN].SUPPLIED) { - param_set.TYPE[LAI_IN].N_ELEM = veg_con[0].vegetat_type_num; + if (param_set.TYPE[LAI].SUPPLIED) { + param_set.TYPE[LAI].N_ELEM = veg_con[0].vegetat_type_num; } if (param_set.TYPE[FCANOPY].SUPPLIED) { param_set.TYPE[FCANOPY].N_ELEM = veg_con[0].vegetat_type_num; @@ -246,11 +246,11 @@ vic_force(force_data_struct *force, veg_hist_data[ALBEDO][v][uidx]; } } - if (param_set.TYPE[LAI_IN].SUPPLIED && + if (param_set.TYPE[LAI].SUPPLIED && options.LAI_SRC == FROM_VEGHIST) { - if (veg_hist_data[LAI_IN][v][uidx] != NODATA_VH) { + if (veg_hist_data[LAI][v][uidx] != NODATA_VH) { veg_hist[rec][v].LAI[i] = - veg_hist_data[LAI_IN][v][uidx]; + veg_hist_data[LAI][v][uidx]; } } if (param_set.TYPE[FCANOPY].SUPPLIED && @@ -289,7 +289,7 @@ vic_force(force_data_struct *force, for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { + if (i != ALBEDO && i != LAI && i != FCANOPY) { free(forcing_data[i]); } else { diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index 4bf4f71f6..e02df18cf 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -60,14 +60,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 67344cdee..1957716c8 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -527,15 +527,6 @@ get_global_param(FILE *gp) else if (strcasecmp("OUT_FORMAT", optstr) == 0) { ; // do nothing } - // vegetation history not yet implemented in image mode - // TBD: feature in VIC 4.2 that has been ported to classic - // mode, but that does not exist in image mode (yet) - else if (strcasecmp("ALBEDO", optstr) == 0 || - strcasecmp("LAI_IN", optstr) == 0 || - strcasecmp("FCANOPY", optstr) == 0) { - log_err("Time-varying vegetation parameters not implemented " - "in image mode"); - } /************************************* Fail when classic driver specific options are used diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 1209335e0..033a9f057 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -316,14 +316,14 @@ vic_force(void) d4count[2] = global_domain.n_ny; d4count[3] = global_domain.n_nx; - // Leaf Area Index: lai + // Leaf Area Index: LAI if (options.LAI_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "lai", + get_scatter_nc_field_double(&(filenames.forcing[1]), "LAI", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; @@ -335,15 +335,16 @@ vic_force(void) } } - // Partial veg cover fraction: fcan + // Partial veg cover fraction: fcanopy if (options.FCAN_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "fcan", - d4start, d4count, dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), + "fcanopy", d4start, d4count, + dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { @@ -354,15 +355,16 @@ vic_force(void) } } - // Albedo: alb + // Albedo: albedo if (options.ALB_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "alb", - d4start, d4count, dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), + "albedo", d4start, d4count, + dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { diff --git a/vic/drivers/python/src/display_current_settings.c b/vic/drivers/python/src/display_current_settings.c index 305ea4892..8764ab752 100644 --- a/vic/drivers/python/src/display_current_settings.c +++ b/vic/drivers/python/src/display_current_settings.c @@ -53,14 +53,12 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); - fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); - fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index c042ecf50..b60a97808 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -93,7 +93,7 @@ enum CHANNEL_IN, /**< incoming channel flow [m3] */ FCANOPY, /**< fractional area covered by plant canopy [fraction] */ FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ - LAI_IN, /**< leaf area index [m2/m2] */ + LAI, /**< leaf area index [m2/m2] */ LWDOWN, /**< incoming longwave radiation [W/m2] */ PAR, /**< incoming photosynthetically active radiation [W/m2] */ PREC, /**< total precipitation (rain and snow) [mm] */ diff --git a/vic/drivers/shared_all/src/compute_derived_state_vars.c b/vic/drivers/shared_all/src/compute_derived_state_vars.c index c0a61cabb..bff4c87a7 100644 --- a/vic/drivers/shared_all/src/compute_derived_state_vars.c +++ b/vic/drivers/shared_all/src/compute_derived_state_vars.c @@ -46,6 +46,10 @@ compute_derived_state_vars(all_vars_struct *all_vars, size_t veg; size_t lidx; size_t band; + size_t tmpMshape[] = { + options.NVEGTYPES + 1, options.SNOW_BAND, + options.Nlayer + }; size_t tmpTshape[] = { options.Nlayer, options.Nnode, options.Nfrost + 1 @@ -55,9 +59,9 @@ compute_derived_state_vars(all_vars_struct *all_vars, }; int ErrorFlag; double Cv; - double moist[MAX_VEG][MAX_BANDS][MAX_LAYERS]; double dt_thresh; double tmp_runoff; + double ***tmpM; double ***tmpT; double **tmpZ; @@ -70,9 +74,12 @@ compute_derived_state_vars(all_vars_struct *all_vars, snow = all_vars->snow; Nveg = veg_con[0].vegetat_type_num; - // allocate memory for tmpT and tmpZ - malloc_3d_double(tmpTshape, &tmpT); - malloc_2d_double(tmpZshape, &tmpZ); + // allocate memory for tmp* arrays + malloc_3d_double(tmpMshape, &tmpM); + if (!options.QUICK_FLUX) { + malloc_3d_double(tmpTshape, &tmpT); + malloc_2d_double(tmpZshape, &tmpZ); + } /****************************************** Compute derived soil layer vars @@ -85,14 +92,14 @@ compute_derived_state_vars(all_vars_struct *all_vars, for (band = 0; band < options.SNOW_BAND; band++) { // Initialize soil for existing snow elevation bands if (soil_con->AreaFract[band] > 0.) { - // set up temporary moist arrays + // set up temporary moist array for (lidx = 0; lidx < options.Nlayer; lidx++) { - moist[veg][band][lidx] = + tmpM[veg][band][lidx] = cell[veg][band].layer[lidx].moist; } // compute saturated area and water table - compute_runoff_and_asat(soil_con, moist[veg][band], 0, + compute_runoff_and_asat(soil_con, tmpM[veg][band], 0, &(cell[veg][band].asat), &tmp_runoff); wrap_compute_zwt(soil_con, &(cell[veg][band])); @@ -152,7 +159,7 @@ compute_derived_state_vars(all_vars_struct *all_vars, soil_con->max_moist_node, soil_con->expt_node, soil_con->bubble_node, - moist[veg][band], + tmpM[veg][band], soil_con->depth, soil_con->soil_dens_min, soil_con->bulk_dens_min, @@ -248,7 +255,10 @@ compute_derived_state_vars(all_vars_struct *all_vars, } } } - // free memory for tmpT and tmpZ - free_3d_double(tmpTshape, tmpT); - free_2d_double(tmpZshape, tmpZ); + // free memory for tmp* arrays + free_3d_double(tmpMshape, tmpM); + if (!options.QUICK_FLUX) { + free_3d_double(tmpTshape, tmpT); + free_2d_double(tmpZshape, tmpZ); + } } diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index e38a39c76..75746a94c 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -391,7 +391,7 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_BF_IN].standard_name, "infiltration_amount"); strcpy(out_metadata[OUT_LAKE_BF_IN].units, "mm"); strcpy(out_metadata[OUT_LAKE_BF_IN].description, - "oisture that reaches top of soil column"); + "incoming baseflow from lake catchment"); /* incoming volumetric baseflow from lake catchment [m3] */ strcpy(out_metadata[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); diff --git a/vic/drivers/shared_all/src/initialize_soil.c b/vic/drivers/shared_all/src/initialize_soil.c index 6b9761f92..8850fb3bd 100644 --- a/vic/drivers/shared_all/src/initialize_soil.c +++ b/vic/drivers/shared_all/src/initialize_soil.c @@ -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; } } diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index ef9efdeaa..4dd95fdda 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -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); } diff --git a/vic/drivers/shared_all/src/put_data.c b/vic/drivers/shared_all/src/put_data.c index 700310480..d2ab6eaeb 100644 --- a/vic/drivers/shared_all/src/put_data.c +++ b/vic/drivers/shared_all/src/put_data.c @@ -67,7 +67,7 @@ put_data(all_vars_struct *all_vars, double inflow; double outflow; double storage; - double TreeAdjustFactor[MAX_BANDS]; + double *TreeAdjustFactor; double ThisAreaFract; double ThisTreeAdjust; size_t i; @@ -93,6 +93,8 @@ put_data(all_vars_struct *all_vars, dt_sec = global_param.dt; // Compute treeline adjustment factors + TreeAdjustFactor = calloc(options.SNOW_BAND, sizeof(*TreeAdjustFactor)); + check_alloc_status(TreeAdjustFactor, "Memory allocation error."); for (band = 0; band < options.SNOW_BAND; band++) { if (AboveTreeLine[band]) { Cv = 0; @@ -569,6 +571,8 @@ put_data(all_vars_struct *all_vars, out_data[OUT_ENERGY_ERROR][0] = MISSING; } + free((char *) (TreeAdjustFactor)); + // vic_run run time out_data[OUT_TIME_VICRUN_WALL][0] = timer->delta_wall; out_data[OUT_TIME_VICRUN_CPU][0] = timer->delta_cpu; @@ -608,19 +612,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; diff --git a/vic/drivers/shared_image/src/set_force_type.c b/vic/drivers/shared_image/src/set_force_type.c index 89cdbfe89..c4a523386 100644 --- a/vic/drivers/shared_image/src/set_force_type.c +++ b/vic/drivers/shared_image/src/set_force_type.c @@ -76,42 +76,42 @@ set_force_type(char *cmdstr, else if (strcasecmp("CHANNEL_IN", optstr) == 0) { type = CHANNEL_IN; } - /* type 4: direct fraction of shortwave [fraction] */ + /* type 4: vegetation cover fraction [fraction] */ + else if (strcasecmp("FCANOPY", optstr) == 0) { + type = FCANOPY; + } + /* type 5: direct fraction of shortwave [fraction] */ else if (strcasecmp("FDIR", optstr) == 0) { type = FDIR; } - /* type 5: LAI [m2/m2] */ - else if (strcasecmp("LAI_IN", optstr) == 0) { - type = LAI_IN; + /* type 6: LAI [m2/m2] */ + else if (strcasecmp("LAI", optstr) == 0) { + type = LAI; } - /* type 6: incoming longwave radiation [W/m2] */ + /* type 7: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { type = LWDOWN; } - /* type 7: photosynthetically active radiation [uE/m2s] */ + /* type 8: photosynthetically active radiation [uE/m2s] */ else if (strcasecmp("PAR", optstr) == 0) { type = PAR; } - /* type 8: precipitation [mm] */ + /* type 9: precipitation [mm] */ else if (strcasecmp("PREC", optstr) == 0) { type = PREC; } - /* type 9: air pressure [kPa] */ + /* type 10: air pressure [kPa] */ else if (strcasecmp("PRESSURE", optstr) == 0) { type = PRESSURE; } - /* type 10: vapor pressure [kPa] */ + /* type 11: vapor pressure [kPa] */ else if (strcasecmp("VP", optstr) == 0) { type = VP; } - /* type 11: incoming shortwave radiation [W/m2] */ + /* type 12: incoming shortwave radiation [W/m2] */ else if (strcasecmp("SWDOWN", optstr) == 0) { type = SWDOWN; } - /* type 12: vegetation cover fraction */ - else if (strcasecmp("FCANOPY", optstr) == 0) { - type = FCANOPY; - } /* type 13: wind speed [m/s] */ else if (strcasecmp("WIND", optstr) == 0) { type = WIND; diff --git a/vic/drivers/shared_image/src/vic_alloc.c b/vic/drivers/shared_image/src/vic_alloc.c index 34ecfec9d..005089375 100644 --- a/vic/drivers/shared_image/src/vic_alloc.c +++ b/vic/drivers/shared_image/src/vic_alloc.c @@ -158,7 +158,7 @@ vic_alloc(void) veg_lib[i] = calloc(options.NVEGTYPES, sizeof(*(veg_lib[i]))); check_alloc_status(veg_lib[i], "Memory allocation error."); - all_vars[i] = make_all_vars(veg_con_map[i].nv_active); + all_vars[i] = make_all_vars(veg_con_map[i].nv_active - 1); // allocate memory for veg_hist veg_hist[i] = calloc(veg_con_map[i].nv_active, sizeof(*(veg_hist[i]))); diff --git a/vic/drivers/shared_image/src/vic_finalize.c b/vic/drivers/shared_image/src/vic_finalize.c index cc643876f..26043e199 100644 --- a/vic/drivers/shared_image/src/vic_finalize.c +++ b/vic/drivers/shared_image/src/vic_finalize.c @@ -94,7 +94,7 @@ vic_finalize(void) } free_veg_hist(&(veg_hist[i][j])); } - free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active); + free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active - 1); free(veg_con_map[i].vidx); free(veg_con_map[i].Cv); free(veg_con[i]); diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 83a7cf769..5bd57d410 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -272,6 +272,7 @@ vic_init(void) else { veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; } + veg_lib[i][j].fcanopy[k] = 1.0; } } } @@ -988,11 +989,17 @@ vic_init(void) } if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Sum of the snow band area fractions does not equal " - "1 (%f), dividing each fraction by the sum\n%s", - sum, locstr); - for (j = 0; j < options.SNOW_BAND; j++) { - soil_con[i].AreaFract[j] /= sum; + if (sum > 0) { + log_warn("Sum of the snow band area fractions does not " + "equal 1 (%f), dividing each fraction by the " + "sum\n%s", sum, locstr); + for (j = 0; j < options.SNOW_BAND; j++) { + soil_con[i].AreaFract[j] /= sum; + } + } + else { + log_err("Sum of the snow band area fractions is 0\n%s", + locstr); } } // check that the mean elevation from the snow bands matches the @@ -1228,11 +1235,11 @@ vic_init(void) // TODO: handle bare soil adjustment for compute treeline option // If the sum of the tile fractions is not within a tolerance, - // throw an error + // readjust Cvs to sum to 1.0 if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", - Cv_sum[i], i, locstr); + log_warn("Cv != 1.0 (%f) at grid cell %zd. Adjusting fractions " + "...\n%s", Cv_sum[i], i, locstr); for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; veg_con[i][vidx].Cv /= Cv_sum[i]; diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 184ede176..f90bca69f 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -59,10 +59,8 @@ #define ERROR -999 /**< Error Flag returned by subroutines */ /***** Define maximum array sizes for model source code *****/ -#define MAX_VEG 12 /**< maximum number of vegetation types per cell */ #define MAX_LAYERS 3 /**< maximum number of soil moisture layers */ #define MAX_NODES 50 /**< maximum number of soil thermal nodes */ -#define MAX_BANDS 10 /**< maximum number of snow bands */ #define MAX_FRONTS 3 /**< maximum number of freezing and thawing front depths to store */ #define MAX_FROST_AREAS 10 /**< maximum number of frost sub-areas */ #define MAX_LAKE_NODES 20 /**< maximum number of lake thermal nodes */ @@ -235,10 +233,8 @@ typedef struct { size_t Nnode; /**< Number of soil thermal nodes in the model */ bool NOFLUX; /**< TRUE = Use no flux lower bondary when computing soil thermal fluxes */ - size_t NVEGTYPES; /**< number of vegetation types in veg_param file - (used by image driver) */ - size_t NLAKENODES; /**< number of lake layers in lake_param file - (used by image driver) */ + size_t NVEGTYPES; /**< number of vegetation types in veg_param file */ + size_t NLAKENODES; /**< number of lake layers in lake_param file */ unsigned short int RC_MODE; /**< RC_JARVIS = compute canopy resistance via Jarvis formulation (default) RC_PHOTO = compute canopy resistance based on photosynthetic activity */ size_t ROOT_ZONES; /**< Number of root zones used in simulation */ @@ -772,8 +768,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; /****************************************************************************** diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 02ae0c073..9c6e4cfbd 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -217,8 +217,8 @@ void photosynth(char, double, double, double, double, double, double, double, double, double, char *, double *, double *, double *, double *, double *); void polint(double xa[], double ya[], int n, double x, double *y, double *dy); -void prepare_full_energy(int, all_vars_struct *, soil_con_struct *, double *, - double *); +void prepare_full_energy(cell_data_struct *, energy_bal_struct *, + soil_con_struct *, double *, double *); double qromb( double (*sub_with_height)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, double b); diff --git a/vic/vic_run/src/arno_evap.c b/vic/vic_run/src/arno_evap.c index 7b3ed3a32..3f4db87e9 100644 --- a/vic/vic_run/src/arno_evap.c +++ b/vic/vic_run/src/arno_evap.c @@ -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; @@ -115,7 +115,7 @@ arno_evap(layer_data_struct *layer, /**********************************************************************/ if (tmp >= max_infil) { - evap = Epot; + esoil = Epot; } else { /********************************************************************/ @@ -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; } /***********************************************************************/ @@ -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); } diff --git a/vic/vic_run/src/canopy_evap.c b/vic/vic_run/src/canopy_evap.c index 8f6689497..51b7ce3ab 100644 --- a/vic/vic_run/src/canopy_evap.c +++ b/vic/vic_run/src/canopy_evap.c @@ -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; @@ -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); } @@ -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); @@ -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, @@ -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; @@ -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 transipration based on root fraction. ******************************************************************/ if (options.SHARE_LAYER_MOIST && @@ -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) * + 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]) { @@ -345,24 +345,25 @@ 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. @@ -380,7 +381,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; } @@ -428,7 +429,7 @@ transpiration(layer_data_struct *layer, } /* compute transpiration */ - layerevap[i] = penman(air_temp, elevation, rad, vpd, ra, + layertransp[i] = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc, vic_run_veg_lib[veg_class].rarc) * delta_t / CONST_CDAY * dryFrac * @@ -453,7 +454,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++) { @@ -494,32 +495,32 @@ transpiration(layer_data_struct *layer, } /**************************************************************** - Check that evapotransipration does not cause soil moisture to + Check that transipration 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; } } } diff --git a/vic/vic_run/src/func_surf_energy_bal.c b/vic/vic_run/src/func_surf_energy_bal.c index 1fe7ef4ca..4e47301f9 100644 --- a/vic/vic_run/src/func_surf_energy_bal.c +++ b/vic/vic_run/src/func_surf_energy_bal.c @@ -203,7 +203,7 @@ func_surf_energy_bal(double Ts, double T1_plus; double D1_minus; double D1_plus; - double *transp = NULL; + double SurfRad; double Ra_bare[3]; double tmp_wind[3]; double tmp_height; @@ -366,12 +366,6 @@ func_surf_energy_bal(double Ts, TMean = Ts; - transp = calloc(options.Nlayer, sizeof(*transp)); - check_alloc_status(transp, "Memory allocation error."); - for (i = 0; i < options.Nlayer; i++) { - transp[i] = 0.; - } - /********************************************** Compute Surface Temperature at Half Time Step **********************************************/ @@ -749,67 +743,46 @@ func_surf_energy_bal(double Ts, Should evapotranspiration be active when the ground is only partially covered with snow???? - - Use Arno Evap in the exposed soil portion, and/or - if LAI is zero. *************************************************/ - if (VEG && !SNOWING && veg_var->fcanopy > 0) { - Evap = canopy_evap(layer, veg_var, true, - veg_class, Wdew, delta_t, NetBareRad, vpd, - NetShortBare, Tair, Ra_veg[1], elevation, rainfall, - Wmax, Wcr, Wpwp, frost_fract, root, dryFrac, - shortwave, Catm, CanopLayerBnd); - if (veg_var->fcanopy < 1) { - for (i = 0; i < options.Nlayer; i++) { - transp[i] = layer[i].evap; - layer[i].evap = 0.; - } + for (i=0; ifcanopy > 0) { + Evap = canopy_evap(layer, veg_var, true, veg_class, Wdew, + delta_t, NetBareRad, vpd, NetShortBare, + Tair, Ra_veg[1], elevation, rainfall, + Wmax, Wcr, Wpwp, frost_fract, root, + dryFrac, shortwave, Catm, CanopLayerBnd); Evap *= veg_var->fcanopy; - Evap += (1 - veg_var->fcanopy) * - arno_evap(layer, surf_atten * NetBareRad, Tair, vpd, - depth[0], max_moist * depth[0] * MM_PER_M, - elevation, b_infilt, Ra_used[0], delta_t, - resid_moist[0], frost_fract); - for (i = 0; i < options.Nlayer; i++) { - layer[i].evap = veg_var->fcanopy * transp[i] + - (1 - veg_var->fcanopy) * layer[i].evap; - if (layer[i].evap > 0.) { - layer[i].bare_evap_frac = 1 - - (veg_var->fcanopy * - transp[i]) / layer[i].evap; - } - else { - layer[i].bare_evap_frac = 0.; - } + for (i=0; ifcanopy; } - veg_var->throughfall = - (1 - - veg_var->fcanopy) * rainfall + veg_var->fcanopy * - veg_var->throughfall; - veg_var->canopyevap *= veg_var->fcanopy; - veg_var->Wdew *= veg_var->fcanopy; + SurfRad = surf_atten*NetBareRad; } else { - for (i = 0; i < options.Nlayer; i++) { - layer[i].bare_evap_frac = 0.; - } + SurfRad = NetBareRad; } - } - else if (!SNOWING) { - Evap = arno_evap(layer, NetBareRad, Tair, vpd, - depth[0], max_moist * depth[0] * MM_PER_M, - elevation, b_infilt, Ra_used[0], delta_t, - resid_moist[0], frost_fract); + Evap += (1 - veg_var->fcanopy) * + arno_evap(layer, SurfRad, Tair, vpd, + depth[0], max_moist * depth[0] * MM_PER_M, + elevation, b_infilt, Ra_used[0], delta_t, + resid_moist[0], frost_fract); for (i = 0; i < options.Nlayer; i++) { - layer[i].bare_evap_frac = 1; + layer[i].esoil *= (1 - veg_var->fcanopy); + layer[i].evap = layer[i].transp + layer[i].esoil; } + veg_var->throughfall = (1 - veg_var->fcanopy) * rainfall + + veg_var->fcanopy * veg_var->throughfall; + veg_var->canopyevap *= veg_var->fcanopy; + veg_var->Wdew *= veg_var->fcanopy; } else { Evap = 0.; } - free(transp); - /********************************************************************** Compute the Latent Heat Flux from the Surface and Covering Vegetation **********************************************************************/ diff --git a/vic/vic_run/src/prepare_full_energy.c b/vic/vic_run/src/prepare_full_energy.c index 409803c87..33f1c3f38 100644 --- a/vic/vic_run/src/prepare_full_energy.c +++ b/vic/vic_run/src/prepare_full_energy.c @@ -34,78 +34,64 @@ * ground heat flux solution. *****************************************************************************/ void -prepare_full_energy(int iveg, - all_vars_struct *all_vars, - soil_con_struct *soil_con, - double *moist0, - double *ice0) +prepare_full_energy(cell_data_struct *cell, + energy_bal_struct *energy, + soil_con_struct *soil_con, + double *moist0, + double *ice0) { extern option_struct options; - size_t i, band; + size_t i; layer_data_struct *layer = NULL; layer = calloc(options.Nlayer, sizeof(*layer)); check_alloc_status(layer, "Memory allocation error."); - for (band = 0; band < options.SNOW_BAND; band++) { - if (soil_con->AreaFract[band] > 0.0) { - for (i = 0; i < options.Nlayer; i++) { - layer[i] = all_vars->cell[iveg][band].layer[i]; - } - - /* Compute top soil layer moisture content (mm/mm) */ - - moist0[band] = layer[0].moist / (soil_con->depth[0] * MM_PER_M); + for (i = 0; i < options.Nlayer; i++) { + layer[i] = cell->layer[i]; + } - /* Compute top soil layer ice content (mm/mm) */ + /* Compute top soil layer moisture content (mm/mm) */ + *moist0 = layer[0].moist / (soil_con->depth[0] * MM_PER_M); - if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { - if ((all_vars->energy[iveg][band].T[0] + - all_vars->energy[iveg][band].T[1]) / 2. < 0.) { - ice0[band] = moist0[band] - - maximum_unfrozen_water((all_vars->energy[iveg][ - band].T[0] + - all_vars->energy[iveg][ - band].T[1]) / 2., - soil_con->max_moist[0] / - (soil_con->depth[0] * - MM_PER_M), - soil_con->bubble[0], - soil_con->expt[0]); - if (ice0[band] < 0.) { - ice0[band] = 0.; - } - } - else { - ice0[band] = 0.; - } - } - else { - ice0[band] = 0.; + /* Compute top soil layer ice content (mm/mm) */ + if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { + if ((energy->T[0] + energy->T[1]) / 2. < 0.) { + *ice0 = *moist0 - + maximum_unfrozen_water((energy->T[0] + energy->T[1]) / 2., + soil_con->max_moist[0] / + (soil_con->depth[0] * MM_PER_M), + soil_con->bubble[0], + soil_con->expt[0]); + if (*ice0 < 0.) { + *ice0 = 0.; } - - /** Compute Soil Thermal Properties **/ - compute_soil_layer_thermal_properties(layer, soil_con->depth, - soil_con->bulk_dens_min, - soil_con->soil_dens_min, - soil_con->quartz, - soil_con->bulk_density, - soil_con->soil_density, - soil_con->organic, - soil_con->frost_fract, - options.Nlayer); - - /** Save Thermal Conductivities for Energy Balance **/ - all_vars->energy[iveg][band].kappa[0] = layer[0].kappa; - all_vars->energy[iveg][band].Cs[0] = layer[0].Cs; - all_vars->energy[iveg][band].kappa[1] = layer[1].kappa; - all_vars->energy[iveg][band].Cs[1] = layer[1].Cs; } else { - ice0[band] = 0.; + *ice0 = 0.; } } + else { + *ice0 = 0.; + } + + /** Compute Soil Thermal Properties **/ + compute_soil_layer_thermal_properties(layer, soil_con->depth, + soil_con->bulk_dens_min, + soil_con->soil_dens_min, + soil_con->quartz, + soil_con->bulk_density, + soil_con->soil_density, + soil_con->organic, + soil_con->frost_fract, + options.Nlayer); + + /** Save Thermal Conductivities for Energy Balance **/ + energy->kappa[0] = layer[0].kappa; + energy->Cs[0] = layer[0].Cs; + energy->kappa[1] = layer[1].kappa; + energy->Cs[1] = layer[1].Cs; free((char *) layer); } diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index f885d7514..fd6988875 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -47,20 +47,19 @@ vic_run(force_data_struct *force, extern parameters_struct param; char overstory; - int j; - size_t lidx; + size_t l; unsigned short iveg; size_t Nveg; unsigned short veg_class; unsigned short band; size_t Nbands; int ErrorFlag; - double out_prec[2 * MAX_BANDS]; - double out_rain[2 * MAX_BANDS]; - double out_snow[2 * MAX_BANDS]; + double *out_prec; + double *out_rain; + double *out_snow; double dp; - double ice0[MAX_BANDS]; - double moist0[MAX_BANDS]; + double ice0; + double moist0; double surf_atten; double wind_h; double height; @@ -70,9 +69,9 @@ vic_run(force_data_struct *force, double aero_resist[3]; double Cv; double Le; - double Melt[2 * MAX_BANDS]; + double *Melt; double bare_albedo; - double snow_inflow[MAX_BANDS]; + double *snow_inflow; double rainonly; double sum_runoff; double sum_baseflow; @@ -89,10 +88,21 @@ vic_run(force_data_struct *force, double rainprec; size_t cidx; lake_var_struct *lake_var; - cell_data_struct **cell; - veg_var_struct **veg_var; - energy_bal_struct **energy; - snow_data_struct **snow; + cell_data_struct *cell; + veg_var_struct *veg_var; + energy_bal_struct *energy; + snow_data_struct *snow; + + out_prec = calloc(options.SNOW_BAND, sizeof(*out_prec)); + check_alloc_status(out_prec, "Memory allocation error."); + out_rain = calloc(options.SNOW_BAND, sizeof(*out_rain)); + check_alloc_status(out_rain, "Memory allocation error."); + out_snow = calloc(options.SNOW_BAND, sizeof(*out_snow)); + check_alloc_status(out_snow, "Memory allocation error."); + Melt = calloc(options.SNOW_BAND, sizeof(*Melt)); + check_alloc_status(Melt, "Memory allocation error."); + snow_inflow = calloc(options.SNOW_BAND, sizeof(*snow_inflow)); + check_alloc_status(snow_inflow, "Memory allocation error."); // assign vic_run_veg_lib to veg_lib, so that the veg_lib for the correct // grid cell is used within vic_run. For simplicity sake, use vic_run_veg_lib @@ -100,15 +110,11 @@ vic_run(force_data_struct *force, vic_run_veg_lib = veg_lib; /* set local pointers */ - cell = all_vars->cell; - energy = all_vars->energy; lake_var = &all_vars->lake_var; - snow = all_vars->snow; - veg_var = all_vars->veg_var; Nbands = options.SNOW_BAND; - /* Set number of vegetation types */ + /* Set number of vegetation tiles */ Nveg = veg_con[0].vegetat_type_num; /** Set Damping Depth **/ @@ -129,28 +135,23 @@ vic_run(force_data_struct *force, force->out_rain = 0; force->out_snow = 0; - // Convert LAI from global to local - for (iveg = 0; iveg < Nveg; iveg++) { - veg_class = veg_con[iveg].veg_class; - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].LAI /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdew /= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax = veg_var[iveg][band].LAI * - param.VEG_LAI_WATER_FACTOR; - snow[iveg][band].snow_canopy /= veg_var[iveg][band].fcanopy; - } - } - /************************************************** Solve Energy and/or Water Balance for Each - Vegetation Type + Vegetation Tile **************************************************/ for (iveg = 0; iveg <= Nveg; iveg++) { - /** Solve Veg Type only if Coverage Greater than 0% **/ + /** Solve Veg Tile only if Coverage Greater than 0% **/ if (veg_con[iveg].Cv > 0.0) { Cv = veg_con[iveg].Cv; Nbands = options.SNOW_BAND; + /** Define vegetation class number **/ + veg_class = veg_con[iveg].veg_class; + + /************************************************** + Initialize Model Parameters + **************************************************/ + /** Lake-specific processing **/ if (veg_con[iveg].LAKE) { /* Update areai to equal new ice area from previous time step. */ @@ -179,74 +180,21 @@ vic_run(force_data_struct *force, } } - /************************************************** - Initialize Model Parameters - **************************************************/ - - for (band = 0; band < Nbands; band++) { - if (soil_con->AreaFract[band] > 0) { - /* Initialize energy balance variables */ - energy[iveg][band].shortwave = 0; - energy[iveg][band].longwave = 0.; - - /* Initialize snow variables */ - snow[iveg][band].vapor_flux = 0.; - snow[iveg][band].canopy_vapor_flux = 0.; - snow_inflow[band] = 0.; - Melt[band * 2] = 0.; - } - } - - /* Initialize precipitation storage */ - for (j = 0; j < 2 * MAX_BANDS; j++) { - out_prec[j] = 0; - out_rain[j] = 0; - out_snow[j] = 0; - } - - /** Define vegetation class number **/ - veg_class = veg_con[iveg].veg_class; - - /** Initialize other veg vars **/ - if (iveg < Nveg) { - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].rc = param.HUGE_RESIST; - } - } + /* local pointer to veg_var */ + veg_var = &(all_vars->veg_var[iveg][0]); /** Assign wind_h **/ /** Note: this is ignored below **/ wind_h = vic_run_veg_lib[veg_class].wind_h; - /** Compute Surface Attenuation due to Vegetation Coverage **/ - surf_atten = (1 - veg_var[iveg][0].fcanopy) * 1.0 + - veg_var[iveg][0].fcanopy * - exp(-vic_run_veg_lib[veg_class].rad_atten * - veg_var[iveg][0].LAI); - - /* Initialize soil thermal properties for the top two layers */ - prepare_full_energy(iveg, all_vars, soil_con, moist0, ice0); - - /** Compute Bare (free of snow) Albedo **/ - if (iveg != Nveg) { - bare_albedo = veg_var[iveg][0].albedo; - } - else { - bare_albedo = param.ALBEDO_BARE_SOIL; - } - - /************************************* - Compute the aerodynamic resistance - *************************************/ - /* Initialize wind speeds */ tmp_wind[0] = force->wind[NR]; tmp_wind[1] = MISSING; tmp_wind[2] = MISSING; /* Set surface descriptive variables */ - displacement[0] = veg_var[iveg][0].displacement; - roughness[0] = veg_var[iveg][0].roughness; + displacement[0] = veg_var->displacement; + roughness[0] = veg_var->roughness; if (roughness[0] == 0) { roughness[0] = soil_con->rough; } @@ -275,70 +223,117 @@ vic_run(force_data_struct *force, return (ERROR); } - /* Initialize final aerodynamic resistance values */ - for (band = 0; band < Nbands; band++) { - if (soil_con->AreaFract[band] > 0) { - cell[iveg][band].aero_resist[0] = - aero_resist[0]; - cell[iveg][band].aero_resist[1] = - aero_resist[1]; - } - } + /** Compute Surface Attenuation due to Vegetation Coverage **/ + surf_atten = (1 - veg_var->fcanopy) * 1.0 + + veg_var->fcanopy * + exp(-vic_run_veg_lib[veg_class].rad_atten * + veg_var->LAI); - // Compute nitrogen scaling factors and initialize other veg vars - if (options.CARBON && iveg < Nveg) { - for (band = 0; band < Nbands; band++) { - for (cidx = 0; cidx < options.Ncanopy; cidx++) { - veg_var[iveg][band].rsLayer[cidx] = param.HUGE_RESIST; - } - veg_var[iveg][band].aPAR = 0; - calc_Nscale_factors( - vic_run_veg_lib[veg_class].NscaleFlag, - veg_con[iveg].CanopLayerBnd, - veg_var[iveg][band].LAI, - force->coszen[NR], - veg_var[iveg][band].NscaleFactor); - // TBD: move this outside of vic_run() - if (dmy->day_in_year == 1) { - veg_var[iveg][band].AnnualNPPPrev = - veg_var[iveg][band].AnnualNPP; - veg_var[iveg][band].AnnualNPP = 0; - } - } + /** Compute Bare (free of snow) Albedo **/ + if (iveg != Nveg) { + bare_albedo = veg_var->albedo; + } + else { + bare_albedo = param.ALBEDO_BARE_SOIL; } - /****************************** - Solve ground surface fluxes - ******************************/ - + /************************************************** + Loop over elevation bands + **************************************************/ for (band = 0; band < Nbands; band++) { + /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { + + /* Set local pointers */ + cell = &(all_vars->cell[iveg][band]); + veg_var = &(all_vars->veg_var[iveg][band]); + snow = &(all_vars->snow[iveg][band]); + energy = &(all_vars->energy[iveg][band]); + + /****************************************** + Initialize Band-dependent Model Parameters + ******************************************/ + + /* Initialize soil thermal properties for the top two layers */ + prepare_full_energy(cell, energy, soil_con, &moist0, &ice0); + + /* Initialize final aerodynamic resistance values */ + cell->aero_resist[0] = aero_resist[0]; + cell->aero_resist[1] = aero_resist[1]; + + /* Initialize pot_evap */ + cell->pot_evap = 0; + + // Convert LAI from global to local + veg_var->LAI /= veg_var->fcanopy; + veg_var->Wdew /= veg_var->fcanopy; + veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; + snow->snow_canopy /= veg_var->fcanopy; + + /** Initialize other veg vars **/ + if (iveg < Nveg) { + veg_var->rc = param.HUGE_RESIST; + + /* Carbon-related variables */ + if (options.CARBON) { + for (cidx = 0; cidx < options.Ncanopy; cidx++) { + veg_var->rsLayer[cidx] = param.HUGE_RESIST; + } + veg_var->aPAR = 0; + + calc_Nscale_factors( + vic_run_veg_lib[veg_class].NscaleFlag, + veg_con[iveg].CanopLayerBnd, + veg_var->LAI, + force->coszen[NR], + veg_var->NscaleFactor); + + // TBD: move this outside of vic_run() + if (dmy->day_in_year == 1) { + veg_var->AnnualNPPPrev = veg_var->AnnualNPP; + veg_var->AnnualNPP = 0; + } + } // if options.CARBON + } // if iveg < Nveg + + /* Initialize energy balance variables */ + energy->shortwave = 0; + energy->longwave = 0.; + + /* Initialize snow variables */ + snow->vapor_flux = 0.; + snow->canopy_vapor_flux = 0.; + snow_inflow[band] = 0.; + Melt[band] = 0.; + + /* Initialize precipitation storage */ + out_prec[band] = 0; + out_rain[band] = 0; + out_snow[band] = 0; + + /****************************** + Solve ground surface fluxes + ******************************/ + lag_one = veg_con[iveg].lag_one; sigma_slope = veg_con[iveg].sigma_slope; fetch = veg_con[iveg].fetch; - /* Initialize pot_evap */ - cell[iveg][band].pot_evap = 0; - ErrorFlag = surface_fluxes(overstory, bare_albedo, - ice0[band], moist0[band], - surf_atten, &(Melt[band * 2]), - &Le, - aero_resist, + ice0, moist0, surf_atten, + &(Melt[band]), &Le, aero_resist, displacement, gauge_correction, - &out_prec[band * 2], - &out_rain[band * 2], - &out_snow[band * 2], + &out_prec[band], + &out_rain[band], + &out_snow[band], ref_height, roughness, &snow_inflow[band], tmp_wind, veg_con[iveg].root, options.Nlayer, Nveg, band, dp, iveg, veg_class, force, dmy, - &(energy[iveg][band]), gp, - &(cell[iveg][band]), - &(snow[iveg][band]), - soil_con, &(veg_var[iveg][band]), - lag_one, sigma_slope, fetch, + energy, gp, cell, snow, + soil_con, veg_var, lag_one, + sigma_slope, fetch, veg_con[iveg].CanopLayerBnd); if (ErrorFlag == ERROR) { @@ -346,46 +341,41 @@ vic_run(force_data_struct *force, } force->out_prec += - out_prec[band * 2] * Cv * soil_con->AreaFract[band]; + out_prec[band] * Cv * soil_con->AreaFract[band]; force->out_rain += - out_rain[band * 2] * Cv * soil_con->AreaFract[band]; + out_rain[band] * Cv * soil_con->AreaFract[band]; force->out_snow += - out_snow[band * 2] * Cv * soil_con->AreaFract[band]; + out_snow[band] * Cv * soil_con->AreaFract[band]; /******************************************************** Compute soil wetness and root zone soil moisture ********************************************************/ - cell[iveg][band].rootmoist = 0; - cell[iveg][band].wetness = 0; - for (lidx = 0; lidx < options.Nlayer; lidx++) { - if (veg_con[iveg].root[lidx] > 0) { - cell[iveg][band].rootmoist += - cell[iveg][band].layer[lidx].moist; + cell->rootmoist = 0; + cell->wetness = 0; + for (l = 0; l < options.Nlayer; l++) { + if (veg_con[iveg].root[l] > 0) { + cell->rootmoist += cell->layer[l].moist; } - cell[iveg][band].wetness += - (cell[iveg][band].layer[lidx].moist - - soil_con->Wpwp[lidx]) / - (soil_con->porosity[lidx] * soil_con->depth[lidx] * - MM_PER_M - soil_con->Wpwp[lidx]); + cell->wetness += + (cell->layer[l].moist - soil_con->Wpwp[l]) / + (soil_con->porosity[l] * soil_con->depth[l] * + MM_PER_M - soil_con->Wpwp[l]); } - cell[iveg][band].wetness /= options.Nlayer; + cell->wetness /= options.Nlayer; + + /* Convert LAI back to global */ + veg_var->LAI *= veg_var->fcanopy; + veg_var->Wdmax *= veg_var->fcanopy; } /** End non-zero area band **/ } /** End Loop Through Elevation Bands **/ } /** end non-zero area veg tile **/ } /** end of vegetation loop **/ - /* Convert LAI back to global */ - for (iveg = 0; iveg < Nveg; iveg++) { - for (band = 0; band < Nbands; band++) { - veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; - veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; - } - } - // Compute gridcell-averaged albedo calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, force->shortwave[NR], Nveg, overstory, - energy, snow, veg_con, soil_con); + all_vars->energy, all_vars->snow, veg_con, + soil_con); /**************************** Run Lake Model @@ -411,23 +401,23 @@ vic_run(force_data_struct *force, // Loop through snow elevation bands for (band = 0; band < Nbands; band++) { if (soil_con->AreaFract[band] > 0) { + /* Set local pointers */ + cell = &(all_vars->cell[iveg][band]); if (veg_con[iveg].LAKE) { - wetland_runoff += (cell[iveg][band].runoff * - Cv * soil_con->AreaFract[band]); - wetland_baseflow += (cell[iveg][band].baseflow * - Cv * + wetland_runoff += (cell->runoff * Cv * + soil_con->AreaFract[band]); + wetland_baseflow += (cell->baseflow * Cv * soil_con->AreaFract[band]); - cell[iveg][band].runoff = 0; - cell[iveg][band].baseflow = 0; + cell->runoff = 0; + cell->baseflow = 0; } else { - sum_runoff += (cell[iveg][band].runoff * - Cv * soil_con->AreaFract[band]); - sum_baseflow += (cell[iveg][band].baseflow * - Cv * soil_con->AreaFract[band]); - cell[iveg][band].runoff *= (1 - lake_con->rpercent); - cell[iveg][band].baseflow *= - (1 - lake_con->rpercent); + sum_runoff += (cell->runoff * Cv * + soil_con->AreaFract[band]); + sum_baseflow += (cell->baseflow * Cv * + soil_con->AreaFract[band]); + cell->runoff *= (1 - lake_con->rpercent); + cell->baseflow *= (1 - lake_con->rpercent); } } } @@ -488,5 +478,11 @@ vic_run(force_data_struct *force, } } // end if (options.LAKES && lake_con->lake_idx >= 0) + free((char *) (out_prec)); + free((char *) (out_rain)); + free((char *) (out_snow)); + free((char *) (Melt)); + free((char *) (snow_inflow)); + return (0); } From d3d5e17f8349b31b02ec57726a899ad4689fb3a1 Mon Sep 17 00:00:00 2001 From: ted Date: Fri, 12 Jan 2018 13:29:37 -0700 Subject: [PATCH 250/294] Fixed bug in location of conversion from global to local LAI etc. --- vic/vic_run/src/vic_run.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index fd6988875..40067213c 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -180,8 +180,15 @@ vic_run(force_data_struct *force, } } - /* local pointer to veg_var */ + /* local pointer to veg_var and snow */ veg_var = &(all_vars->veg_var[iveg][0]); + snow = &(all_vars->snow[iveg][0]); + + // Convert LAI from global to local + veg_var->LAI /= veg_var->fcanopy; + veg_var->Wdew /= veg_var->fcanopy; + veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; + snow->snow_canopy /= veg_var->fcanopy; /** Assign wind_h **/ /** Note: this is ignored below **/ @@ -264,12 +271,6 @@ vic_run(force_data_struct *force, /* Initialize pot_evap */ cell->pot_evap = 0; - // Convert LAI from global to local - veg_var->LAI /= veg_var->fcanopy; - veg_var->Wdew /= veg_var->fcanopy; - veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; - snow->snow_canopy /= veg_var->fcanopy; - /** Initialize other veg vars **/ if (iveg < Nveg) { veg_var->rc = param.HUGE_RESIST; From a29c12d44ded99c51da8491f8989cc8557028b2f Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 16:59:21 -0800 Subject: [PATCH 251/294] initial commit to move MAX_ITER_GRND_CANOPY to param struct in order to modify it more easily --- docs/Documentation/Constants.md | 1 + vic/drivers/cesm/bld/vic.constants.txt | 6 +++--- vic/drivers/shared_all/src/get_parameters.c | 9 +++++++++ vic/drivers/shared_all/src/initialize_parameters.c | 3 +++ vic/drivers/shared_all/src/print_library_shared.c | 1 + vic/drivers/shared_image/src/vic_mpi_support.c | 4 ++++ vic/vic_run/include/vic_def.h | 3 +++ vic/vic_run/src/surface_fluxes.c | 13 +++++-------- 8 files changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/Documentation/Constants.md b/docs/Documentation/Constants.md index 27fffda65..a8a3d9b4a 100644 --- a/docs/Documentation/Constants.md +++ b/docs/Documentation/Constants.md @@ -161,6 +161,7 @@ The table below lists the constants available for manipulation via the `CONSTANT | TOL_GRND | | | TOL_OVER | | | FROZEN_MAXITER | | +| MAX_ITER_GRND_CANOPY | | | NEWT_RAPH_MAXTRIAL | | | NEWT_RAPH_TOLX | | | NEWT_RAPH_TOLF | | diff --git a/vic/drivers/cesm/bld/vic.constants.txt b/vic/drivers/cesm/bld/vic.constants.txt index c9350bafc..c0bbf9086 100644 --- a/vic/drivers/cesm/bld/vic.constants.txt +++ b/vic/drivers/cesm/bld/vic.constants.txt @@ -172,6 +172,9 @@ # Frozen Soil Parameters # FROZEN_MAXITER 1000 +# Canopy Iterations +# MAX_ITER_GRND_CANOPY 10 + # Newton-Raphson solver parameters # NEWT_RAPH_MAXTRIAL 150 # NEWT_RAPH_TOLX 1.0e-4 @@ -188,6 +191,3 @@ # ROOT_BRENT_MAXITER 1000 # ROOT_BRENT_TSTEP 10 # ROOT_BRENT_T 1.0e-7 - -# Frozen Soil Parameters -# FROZEN_MAXITER 1000 diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index 45b8aa6f4..26024d5e8 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -481,6 +481,10 @@ get_parameters(FILE *paramfile) else if (strcasecmp("FROZEN_MAXITER", optstr) == 0) { sscanf(cmdstr, "%*s %d", ¶m.FROZEN_MAXITER); } + // Canopy Iterations + else if (strcasecmp("MAX_ITER_GRND_CANOPY", optstr) == 0) { + sscanf(cmdstr, "%*s %d", ¶m.MAX_ITER_GRND_CANOPY); + } // Newton-Raphson Solver Parameters else if (strcasecmp("NEWT_RAPH_MAXTRIAL", optstr) == 0) { sscanf(cmdstr, "%*s %d", ¶m.NEWT_RAPH_MAXTRIAL); @@ -880,6 +884,11 @@ validate_parameters() log_err( "FROZEN_MAXITER must be defined on the interval [0, inf) (iterations"); } + // Canopy Iterations + if (!(param.MAX_ITER_GRND_CANOPY >= 0)) { + log_err( + "MAX_ITER_GRND_CANOPY must be defined on the interval [0, inf) (iterations"); + } // Newton-Raphson Solver Parameters if (!(param.NEWT_RAPH_MAXTRIAL >= 0)) { log_err( diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index 1add5498d..b677f9f69 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -211,6 +211,9 @@ initialize_parameters() // Frozen Soil Parameters param.FROZEN_MAXITER = 1000; + // Canopy Iterations + param.MAX_ITER_GRND_CANOPY = 10; + // Newton-Raphson solver parameters param.NEWT_RAPH_MAXTRIAL = 150; param.NEWT_RAPH_TOLX = 1.0e-4; diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index ef9efdeaa..ccbd9b223 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -797,6 +797,7 @@ print_parameters(parameters_struct *param) fprintf(LOG_DEST, "\tTOL_GRND: %.4f\n", param->TOL_GRND); fprintf(LOG_DEST, "\tTOL_OVER: %.4f\n", param->TOL_OVER); fprintf(LOG_DEST, "\tFROZEN_MAXITER: %d\n", param->FROZEN_MAXITER); + fprintf(LOG_DEST, "\tMAX_ITER_GRND_CANOPY: %d\n", param->MAX_ITER_GRND_CANOPY); fprintf(LOG_DEST, "\tNEWT_RAPH_MAXTRIAL: %d\n", param->NEWT_RAPH_MAXTRIAL); fprintf(LOG_DEST, "\tNEWT_RAPH_TOLX: %.4f\n", param->NEWT_RAPH_TOLX); fprintf(LOG_DEST, "\tNEWT_RAPH_TOLF: %.4f\n", param->NEWT_RAPH_TOLF); diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index ed92f10fc..3be4745e6 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -1333,6 +1333,10 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(parameters_struct, FROZEN_MAXITER); mpi_types[i++] = MPI_INT; + // int MAX_ITER_GRND_CANOPY + offsets[i] = offsetof(parameters_struct, MAX_ITER_GRND_CANOPY); + mpi_types[i++] = MPI_INT; + // int NEWT_RAPH_MAXTRIAL offsets[i] = offsetof(parameters_struct, NEWT_RAPH_MAXTRIAL); mpi_types[i++] = MPI_INT; diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 184ede176..0ad47f2c5 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -518,6 +518,9 @@ typedef struct { // Frozen Soil Parameters int FROZEN_MAXITER; + // Canopy Iterations + int MAX_ITER_GRND_CANOPY; + // Newton-Raphson Solver Parameters int NEWT_RAPH_MAXTRIAL; double NEWT_RAPH_TOLX; diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index 8354ba743..d32749b60 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -73,7 +73,6 @@ surface_fluxes(bool overstory, extern option_struct options; extern parameters_struct param; - int MAX_ITER_GRND_CANOPY; int ErrorFlag; int INCLUDE_SNOW = false; int UNSTABLE_CNT; @@ -225,11 +224,9 @@ surface_fluxes(bool overstory, double store_Raut; double store_NPP; - if (options.CLOSE_ENERGY) { - MAX_ITER_GRND_CANOPY = 10; - } - else { - MAX_ITER_GRND_CANOPY = 0; + if (!options.CLOSE_ENERGY) { + // if not closing energy balance, don't iterate + param.MAX_ITER_CANOPY_GRND = 0; } if (options.CARBON) { @@ -722,11 +719,11 @@ surface_fluxes(bool overstory, } } while ((fabs(tol_under - last_tol_under) > param.TOL_GRND) && - (tol_under != 0) && (under_iter < MAX_ITER_GRND_CANOPY)); + (tol_under != 0) && (under_iter < param.MAX_ITER_CANOPY_GRND)); } while ((fabs(tol_over - last_tol_over) > param.TOL_OVER && overstory) && (tol_over != 0) && - (over_iter < MAX_ITER_GRND_CANOPY)); + (over_iter < param.MAX_ITER_CANOPY_GRND)); /************************************** Compute GPP, Raut, and NPP From 503b3bbe9222b14611749226f13aaeecdfcbf246 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 20:07:22 -0500 Subject: [PATCH 252/294] fix typos --- vic/vic_run/src/surface_fluxes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index d32749b60..12f4a9140 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -226,7 +226,7 @@ surface_fluxes(bool overstory, if (!options.CLOSE_ENERGY) { // if not closing energy balance, don't iterate - param.MAX_ITER_CANOPY_GRND = 0; + param.MAX_ITER_GRND_CANOPY = 0; } if (options.CARBON) { @@ -719,11 +719,11 @@ surface_fluxes(bool overstory, } } while ((fabs(tol_under - last_tol_under) > param.TOL_GRND) && - (tol_under != 0) && (under_iter < param.MAX_ITER_CANOPY_GRND)); + (tol_under != 0) && (under_iter < param.MAX_ITER_GRND_CANOPY)); } while ((fabs(tol_over - last_tol_over) > param.TOL_OVER && overstory) && (tol_over != 0) && - (over_iter < param.MAX_ITER_CANOPY_GRND)); + (over_iter < param.MAX_ITER_GRND_CANOPY)); /************************************** Compute GPP, Raut, and NPP From 468287ce43c71933cb273cb13679258f4f60b7c8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 20:36:58 -0500 Subject: [PATCH 253/294] fix mpi bug --- vic/drivers/shared_image/src/vic_mpi_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 3be4745e6..371c92bec 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -755,7 +755,7 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in parameters_struct - nitems = 153; + nitems = 154; blocklengths = malloc(nitems * sizeof(*blocklengths)); check_alloc_status(blocklengths, "Memory allocation error."); From c33a0b3be8b4b5d6b775262812a6fb436cc442f0 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 17:49:38 -0800 Subject: [PATCH 254/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 1824d489d..c84076d54 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -111,6 +111,10 @@ To check which release of VIC you are running: The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. +9. Moved MAX_ITER_GRND_CANOPY, which controls the maximum number of ground-canopy iterations in CLOSE_ENERGY mode for vegetation types with an overstory, to the parameters struct + + Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. + #### Bug Fixes: 1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) From 7ba492af0e68d54bda0f7dfa15f3452bbe314fc6 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 21:46:57 -0800 Subject: [PATCH 255/294] ran uncrustify --- vic/drivers/shared_all/src/get_parameters.c | 2 +- vic/drivers/shared_all/src/print_library_shared.c | 3 ++- vic/vic_run/src/surface_fluxes.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index 26024d5e8..634351bef 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -884,7 +884,7 @@ validate_parameters() log_err( "FROZEN_MAXITER must be defined on the interval [0, inf) (iterations"); } - // Canopy Iterations + // Canopy Iterations if (!(param.MAX_ITER_GRND_CANOPY >= 0)) { log_err( "MAX_ITER_GRND_CANOPY must be defined on the interval [0, inf) (iterations"); diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index c6965efd8..ed5667f8a 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -798,7 +798,8 @@ print_parameters(parameters_struct *param) fprintf(LOG_DEST, "\tTOL_GRND: %.4f\n", param->TOL_GRND); fprintf(LOG_DEST, "\tTOL_OVER: %.4f\n", param->TOL_OVER); fprintf(LOG_DEST, "\tFROZEN_MAXITER: %d\n", param->FROZEN_MAXITER); - fprintf(LOG_DEST, "\tMAX_ITER_GRND_CANOPY: %d\n", param->MAX_ITER_GRND_CANOPY); + fprintf(LOG_DEST, "\tMAX_ITER_GRND_CANOPY: %d\n", + param->MAX_ITER_GRND_CANOPY); fprintf(LOG_DEST, "\tNEWT_RAPH_MAXTRIAL: %d\n", param->NEWT_RAPH_MAXTRIAL); fprintf(LOG_DEST, "\tNEWT_RAPH_TOLX: %.4f\n", param->NEWT_RAPH_TOLX); fprintf(LOG_DEST, "\tNEWT_RAPH_TOLF: %.4f\n", param->NEWT_RAPH_TOLF); diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index 12f4a9140..4c31d5ba9 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -719,7 +719,8 @@ surface_fluxes(bool overstory, } } while ((fabs(tol_under - last_tol_under) > param.TOL_GRND) && - (tol_under != 0) && (under_iter < param.MAX_ITER_GRND_CANOPY)); + (tol_under != 0) && + (under_iter < param.MAX_ITER_GRND_CANOPY)); } while ((fabs(tol_over - last_tol_over) > param.TOL_OVER && overstory) && (tol_over != 0) && From 50b137cacb38917ccd8c165a2606a08656e10c9e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Mon, 15 Jan 2018 21:49:53 -0800 Subject: [PATCH 256/294] update release notes entry w/ PR # --- docs/Development/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 579b4fe59..04079e0e5 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -111,7 +111,7 @@ To check which release of VIC you are running: The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. -9. Moved MAX_ITER_GRND_CANOPY, which controls the maximum number of ground-canopy iterations in CLOSE_ENERGY mode for vegetation types with an overstory, to the parameters struct +9. Moved MAX_ITER_GRND_CANOPY, which controls the maximum number of ground-canopy iterations in CLOSE_ENERGY mode for vegetation types with an overstory, to the parameters struct ([GH#771](https://github.com/UW-Hydro/VIC/pull/771)) Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. From e640ff711a8918b153377a9c0d58dbe0beff9fdf Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Tue, 16 Jan 2018 11:52:02 -0700 Subject: [PATCH 257/294] Revert "Clean up esoil (#766)" This reverts commit f2b519ec2f9bd42f40d072d00b52e4abd9645f73. --- docs/Development/ReleaseNotes.md | 22 +- .../Drivers/Classic/ForcingData.md | 4 +- .../Drivers/Classic/GlobalParam.md | 22 +- docs/Documentation/Drivers/Classic/VegLib.md | 2 +- .../Documentation/Drivers/Classic/VegParam.md | 4 +- .../Drivers/Image/GlobalParam.md | 16 +- docs/Documentation/Drivers/Image/Params.md | 6 +- .../cesm/src/display_current_settings.c | 2 + vic/drivers/cesm/src/get_global_param.c | 11 +- .../classic/src/display_current_settings.c | 2 + vic/drivers/classic/src/get_force_type.c | 4 +- vic/drivers/classic/src/get_global_param.c | 14 +- vic/drivers/classic/src/parse_output_info.c | 1 + vic/drivers/classic/src/read_atmos_data.c | 4 +- vic/drivers/classic/src/read_forcing_data.c | 2 +- vic/drivers/classic/src/read_veglib.c | 1 - vic/drivers/classic/src/read_vegparam.c | 6 + vic/drivers/classic/src/vic_force.c | 12 +- .../image/src/display_current_settings.c | 2 + vic/drivers/image/src/get_global_param.c | 9 + vic/drivers/image/src/vic_force.c | 18 +- .../python/src/display_current_settings.c | 2 + .../include/vic_driver_shared_all.h | 2 +- .../src/compute_derived_state_vars.c | 32 +- vic/drivers/shared_all/src/history_metadata.c | 2 +- vic/drivers/shared_all/src/initialize_soil.c | 3 +- .../shared_all/src/print_library_shared.c | 3 +- vic/drivers/shared_all/src/put_data.c | 22 +- vic/drivers/shared_image/src/set_force_type.c | 28 +- vic/drivers/shared_image/src/vic_alloc.c | 2 +- vic/drivers/shared_image/src/vic_finalize.c | 2 +- vic/drivers/shared_image/src/vic_init.c | 23 +- vic/vic_run/include/vic_def.h | 11 +- vic/vic_run/include/vic_run.h | 4 +- vic/vic_run/src/arno_evap.c | 22 +- vic/vic_run/src/canopy_evap.c | 67 ++-- vic/vic_run/src/func_surf_energy_bal.c | 83 +++-- vic/vic_run/src/prepare_full_energy.c | 100 ++--- vic/vic_run/src/vic_run.c | 344 +++++++++--------- 39 files changed, 483 insertions(+), 433 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 2e6068ee5..1824d489d 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -101,35 +101,19 @@ To check which release of VIC you are running: 6. Cleanup of the initialization sections of the ``image`` and ``cesm`` drivers ([GH#701](https://github.com/UW-Hydro/VIC/pull/701)) - Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. + Codified behavior in the initialization of the ``image`` and `cesm` drivers that requires the parameter variables `AreaFract`, `Pfactor`, `zone_fract`, and `Cv` must sum exactly to 1.0. If using the `SNOW_BAND` option, the area weighted `elevation` must match the mean grid cell elevation (`elev`). VIC will print *warnings* if any of these criteria are violated. 7. Added thread parallelization using OPENMP ([GH#712](https://github.com/UW-Hydro/VIC/pull/712)) - The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. + The VIC image and CESM drivers now may be optionally compiled with OPENMP to enable shared memory thread parallelization. This option should improve the parallel scaling of these drivers by reducing the number of MPI messages and increasing message size. 8. Added streamflow routing extensions ROUT_STUB and ROUT_RVIC for the VIC image driver ([GH#231](https://github.com/UW-Hydro/VIC/pull/231)) The VIC image driver can be optionally compiled with ROUT_RVIC to enable routing in image mode (ROUT_STUB is the default extension which means no routing). With ROUT_RVIC enabled, the output variable ``OUT_DISCHARGE`` is available, and there will also be an extra state variable ``STATE_ROUT_RING`` stored in the state file. -9. Miscellaneous clean-up: - - [GH#723](https://github.com/UW-Hydro/VIC/pull/723) - - 1. Added support for veg_hist forcings (non-climatological) in image mode - 2. Fixed erroneous allocation of extra veg tile in image mode - 3. Simplified looping over veg tiles and bands in vic_run() and prepare_full_energy() - 4. Replaced lengthy data structures with local pointers in vic_run() - 5. Simplified out_prec, out_rain, and Melt arrays - 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. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) +1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) ------------------------------ diff --git a/docs/Documentation/Drivers/Classic/ForcingData.md b/docs/Documentation/Drivers/Classic/ForcingData.md index 98a875c73..49106ee14 100644 --- a/docs/Documentation/Drivers/Classic/ForcingData.md +++ b/docs/Documentation/Drivers/Classic/ForcingData.md @@ -19,8 +19,8 @@ The VIC Classic Driver requires subdaily forcings (meteorological or other). For | Variable | Description | Units | |------------|----------------------------------------------------------|---------------------------- | | ALBEDO | Surface Albedo | fraction (between 0 and 1) | -| LAI | Leaf Area Index | m2/m2 | -| FCANOPY | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | +| LAI_IN | Leaf Area Index | m2/m2 | +| VEGCOVER | Partial veg cover fraction ( = 1 - canopy gap fraction ) | fraction (between 0 and 1) | #### Lake Forcings, Required when LAKES is TRUE: diff --git a/docs/Documentation/Drivers/Classic/GlobalParam.md b/docs/Documentation/Drivers/Classic/GlobalParam.md index ab28f10a6..0b434d84f 100644 --- a/docs/Documentation/Drivers/Classic/GlobalParam.md +++ b/docs/Documentation/Drivers/Classic/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -75,7 +75,7 @@ Generally these default values do not need to be overridden. | BLOWING_SPATIAL_WIND | string | TRUE or FALSE | If TRUE, multiple wind speed ranges, calculated according to a probability distribution, are used to determine the sublimation flux from blowing snow. If FALSE, then a single wind speed is used. See Lu and Pomeroy (1997) for details.

    Default: TRUE. | | COMPUTE_TREELINE | string or integer | FALSE or veg class id | Options for handling above-treeline vegetation:FALSE = Do not compute treeline or replace vegetation above the treeline.CLASS_ID = Compute the treeline elevation based on average July temperatures; for those elevation bands with elevations above the treeline (or the entire grid cell if SNOW_BAND == 1 and the grid cell elevation is above the tree line), if they contain vegetation tiles having overstory, replace that vegetation with the vegetation having id CLASS_ID in the vegetation library. NOTE 1: You MUST supply VIC with a July average air temperature, in the optional July_Tavg field, AND set theJULY_TAVG_SUPPLIED option to TRUE so that VIC can read the soil parameter file correctly. NOTE 2: If LAKES=TRUE, COMPUTE_TREELINE MUST be FALSE.Default = FALSE. | | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -148,8 +148,8 @@ All FORCING filenames are actually the pathname, and prefix for gridded data typ | FORCING2 | string | pathname and file prefix | Second forcing file name, or FALSE if only one file used.This must precede all other forcing parameters used to define the second forcing file, and follow those used to define the first forcing file. | | FORCE_FORMAT | string | BINARY or ASCII | Defines the format type for the forcing files. | | FORCE_ENDIAN | string | BIG or LITTLE | Identifies the architecture of the machine on which the binary forcing files were created:BIG = big-endian (e.g. SUN).LITTLE = little-endian (e.g. PC/linux). Model will identify the endian of the current machine, and swap bytes if necessary. Required for binary forcing file, not used for ASCII forcing file. | -| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI, and FCANOPY each count as only 1 variable despite covering multiple columns. | -| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | +| N_TYPES | int | N/A | Number of columns in the current data file, with the following exception: for the vegetation history variables ALBEDO, LAI_IN, and FCANOPY, there must be multiple columns for these variables, one per vegetation tile. In this case, ALBEDO, LAI_IN, and FCANOPY each count as only 1 variable despite covering multiple columns. | +| FORCE_TYPE | stringstringfloat | VarName(un)signedmultiplier | Defines what forcing types are read from the file, and in what order. For ASCII file only the forcing type needs to be defined, but for Binary file each line must also define whether the column is SIGNED or UNSIGNED short int and by what factor values are multiplied before being written to output. Note: Unlike other variables, ALBEDO, LAI_IN, and FCANOPY, each span multiple columns, one column per veg tile. This will generally vary from one grid cell to the next as the number of veg tiles varies. However, ALBEDO, LAI_IN, and FCANOPY should each have only one FORCE_TYPE entry. [Click here for details](ForcingData.md). | | FORCE_STEPS_PER_DAY | integer | steps | Number of timesteps per day in forcing file (must be = SNOW_STPES_PER_DAY) | | FORCEYEAR | integer | year | Year meteorological forcing files start | | FORCEMONTH | integer | month | Month meteorological forcing files start | @@ -211,17 +211,17 @@ The following options describe the input parameter files. | SOIL | string | path/filename | the Soil parameter file. | | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file:ARNO = fields 5-8 of the soil parameter file are the standard VIC baseflow parametersNIJSSEN2001 = fields 5-8 of the soil parameter file are the baseflow parameters from Nijssen et al (2001) Default = ARNO. | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional column (July_Tavg) in the soil parameter file to contain the grid cell's average July temperature. If your soil parameter file contains this optional column, you MUST set JULY_TAVG_SUPPLIED to TRUE so that VIC can read the soil parameter file correctly. NOTE: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE. Default = FALSE. | -| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer. FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | +| ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the soil parameter file contains 3*Nlayer extra columns, listing, for each layer: the organic fraction, and the bulk density and soil particle density of the organic matter in the soil layer.FALSE = the soil parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0. Default = FALSE. | | VEGLIB | string | path/filename | Vegetation library file name | | VEGPARAM | string | path/filename | Vegetation parameter file name | | ROOT_ZONES | integer | N/A | Number of defined root zones defined for root distribution. | | VEGPARAM_ALB | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly ALBEDO values for each vegetation type for each grid cell. Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE. FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values:FROM_VEGLIB = Use the ALBEDO values listed in the vegetation library file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_ALB must be TRUE.FROM_VEGHIST = Use the ALBEDO values listed in the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGPARAM_LAI | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly LAI values for each vegetation type for each grid cell. Default = FALSE. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values:FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | | VEGLIB_FCAN | string | TRUE or FALSE | If TRUE the vegetation library file contains monthly FCANOPY values for each vegetation type for each grid cell (between the LAI and ALBEDO values). Default = FALSE. | | VEGPARAM_FCAN | string | TRUE or FALSE | If TRUE the vegetation parameter file contains an extra line for each vegetation type that defines monthly FCANOPY values for each vegetation type for each grid cell. Default = FALSE. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | integer[string] | N/A [path/filename] | Maximum number of snow elevation bands to use, and the name (with path) of the snow elevation band file. For example: SNOW_BAND 5 path/filename. To turn off this feature, set the number of snow bands to 1 and do not follow this with a snow elevation band file name. Default = 1. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Classic/VegLib.md b/docs/Documentation/Drivers/Classic/VegLib.md index 218fccf40..7491c0d03 100644 --- a/docs/Documentation/Drivers/Classic/VegLib.md +++ b/docs/Documentation/Drivers/Classic/VegLib.md @@ -11,7 +11,7 @@ Vegetation parameters needed for each vegetation type used in the VIC model are | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/docs/Documentation/Drivers/Classic/VegParam.md b/docs/Documentation/Drivers/Classic/VegParam.md index 10ceea7c2..9e40530b3 100644 --- a/docs/Documentation/Drivers/Classic/VegParam.md +++ b/docs/Documentation/Drivers/Classic/VegParam.md @@ -37,11 +37,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: +OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| FCANOPY | fraction | Partial vegetation cover fraction, one per month | +| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there must be a line containing the following parameters: diff --git a/docs/Documentation/Drivers/Image/GlobalParam.md b/docs/Documentation/Drivers/Image/GlobalParam.md index d080294ec..de2fa16d7 100644 --- a/docs/Documentation/Drivers/Image/GlobalParam.md +++ b/docs/Documentation/Drivers/Image/GlobalParam.md @@ -49,16 +49,16 @@ The following options determine the type of simulation that will be performed. | Name | Type | Units | Description | |-------------------|-------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils. TRUE = account for water/ice phase change (including latent heat). FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | -| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile. TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes. FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | +| FROZEN_SOIL | string | TRUE or FALSE | Option for handling the water/ice phase change in frozen soils.TRUE = account for water/ice phase change (including latent heat).FALSE = soil moisture always remains liquid, even when below 0 C; no latent heat effects and ice content is always 0. Default = FALSE. Note: to activate this option, the user must also set theFS_ACTIVE flag to 1 in the soil parameter file for each grid cell where this option is desired. In other words, the user can choose for some grid cells (e.g. cold ones) to compute ice contents and for others (e.g. warm ones) to skip the extra computation. | +| QUICK_FLUX | string | TRUE or FALSE | Option for computing the soil vertical temperature profile.TRUE = use the approximate method described by Liang et al. (1999) to compute soil temperatures and ground heat flux; this method ignores water/ice phase changes.FALSE = use the finite element method described in Cherkauer and Lettenmaier (1999) to compute soil temperatures and ground heat flux; this method is appropriate for accounting for water/ice phase changes. Default = FALSE (i.e. use Cherkauer and Lettenmaier (1999)) when running FROZEN_SOIL; and TRUE (i.e. use Liang et al. (1999)) in all other cases. | | IMPLICIT | string | TRUE or FALSE | If TRUE the model will use an implicit solution for the soil heat flux equation of Cherkauer and Lettenmaier (1999)(QUICK_FLUX is FALSE), otherwise uses original explicit solution. When QUICK_FLUX is TRUE the implicit solution has no effect. The user can override this option by setting IMPLICIT to FALSE in the global parameter file. The implicit solution is guaranteed to be stable for all combinations of time step and thermal node spacing; the explicit solution is only stable for some combinations. If the user sets IMPLICIT to FALSE, VIC will check the time step, node spacing, and soil thermal properties to confirm stability. If the explicit solution will not be stable, VIC will exit with an error message. Default = TRUE. | | QUICK_SOLVE | string | TRUE or FALSE | This option is a hybrid of QUICK_FLUX TRUE and FALSE. If TRUE model will use the method described by Liang et al. (1999)to compute ground heat flux during the surface energy balance iterations, and then will use the method described in Cherkauer and Lettenmaier (1999) for the final solution step. Default = FALSE. | | NOFLUX | string | TRUE or FALSE | If TRUE model will use a no flux bottom boundary with the finite difference soil thermal solution (i.e. QUICK_FLUX = FALSE or FULL_ENERGY = TRUE or FROZEN_SOIL = TRUE). Default = FALSE (i.e., use a constant temperature bottom boundary condition). | | EXP_TRANS | string | TRUE or FALSE | If TRUE the model will exponentially distributes the thermal nodes in the Cherkauer and Lettenmaier (1999) finite difference algorithm, otherwise uses linear distribution. (This is only used if FROZEN_SOIL = TRUE). Default = TRUE. | | GRND_FLUX_TYPE | string | N/A | Options for handling ground flux:GF_406 = use (flawed) formulas for ground flux, deltaH, and fusion as in VIC 4.0.6 and earlier.GF_410 = use formulas from VIC 4.1.0. NOTE: this option exists for backwards compatibility with earlier releases and likely will be removed in later releases. Default = GF_410. | -| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge. FALSE = if T iteration fails to converge, report an error. TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | +| TFALLBACK | string | TRUE or FALSE | Options for handling failures of T iterations to converge.FALSE = if T iteration fails to converge, report an error.TRUE = if T iteration fails to converge, use the previous time step's T value. This option affects the temperatures of canopy air, canopy snow, ground snow pack, ground surface, and soil T nodes. If TFALLBACK is TRUE, VIC will report the total number of instances in which the previous step's T was used, at the end of each grid cell's simulation. In addition, a time series of when these instances occurred (averaged across all veg tile/snow band combinations) can be written to the output files, using the following output variables:OUT_TFOL_FBFLAG = time series of T fallbacks in canopy snow T solution.OUT_TCAN_FBFLAG = time series of T fallbacks in canopy air T solution. OUT_SNOWT_FBFLAG = time series of T fallbacks in snow pack surface T solution.OUT_SURFT_FBFLAG = time series of T fallbacks in ground surface T solution.OUT_SOILT_FBFLAG = time series of T fallbacks in soil node T solution (one time series per node). Default = TRUE. | | SHARE_LAYER_MOIST | string | TRUE or FALSE | If TRUE, then *if* the soil moisture in the layer that contains more than half of the roots is above the critical point, then the plant's roots in the drier layers can access the moisture of the wetter layer so that the plant does not experience moisture limitation.
    If FALSE or all of the soil layer moistures are below the critical point, transpiration in each layer is limited by the layer's soil moisture.

    Default: TRUE. | -| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth). TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | +| SPATIAL_FROST | string (+integer) | string: TRUE or FALSE integer: N/A | Option to allow spatial heterogeneity in soil temperature:FALSE = Assume soil temperature is horizontally constant (only varies with depth).TRUE = Assume soil temperatures at each given depth are distributed horizontally with a uniform (linear) distribution, so that even when the mean temperature is below freezing, some portion of the soil within the grid cell at that depth could potentially be above freezing. This requires specifying a frost slope value as an extra field in the soil parameter file, so that the minimum/maximum temperatures can be computed from the mean value. The maximum and minimum temperatures will be set to mean temperature +/- frost_slope.If TRUE is specified, you must follow this with an integer value for Nfrost, the number of frost sub-areas (each having a distinct temperature). Default = FALSE. | ## Precipitation (Rain and Snow) Parameters @@ -77,7 +77,7 @@ Generally these default values do not need to be overridden. | CORRPREC | string | TRUE or FALSE | If TRUE correct precipitation for gauge undercatch. NOTE: This option is not supported when using snow/elevation bands. Default = FALSE. | | MAX_SNOW_TEMP | float | deg C | Maximum temperature at which snow can fall. Default = 0.5 C. | | MIN_RAIN_TEMP | float | deg C | Minimum temperature at which rain can fall. Default = -0.5 C. | -| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell. TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | +| SPATIAL_SNOW | string | TRUE or FALSE | Option to allow spatial heterogeneity in snow water equivalent (yielding partial snow coverage) when the snow pack is melting:FALSE = Assume snow water equivalent is constant across grid cell.TRUE = Assume snow water equivalent is distributed horizontally with a uniform (linear) distribution, so that some portion of the grid cell has 0 snow pack. This requires specifying the max_snow_distrib_slope value as an extra field in the soil parameter file. NOTE: max_snow_distrib_slope should be set to twice the desired minimum spatial average snow pack depth [m]. I.e., if we define depth_thresh to be the minimum spatial average snow depth below which coverage < 1.0, then max_snow_distrib_slope = 2*depth_thresh. NOTE: Partial snow coverage is only computed when the snow pack has started melting and the spatial average snow pack depth <= max_snow_distrib_slope/2. During the accumulation season, coverage is 1.0. Even after the pack has started melting and depth <= max_snow_distrib_slope/2, new snowfall resets coverage to 1.0, and the previous partial coverage is stored. Coverage remains at 1.0 until the new snow has melted away, at which point the previous partial coverage is recovered. Default = FALSE. | ## Turbulent Flux Parameters @@ -175,9 +175,9 @@ The following options describe the input parameter files. | BASEFLOW | string | N/A | This option describes the form of the baseflow parameters in the soil parameter file. Valid options: ARNO, NIJSSEN2001. See classic driver global parameter file for detail (../Classic/GlobalParam.md). | | JULY_TAVG_SUPPLIED | string | TRUE or FALSE | If TRUE then VIC will expect an additional variable in the parameter file (July_Tavg) to contain the grid cell's average July temperature. *NOTE*: Supplying July average temperature is only required if the COMPUTE_TREELINE option is set to TRUE.

    Default = FALSE. | | ORGANIC_FRACT | string | TRUE or FALSE | TRUE = the parameter file contains extra variables: the organic fraction, and the bulk density and soil particle density of the organic matter in each soil layer. FALSE = the parameter file does not contain any information about organic soil, and organic fraction should be assumed to be 0.

    Default = FALSE. | -| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file. FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | -| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file. FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE. FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | -| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values: FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations. FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE.. FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE. FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | +| ALB_SRC | string | N/A | This option tells VIC where to look for ALBEDO values: if FROM_VEGLIB or FROM_VEGPARAM = Use the ALBEDO values from the parameter file.FROM_VEGPARAM = Use the ALBEDO values listed in the vegetation parameter file. If FROM_VEGHIST = Use the ALBEDO values from the veg_hist forcing files. Note: for this to work, ALBEDO must be supplied in the veg_hist files and listed in the global parameter file as one of the variables in the files.

    Default = FROM_VEGLIB. | +| LAI_SRC | string | N/A | This option tells VIC where to look for LAI values: FROM_VEGLIB = Use the LAI values listed in the vegetation library file.FROM_VEGPARAM = Use the LAI values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_LAI must be TRUE.FROM_VEGHIST = Use the LAI values listed in the veg_hist forcing files. Note: for this to work, LAI_IN must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_VEGLIB. | +| FCAN_SRC | string | N/A | This option tells VIC where to look for FCANOPY values:FROM_DEFAULT = Set FCANOPY to 1.0 for all veg classes, all times, and all locations.FROM_VEGLIB = Use the FCANOPY values listed in the vegetation library file. Note: for this to work, VEGLIB_FCANOPY must be TRUE..FROM_VEGPARAM = Use the FCANOPY values listed in the vegetation parameter file. Note: for this to work, VEGPARAM_FCANOPY must be TRUE.FROM_VEGHIST = Use the FCANOPY values listed in the veg_hist forcing files. Note: for this to work, FCANOPY must be supplied in the veg_hist files and listd in the global parameter file as one of the variables in the files. Default = FROM_DEFAULT. | | SNOW_BAND | string | TRUE or FALSE | Whether multiple snowband option is enables. If TRUE, snowband information is specified in the parameter netCDF file.

    Default = FALSE. | | CONSTANTS | string | path/filename | Constants / Parameters file name | diff --git a/docs/Documentation/Drivers/Image/Params.md b/docs/Documentation/Drivers/Image/Params.md index ef05570c5..5be216247 100644 --- a/docs/Documentation/Drivers/Image/Params.md +++ b/docs/Documentation/Drivers/Image/Params.md @@ -94,11 +94,11 @@ OPTIONAL - If VEGPARAM_LAI is TRUE in global parameter file, then for each veget |--------------- |---------- |-------------------------------- | | LAI | fraction | Leaf Area Index, one per month | -OPTIONAL - If VEGPARAM_FCAN is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: +OPTIONAL - If VEGPARAM_VEGCOVER is TRUE in global parameter file, then for each vegetation tile, the following parameters will also be included: | Variable Name | Units | Description | |--------------- |---------- |-------------------------------------------------- | -| FCANOPY | fraction | Partial vegetation cover fraction, one per month | +| VEGCOVER | fraction | Partial vegetation cover fraction, one per month | OPTIONAL - If VEGPARAM_ALBEDO is TRUE in global parameter file, then for each vegetation tile, there following parameters will also be included in the NetCDF parameter file: @@ -118,7 +118,7 @@ Vegetation parameters are given for different vegetation types. Below are a list | rarc | s/m | 1 | Architectural resistance of vegetation type (~2 s/m) | | rmin | s/m | 1 | Minimum stomatal resistance of vegetation type (~100 s/m) | | LAI | fraction | 12 | Leaf-area index of vegetation type | -| FCANOPY (Only present if VEGLIB_FCAN=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | +| VEGCOVER (Only present if VEGLIB_VEGCOVER=TRUE in [global parameter file](GlobalParam.md) | fraction | 12 | Partial vegetation cover fraction | | albedo | fraction | 12 | Shortwave albedo for vegetation type | | rough | m | 12 | Vegetation roughness length (typically `0.123 * vegetation height`) | | displacement | m | 12 | Vegetation displacement height (typically `0.67 * vegetation height`) | diff --git a/vic/drivers/cesm/src/display_current_settings.c b/vic/drivers/cesm/src/display_current_settings.c index 85a0dc2d9..029575613 100644 --- a/vic/drivers/cesm/src/display_current_settings.c +++ b/vic/drivers/cesm/src/display_current_settings.c @@ -56,12 +56,14 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); + fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); + fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/cesm/src/get_global_param.c b/vic/drivers/cesm/src/get_global_param.c index ef0c6ff82..89ab7c3c4 100644 --- a/vic/drivers/cesm/src/get_global_param.c +++ b/vic/drivers/cesm/src/get_global_param.c @@ -448,7 +448,7 @@ get_global_param(FILE *gp) // TBD: feature in VIC 4.2 that has been ported to classic // mode, but that does not exist in image mode (yet) else if (strcasecmp("ALBEDO", optstr) == 0 || - strcasecmp("LAI", optstr) == 0 || + strcasecmp("LAI_IN", optstr) == 0 || strcasecmp("FCANOPY", optstr) == 0) { log_err("Time-varying vegetation parameters not implemented " "in CESM driver"); @@ -562,7 +562,14 @@ validate_options(option_struct *options) } // Validate the elevation band file information - if (options->SNOW_BAND <= 0) { + if (options->SNOW_BAND > 1) { + if (options->SNOW_BAND > MAX_BANDS) { + log_err("Global file wants more snow bands (%zu) than are " + "defined by MAX_BANDS (%d). Edit vicNl_def.h and " + "recompile.", options->SNOW_BAND, MAX_BANDS); + } + } + else if (options->SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " "file (%zu). Number of bands must be >= 1.", options->SNOW_BAND); diff --git a/vic/drivers/classic/src/display_current_settings.c b/vic/drivers/classic/src/display_current_settings.c index f0c5d7c8f..ccd3a9e91 100644 --- a/vic/drivers/classic/src/display_current_settings.c +++ b/vic/drivers/classic/src/display_current_settings.c @@ -58,12 +58,14 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); + fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); + fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/classic/src/get_force_type.c b/vic/drivers/classic/src/get_force_type.c index 98bde93f5..03e2fb984 100644 --- a/vic/drivers/classic/src/get_force_type.c +++ b/vic/drivers/classic/src/get_force_type.c @@ -82,8 +82,8 @@ get_force_type(char *cmdstr, type = FDIR; } /* type 6: LAI [m2/m2] */ - else if (strcasecmp("LAI", optstr) == 0) { - type = LAI; + else if (strcasecmp("LAI_IN", optstr) == 0) { + type = LAI_IN; } /* type 7: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { diff --git a/vic/drivers/classic/src/get_global_param.c b/vic/drivers/classic/src/get_global_param.c index 064c98c76..4a6534ab9 100644 --- a/vic/drivers/classic/src/get_global_param.c +++ b/vic/drivers/classic/src/get_global_param.c @@ -1038,13 +1038,13 @@ get_global_param(FILE *gp) log_err("ROOT_ZONES must be defined to a positive integer greater " "than 0, in the global control file."); } - if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI].SUPPLIED) { + if (options.LAI_SRC == FROM_VEGHIST && !param_set.TYPE[LAI_IN].SUPPLIED) { log_err("\"LAI_SRC\" was specified as \"FROM_VEGHIST\", but " - "\"LAI\" was not specified as an input forcing in the " + "\"LAI_IN\" was not specified as an input forcing in the " "global parameter file. If you want VIC to read LAI " "values from the veg_hist file, you MUST make sure the veg " - "hist file contains Nveg columns of LAI values, 1 for " - "each veg tile in the grid cell, AND specify LAI as a " + "hist file contains Nveg columns of LAI_IN values, 1 for " + "each veg tile in the grid cell, AND specify LAI_IN as a " "forcing variable in the veg_hist forcing file in the " "global parameter file."); } @@ -1170,6 +1170,12 @@ get_global_param(FILE *gp) "file on the line that begins with \"SNOW_BAND\" " "(after the number of bands).", options.SNOW_BAND); } + if (options.SNOW_BAND > MAX_BANDS) { + log_err("Global file wants more snow bands (%zu) than are " + "defined by MAX_BANDS (%d). Edit vic_run/include/vic_def.h " + "and recompile.", options.SNOW_BAND, + MAX_BANDS); + } } else if (options.SNOW_BAND <= 0) { log_err("Invalid number of elevation bands specified in global " diff --git a/vic/drivers/classic/src/parse_output_info.c b/vic/drivers/classic/src/parse_output_info.c index d661e1f6d..1641a406e 100644 --- a/vic/drivers/classic/src/parse_output_info.c +++ b/vic/drivers/classic/src/parse_output_info.c @@ -36,6 +36,7 @@ parse_output_info(FILE *gp, dmy_struct *dmy_current) { extern option_struct options; + extern global_param_struct global_param; char cmdstr[MAXSTRING]; char optstr[MAXSTRING]; diff --git a/vic/drivers/classic/src/read_atmos_data.c b/vic/drivers/classic/src/read_atmos_data.c index 0930987b1..deab975e4 100644 --- a/vic/drivers/classic/src/read_atmos_data.c +++ b/vic/drivers/classic/src/read_atmos_data.c @@ -145,7 +145,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI && + if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && field_index[i] != FCANOPY) { if (param_set.TYPE[field_index[i]].SIGNED) { fread(&stmp, sizeof(short int), 1, infile); @@ -226,7 +226,7 @@ read_atmos_data(FILE *infile, while (!feof(infile) && (rec * param_set.FORCE_DT[file_num] < global_param.nrecs * global_param.dt)) { for (i = 0; i < Nfields; i++) { - if (field_index[i] != ALBEDO && field_index[i] != LAI && + if (field_index[i] != ALBEDO && field_index[i] != LAI_IN && field_index[i] != FCANOPY) { fscanf(infile, "%lf", &forcing_data[field_index[i]][rec]); } diff --git a/vic/drivers/classic/src/read_forcing_data.c b/vic/drivers/classic/src/read_forcing_data.c index 71f4720f6..cfaec814c 100644 --- a/vic/drivers/classic/src/read_forcing_data.c +++ b/vic/drivers/classic/src/read_forcing_data.c @@ -50,7 +50,7 @@ read_forcing_data(FILE **infile, check_alloc_status((*veg_hist_data), "Memory allocation error."); for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI && i != FCANOPY) { + if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { forcing_data[i] = calloc(global_param.nrecs * NF, sizeof(*(forcing_data[i]))); check_alloc_status(forcing_data[i], "Memory allocation error."); diff --git a/vic/drivers/classic/src/read_veglib.c b/vic/drivers/classic/src/read_veglib.c index af7853846..703074a04 100644 --- a/vic/drivers/classic/src/read_veglib.c +++ b/vic/drivers/classic/src/read_veglib.c @@ -62,7 +62,6 @@ read_veglib(FILE *veglib, // +1 for bare soil temp = calloc(Nveg_type + 1, sizeof(*temp)); - options.NVEGTYPES = Nveg_type + 1; fscanf(veglib, "%s", str); i = 0; diff --git a/vic/drivers/classic/src/read_vegparam.c b/vic/drivers/classic/src/read_vegparam.c index 13ea80878..c322a0833 100644 --- a/vic/drivers/classic/src/read_vegparam.c +++ b/vic/drivers/classic/src/read_vegparam.c @@ -92,6 +92,12 @@ read_vegparam(FILE *vegparam, if (vegcel != gridcel) { log_err("Grid cell %d not found", gridcel); } + if (vegetat_type_num >= MAX_VEG) { + log_err("Vegetation parameter file wants more vegetation tiles in " + "grid cell %i (%i) than are allowed by MAX_VEG (%i) [NOTE: " + "bare soil class is assumed]. Edit vic_run/vic_def.h and " + "recompile.", gridcel, vegetat_type_num + 1, MAX_VEG); + } // Make sure to allocate extra memory for bare soil tile // and optionally an above-treeline veg tile diff --git a/vic/drivers/classic/src/vic_force.c b/vic/drivers/classic/src/vic_force.c index 09f1fb770..36c9f85a7 100644 --- a/vic/drivers/classic/src/vic_force.c +++ b/vic/drivers/classic/src/vic_force.c @@ -95,8 +95,8 @@ vic_force(force_data_struct *force, if (param_set.TYPE[ALBEDO].SUPPLIED) { param_set.TYPE[ALBEDO].N_ELEM = veg_con[0].vegetat_type_num; } - if (param_set.TYPE[LAI].SUPPLIED) { - param_set.TYPE[LAI].N_ELEM = veg_con[0].vegetat_type_num; + if (param_set.TYPE[LAI_IN].SUPPLIED) { + param_set.TYPE[LAI_IN].N_ELEM = veg_con[0].vegetat_type_num; } if (param_set.TYPE[FCANOPY].SUPPLIED) { param_set.TYPE[FCANOPY].N_ELEM = veg_con[0].vegetat_type_num; @@ -246,11 +246,11 @@ vic_force(force_data_struct *force, veg_hist_data[ALBEDO][v][uidx]; } } - if (param_set.TYPE[LAI].SUPPLIED && + if (param_set.TYPE[LAI_IN].SUPPLIED && options.LAI_SRC == FROM_VEGHIST) { - if (veg_hist_data[LAI][v][uidx] != NODATA_VH) { + if (veg_hist_data[LAI_IN][v][uidx] != NODATA_VH) { veg_hist[rec][v].LAI[i] = - veg_hist_data[LAI][v][uidx]; + veg_hist_data[LAI_IN][v][uidx]; } } if (param_set.TYPE[FCANOPY].SUPPLIED && @@ -289,7 +289,7 @@ vic_force(force_data_struct *force, for (i = 0; i < N_FORCING_TYPES; i++) { if (param_set.TYPE[i].SUPPLIED) { - if (i != ALBEDO && i != LAI && i != FCANOPY) { + if (i != ALBEDO && i != LAI_IN && i != FCANOPY) { free(forcing_data[i]); } else { diff --git a/vic/drivers/image/src/display_current_settings.c b/vic/drivers/image/src/display_current_settings.c index e02df18cf..4bf4f71f6 100644 --- a/vic/drivers/image/src/display_current_settings.c +++ b/vic/drivers/image/src/display_current_settings.c @@ -60,12 +60,14 @@ display_current_settings(int mode) fprintf(LOG_DEST, "LOG_LEVEL:\t\t%d\n", LOG_LVL); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); + fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); + fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/image/src/get_global_param.c b/vic/drivers/image/src/get_global_param.c index 1957716c8..67344cdee 100644 --- a/vic/drivers/image/src/get_global_param.c +++ b/vic/drivers/image/src/get_global_param.c @@ -527,6 +527,15 @@ get_global_param(FILE *gp) else if (strcasecmp("OUT_FORMAT", optstr) == 0) { ; // do nothing } + // vegetation history not yet implemented in image mode + // TBD: feature in VIC 4.2 that has been ported to classic + // mode, but that does not exist in image mode (yet) + else if (strcasecmp("ALBEDO", optstr) == 0 || + strcasecmp("LAI_IN", optstr) == 0 || + strcasecmp("FCANOPY", optstr) == 0) { + log_err("Time-varying vegetation parameters not implemented " + "in image mode"); + } /************************************* Fail when classic driver specific options are used diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 033a9f057..1209335e0 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -316,14 +316,14 @@ vic_force(void) d4count[2] = global_domain.n_ny; d4count[3] = global_domain.n_nx; - // Leaf Area Index: LAI + // Leaf Area Index: lai if (options.LAI_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), "LAI", + get_scatter_nc_field_double(&(filenames.forcing[1]), "lai", d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; @@ -335,16 +335,15 @@ vic_force(void) } } - // Partial veg cover fraction: fcanopy + // Partial veg cover fraction: fcan if (options.FCAN_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), - "fcanopy", d4start, d4count, - dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), "fcan", + d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { @@ -355,16 +354,15 @@ vic_force(void) } } - // Albedo: albedo + // Albedo: alb if (options.ALB_SRC == FROM_VEGHIST) { for (j = 0; j < NF; j++) { d4start[0] = global_param.forceskip[1] + global_param.forceoffset[1] + j; for (v = 0; v < options.NVEGTYPES; v++) { d4start[1] = v; - get_scatter_nc_field_double(&(filenames.forcing[1]), - "albedo", d4start, d4count, - dvar); + get_scatter_nc_field_double(&(filenames.forcing[1]), "alb", + d4start, d4count, dvar); for (i = 0; i < local_domain.ncells_active; i++) { vidx = veg_con_map[i].vidx[v]; if (vidx != NODATA_VEG) { diff --git a/vic/drivers/python/src/display_current_settings.c b/vic/drivers/python/src/display_current_settings.c index 8764ab752..305ea4892 100644 --- a/vic/drivers/python/src/display_current_settings.c +++ b/vic/drivers/python/src/display_current_settings.c @@ -53,12 +53,14 @@ display_current_settings(int mode) fprintf(LOG_DEST, "VIC_DRIVER:\t\t%s\n", VIC_DRIVER); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "Maximum Array Sizes:\n"); + fprintf(LOG_DEST, "MAX_BANDS\t\t%2d\n", MAX_BANDS); fprintf(LOG_DEST, "MAX_FRONTS\t\t%2d\n", MAX_FRONTS); fprintf(LOG_DEST, "MAX_FROST_AREAS\t\t\t%2d\n", MAX_FROST_AREAS); fprintf(LOG_DEST, "MAX_LAKE_NODES\t\t%2d\n", MAX_LAKE_NODES); fprintf(LOG_DEST, "MAX_ZWTVMOIST\t\t%2d\n", MAX_ZWTVMOIST); fprintf(LOG_DEST, "MAX_LAYERS\t\t%2d\n", MAX_LAYERS); fprintf(LOG_DEST, "MAX_NODES\t\t%2d\n", MAX_NODES); + fprintf(LOG_DEST, "MAX_VEG\t\t\t%2d\n", MAX_VEG); fprintf(LOG_DEST, "\n"); fprintf(LOG_DEST, "MINSOILDEPTH\t\t%f\n", MINSOILDEPTH); fprintf(LOG_DEST, "MIN_FCANOPY\t\t%f\n", MIN_FCANOPY); diff --git a/vic/drivers/shared_all/include/vic_driver_shared_all.h b/vic/drivers/shared_all/include/vic_driver_shared_all.h index b60a97808..c042ecf50 100644 --- a/vic/drivers/shared_all/include/vic_driver_shared_all.h +++ b/vic/drivers/shared_all/include/vic_driver_shared_all.h @@ -93,7 +93,7 @@ enum CHANNEL_IN, /**< incoming channel flow [m3] */ FCANOPY, /**< fractional area covered by plant canopy [fraction] */ FDIR, /**< fraction of incoming shortwave that is direct [fraction] */ - LAI, /**< leaf area index [m2/m2] */ + LAI_IN, /**< leaf area index [m2/m2] */ LWDOWN, /**< incoming longwave radiation [W/m2] */ PAR, /**< incoming photosynthetically active radiation [W/m2] */ PREC, /**< total precipitation (rain and snow) [mm] */ diff --git a/vic/drivers/shared_all/src/compute_derived_state_vars.c b/vic/drivers/shared_all/src/compute_derived_state_vars.c index bff4c87a7..c0a61cabb 100644 --- a/vic/drivers/shared_all/src/compute_derived_state_vars.c +++ b/vic/drivers/shared_all/src/compute_derived_state_vars.c @@ -46,10 +46,6 @@ compute_derived_state_vars(all_vars_struct *all_vars, size_t veg; size_t lidx; size_t band; - size_t tmpMshape[] = { - options.NVEGTYPES + 1, options.SNOW_BAND, - options.Nlayer - }; size_t tmpTshape[] = { options.Nlayer, options.Nnode, options.Nfrost + 1 @@ -59,9 +55,9 @@ compute_derived_state_vars(all_vars_struct *all_vars, }; int ErrorFlag; double Cv; + double moist[MAX_VEG][MAX_BANDS][MAX_LAYERS]; double dt_thresh; double tmp_runoff; - double ***tmpM; double ***tmpT; double **tmpZ; @@ -74,12 +70,9 @@ compute_derived_state_vars(all_vars_struct *all_vars, snow = all_vars->snow; Nveg = veg_con[0].vegetat_type_num; - // allocate memory for tmp* arrays - malloc_3d_double(tmpMshape, &tmpM); - if (!options.QUICK_FLUX) { - malloc_3d_double(tmpTshape, &tmpT); - malloc_2d_double(tmpZshape, &tmpZ); - } + // allocate memory for tmpT and tmpZ + malloc_3d_double(tmpTshape, &tmpT); + malloc_2d_double(tmpZshape, &tmpZ); /****************************************** Compute derived soil layer vars @@ -92,14 +85,14 @@ compute_derived_state_vars(all_vars_struct *all_vars, for (band = 0; band < options.SNOW_BAND; band++) { // Initialize soil for existing snow elevation bands if (soil_con->AreaFract[band] > 0.) { - // set up temporary moist array + // set up temporary moist arrays for (lidx = 0; lidx < options.Nlayer; lidx++) { - tmpM[veg][band][lidx] = + moist[veg][band][lidx] = cell[veg][band].layer[lidx].moist; } // compute saturated area and water table - compute_runoff_and_asat(soil_con, tmpM[veg][band], 0, + compute_runoff_and_asat(soil_con, moist[veg][band], 0, &(cell[veg][band].asat), &tmp_runoff); wrap_compute_zwt(soil_con, &(cell[veg][band])); @@ -159,7 +152,7 @@ compute_derived_state_vars(all_vars_struct *all_vars, soil_con->max_moist_node, soil_con->expt_node, soil_con->bubble_node, - tmpM[veg][band], + moist[veg][band], soil_con->depth, soil_con->soil_dens_min, soil_con->bulk_dens_min, @@ -255,10 +248,7 @@ compute_derived_state_vars(all_vars_struct *all_vars, } } } - // free memory for tmp* arrays - free_3d_double(tmpMshape, tmpM); - if (!options.QUICK_FLUX) { - free_3d_double(tmpTshape, tmpT); - free_2d_double(tmpZshape, tmpZ); - } + // free memory for tmpT and tmpZ + free_3d_double(tmpTshape, tmpT); + free_2d_double(tmpZshape, tmpZ); } diff --git a/vic/drivers/shared_all/src/history_metadata.c b/vic/drivers/shared_all/src/history_metadata.c index 75746a94c..e38a39c76 100644 --- a/vic/drivers/shared_all/src/history_metadata.c +++ b/vic/drivers/shared_all/src/history_metadata.c @@ -391,7 +391,7 @@ set_output_met_data_info() strcpy(out_metadata[OUT_LAKE_BF_IN].standard_name, "infiltration_amount"); strcpy(out_metadata[OUT_LAKE_BF_IN].units, "mm"); strcpy(out_metadata[OUT_LAKE_BF_IN].description, - "incoming baseflow from lake catchment"); + "oisture that reaches top of soil column"); /* incoming volumetric baseflow from lake catchment [m3] */ strcpy(out_metadata[OUT_LAKE_BF_IN_V].varname, "OUT_LAKE_BF_IN_V"); diff --git a/vic/drivers/shared_all/src/initialize_soil.c b/vic/drivers/shared_all/src/initialize_soil.c index 8850fb3bd..6b9761f92 100644 --- a/vic/drivers/shared_all/src/initialize_soil.c +++ b/vic/drivers/shared_all/src/initialize_soil.c @@ -70,8 +70,7 @@ 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].esoil = 0.0; - cell[veg][band].layer[lindex].transp = 0.0; + cell[veg][band].layer[lindex].bare_evap_frac = 0.0; cell[veg][band].layer[lindex].evap = 0.0; } } diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index 4dd95fdda..ef9efdeaa 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -420,8 +420,7 @@ void print_layer_data_fluxes(layer_data_struct *ldata) { fprintf(LOG_DEST, "layer_data (fluxes):\n"); - fprintf(LOG_DEST, "\tesoil: %f\n", ldata->esoil); - fprintf(LOG_DEST, "\ttransp: %f\n", ldata->transp); + fprintf(LOG_DEST, "\tbare_evap_frac: %f\n", ldata->evap); fprintf(LOG_DEST, "\tevap: %f\n", ldata->evap); } diff --git a/vic/drivers/shared_all/src/put_data.c b/vic/drivers/shared_all/src/put_data.c index d2ab6eaeb..700310480 100644 --- a/vic/drivers/shared_all/src/put_data.c +++ b/vic/drivers/shared_all/src/put_data.c @@ -67,7 +67,7 @@ put_data(all_vars_struct *all_vars, double inflow; double outflow; double storage; - double *TreeAdjustFactor; + double TreeAdjustFactor[MAX_BANDS]; double ThisAreaFract; double ThisTreeAdjust; size_t i; @@ -93,8 +93,6 @@ put_data(all_vars_struct *all_vars, dt_sec = global_param.dt; // Compute treeline adjustment factors - TreeAdjustFactor = calloc(options.SNOW_BAND, sizeof(*TreeAdjustFactor)); - check_alloc_status(TreeAdjustFactor, "Memory allocation error."); for (band = 0; band < options.SNOW_BAND; band++) { if (AboveTreeLine[band]) { Cv = 0; @@ -571,8 +569,6 @@ put_data(all_vars_struct *all_vars, out_data[OUT_ENERGY_ERROR][0] = MISSING; } - free((char *) (TreeAdjustFactor)); - // vic_run run time out_data[OUT_TIME_VICRUN_WALL][0] = timer->delta_wall; out_data[OUT_TIME_VICRUN_CPU][0] = timer->delta_cpu; @@ -612,11 +608,19 @@ 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_TRANSP_VEG][0] += cell.layer[index].transp * - AreaFactor; + 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; } } tmp_evap += snow.vapor_flux * MM_PER_M; diff --git a/vic/drivers/shared_image/src/set_force_type.c b/vic/drivers/shared_image/src/set_force_type.c index c4a523386..89cdbfe89 100644 --- a/vic/drivers/shared_image/src/set_force_type.c +++ b/vic/drivers/shared_image/src/set_force_type.c @@ -76,42 +76,42 @@ set_force_type(char *cmdstr, else if (strcasecmp("CHANNEL_IN", optstr) == 0) { type = CHANNEL_IN; } - /* type 4: vegetation cover fraction [fraction] */ - else if (strcasecmp("FCANOPY", optstr) == 0) { - type = FCANOPY; - } - /* type 5: direct fraction of shortwave [fraction] */ + /* type 4: direct fraction of shortwave [fraction] */ else if (strcasecmp("FDIR", optstr) == 0) { type = FDIR; } - /* type 6: LAI [m2/m2] */ - else if (strcasecmp("LAI", optstr) == 0) { - type = LAI; + /* type 5: LAI [m2/m2] */ + else if (strcasecmp("LAI_IN", optstr) == 0) { + type = LAI_IN; } - /* type 7: incoming longwave radiation [W/m2] */ + /* type 6: incoming longwave radiation [W/m2] */ else if (strcasecmp("LWDOWN", optstr) == 0) { type = LWDOWN; } - /* type 8: photosynthetically active radiation [uE/m2s] */ + /* type 7: photosynthetically active radiation [uE/m2s] */ else if (strcasecmp("PAR", optstr) == 0) { type = PAR; } - /* type 9: precipitation [mm] */ + /* type 8: precipitation [mm] */ else if (strcasecmp("PREC", optstr) == 0) { type = PREC; } - /* type 10: air pressure [kPa] */ + /* type 9: air pressure [kPa] */ else if (strcasecmp("PRESSURE", optstr) == 0) { type = PRESSURE; } - /* type 11: vapor pressure [kPa] */ + /* type 10: vapor pressure [kPa] */ else if (strcasecmp("VP", optstr) == 0) { type = VP; } - /* type 12: incoming shortwave radiation [W/m2] */ + /* type 11: incoming shortwave radiation [W/m2] */ else if (strcasecmp("SWDOWN", optstr) == 0) { type = SWDOWN; } + /* type 12: vegetation cover fraction */ + else if (strcasecmp("FCANOPY", optstr) == 0) { + type = FCANOPY; + } /* type 13: wind speed [m/s] */ else if (strcasecmp("WIND", optstr) == 0) { type = WIND; diff --git a/vic/drivers/shared_image/src/vic_alloc.c b/vic/drivers/shared_image/src/vic_alloc.c index 005089375..34ecfec9d 100644 --- a/vic/drivers/shared_image/src/vic_alloc.c +++ b/vic/drivers/shared_image/src/vic_alloc.c @@ -158,7 +158,7 @@ vic_alloc(void) veg_lib[i] = calloc(options.NVEGTYPES, sizeof(*(veg_lib[i]))); check_alloc_status(veg_lib[i], "Memory allocation error."); - all_vars[i] = make_all_vars(veg_con_map[i].nv_active - 1); + all_vars[i] = make_all_vars(veg_con_map[i].nv_active); // allocate memory for veg_hist veg_hist[i] = calloc(veg_con_map[i].nv_active, sizeof(*(veg_hist[i]))); diff --git a/vic/drivers/shared_image/src/vic_finalize.c b/vic/drivers/shared_image/src/vic_finalize.c index 26043e199..cc643876f 100644 --- a/vic/drivers/shared_image/src/vic_finalize.c +++ b/vic/drivers/shared_image/src/vic_finalize.c @@ -94,7 +94,7 @@ vic_finalize(void) } free_veg_hist(&(veg_hist[i][j])); } - free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active - 1); + free_all_vars(&(all_vars[i]), veg_con_map[i].nv_active); free(veg_con_map[i].vidx); free(veg_con_map[i].Cv); free(veg_con[i]); diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 5bd57d410..83a7cf769 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -272,7 +272,6 @@ vic_init(void) else { veg_lib[i][j].fcanopy[k] = MIN_FCANOPY; } - veg_lib[i][j].fcanopy[k] = 1.0; } } } @@ -989,17 +988,11 @@ vic_init(void) } if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - if (sum > 0) { - log_warn("Sum of the snow band area fractions does not " - "equal 1 (%f), dividing each fraction by the " - "sum\n%s", sum, locstr); - for (j = 0; j < options.SNOW_BAND; j++) { - soil_con[i].AreaFract[j] /= sum; - } - } - else { - log_err("Sum of the snow band area fractions is 0\n%s", - locstr); + log_warn("Sum of the snow band area fractions does not equal " + "1 (%f), dividing each fraction by the sum\n%s", + sum, locstr); + for (j = 0; j < options.SNOW_BAND; j++) { + soil_con[i].AreaFract[j] /= sum; } } // check that the mean elevation from the snow bands matches the @@ -1235,11 +1228,11 @@ vic_init(void) // TODO: handle bare soil adjustment for compute treeline option // If the sum of the tile fractions is not within a tolerance, - // readjust Cvs to sum to 1.0 + // throw an error if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Cv != 1.0 (%f) at grid cell %zd. Adjusting fractions " - "...\n%s", Cv_sum[i], i, locstr); + log_warn("Cv != 1.0 (%f) at grid cell %zd. Exiting ...\n%s", + Cv_sum[i], i, locstr); for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; veg_con[i][vidx].Cv /= Cv_sum[i]; diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index f90bca69f..184ede176 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -59,8 +59,10 @@ #define ERROR -999 /**< Error Flag returned by subroutines */ /***** Define maximum array sizes for model source code *****/ +#define MAX_VEG 12 /**< maximum number of vegetation types per cell */ #define MAX_LAYERS 3 /**< maximum number of soil moisture layers */ #define MAX_NODES 50 /**< maximum number of soil thermal nodes */ +#define MAX_BANDS 10 /**< maximum number of snow bands */ #define MAX_FRONTS 3 /**< maximum number of freezing and thawing front depths to store */ #define MAX_FROST_AREAS 10 /**< maximum number of frost sub-areas */ #define MAX_LAKE_NODES 20 /**< maximum number of lake thermal nodes */ @@ -233,8 +235,10 @@ typedef struct { size_t Nnode; /**< Number of soil thermal nodes in the model */ bool NOFLUX; /**< TRUE = Use no flux lower bondary when computing soil thermal fluxes */ - size_t NVEGTYPES; /**< number of vegetation types in veg_param file */ - size_t NLAKENODES; /**< number of lake layers in lake_param file */ + size_t NVEGTYPES; /**< number of vegetation types in veg_param file + (used by image driver) */ + size_t NLAKENODES; /**< number of lake layers in lake_param file + (used by image driver) */ unsigned short int RC_MODE; /**< RC_JARVIS = compute canopy resistance via Jarvis formulation (default) RC_PHOTO = compute canopy resistance based on photosynthetic activity */ size_t ROOT_ZONES; /**< Number of root zones used in simulation */ @@ -768,9 +772,8 @@ typedef struct { double phi; /**< moisture diffusion parameter */ double zwt; /**< water table position relative to soil surface within the layer (cm) */ // Fluxes - double esoil; /**< soil evaporation from soil layer (mm) */ + double bare_evap_frac; /**< fraction of evapotranspiration coming from bare soil evap, from soil layer (mm) */ double evap; /**< evapotranspiration from soil layer (mm) */ - double transp; /**< transpiration from soil layer (mm) */ } layer_data_struct; /****************************************************************************** diff --git a/vic/vic_run/include/vic_run.h b/vic/vic_run/include/vic_run.h index 9c6e4cfbd..02ae0c073 100644 --- a/vic/vic_run/include/vic_run.h +++ b/vic/vic_run/include/vic_run.h @@ -217,8 +217,8 @@ void photosynth(char, double, double, double, double, double, double, double, double, double, char *, double *, double *, double *, double *, double *); void polint(double xa[], double ya[], int n, double x, double *y, double *dy); -void prepare_full_energy(cell_data_struct *, energy_bal_struct *, - soil_con_struct *, double *, double *); +void prepare_full_energy(int, all_vars_struct *, soil_con_struct *, double *, + double *); double qromb( double (*sub_with_height)(), double es, double Wind, double AirDens, double ZO, double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, double a, double b); diff --git a/vic/vic_run/src/arno_evap.c b/vic/vic_run/src/arno_evap.c index 3f4db87e9..7b3ed3a32 100644 --- a/vic/vic_run/src/arno_evap.c +++ b/vic/vic_run/src/arno_evap.c @@ -59,7 +59,7 @@ arno_evap(layer_data_struct *layer, double ratio, as; double Epot; /* potential bare soil evaporation */ double moist; - double esoil; + double evap; double max_infil; double Evap; double tmpsum; @@ -115,7 +115,7 @@ arno_evap(layer_data_struct *layer, /**********************************************************************/ if (tmp >= max_infil) { - esoil = Epot; + evap = Epot; } else { /********************************************************************/ @@ -159,7 +159,7 @@ arno_evap(layer_data_struct *layer, } beta_asp = as + (1.0 - as) * (1.0 - ratio) * dummy; - esoil = Epot * beta_asp; + evap = Epot * beta_asp; } /***********************************************************************/ @@ -168,21 +168,21 @@ arno_evap(layer_data_struct *layer, /***********************************************************************/ /* only consider positive evaporation; we won't put limits on condensation */ - if (esoil > 0.0) { + if (evap > 0.0) { if (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; + /* 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; } } else { - /* no moisture available; cap esoil at 0 */ - esoil = 0.0; + /* no moisture available; cap evap at 0 */ + evap = 0.0; } } - layer[0].esoil = esoil; - Evap += esoil / MM_PER_M / delta_t; + layer[0].evap = evap; + Evap += evap / MM_PER_M / delta_t; return(Evap); } diff --git a/vic/vic_run/src/canopy_evap.c b/vic/vic_run/src/canopy_evap.c index 51b7ce3ab..8f6689497 100644 --- a/vic/vic_run/src/canopy_evap.c +++ b/vic/vic_run/src/canopy_evap.c @@ -70,14 +70,14 @@ canopy_evap(layer_data_struct *layer, double tmp_Evap; double canopyevap; double tmp_Wdew; - double layertransp[MAX_LAYERS]; + double layerevap[MAX_LAYERS]; double rc; Evap = 0; /* Initialize variables */ for (i = 0; i < options.Nlayer; i++) { - layertransp[i] = 0; + layerevap[i] = 0; } canopyevap = 0; throughfall = 0; @@ -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, layertransp, frost_fract, root, shortwave, Catm, + Wpwp, layerevap, frost_fract, root, shortwave, Catm, CanopLayerBnd); } @@ -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].transp = layertransp[i]; - tmp_Evap += layertransp[i]; + layer[i].evap = layerevap[i]; + tmp_Evap += layerevap[i]; } Evap += tmp_Evap / (MM_PER_M * delta_t); @@ -180,7 +180,7 @@ transpiration(layer_data_struct *layer, double *Wmax, double *Wcr, double *Wpwp, - double *layertransp, + double *layerevap, double *frost_fract, double *root, double shortwave, @@ -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 transp; /* tmp holding for transp total */ + double evap; /* tmp holding for evap total */ double Wcr1; /* tmp holding of critical water for upper layers */ double root_sum; /* proportion of roots in moist>Wcr zones */ - double spare_transp; /* transp for 2nd distribution */ + double spare_evap; /* evap for 2nd distribution */ double avail_moist[MAX_LAYERS]; /* moisture available for trans */ double ice[MAX_LAYERS]; double gc; @@ -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 - transpiration is taken from the wetter layer. Otherwise layers - contribute to transipration based on root fraction. + evaporation is taken from the wetter layer. Otherwise layers + contribute to evapotransipration based on root fraction. ******************************************************************/ if (options.SHARE_LAYER_MOIST && @@ -324,17 +324,17 @@ transpiration(layer_data_struct *layer, } /* compute transpiration */ - transp = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc, - vic_run_veg_lib[veg_class].rarc) * + evap = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc, + vic_run_veg_lib[veg_class].rarc) * delta_t / CONST_CDAY * dryFrac; - /** divide up transp based on root distribution **/ + /** divide up evap based on root distribution **/ /** Note the indexing of the roots **/ root_sum = 1.0; - spare_transp = 0.0; + spare_evap = 0.0; for (i = 0; i < options.Nlayer; i++) { if (avail_moist[i] >= Wcr[i]) { - layertransp[i] = transp * (double) root[i]; + layerevap[i] = evap * (double) root[i]; } else { if (avail_moist[i] >= Wpwp[i]) { @@ -345,25 +345,24 @@ transpiration(layer_data_struct *layer, gsm_inv = 0.0; } - layertransp[i] = transp * gsm_inv * (double) root[i]; + layerevap[i] = evap * gsm_inv * (double) root[i]; root_sum -= root[i]; - spare_transp = transp * (double) root[i] * (1.0 - gsm_inv); + spare_evap = evap * (double) root[i] * (1.0 - gsm_inv); } } - /** Assign excess transpiration to wetter layer **/ - if (spare_transp > 0.0) { + /** Assign excess evaporation to wetter layer **/ + if (spare_evap > 0.0) { for (i = 0; i < options.Nlayer; i++) { if (avail_moist[i] >= Wcr[i]) { - layertransp[i] += (double) root[i] * - spare_transp / root_sum; + layerevap[i] += (double) root[i] * spare_evap / root_sum; } } } } /********************************************************************* - CASE 2: Independent transpirations + CASE 2: Independent evapotranspirations Evapotranspiration is restricted by low soil moisture. Evaporation is computed independantly from each soil layer. @@ -381,7 +380,7 @@ transpiration(layer_data_struct *layer, } for (i = 0; i < options.Nlayer; i++) { - /** Set transpiration restriction factor **/ + /** Set evaporation restriction factor **/ if (avail_moist[i] >= Wcr[i]) { gsm_inv = 1.0; } @@ -429,7 +428,7 @@ transpiration(layer_data_struct *layer, } /* compute transpiration */ - layertransp[i] = penman(air_temp, elevation, rad, vpd, ra, + layerevap[i] = penman(air_temp, elevation, rad, vpd, ra, veg_var->rc, vic_run_veg_lib[veg_class].rarc) * delta_t / CONST_CDAY * dryFrac * @@ -454,7 +453,7 @@ transpiration(layer_data_struct *layer, } } else { - layertransp[i] = 0.0; + layerevap[i] = 0.0; gc += 0; if (options.CARBON) { for (cidx = 0; cidx < options.Ncanopy; cidx++) { @@ -495,32 +494,32 @@ transpiration(layer_data_struct *layer, } /**************************************************************** - Check that transipration does not cause soil moisture to + Check that evapotransipration 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 (layertransp[i] > avail_moist[i]) { - layertransp[i] = avail_moist[i]; + if (layerevap[i] > avail_moist[i]) { + layerevap[i] = avail_moist[i]; } } else { // ice content less than wilting point restrict loss of unfrozen moist - if (layertransp[i] > layer[i].moist - Wpwp[i]) { - layertransp[i] = layer[i].moist - Wpwp[i]; + if (layerevap[i] > layer[i].moist - Wpwp[i]) { + layerevap[i] = layer[i].moist - Wpwp[i]; } } } else { // No ice restrict loss of unfrozen moist - if (layertransp[i] > layer[i].moist - Wpwp[i]) { - layertransp[i] = layer[i].moist - Wpwp[i]; + if (layerevap[i] > layer[i].moist - Wpwp[i]) { + layerevap[i] = layer[i].moist - Wpwp[i]; } } - if (layertransp[i] < 0.0) { - layertransp[i] = 0.0; + if (layerevap[i] < 0.0) { + layerevap[i] = 0.0; } } } diff --git a/vic/vic_run/src/func_surf_energy_bal.c b/vic/vic_run/src/func_surf_energy_bal.c index 4e47301f9..1fe7ef4ca 100644 --- a/vic/vic_run/src/func_surf_energy_bal.c +++ b/vic/vic_run/src/func_surf_energy_bal.c @@ -203,7 +203,7 @@ func_surf_energy_bal(double Ts, double T1_plus; double D1_minus; double D1_plus; - double SurfRad; + double *transp = NULL; double Ra_bare[3]; double tmp_wind[3]; double tmp_height; @@ -366,6 +366,12 @@ func_surf_energy_bal(double Ts, TMean = Ts; + transp = calloc(options.Nlayer, sizeof(*transp)); + check_alloc_status(transp, "Memory allocation error."); + for (i = 0; i < options.Nlayer; i++) { + transp[i] = 0.; + } + /********************************************** Compute Surface Temperature at Half Time Step **********************************************/ @@ -743,46 +749,67 @@ func_surf_energy_bal(double Ts, Should evapotranspiration be active when the ground is only partially covered with snow???? + + Use Arno Evap in the exposed soil portion, and/or + if LAI is zero. *************************************************/ - for (i=0; ifcanopy > 0) { - Evap = canopy_evap(layer, veg_var, true, veg_class, Wdew, - delta_t, NetBareRad, vpd, NetShortBare, - Tair, Ra_veg[1], elevation, rainfall, - Wmax, Wcr, Wpwp, frost_fract, root, - dryFrac, shortwave, Catm, CanopLayerBnd); + if (VEG && !SNOWING && veg_var->fcanopy > 0) { + Evap = canopy_evap(layer, veg_var, true, + veg_class, Wdew, delta_t, NetBareRad, vpd, + NetShortBare, Tair, Ra_veg[1], elevation, rainfall, + Wmax, Wcr, Wpwp, frost_fract, root, dryFrac, + shortwave, Catm, CanopLayerBnd); + if (veg_var->fcanopy < 1) { + for (i = 0; i < options.Nlayer; i++) { + transp[i] = layer[i].evap; + layer[i].evap = 0.; + } Evap *= veg_var->fcanopy; - for (i=0; ifcanopy; + Evap += (1 - veg_var->fcanopy) * + arno_evap(layer, surf_atten * NetBareRad, Tair, vpd, + depth[0], max_moist * depth[0] * MM_PER_M, + elevation, b_infilt, Ra_used[0], delta_t, + resid_moist[0], frost_fract); + for (i = 0; i < options.Nlayer; i++) { + layer[i].evap = veg_var->fcanopy * transp[i] + + (1 - veg_var->fcanopy) * layer[i].evap; + if (layer[i].evap > 0.) { + layer[i].bare_evap_frac = 1 - + (veg_var->fcanopy * + transp[i]) / layer[i].evap; + } + else { + layer[i].bare_evap_frac = 0.; + } } - SurfRad = surf_atten*NetBareRad; + veg_var->throughfall = + (1 - + veg_var->fcanopy) * rainfall + veg_var->fcanopy * + veg_var->throughfall; + veg_var->canopyevap *= veg_var->fcanopy; + veg_var->Wdew *= veg_var->fcanopy; } else { - SurfRad = NetBareRad; + for (i = 0; i < options.Nlayer; i++) { + layer[i].bare_evap_frac = 0.; + } } - Evap += (1 - veg_var->fcanopy) * - arno_evap(layer, SurfRad, Tair, vpd, - depth[0], max_moist * depth[0] * MM_PER_M, - elevation, b_infilt, Ra_used[0], delta_t, - resid_moist[0], frost_fract); + } + else if (!SNOWING) { + Evap = arno_evap(layer, NetBareRad, Tair, vpd, + depth[0], max_moist * depth[0] * MM_PER_M, + elevation, b_infilt, Ra_used[0], delta_t, + resid_moist[0], frost_fract); for (i = 0; i < options.Nlayer; i++) { - layer[i].esoil *= (1 - veg_var->fcanopy); - layer[i].evap = layer[i].transp + layer[i].esoil; + layer[i].bare_evap_frac = 1; } - veg_var->throughfall = (1 - veg_var->fcanopy) * rainfall + - veg_var->fcanopy * veg_var->throughfall; - veg_var->canopyevap *= veg_var->fcanopy; - veg_var->Wdew *= veg_var->fcanopy; } else { Evap = 0.; } + free(transp); + /********************************************************************** Compute the Latent Heat Flux from the Surface and Covering Vegetation **********************************************************************/ diff --git a/vic/vic_run/src/prepare_full_energy.c b/vic/vic_run/src/prepare_full_energy.c index 33f1c3f38..409803c87 100644 --- a/vic/vic_run/src/prepare_full_energy.c +++ b/vic/vic_run/src/prepare_full_energy.c @@ -34,64 +34,78 @@ * ground heat flux solution. *****************************************************************************/ void -prepare_full_energy(cell_data_struct *cell, - energy_bal_struct *energy, - soil_con_struct *soil_con, - double *moist0, - double *ice0) +prepare_full_energy(int iveg, + all_vars_struct *all_vars, + soil_con_struct *soil_con, + double *moist0, + double *ice0) { extern option_struct options; - size_t i; + size_t i, band; layer_data_struct *layer = NULL; layer = calloc(options.Nlayer, sizeof(*layer)); check_alloc_status(layer, "Memory allocation error."); - for (i = 0; i < options.Nlayer; i++) { - layer[i] = cell->layer[i]; - } + for (band = 0; band < options.SNOW_BAND; band++) { + if (soil_con->AreaFract[band] > 0.0) { + for (i = 0; i < options.Nlayer; i++) { + layer[i] = all_vars->cell[iveg][band].layer[i]; + } + + /* Compute top soil layer moisture content (mm/mm) */ - /* Compute top soil layer moisture content (mm/mm) */ - *moist0 = layer[0].moist / (soil_con->depth[0] * MM_PER_M); + moist0[band] = layer[0].moist / (soil_con->depth[0] * MM_PER_M); - /* Compute top soil layer ice content (mm/mm) */ - if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { - if ((energy->T[0] + energy->T[1]) / 2. < 0.) { - *ice0 = *moist0 - - maximum_unfrozen_water((energy->T[0] + energy->T[1]) / 2., - soil_con->max_moist[0] / - (soil_con->depth[0] * MM_PER_M), - soil_con->bubble[0], - soil_con->expt[0]); - if (*ice0 < 0.) { - *ice0 = 0.; + /* Compute top soil layer ice content (mm/mm) */ + + if (options.FROZEN_SOIL && soil_con->FS_ACTIVE) { + if ((all_vars->energy[iveg][band].T[0] + + all_vars->energy[iveg][band].T[1]) / 2. < 0.) { + ice0[band] = moist0[band] - + maximum_unfrozen_water((all_vars->energy[iveg][ + band].T[0] + + all_vars->energy[iveg][ + band].T[1]) / 2., + soil_con->max_moist[0] / + (soil_con->depth[0] * + MM_PER_M), + soil_con->bubble[0], + soil_con->expt[0]); + if (ice0[band] < 0.) { + ice0[band] = 0.; + } + } + else { + ice0[band] = 0.; + } + } + else { + ice0[band] = 0.; } + + /** Compute Soil Thermal Properties **/ + compute_soil_layer_thermal_properties(layer, soil_con->depth, + soil_con->bulk_dens_min, + soil_con->soil_dens_min, + soil_con->quartz, + soil_con->bulk_density, + soil_con->soil_density, + soil_con->organic, + soil_con->frost_fract, + options.Nlayer); + + /** Save Thermal Conductivities for Energy Balance **/ + all_vars->energy[iveg][band].kappa[0] = layer[0].kappa; + all_vars->energy[iveg][band].Cs[0] = layer[0].Cs; + all_vars->energy[iveg][band].kappa[1] = layer[1].kappa; + all_vars->energy[iveg][band].Cs[1] = layer[1].Cs; } else { - *ice0 = 0.; + ice0[band] = 0.; } } - else { - *ice0 = 0.; - } - - /** Compute Soil Thermal Properties **/ - compute_soil_layer_thermal_properties(layer, soil_con->depth, - soil_con->bulk_dens_min, - soil_con->soil_dens_min, - soil_con->quartz, - soil_con->bulk_density, - soil_con->soil_density, - soil_con->organic, - soil_con->frost_fract, - options.Nlayer); - - /** Save Thermal Conductivities for Energy Balance **/ - energy->kappa[0] = layer[0].kappa; - energy->Cs[0] = layer[0].Cs; - energy->kappa[1] = layer[1].kappa; - energy->Cs[1] = layer[1].Cs; free((char *) layer); } diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index fd6988875..f885d7514 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -47,19 +47,20 @@ vic_run(force_data_struct *force, extern parameters_struct param; char overstory; - size_t l; + int j; + size_t lidx; unsigned short iveg; size_t Nveg; unsigned short veg_class; unsigned short band; size_t Nbands; int ErrorFlag; - double *out_prec; - double *out_rain; - double *out_snow; + double out_prec[2 * MAX_BANDS]; + double out_rain[2 * MAX_BANDS]; + double out_snow[2 * MAX_BANDS]; double dp; - double ice0; - double moist0; + double ice0[MAX_BANDS]; + double moist0[MAX_BANDS]; double surf_atten; double wind_h; double height; @@ -69,9 +70,9 @@ vic_run(force_data_struct *force, double aero_resist[3]; double Cv; double Le; - double *Melt; + double Melt[2 * MAX_BANDS]; double bare_albedo; - double *snow_inflow; + double snow_inflow[MAX_BANDS]; double rainonly; double sum_runoff; double sum_baseflow; @@ -88,21 +89,10 @@ vic_run(force_data_struct *force, double rainprec; size_t cidx; lake_var_struct *lake_var; - cell_data_struct *cell; - veg_var_struct *veg_var; - energy_bal_struct *energy; - snow_data_struct *snow; - - out_prec = calloc(options.SNOW_BAND, sizeof(*out_prec)); - check_alloc_status(out_prec, "Memory allocation error."); - out_rain = calloc(options.SNOW_BAND, sizeof(*out_rain)); - check_alloc_status(out_rain, "Memory allocation error."); - out_snow = calloc(options.SNOW_BAND, sizeof(*out_snow)); - check_alloc_status(out_snow, "Memory allocation error."); - Melt = calloc(options.SNOW_BAND, sizeof(*Melt)); - check_alloc_status(Melt, "Memory allocation error."); - snow_inflow = calloc(options.SNOW_BAND, sizeof(*snow_inflow)); - check_alloc_status(snow_inflow, "Memory allocation error."); + cell_data_struct **cell; + veg_var_struct **veg_var; + energy_bal_struct **energy; + snow_data_struct **snow; // assign vic_run_veg_lib to veg_lib, so that the veg_lib for the correct // grid cell is used within vic_run. For simplicity sake, use vic_run_veg_lib @@ -110,11 +100,15 @@ vic_run(force_data_struct *force, vic_run_veg_lib = veg_lib; /* set local pointers */ + cell = all_vars->cell; + energy = all_vars->energy; lake_var = &all_vars->lake_var; + snow = all_vars->snow; + veg_var = all_vars->veg_var; Nbands = options.SNOW_BAND; - /* Set number of vegetation tiles */ + /* Set number of vegetation types */ Nveg = veg_con[0].vegetat_type_num; /** Set Damping Depth **/ @@ -135,23 +129,28 @@ vic_run(force_data_struct *force, force->out_rain = 0; force->out_snow = 0; + // Convert LAI from global to local + for (iveg = 0; iveg < Nveg; iveg++) { + veg_class = veg_con[iveg].veg_class; + for (band = 0; band < Nbands; band++) { + veg_var[iveg][band].LAI /= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdew /= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdmax = veg_var[iveg][band].LAI * + param.VEG_LAI_WATER_FACTOR; + snow[iveg][band].snow_canopy /= veg_var[iveg][band].fcanopy; + } + } + /************************************************** Solve Energy and/or Water Balance for Each - Vegetation Tile + Vegetation Type **************************************************/ for (iveg = 0; iveg <= Nveg; iveg++) { - /** Solve Veg Tile only if Coverage Greater than 0% **/ + /** Solve Veg Type only if Coverage Greater than 0% **/ if (veg_con[iveg].Cv > 0.0) { Cv = veg_con[iveg].Cv; Nbands = options.SNOW_BAND; - /** Define vegetation class number **/ - veg_class = veg_con[iveg].veg_class; - - /************************************************** - Initialize Model Parameters - **************************************************/ - /** Lake-specific processing **/ if (veg_con[iveg].LAKE) { /* Update areai to equal new ice area from previous time step. */ @@ -180,21 +179,74 @@ vic_run(force_data_struct *force, } } - /* local pointer to veg_var */ - veg_var = &(all_vars->veg_var[iveg][0]); + /************************************************** + Initialize Model Parameters + **************************************************/ + + for (band = 0; band < Nbands; band++) { + if (soil_con->AreaFract[band] > 0) { + /* Initialize energy balance variables */ + energy[iveg][band].shortwave = 0; + energy[iveg][band].longwave = 0.; + + /* Initialize snow variables */ + snow[iveg][band].vapor_flux = 0.; + snow[iveg][band].canopy_vapor_flux = 0.; + snow_inflow[band] = 0.; + Melt[band * 2] = 0.; + } + } + + /* Initialize precipitation storage */ + for (j = 0; j < 2 * MAX_BANDS; j++) { + out_prec[j] = 0; + out_rain[j] = 0; + out_snow[j] = 0; + } + + /** Define vegetation class number **/ + veg_class = veg_con[iveg].veg_class; + + /** Initialize other veg vars **/ + if (iveg < Nveg) { + for (band = 0; band < Nbands; band++) { + veg_var[iveg][band].rc = param.HUGE_RESIST; + } + } /** Assign wind_h **/ /** Note: this is ignored below **/ wind_h = vic_run_veg_lib[veg_class].wind_h; + /** Compute Surface Attenuation due to Vegetation Coverage **/ + surf_atten = (1 - veg_var[iveg][0].fcanopy) * 1.0 + + veg_var[iveg][0].fcanopy * + exp(-vic_run_veg_lib[veg_class].rad_atten * + veg_var[iveg][0].LAI); + + /* Initialize soil thermal properties for the top two layers */ + prepare_full_energy(iveg, all_vars, soil_con, moist0, ice0); + + /** Compute Bare (free of snow) Albedo **/ + if (iveg != Nveg) { + bare_albedo = veg_var[iveg][0].albedo; + } + else { + bare_albedo = param.ALBEDO_BARE_SOIL; + } + + /************************************* + Compute the aerodynamic resistance + *************************************/ + /* Initialize wind speeds */ tmp_wind[0] = force->wind[NR]; tmp_wind[1] = MISSING; tmp_wind[2] = MISSING; /* Set surface descriptive variables */ - displacement[0] = veg_var->displacement; - roughness[0] = veg_var->roughness; + displacement[0] = veg_var[iveg][0].displacement; + roughness[0] = veg_var[iveg][0].roughness; if (roughness[0] == 0) { roughness[0] = soil_con->rough; } @@ -223,117 +275,70 @@ vic_run(force_data_struct *force, return (ERROR); } - /** Compute Surface Attenuation due to Vegetation Coverage **/ - surf_atten = (1 - veg_var->fcanopy) * 1.0 + - veg_var->fcanopy * - exp(-vic_run_veg_lib[veg_class].rad_atten * - veg_var->LAI); - - /** Compute Bare (free of snow) Albedo **/ - if (iveg != Nveg) { - bare_albedo = veg_var->albedo; - } - else { - bare_albedo = param.ALBEDO_BARE_SOIL; - } - - /************************************************** - Loop over elevation bands - **************************************************/ + /* Initialize final aerodynamic resistance values */ for (band = 0; band < Nbands; band++) { - /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { + cell[iveg][band].aero_resist[0] = + aero_resist[0]; + cell[iveg][band].aero_resist[1] = + aero_resist[1]; + } + } - /* Set local pointers */ - cell = &(all_vars->cell[iveg][band]); - veg_var = &(all_vars->veg_var[iveg][band]); - snow = &(all_vars->snow[iveg][band]); - energy = &(all_vars->energy[iveg][band]); - - /****************************************** - Initialize Band-dependent Model Parameters - ******************************************/ - - /* Initialize soil thermal properties for the top two layers */ - prepare_full_energy(cell, energy, soil_con, &moist0, &ice0); - - /* Initialize final aerodynamic resistance values */ - cell->aero_resist[0] = aero_resist[0]; - cell->aero_resist[1] = aero_resist[1]; - - /* Initialize pot_evap */ - cell->pot_evap = 0; - - // Convert LAI from global to local - veg_var->LAI /= veg_var->fcanopy; - veg_var->Wdew /= veg_var->fcanopy; - veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; - snow->snow_canopy /= veg_var->fcanopy; - - /** Initialize other veg vars **/ - if (iveg < Nveg) { - veg_var->rc = param.HUGE_RESIST; - - /* Carbon-related variables */ - if (options.CARBON) { - for (cidx = 0; cidx < options.Ncanopy; cidx++) { - veg_var->rsLayer[cidx] = param.HUGE_RESIST; - } - veg_var->aPAR = 0; - - calc_Nscale_factors( - vic_run_veg_lib[veg_class].NscaleFlag, - veg_con[iveg].CanopLayerBnd, - veg_var->LAI, - force->coszen[NR], - veg_var->NscaleFactor); - - // TBD: move this outside of vic_run() - if (dmy->day_in_year == 1) { - veg_var->AnnualNPPPrev = veg_var->AnnualNPP; - veg_var->AnnualNPP = 0; - } - } // if options.CARBON - } // if iveg < Nveg - - /* Initialize energy balance variables */ - energy->shortwave = 0; - energy->longwave = 0.; - - /* Initialize snow variables */ - snow->vapor_flux = 0.; - snow->canopy_vapor_flux = 0.; - snow_inflow[band] = 0.; - Melt[band] = 0.; - - /* Initialize precipitation storage */ - out_prec[band] = 0; - out_rain[band] = 0; - out_snow[band] = 0; + // Compute nitrogen scaling factors and initialize other veg vars + if (options.CARBON && iveg < Nveg) { + for (band = 0; band < Nbands; band++) { + for (cidx = 0; cidx < options.Ncanopy; cidx++) { + veg_var[iveg][band].rsLayer[cidx] = param.HUGE_RESIST; + } + veg_var[iveg][band].aPAR = 0; + calc_Nscale_factors( + vic_run_veg_lib[veg_class].NscaleFlag, + veg_con[iveg].CanopLayerBnd, + veg_var[iveg][band].LAI, + force->coszen[NR], + veg_var[iveg][band].NscaleFactor); + // TBD: move this outside of vic_run() + if (dmy->day_in_year == 1) { + veg_var[iveg][band].AnnualNPPPrev = + veg_var[iveg][band].AnnualNPP; + veg_var[iveg][band].AnnualNPP = 0; + } + } + } - /****************************** - Solve ground surface fluxes - ******************************/ + /****************************** + Solve ground surface fluxes + ******************************/ + for (band = 0; band < Nbands; band++) { + if (soil_con->AreaFract[band] > 0) { lag_one = veg_con[iveg].lag_one; sigma_slope = veg_con[iveg].sigma_slope; fetch = veg_con[iveg].fetch; + /* Initialize pot_evap */ + cell[iveg][band].pot_evap = 0; + ErrorFlag = surface_fluxes(overstory, bare_albedo, - ice0, moist0, surf_atten, - &(Melt[band]), &Le, aero_resist, + ice0[band], moist0[band], + surf_atten, &(Melt[band * 2]), + &Le, + aero_resist, displacement, gauge_correction, - &out_prec[band], - &out_rain[band], - &out_snow[band], + &out_prec[band * 2], + &out_rain[band * 2], + &out_snow[band * 2], ref_height, roughness, &snow_inflow[band], tmp_wind, veg_con[iveg].root, options.Nlayer, Nveg, band, dp, iveg, veg_class, force, dmy, - energy, gp, cell, snow, - soil_con, veg_var, lag_one, - sigma_slope, fetch, + &(energy[iveg][band]), gp, + &(cell[iveg][band]), + &(snow[iveg][band]), + soil_con, &(veg_var[iveg][band]), + lag_one, sigma_slope, fetch, veg_con[iveg].CanopLayerBnd); if (ErrorFlag == ERROR) { @@ -341,41 +346,46 @@ vic_run(force_data_struct *force, } force->out_prec += - out_prec[band] * Cv * soil_con->AreaFract[band]; + out_prec[band * 2] * Cv * soil_con->AreaFract[band]; force->out_rain += - out_rain[band] * Cv * soil_con->AreaFract[band]; + out_rain[band * 2] * Cv * soil_con->AreaFract[band]; force->out_snow += - out_snow[band] * Cv * soil_con->AreaFract[band]; + out_snow[band * 2] * Cv * soil_con->AreaFract[band]; /******************************************************** Compute soil wetness and root zone soil moisture ********************************************************/ - cell->rootmoist = 0; - cell->wetness = 0; - for (l = 0; l < options.Nlayer; l++) { - if (veg_con[iveg].root[l] > 0) { - cell->rootmoist += cell->layer[l].moist; + cell[iveg][band].rootmoist = 0; + cell[iveg][band].wetness = 0; + for (lidx = 0; lidx < options.Nlayer; lidx++) { + if (veg_con[iveg].root[lidx] > 0) { + cell[iveg][band].rootmoist += + cell[iveg][band].layer[lidx].moist; } - cell->wetness += - (cell->layer[l].moist - soil_con->Wpwp[l]) / - (soil_con->porosity[l] * soil_con->depth[l] * - MM_PER_M - soil_con->Wpwp[l]); + cell[iveg][band].wetness += + (cell[iveg][band].layer[lidx].moist - + soil_con->Wpwp[lidx]) / + (soil_con->porosity[lidx] * soil_con->depth[lidx] * + MM_PER_M - soil_con->Wpwp[lidx]); } - cell->wetness /= options.Nlayer; - - /* Convert LAI back to global */ - veg_var->LAI *= veg_var->fcanopy; - veg_var->Wdmax *= veg_var->fcanopy; + cell[iveg][band].wetness /= options.Nlayer; } /** End non-zero area band **/ } /** End Loop Through Elevation Bands **/ } /** end non-zero area veg tile **/ } /** end of vegetation loop **/ + /* Convert LAI back to global */ + for (iveg = 0; iveg < Nveg; iveg++) { + for (band = 0; band < Nbands; band++) { + veg_var[iveg][band].LAI *= veg_var[iveg][band].fcanopy; + veg_var[iveg][band].Wdmax *= veg_var[iveg][band].fcanopy; + } + } + // Compute gridcell-averaged albedo calc_gridcell_avg_albedo(&all_vars->gridcell_avg.avg_albedo, force->shortwave[NR], Nveg, overstory, - all_vars->energy, all_vars->snow, veg_con, - soil_con); + energy, snow, veg_con, soil_con); /**************************** Run Lake Model @@ -401,23 +411,23 @@ vic_run(force_data_struct *force, // Loop through snow elevation bands for (band = 0; band < Nbands; band++) { if (soil_con->AreaFract[band] > 0) { - /* Set local pointers */ - cell = &(all_vars->cell[iveg][band]); if (veg_con[iveg].LAKE) { - wetland_runoff += (cell->runoff * Cv * - soil_con->AreaFract[band]); - wetland_baseflow += (cell->baseflow * Cv * + wetland_runoff += (cell[iveg][band].runoff * + Cv * soil_con->AreaFract[band]); + wetland_baseflow += (cell[iveg][band].baseflow * + Cv * soil_con->AreaFract[band]); - cell->runoff = 0; - cell->baseflow = 0; + cell[iveg][band].runoff = 0; + cell[iveg][band].baseflow = 0; } else { - sum_runoff += (cell->runoff * Cv * - soil_con->AreaFract[band]); - sum_baseflow += (cell->baseflow * Cv * - soil_con->AreaFract[band]); - cell->runoff *= (1 - lake_con->rpercent); - cell->baseflow *= (1 - lake_con->rpercent); + sum_runoff += (cell[iveg][band].runoff * + Cv * soil_con->AreaFract[band]); + sum_baseflow += (cell[iveg][band].baseflow * + Cv * soil_con->AreaFract[band]); + cell[iveg][band].runoff *= (1 - lake_con->rpercent); + cell[iveg][band].baseflow *= + (1 - lake_con->rpercent); } } } @@ -478,11 +488,5 @@ vic_run(force_data_struct *force, } } // end if (options.LAKES && lake_con->lake_idx >= 0) - free((char *) (out_prec)); - free((char *) (out_rain)); - free((char *) (out_snow)); - free((char *) (Melt)); - free((char *) (snow_inflow)); - return (0); } From 4ec3e4fd9079682bb43d207673e7d4f4a99ba0af Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Wed, 17 Jan 2018 10:10:09 +0100 Subject: [PATCH 258/294] fixed little bug --- vic/drivers/image/src/vic_force.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/drivers/image/src/vic_force.c b/vic/drivers/image/src/vic_force.c index 033a9f057..4b879b61f 100644 --- a/vic/drivers/image/src/vic_force.c +++ b/vic/drivers/image/src/vic_force.c @@ -245,7 +245,7 @@ vic_force(void) if (mpi_rank == VIC_MPI_ROOT) { // Close forcing file if it is the last time step - if (current == global_param.nrecs) { + if (current == global_param.nrecs - 1) { status = nc_close(filenames.forcing[0].nc_id); check_nc_status(status, "Error closing %s", filenames.forcing[0].nc_filename); @@ -377,7 +377,7 @@ vic_force(void) if (mpi_rank == VIC_MPI_ROOT) { // Close forcing file if it is the last time step - if (current == global_param.nrecs) { + if (current == global_param.nrecs - 1) { status = nc_close(filenames.forcing[1].nc_id); check_nc_status(status, "Error closing %s", filenames.forcing[1].nc_filename); From 524ee952927ac0c61c2c6d76a195cf4e87400718 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 18 Jan 2018 14:50:14 -0500 Subject: [PATCH 259/294] move MAX_ITER_GRND_CANOPY parameter update to initialize_parameters.c in shared_all from surface_fluxes.c in vic_run --- vic/drivers/shared_all/src/initialize_parameters.c | 9 ++++++++- vic/vic_run/src/surface_fluxes.c | 5 ----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index b677f9f69..cb00aec7f 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -33,6 +33,7 @@ void initialize_parameters() { extern parameters_struct param; + extern option_struct options; // Initialize temporary parameters // Lapse Rate @@ -212,7 +213,13 @@ initialize_parameters() param.FROZEN_MAXITER = 1000; // Canopy Iterations - param.MAX_ITER_GRND_CANOPY = 10; + if (options.CLOSE_ENERGY) { + // iterate to close energy balance + param.MAX_ITER_GRND_CANOPY = 10; + } + else { + param.MAX_ITER_GRND_CANOPY = 0; + } // Newton-Raphson solver parameters param.NEWT_RAPH_MAXTRIAL = 150; diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index 12f4a9140..274f73dd3 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -224,11 +224,6 @@ surface_fluxes(bool overstory, double store_Raut; double store_NPP; - if (!options.CLOSE_ENERGY) { - // if not closing energy balance, don't iterate - param.MAX_ITER_GRND_CANOPY = 0; - } - if (options.CARBON) { store_gsLayer = calloc(options.Ncanopy, sizeof(*store_gsLayer)); check_alloc_status(store_gsLayer, "Memory allocation error."); From 07e4601b89d32e22edcbc5171ebbbd44cd586b6e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 18 Jan 2018 14:41:13 -0800 Subject: [PATCH 260/294] ran uncrustify --- vic/drivers/shared_all/src/initialize_parameters.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index cb00aec7f..0a3b3c4ff 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -33,7 +33,7 @@ void initialize_parameters() { extern parameters_struct param; - extern option_struct options; + extern option_struct options; // Initialize temporary parameters // Lapse Rate @@ -218,7 +218,7 @@ initialize_parameters() param.MAX_ITER_GRND_CANOPY = 10; } else { - param.MAX_ITER_GRND_CANOPY = 0; + param.MAX_ITER_GRND_CANOPY = 0; } // Newton-Raphson solver parameters From cc03ff7a50658f69e8a10142dc3979bc8616ad48 Mon Sep 17 00:00:00 2001 From: Wietse Franssen Date: Mon, 22 Jan 2018 08:49:49 +0100 Subject: [PATCH 261/294] added a note --- docs/Development/ReleaseNotes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 2e6068ee5..af8214d62 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -131,6 +131,8 @@ To check which release of VIC you are running: 1. Renamed "fcov" to "fcan" in image driver to better match variable code name ([GH#673](https://github.com/UW-Hydro/VIC/pull/673)) +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)) + ------------------------------ ## VIC 5.0.1 From 848e13ad093e3d93c6de5694d919937a06a63d26 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 14:08:37 -0800 Subject: [PATCH 262/294] initial cleanup of ground flux from the snowpack equation --- vic/vic_run/src/SnowPackEnergyBalance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 96a96b6e4..0ee6ad73b 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -250,8 +250,8 @@ SnowPackEnergyBalance(double TSurf, /* Calculate Ground Heat Flux */ if (SnowDepth > 0.) { - *GroundFlux = 2.9302e-6 * SnowDensity * SnowDensity * - (TGrnd - TMean) / SnowDepth / (Dt); + *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * + (TGrnd - TMean) * Dt / SnowDepth; } else { *GroundFlux = 0; From 1ec05b14e927b8cf2601dcdd9127ecc2da38205e Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 14:10:27 -0800 Subject: [PATCH 263/294] remove unnecessary parentheses from Dt terms --- vic/vic_run/src/SnowPackEnergyBalance.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 0ee6ad73b..236a01967 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -238,7 +238,7 @@ SnowPackEnergyBalance(double TSurf, Equation 7.3.12 from H.B.H. for rain falling on melting snowpack */ if (TMean == 0.) { - *AdvectedEnergy = (CONST_CPFW * CONST_RHOFW * (Tair) * Rain) / (Dt); + *AdvectedEnergy = (CONST_CPFW * CONST_RHOFW * (Tair) * Rain) / Dt; } else { *AdvectedEnergy = 0.; @@ -246,7 +246,7 @@ SnowPackEnergyBalance(double TSurf, /* Calculate change in cold content */ *DeltaColdContent = CONST_VCPICE_WQ * SweSurfaceLayer * - (TSurf - OldTSurf) / (Dt); + (TSurf - OldTSurf) / Dt; /* Calculate Ground Heat Flux */ if (SnowDepth > 0.) { @@ -263,7 +263,7 @@ SnowPackEnergyBalance(double TSurf, *AdvectedEnergy + *GroundFlux - *DeltaColdContent + *AdvectedSensibleHeat; - *RefreezeEnergy = (SurfaceLiquidWater * CONST_LATICE * Density) / (Dt); + *RefreezeEnergy = (SurfaceLiquidWater * CONST_LATICE * Density) / Dt; if (TSurf == 0.0 && RestTerm > -(*RefreezeEnergy)) { *RefreezeEnergy = -RestTerm; /* available energy input over cold content From 6ff7765e1f6c40d918a95d3e8694d550c7be1934 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 16:22:23 -0800 Subject: [PATCH 264/294] add comment to explain reference for ground flux equation --- vic/vic_run/src/SnowPackEnergyBalance.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 236a01967..74e91dbb8 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -2,6 +2,10 @@ * @section DESCRIPTION * * Calculate snow pack energy balance + * + * Based on the SnowPackEnergyBalance function in DHSVM + * Reference: Bras, R.A., Hydrology, an introduction to hydrologic science, + * Addison Wesley, Inc., Reading, etc., 1990. * * @section LICENSE * From ad5d9287d7980b073786a3f2c0b5ea0bab5b5592 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 16:28:12 -0800 Subject: [PATCH 265/294] add new snow density cap to prevent Hedstrom and Pomeroy 1998 equation from blowing up --- vic/vic_run/src/snow_utility.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 8f8fb83f1..818bdb2a9 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -235,6 +235,15 @@ new_snow_density(double air_temp) log_err("Unknown SNOW_DENSITY option"); } + // cap new snow density to prevent the calculation from + // becoming unphysical + // maximum snow density based on Warren et al. 1999, + // Bormann et al. 2013, and Maidment's Handbook of Hydrology + // Figure 7.2.3 + if (density_new > 500.) { + density_new = 500.0; + } + return (density_new); } From ba6387d544e435d33c48ee9a3e73bb037448d7d2 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 16:54:32 -0800 Subject: [PATCH 266/294] pull max new snow density out of snow_utility and put in parameters struct --- docs/Documentation/Constants.md | 1 + vic/drivers/cesm/bld/vic.constants.txt | 1 + vic/drivers/shared_all/src/get_parameters.c | 7 +++++++ vic/drivers/shared_all/src/initialize_parameters.c | 1 + vic/drivers/shared_all/src/print_library_shared.c | 2 ++ vic/drivers/shared_image/src/vic_mpi_support.c | 2 +- vic/vic_run/include/vic_def.h | 1 + vic/vic_run/src/snow_utility.c | 9 +++------ 8 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/Documentation/Constants.md b/docs/Documentation/Constants.md index 27fffda65..9bb6c1aab 100644 --- a/docs/Documentation/Constants.md +++ b/docs/Documentation/Constants.md @@ -111,6 +111,7 @@ The table below lists the constants available for manipulation via the `CONSTANT | SNOW_MAX_SURFACE_SWE | | | SNOW_LIQUID_WATER_CAPACITY | | | SNOW_NEW_SNOW_DENSITY | | +| SNOW_NEW_SNOW_DENS_MAX | | | SNOW_DENS_DMLIMIT | | | SNOW_DENS_DMLIMIT_FACTOR | | | SNOW_DENS_MAX_CHANGE | | diff --git a/vic/drivers/cesm/bld/vic.constants.txt b/vic/drivers/cesm/bld/vic.constants.txt index c9350bafc..80f3337bf 100644 --- a/vic/drivers/cesm/bld/vic.constants.txt +++ b/vic/drivers/cesm/bld/vic.constants.txt @@ -122,6 +122,7 @@ # SNOW_MAX_SURFACE_SWE 0.125 # SNOW_LIQUID_WATER_CAPACITY 0.035 # SNOW_NEW_SNOW_DENSITY 50.0 +# SNOW_NEW_SNOW_DENS_MAX 500.0 # SNOW_DENS_DMLIMIT 100.0 # SNOW_DENS_MAX_CHANGE 0.9 # SNOW_DENS_ETA0 3.6e6 diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index 45b8aa6f4..ade58b86d 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -326,6 +326,9 @@ get_parameters(FILE *paramfile) else if (strcasecmp("SNOW_NEW_SNOW_DENSITY", optstr) == 0) { sscanf(cmdstr, "%*s %lf", ¶m.SNOW_NEW_SNOW_DENSITY); } + else if (strcasecmp("SNOW_NEW_SNOW_DENS_MAX", optstr) == 0) { + sscanf(cmdstr, "%*s %lf", ¶m.SNOW_NEW_SNOW_DENS_MAX); + } else if (strcasecmp("SNOW_DENS_DMLIMIT", optstr) == 0) { sscanf(cmdstr, "%*s %lf", ¶m.SNOW_DENS_DMLIMIT); } @@ -758,6 +761,10 @@ validate_parameters() log_err( "SNOW_DENS_DMLIMIT must be defined on the interval [0, inf) (kg/m^3)"); } + if (!(param.SNOW_NEW_SNOW_DENS_MAX >= 700.)) { + log_err( + "SNOW_NEW_SNOW_DENS_MAX must be defined on the interval [0, 700) (kg/m^3)"); + } if (!(param.SNOW_DENS_MAX_CHANGE >= 0 && param.SNOW_DENS_MAX_CHANGE <= 1)) { log_err("SNOW_DENS_MAX_CHANGE must be defined on the interval [0,1] (-)") } diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index 1add5498d..f668e1907 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -150,6 +150,7 @@ initialize_parameters() param.SNOW_MAX_SURFACE_SWE = 0.125; param.SNOW_LIQUID_WATER_CAPACITY = 0.035; param.SNOW_NEW_SNOW_DENSITY = 50.0; + param.SNOW_NEW_SNOW_DENS_MAX = 500.0; param.SNOW_DENS_DMLIMIT = 100.0; param.SNOW_DENS_DMLIMIT_FACTOR = 1.15; param.SNOW_DENS_MAX_CHANGE = 0.9; diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index ef9efdeaa..635f6bd89 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -753,6 +753,8 @@ print_parameters(parameters_struct *param) param->SNOW_LIQUID_WATER_CAPACITY); fprintf(LOG_DEST, "\tSNOW_NEW_SNOW_DENSITY: %.4f\n", param->SNOW_NEW_SNOW_DENSITY); + fprintf(LOG_DEST, "\tSNOW_NEW_SNOW_DENS_MAX: %.4f\n", + param->SNOW_NEW_SNOW_DENS_MAX); fprintf(LOG_DEST, "\tSNOW_DENS_DMLIMIT: %.4f\n", param->SNOW_DENS_DMLIMIT); fprintf(LOG_DEST, "\tSNOW_DENS_MAX_CHANGE: %.4f\n", param->SNOW_DENS_MAX_CHANGE); diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index ed92f10fc..2f24240d7 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -755,7 +755,7 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in parameters_struct - nitems = 153; + nitems = 154; blocklengths = malloc(nitems * sizeof(*blocklengths)); check_alloc_status(blocklengths, "Memory allocation error."); diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index 184ede176..86618cb07 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -457,6 +457,7 @@ typedef struct { double SNOW_MAX_SURFACE_SWE; /**< maximum depth of the surface layer in water equivalent (m) */ double SNOW_LIQUID_WATER_CAPACITY; /**< water holding capacity of snow as a fraction of snow-water-equivalent */ double SNOW_NEW_SNOW_DENSITY; /**< density of new fallen snow */ + double SNOW_NEW_SNOW_DENS_MAX; /**< new snow density max for Hedstrom and Pomeroy 1998 equation [Warren et al. 1999, Bormann et al. 2013, Maidment Figure 7.2.3] */ double SNOW_DENS_DMLIMIT; /**< Density limit used in calculation of destructive metamorphism (kg/m^3) */ double SNOW_DENS_DMLIMIT_FACTOR; /**< Density limit factor used in calculation of destructive metamorphism (kg/m^3) */ double SNOW_DENS_MAX_CHANGE; /**< maximum change in snowfall depth (fraction of swe) */ diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 818bdb2a9..18f41bfa9 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -236,12 +236,9 @@ new_snow_density(double air_temp) } // cap new snow density to prevent the calculation from - // becoming unphysical - // maximum snow density based on Warren et al. 1999, - // Bormann et al. 2013, and Maidment's Handbook of Hydrology - // Figure 7.2.3 - if (density_new > 500.) { - density_new = 500.0; + // becoming unphysical + if (density_new > param.SNOW_NEW_SNOW_DENS_MAX.) { + density_new = param.SNOW_NEW_SNOW_DENS_MAX; } return (density_new); From 6b050172aece82eb5f7f41e751a7eaccb35c4751 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 16:56:06 -0800 Subject: [PATCH 267/294] update ground flux out of the snowpack calculation --- vic/vic_run/src/SnowPackEnergyBalance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 74e91dbb8..45a74983f 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -253,7 +253,7 @@ SnowPackEnergyBalance(double TSurf, (TSurf - OldTSurf) / Dt; /* Calculate Ground Heat Flux */ - if (SnowDepth > 0.) { + if (SnowDepth > DBL_EPSILON) { *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * (TGrnd - TMean) * Dt / SnowDepth; } From 02c87f585b83e2fcafa660f5c72815e847f3762c Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 20:12:34 -0500 Subject: [PATCH 268/294] fix typo --- vic/vic_run/src/snow_utility.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 18f41bfa9..06e927a49 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -237,7 +237,7 @@ new_snow_density(double air_temp) // cap new snow density to prevent the calculation from // becoming unphysical - if (density_new > param.SNOW_NEW_SNOW_DENS_MAX.) { + if (density_new > param.SNOW_NEW_SNOW_DENS_MAX) { density_new = param.SNOW_NEW_SNOW_DENS_MAX; } From 63adf278aa854fcd0e5b4c8f57e913f9ee5be718 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Tue, 30 Jan 2018 21:40:33 -0500 Subject: [PATCH 269/294] add necessary mpi code --- vic/drivers/shared_image/src/vic_mpi_support.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 2f24240d7..07e147fc6 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -1133,6 +1133,10 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(parameters_struct, SNOW_NEW_SNOW_DENSITY); mpi_types[i++] = MPI_DOUBLE; + // double SNOW_NEW_SNOW_DENS_MAX + offsets[i] = offsetof(parameters_struct, SNOW_NEW_SNOW_DENS_MAX); + mpi_types[i++] = MPI_DOUBLE; + // double SNOW_DENS_DMLIMIT offsets[i] = offsetof(parameters_struct, SNOW_DENS_DMLIMIT); mpi_types[i++] = MPI_DOUBLE; From 03aed70bda7eb46d43b88e6ab414a1eb36c97067 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 31 Jan 2018 19:56:18 -0500 Subject: [PATCH 270/294] further update to groundflux eqtn --- vic/drivers/shared_all/src/get_parameters.c | 2 +- vic/drivers/shared_all/src/initialize_parameters.c | 2 +- vic/vic_run/src/SnowPackEnergyBalance.c | 6 ++++-- vic/vic_run/src/snow_utility.c | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index ade58b86d..b4d31559e 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -761,7 +761,7 @@ validate_parameters() log_err( "SNOW_DENS_DMLIMIT must be defined on the interval [0, inf) (kg/m^3)"); } - if (!(param.SNOW_NEW_SNOW_DENS_MAX >= 700.)) { + if (!(param.SNOW_NEW_SNOW_DENS_MAX >= 0. && param.SNOW_NEW_SNOW_DENS_MAX <= 700.)) { log_err( "SNOW_NEW_SNOW_DENS_MAX must be defined on the interval [0, 700) (kg/m^3)"); } diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index f668e1907..62ad30071 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -150,7 +150,7 @@ initialize_parameters() param.SNOW_MAX_SURFACE_SWE = 0.125; param.SNOW_LIQUID_WATER_CAPACITY = 0.035; param.SNOW_NEW_SNOW_DENSITY = 50.0; - param.SNOW_NEW_SNOW_DENS_MAX = 500.0; + param.SNOW_NEW_SNOW_DENS_MAX = 400.0; param.SNOW_DENS_DMLIMIT = 100.0; param.SNOW_DENS_DMLIMIT_FACTOR = 1.15; param.SNOW_DENS_MAX_CHANGE = 0.9; diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 45a74983f..edddb2d39 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -253,9 +253,11 @@ SnowPackEnergyBalance(double TSurf, (TSurf - OldTSurf) / Dt; /* Calculate Ground Heat Flux */ + fprintf(LOG_DEST, "\tSnowDepth = %f\n", SnowDepth); + fprintf(LOG_DEST, "\tSnowDensity = %f\n", SnowDensity); if (SnowDepth > DBL_EPSILON) { - *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * - (TGrnd - TMean) * Dt / SnowDepth; + *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) + * (TGrnd - TMean) / SnowDepth / Dt; } else { *GroundFlux = 0; diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 06e927a49..4cae5afa9 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -236,11 +236,12 @@ new_snow_density(double air_temp) } // cap new snow density to prevent the calculation from - // becoming unphysical + // becoming unphysical + fprintf(LOG_DEST, "\tdensity_first = %f\n", density_new); if (density_new > param.SNOW_NEW_SNOW_DENS_MAX) { density_new = param.SNOW_NEW_SNOW_DENS_MAX; } - + fprintf(LOG_DEST, "\tdensity_second = %f\n", density_new); return (density_new); } From 2624c90fb7bd2ed09e24ac9f72dfe48dc7064594 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 16:58:32 -0500 Subject: [PATCH 271/294] add epsilon_snow to prevent snow depth from getting too small and root_brent not converging --- vic/vic_run/src/SnowPackEnergyBalance.c | 5 ++--- vic/vic_run/src/snow_utility.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index edddb2d39..dbbfa042f 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -109,6 +109,7 @@ SnowPackEnergyBalance(double TSurf, intercepted snow (kg/m2s) */ double BlowingMassFlux; /* Mass flux of water vapor from blowing snow. (kg/m2s) */ double SurfaceMassFlux; /* Mass flux of water vapor from pack snow. (kg/m2s) */ + double epsilon_snow = 1.e-8; /* Snow depth below which we ignore the ground flux from the snowpack */ /* Assign the elements of the array to the appropriate variables. The list is traversed as if the elements are doubles, because: @@ -253,9 +254,7 @@ SnowPackEnergyBalance(double TSurf, (TSurf - OldTSurf) / Dt; /* Calculate Ground Heat Flux */ - fprintf(LOG_DEST, "\tSnowDepth = %f\n", SnowDepth); - fprintf(LOG_DEST, "\tSnowDensity = %f\n", SnowDensity); - if (SnowDepth > DBL_EPSILON) { + if (SnowDepth > epsilon_snow) { *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * (TGrnd - TMean) / SnowDepth / Dt; } diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 4cae5afa9..188e51617 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -237,11 +237,10 @@ new_snow_density(double air_temp) // cap new snow density to prevent the calculation from // becoming unphysical - fprintf(LOG_DEST, "\tdensity_first = %f\n", density_new); if (density_new > param.SNOW_NEW_SNOW_DENS_MAX) { density_new = param.SNOW_NEW_SNOW_DENS_MAX; } - fprintf(LOG_DEST, "\tdensity_second = %f\n", density_new); + return (density_new); } From af5e6316be735e59f080614196efe5f2e494b7b3 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 14:03:07 -0800 Subject: [PATCH 272/294] update mpi parameters struct size after merging in develop branch --- vic/drivers/shared_image/src/vic_mpi_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 6750520b5..3f1bf9ebb 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -755,7 +755,7 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in parameters_struct - nitems = 154; + nitems = 155; blocklengths = malloc(nitems * sizeof(*blocklengths)); check_alloc_status(blocklengths, "Memory allocation error."); From 8c830836da4f206a8f198aec81e249dafcc03781 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 14:04:29 -0800 Subject: [PATCH 273/294] ran uncrustify --- vic/drivers/shared_all/src/get_parameters.c | 3 ++- vic/vic_run/src/SnowPackEnergyBalance.c | 8 ++++---- vic/vic_run/src/snow_utility.c | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index def747e61..de65e02ba 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -765,7 +765,8 @@ validate_parameters() log_err( "SNOW_DENS_DMLIMIT must be defined on the interval [0, inf) (kg/m^3)"); } - if (!(param.SNOW_NEW_SNOW_DENS_MAX >= 0. && param.SNOW_NEW_SNOW_DENS_MAX <= 700.)) { + if (!(param.SNOW_NEW_SNOW_DENS_MAX >= 0. && + param.SNOW_NEW_SNOW_DENS_MAX <= 700.)) { log_err( "SNOW_NEW_SNOW_DENS_MAX must be defined on the interval [0, 700) (kg/m^3)"); } diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index dbbfa042f..3bcfc6ac6 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -2,9 +2,9 @@ * @section DESCRIPTION * * Calculate snow pack energy balance - * + * * Based on the SnowPackEnergyBalance function in DHSVM - * Reference: Bras, R.A., Hydrology, an introduction to hydrologic science, + * Reference: Bras, R.A., Hydrology, an introduction to hydrologic science, * Addison Wesley, Inc., Reading, etc., 1990. * * @section LICENSE @@ -255,8 +255,8 @@ SnowPackEnergyBalance(double TSurf, /* Calculate Ground Heat Flux */ if (SnowDepth > epsilon_snow) { - *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) - * (TGrnd - TMean) / SnowDepth / Dt; + *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * + (TGrnd - TMean) / SnowDepth / Dt; } else { *GroundFlux = 0; diff --git a/vic/vic_run/src/snow_utility.c b/vic/vic_run/src/snow_utility.c index 188e51617..7bc91e39b 100644 --- a/vic/vic_run/src/snow_utility.c +++ b/vic/vic_run/src/snow_utility.c @@ -235,8 +235,8 @@ new_snow_density(double air_temp) log_err("Unknown SNOW_DENSITY option"); } - // cap new snow density to prevent the calculation from - // becoming unphysical + // cap new snow density to prevent the calculation from + // becoming unphysical if (density_new > param.SNOW_NEW_SNOW_DENS_MAX) { density_new = param.SNOW_NEW_SNOW_DENS_MAX; } From fc5f1d6f98e0c4ed15c964f647338e7a35e619c2 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 14:13:44 -0800 Subject: [PATCH 274/294] add release notes entry --- docs/Development/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 59637c99d..4b772541b 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -115,6 +115,10 @@ To check which release of VIC you are running: Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. +10. Updated new snow density function by adding a cap to new snow density that is set in the parameters struct by the parameter SNOW_NEW_SNOW_DENS_MAX + + Previously the change in cold content of the snowpack term (deltaCC in the snow_data_struct) would get unreasonably large if the Hedstrom and Pomeroy 1998 equation used to calculate snow density, which depends only on air temperature, was calculated with air temperatures above about 2 deg C. We use this term to calculate the ground flux from the snowpack and snow depth, which resulted in extremely small snow depths and unreasonably large ground fluxes from the snowpack (and thus changes in snowpack cold content). Now there is a cap on new snow density with the new parameter SNOW_NEW_SNOW_DENS_MAX as well as a snow depth below which we disregard the ground flux from the snowpack (1.e-8). + 10. Miscellaneous clean-up: [GH#723](https://github.com/UW-Hydro/VIC/pull/723) From e0393026938eaf60fff0587e1e6fc716d463dd47 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 14:28:06 -0800 Subject: [PATCH 275/294] update cesm bld constants --- vic/drivers/cesm/bld/vic.constants.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/drivers/cesm/bld/vic.constants.txt b/vic/drivers/cesm/bld/vic.constants.txt index 0de132492..c4c059b51 100644 --- a/vic/drivers/cesm/bld/vic.constants.txt +++ b/vic/drivers/cesm/bld/vic.constants.txt @@ -122,7 +122,7 @@ # SNOW_MAX_SURFACE_SWE 0.125 # SNOW_LIQUID_WATER_CAPACITY 0.035 # SNOW_NEW_SNOW_DENSITY 50.0 -# SNOW_NEW_SNOW_DENS_MAX 500.0 +# SNOW_NEW_SNOW_DENS_MAX 400.0 # SNOW_DENS_DMLIMIT 100.0 # SNOW_DENS_MAX_CHANGE 0.9 # SNOW_DENS_ETA0 3.6e6 From b13c37617f91739db533db5a5ac53852b2835a45 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 1 Feb 2018 14:31:52 -0800 Subject: [PATCH 276/294] add PR # to release notes entry --- docs/Development/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 4b772541b..a8d198979 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -115,7 +115,7 @@ To check which release of VIC you are running: Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. -10. Updated new snow density function by adding a cap to new snow density that is set in the parameters struct by the parameter SNOW_NEW_SNOW_DENS_MAX +10. Updated new snow density function by adding a cap to new snow density that is set in the parameters struct by the parameter SNOW_NEW_SNOW_DENS_MAX ([GH#776](https://github.com/UW-Hydro/VIC/pull/776)) Previously the change in cold content of the snowpack term (deltaCC in the snow_data_struct) would get unreasonably large if the Hedstrom and Pomeroy 1998 equation used to calculate snow density, which depends only on air temperature, was calculated with air temperatures above about 2 deg C. We use this term to calculate the ground flux from the snowpack and snow depth, which resulted in extremely small snow depths and unreasonably large ground fluxes from the snowpack (and thus changes in snowpack cold content). Now there is a cap on new snow density with the new parameter SNOW_NEW_SNOW_DENS_MAX as well as a snow depth below which we disregard the ground flux from the snowpack (1.e-8). From 40bd7719aba552efb091209646f9eeb35504da4b Mon Sep 17 00:00:00 2001 From: ted Date: Fri, 2 Feb 2018 16:46:11 -0700 Subject: [PATCH 277/294] Fixed problem with nans caused by location of global to local conversion. --- vic/vic_run/src/vic_run.c | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 40067213c..5aac937e2 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -180,15 +180,8 @@ vic_run(force_data_struct *force, } } - /* local pointer to veg_var and snow */ + /* local pointer to veg_var */ veg_var = &(all_vars->veg_var[iveg][0]); - snow = &(all_vars->snow[iveg][0]); - - // Convert LAI from global to local - veg_var->LAI /= veg_var->fcanopy; - veg_var->Wdew /= veg_var->fcanopy; - veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; - snow->snow_canopy /= veg_var->fcanopy; /** Assign wind_h **/ /** Note: this is ignored below **/ @@ -230,20 +223,6 @@ vic_run(force_data_struct *force, return (ERROR); } - /** Compute Surface Attenuation due to Vegetation Coverage **/ - surf_atten = (1 - veg_var->fcanopy) * 1.0 + - veg_var->fcanopy * - exp(-vic_run_veg_lib[veg_class].rad_atten * - veg_var->LAI); - - /** Compute Bare (free of snow) Albedo **/ - if (iveg != Nveg) { - bare_albedo = veg_var->albedo; - } - else { - bare_albedo = param.ALBEDO_BARE_SOIL; - } - /************************************************** Loop over elevation bands **************************************************/ @@ -257,11 +236,31 @@ vic_run(force_data_struct *force, snow = &(all_vars->snow[iveg][band]); energy = &(all_vars->energy[iveg][band]); + // Convert LAI from global to local + veg_var->LAI /= veg_var->fcanopy; + veg_var->Wdew /= veg_var->fcanopy; + veg_var->Wdmax = veg_var->LAI * param.VEG_LAI_WATER_FACTOR; + snow->snow_canopy /= veg_var->fcanopy; + /****************************************** Initialize Band-dependent Model Parameters ******************************************/ - /* Initialize soil thermal properties for the top two layers */ + /** Surface Attenuation due to Vegetation Coverage **/ + surf_atten = (1 - veg_var->fcanopy) * 1.0 + + veg_var->fcanopy * + exp(-vic_run_veg_lib[veg_class].rad_atten * + veg_var->LAI); + + /** Bare (free of snow) Albedo **/ + if (iveg != Nveg) { + bare_albedo = veg_var->albedo; + } + else { + bare_albedo = param.ALBEDO_BARE_SOIL; + } + + /* Soil thermal properties for the top two layers */ prepare_full_energy(cell, energy, soil_con, &moist0, &ice0); /* Initialize final aerodynamic resistance values */ From 8362a339fe4a6ec45c90e146bcbcd800a504076c Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 7 Feb 2018 12:24:09 -0800 Subject: [PATCH 278/294] update to add snow depth threshold as a parameter --- docs/Documentation/Constants.md | 1 + vic/drivers/shared_all/src/get_parameters.c | 7 +++++++ vic/drivers/shared_all/src/initialize_parameters.c | 1 + vic/drivers/shared_all/src/print_library_shared.c | 2 ++ vic/drivers/shared_image/src/vic_mpi_support.c | 6 +++++- vic/vic_run/include/vic_def.h | 1 + vic/vic_run/src/SnowPackEnergyBalance.c | 3 +-- 7 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/Documentation/Constants.md b/docs/Documentation/Constants.md index 0bc43dd50..b57f67f90 100644 --- a/docs/Documentation/Constants.md +++ b/docs/Documentation/Constants.md @@ -112,6 +112,7 @@ The table below lists the constants available for manipulation via the `CONSTANT | SNOW_LIQUID_WATER_CAPACITY | | | SNOW_NEW_SNOW_DENSITY | | | SNOW_NEW_SNOW_DENS_MAX | | +| SNOW_DEPTH_THRES | | | SNOW_DENS_DMLIMIT | | | SNOW_DENS_DMLIMIT_FACTOR | | | SNOW_DENS_MAX_CHANGE | | diff --git a/vic/drivers/shared_all/src/get_parameters.c b/vic/drivers/shared_all/src/get_parameters.c index de65e02ba..2fb271627 100644 --- a/vic/drivers/shared_all/src/get_parameters.c +++ b/vic/drivers/shared_all/src/get_parameters.c @@ -329,6 +329,9 @@ get_parameters(FILE *paramfile) else if (strcasecmp("SNOW_NEW_SNOW_DENS_MAX", optstr) == 0) { sscanf(cmdstr, "%*s %lf", ¶m.SNOW_NEW_SNOW_DENS_MAX); } + else if (strcasecmp("SNOW_NEW_SNOW_DENS_MAX", optstr) == 0) { + sscanf(cmdstr, "%*s %lf", ¶m.SNOW_NEW_SNOW_DENS_MAX); + } else if (strcasecmp("SNOW_DENS_DMLIMIT", optstr) == 0) { sscanf(cmdstr, "%*s %lf", ¶m.SNOW_DENS_DMLIMIT); } @@ -761,6 +764,10 @@ validate_parameters() log_err( "SNOW_NEW_SNOW_DENSITY must be defined on the interval [0, inf) (kg/m^3)"); } + if (!(param.SNOW_DEPTH_THRES >= 0.)) { + log_err( + "SNOW_DEPTH_THRES must be defined on the interval [0, inf) (m)"); + } if (!(param.SNOW_DENS_DMLIMIT >= 0.)) { log_err( "SNOW_DENS_DMLIMIT must be defined on the interval [0, inf) (kg/m^3)"); diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index e7d4058f8..65ee8c7b5 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -152,6 +152,7 @@ initialize_parameters() param.SNOW_LIQUID_WATER_CAPACITY = 0.035; param.SNOW_NEW_SNOW_DENSITY = 50.0; param.SNOW_NEW_SNOW_DENS_MAX = 400.0; + param.SNOW_DEPTH_THRES = 1.e-8; param.SNOW_DENS_DMLIMIT = 100.0; param.SNOW_DENS_DMLIMIT_FACTOR = 1.15; param.SNOW_DENS_MAX_CHANGE = 0.9; diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index 1d386625a..be48bd09d 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -755,6 +755,8 @@ print_parameters(parameters_struct *param) param->SNOW_NEW_SNOW_DENSITY); fprintf(LOG_DEST, "\tSNOW_NEW_SNOW_DENS_MAX: %.4f\n", param->SNOW_NEW_SNOW_DENS_MAX); + fprintf(LOG_DEST, "\tSNOW_DEPTH_THRES: %.12f\n", + param->SNOW_DEPTH_THRES); fprintf(LOG_DEST, "\tSNOW_DENS_DMLIMIT: %.4f\n", param->SNOW_DENS_DMLIMIT); fprintf(LOG_DEST, "\tSNOW_DENS_MAX_CHANGE: %.4f\n", param->SNOW_DENS_MAX_CHANGE); diff --git a/vic/drivers/shared_image/src/vic_mpi_support.c b/vic/drivers/shared_image/src/vic_mpi_support.c index 3f1bf9ebb..761a77d16 100644 --- a/vic/drivers/shared_image/src/vic_mpi_support.c +++ b/vic/drivers/shared_image/src/vic_mpi_support.c @@ -755,7 +755,7 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) MPI_Datatype *mpi_types; // nitems has to equal the number of elements in parameters_struct - nitems = 155; + nitems = 156; blocklengths = malloc(nitems * sizeof(*blocklengths)); check_alloc_status(blocklengths, "Memory allocation error."); @@ -1137,6 +1137,10 @@ create_MPI_param_struct_type(MPI_Datatype *mpi_type) offsets[i] = offsetof(parameters_struct, SNOW_NEW_SNOW_DENS_MAX); mpi_types[i++] = MPI_DOUBLE; + // double SNOW_DEPTH_THRES + offsets[i] = offsetof(parameters_struct, SNOW_DEPTH_THRES); + mpi_types[i++] = MPI_DOUBLE; + // double SNOW_DENS_DMLIMIT offsets[i] = offsetof(parameters_struct, SNOW_DENS_DMLIMIT); mpi_types[i++] = MPI_DOUBLE; diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index ed1f58e2d..e6ea48473 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -454,6 +454,7 @@ typedef struct { double SNOW_LIQUID_WATER_CAPACITY; /**< water holding capacity of snow as a fraction of snow-water-equivalent */ double SNOW_NEW_SNOW_DENSITY; /**< density of new fallen snow */ double SNOW_NEW_SNOW_DENS_MAX; /**< new snow density max for Hedstrom and Pomeroy 1998 equation [Warren et al. 1999, Bormann et al. 2013, Maidment Figure 7.2.3] */ + double SNOW_DEPTH_THRES; /**< Snow depth threshold below which we do not consider the ground flux out of the snowpack in calculating change in cold content (m) */ double SNOW_DENS_DMLIMIT; /**< Density limit used in calculation of destructive metamorphism (kg/m^3) */ double SNOW_DENS_DMLIMIT_FACTOR; /**< Density limit factor used in calculation of destructive metamorphism (kg/m^3) */ double SNOW_DENS_MAX_CHANGE; /**< maximum change in snowfall depth (fraction of swe) */ diff --git a/vic/vic_run/src/SnowPackEnergyBalance.c b/vic/vic_run/src/SnowPackEnergyBalance.c index 3bcfc6ac6..77b700519 100644 --- a/vic/vic_run/src/SnowPackEnergyBalance.c +++ b/vic/vic_run/src/SnowPackEnergyBalance.c @@ -109,7 +109,6 @@ SnowPackEnergyBalance(double TSurf, intercepted snow (kg/m2s) */ double BlowingMassFlux; /* Mass flux of water vapor from blowing snow. (kg/m2s) */ double SurfaceMassFlux; /* Mass flux of water vapor from pack snow. (kg/m2s) */ - double epsilon_snow = 1.e-8; /* Snow depth below which we ignore the ground flux from the snowpack */ /* Assign the elements of the array to the appropriate variables. The list is traversed as if the elements are doubles, because: @@ -254,7 +253,7 @@ SnowPackEnergyBalance(double TSurf, (TSurf - OldTSurf) / Dt; /* Calculate Ground Heat Flux */ - if (SnowDepth > epsilon_snow) { + if (SnowDepth > param.SNOW_DEPTH_THRES) { *GroundFlux = param.SNOW_CONDUCT * pow(SnowDensity, 2.) * (TGrnd - TMean) / SnowDepth / Dt; } From c5656a01aaaaed113bd3d94c71dfc57c64c6ebd4 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 7 Feb 2018 16:02:18 -0800 Subject: [PATCH 279/294] run uncrustify one more time --- vic/drivers/cesm/bld/vic.constants.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/drivers/cesm/bld/vic.constants.txt b/vic/drivers/cesm/bld/vic.constants.txt index c4c059b51..1ba4496b8 100644 --- a/vic/drivers/cesm/bld/vic.constants.txt +++ b/vic/drivers/cesm/bld/vic.constants.txt @@ -123,6 +123,7 @@ # SNOW_LIQUID_WATER_CAPACITY 0.035 # SNOW_NEW_SNOW_DENSITY 50.0 # SNOW_NEW_SNOW_DENS_MAX 400.0 +# SNOW_DEPTH_THRES 1.e-8 # SNOW_DENS_DMLIMIT 100.0 # SNOW_DENS_MAX_CHANGE 0.9 # SNOW_DENS_ETA0 3.6e6 From abf556cdf09ccbad00e983422a4dc2e8a0b8f05d Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Thu, 15 Feb 2018 14:15:47 -0800 Subject: [PATCH 280/294] initialize MAX_ITER_GRND_CANOPY to default (0) in initialize_parameters and then update in surface_fluxes --- vic/drivers/shared_all/src/initialize_parameters.c | 11 ++--------- vic/vic_run/src/surface_fluxes.c | 9 +++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index 65ee8c7b5..4b1b2db73 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -33,7 +33,6 @@ void initialize_parameters() { extern parameters_struct param; - extern option_struct options; // Initialize temporary parameters // Lapse Rate @@ -214,14 +213,8 @@ initialize_parameters() // Frozen Soil Parameters param.FROZEN_MAXITER = 1000; - // Canopy Iterations - if (options.CLOSE_ENERGY) { - // iterate to close energy balance - param.MAX_ITER_GRND_CANOPY = 10; - } - else { - param.MAX_ITER_GRND_CANOPY = 0; - } + // Canopy Iterations (default is 0) + param.MAX_ITER_GRND_CANOPY = 0; // Newton-Raphson solver parameters param.NEWT_RAPH_MAXTRIAL = 150; diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index afa4018bc..55a7695ab 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -229,6 +229,15 @@ surface_fluxes(bool overstory, check_alloc_status(store_gsLayer, "Memory allocation error."); } + // Canopy Iterations + if (options.CLOSE_ENERGY) { + // iterate to close energy balance + param.MAX_ITER_GRND_CANOPY = 10; + } + else { + param.MAX_ITER_GRND_CANOPY = 0; + } + /*********************************************************************** Set temporary variables for convenience ***********************************************************************/ From 320f6de15dc36fb9bdb98b856344a7608a8c91bc Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 16 Feb 2018 15:13:01 -0500 Subject: [PATCH 281/294] move structure of MAX_ITER_GRND_CANOPY around --- vic/drivers/shared_all/src/initialize_parameters.c | 9 +++++++-- vic/vic_run/src/surface_fluxes.c | 9 --------- vic/vic_run/src/vic_run.c | 7 +++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index 4b1b2db73..00a71d1c6 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -213,8 +213,13 @@ initialize_parameters() // Frozen Soil Parameters param.FROZEN_MAXITER = 1000; - // Canopy Iterations (default is 0) - param.MAX_ITER_GRND_CANOPY = 0; + // Canopy Iterations + // initialized to 10, set to 0 if + // options.CLOSE_ENERGY is false + // this allows for flexibility in + // changing the maximum number of + // iterations + param.MAX_ITER_GRND_CANOPY = 10; // Newton-Raphson solver parameters param.NEWT_RAPH_MAXTRIAL = 150; diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index 55a7695ab..aa17e2644 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -227,15 +227,6 @@ surface_fluxes(bool overstory, if (options.CARBON) { store_gsLayer = calloc(options.Ncanopy, sizeof(*store_gsLayer)); check_alloc_status(store_gsLayer, "Memory allocation error."); - } - - // Canopy Iterations - if (options.CLOSE_ENERGY) { - // iterate to close energy balance - param.MAX_ITER_GRND_CANOPY = 10; - } - else { - param.MAX_ITER_GRND_CANOPY = 0; } /*********************************************************************** diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 5aac937e2..f961a40ec 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -131,6 +131,13 @@ vic_run(force_data_struct *force, gauge_correction[0] = 1; gauge_correction[1] = 1; } + + // Canopy Iterations + if (!options.CLOSE_ENERGY) { + // do not iterate to close energy balance + param.MAX_ITER_GRND_CANOPY = 0; + } + force->out_prec = 0; force->out_rain = 0; force->out_snow = 0; From cb9d03474fbb31e478db733a8d919acc25828795 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 16 Feb 2018 12:17:56 -0800 Subject: [PATCH 282/294] ran uncrustify --- vic/drivers/shared_all/src/initialize_parameters.c | 10 +++++----- vic/vic_run/src/surface_fluxes.c | 2 +- vic/vic_run/src/vic_run.c | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/vic/drivers/shared_all/src/initialize_parameters.c b/vic/drivers/shared_all/src/initialize_parameters.c index 00a71d1c6..680674942 100644 --- a/vic/drivers/shared_all/src/initialize_parameters.c +++ b/vic/drivers/shared_all/src/initialize_parameters.c @@ -213,12 +213,12 @@ initialize_parameters() // Frozen Soil Parameters param.FROZEN_MAXITER = 1000; - // Canopy Iterations - // initialized to 10, set to 0 if + // Canopy Iterations + // initialized to 10, set to 0 if // options.CLOSE_ENERGY is false - // this allows for flexibility in - // changing the maximum number of - // iterations + // this allows for flexibility in + // changing the maximum number of + // iterations param.MAX_ITER_GRND_CANOPY = 10; // Newton-Raphson solver parameters diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index aa17e2644..afa4018bc 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -227,7 +227,7 @@ surface_fluxes(bool overstory, if (options.CARBON) { store_gsLayer = calloc(options.Ncanopy, sizeof(*store_gsLayer)); check_alloc_status(store_gsLayer, "Memory allocation error."); - } + } /*********************************************************************** Set temporary variables for convenience diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index f961a40ec..7160227c1 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -236,7 +236,6 @@ vic_run(force_data_struct *force, for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { - /* Set local pointers */ cell = &(all_vars->cell[iveg][band]); veg_var = &(all_vars->veg_var[iveg][band]); From 7792a1f5ec35629040e33820a754103535c8b8b8 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 16 Feb 2018 17:34:27 -0500 Subject: [PATCH 283/294] move MAX_ITER_GRND_CANOPY out of vic_run and into vic_init for shared image and vic_classic for classic driver --- vic/drivers/classic/src/vic_classic.c | 6 ++++++ vic/drivers/shared_image/src/vic_init.c | 6 ++++++ vic/vic_run/src/surface_fluxes.c | 2 +- vic/vic_run/src/vic_run.c | 6 ------ 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 51be1d43d..73908c8b9 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -163,6 +163,12 @@ main(int argc, filep.statefile = NULL; } + // Canopy Iterations + if (!options.CLOSE_ENERGY) { + // do not iterate to close energy balance + param.MAX_ITER_GRND_CANOPY = 0; + } + /************************************ Run Model for all Active Grid Cells ************************************/ diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 5bd57d410..9289f0c93 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1563,6 +1563,12 @@ vic_init(void) initialize_energy(all_vars[i].energy, nveg); } + // Canopy Iterations + if (!options.CLOSE_ENERGY) { + // do not iterate to close energy balance + param.MAX_ITER_GRND_CANOPY = 0; + } + // set state metadata structure set_state_meta_data_info(); diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index aa17e2644..d9663b63c 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -228,7 +228,7 @@ surface_fluxes(bool overstory, store_gsLayer = calloc(options.Ncanopy, sizeof(*store_gsLayer)); check_alloc_status(store_gsLayer, "Memory allocation error."); } - + fprintf(LOG_DEST, "\tMAX_ITER_GRND_CANOPY: %d\n", param.MAX_ITER_GRND_CANOPY); /*********************************************************************** Set temporary variables for convenience ***********************************************************************/ diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index f961a40ec..b37a2ffe6 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -132,12 +132,6 @@ vic_run(force_data_struct *force, gauge_correction[1] = 1; } - // Canopy Iterations - if (!options.CLOSE_ENERGY) { - // do not iterate to close energy balance - param.MAX_ITER_GRND_CANOPY = 0; - } - force->out_prec = 0; force->out_rain = 0; force->out_snow = 0; From 6d18f280e7f737b573be91e035104181281e9e86 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 16 Feb 2018 14:37:41 -0800 Subject: [PATCH 284/294] ran uncrustify --- vic/vic_run/src/surface_fluxes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/surface_fluxes.c b/vic/vic_run/src/surface_fluxes.c index aa17e2644..afa4018bc 100644 --- a/vic/vic_run/src/surface_fluxes.c +++ b/vic/vic_run/src/surface_fluxes.c @@ -227,7 +227,7 @@ surface_fluxes(bool overstory, if (options.CARBON) { store_gsLayer = calloc(options.Ncanopy, sizeof(*store_gsLayer)); check_alloc_status(store_gsLayer, "Memory allocation error."); - } + } /*********************************************************************** Set temporary variables for convenience From 53daee060507e5a84f83e008cfbc538c3e396535 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Fri, 16 Feb 2018 18:03:47 -0500 Subject: [PATCH 285/294] print parameters struct after global param and options structs in image and cesm drivers --- vic/drivers/cesm/src/cesm_interface_c.c | 3 ++- vic/drivers/image/src/vic_image.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vic/drivers/cesm/src/cesm_interface_c.c b/vic/drivers/cesm/src/cesm_interface_c.c index df4f0336c..9b46ceeb1 100644 --- a/vic/drivers/cesm/src/cesm_interface_c.c +++ b/vic/drivers/cesm/src/cesm_interface_c.c @@ -115,9 +115,10 @@ vic_cesm_init(vic_clock *vclock, // initialization is complete, print settings log_info( - "Initialization is complete, print global param and options structures"); + "Initialization is complete, print global param, parameters and options structures"); print_global_param(&global_param); print_option(&options); + print_parameters(¶m); // stop init timer timer_stop(&(global_timers[TIMER_VIC_INIT])); diff --git a/vic/drivers/image/src/vic_image.c b/vic/drivers/image/src/vic_image.c index ff6699cc4..5fb5f0c66 100644 --- a/vic/drivers/image/src/vic_image.c +++ b/vic/drivers/image/src/vic_image.c @@ -132,9 +132,10 @@ main(int argc, // Initialization is complete, print settings log_info( - "Initialization is complete, print global param and options structures"); + "Initialization is complete, print global param, parameters and options structures"); print_global_param(&global_param); print_option(&options); + print_parameters(¶m); // stop init timer timer_stop(&(global_timers[TIMER_VIC_INIT])); From 3bee1d7121be1b681baeee9ed9dc3548e385e155 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 21 Feb 2018 13:06:07 -0500 Subject: [PATCH 286/294] this needed to be removed as part of the earlier commit --- vic/drivers/classic/src/vic_classic.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/vic/drivers/classic/src/vic_classic.c b/vic/drivers/classic/src/vic_classic.c index 73908c8b9..51be1d43d 100644 --- a/vic/drivers/classic/src/vic_classic.c +++ b/vic/drivers/classic/src/vic_classic.c @@ -163,12 +163,6 @@ main(int argc, filep.statefile = NULL; } - // Canopy Iterations - if (!options.CLOSE_ENERGY) { - // do not iterate to close energy balance - param.MAX_ITER_GRND_CANOPY = 0; - } - /************************************ Run Model for all Active Grid Cells ************************************/ From 1805499437de1510b1b58b0ee032882e75867de9 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 21 Feb 2018 13:08:01 -0500 Subject: [PATCH 287/294] remove vic run changes --- vic/vic_run/src/vic_run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 60bbf36b7..70c65ba91 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -131,7 +131,6 @@ vic_run(force_data_struct *force, gauge_correction[0] = 1; gauge_correction[1] = 1; } - force->out_prec = 0; force->out_rain = 0; force->out_snow = 0; @@ -229,6 +228,7 @@ vic_run(force_data_struct *force, **************************************************/ for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ + if (soil_con->AreaFract[band] > 0) { /* Set local pointers */ cell = &(all_vars->cell[iveg][band]); From ff38de49f10859f5019a462b97cba8aacadcfc21 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 21 Feb 2018 13:09:20 -0500 Subject: [PATCH 288/294] remove other vic run changes --- vic/vic_run/src/vic_run.c | 1 - 1 file changed, 1 deletion(-) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index 70c65ba91..c589d756b 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -228,7 +228,6 @@ vic_run(force_data_struct *force, **************************************************/ for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ - if (soil_con->AreaFract[band] > 0) { /* Set local pointers */ cell = &(all_vars->cell[iveg][band]); From 14d3c5c633afdf79512f281863793c38cb0ae2d6 Mon Sep 17 00:00:00 2001 From: Diana Gergel Date: Wed, 21 Feb 2018 13:12:49 -0500 Subject: [PATCH 289/294] remove other vic run changes --- vic/vic_run/src/vic_run.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vic/vic_run/src/vic_run.c b/vic/vic_run/src/vic_run.c index c589d756b..5aac937e2 100644 --- a/vic/vic_run/src/vic_run.c +++ b/vic/vic_run/src/vic_run.c @@ -229,6 +229,7 @@ vic_run(force_data_struct *force, for (band = 0; band < Nbands; band++) { /** Solve band only if coverage greater than 0% **/ if (soil_con->AreaFract[band] > 0) { + /* Set local pointers */ cell = &(all_vars->cell[iveg][band]); veg_var = &(all_vars->veg_var[iveg][band]); From e03c5a8696a9d0b4cc500cb17c772e6c066c1736 Mon Sep 17 00:00:00 2001 From: ted Date: Wed, 7 Mar 2018 23:46:19 -0700 Subject: [PATCH 290/294] Added check that number of nonzero area tiles is consistent with nveg. --- vic/drivers/shared_image/src/vic_init.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 5bd57d410..e89484358 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1136,6 +1136,13 @@ vic_init(void) veg_con_map[i].vidx[j] = NODATA_VEG; } } + // check the number of nonzero veg tiles + if (k > local_domain.locations[i].nveg) { + sprint_location(locstr, &(local_domain.locations[i])); + log_err("Number of veg tiles with nonzero area (%zu) > nveg " + "(%zu).\n%s", k, local_domain.locations[i].nveg, + locstr); + } } // zone_depth: root zone depths @@ -1242,7 +1249,9 @@ vic_init(void) "...\n%s", Cv_sum[i], i, locstr); for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; - veg_con[i][vidx].Cv /= Cv_sum[i]; + if (vidx != NODATA_VEG) { + veg_con[i][vidx].Cv /= Cv_sum[i]; + } } } } From 91db82d4c1af60b1fce6a78e5b9feb35f49fa7e1 Mon Sep 17 00:00:00 2001 From: ted Date: Sat, 10 Mar 2018 16:19:24 -0700 Subject: [PATCH 291/294] Updated warning messages to have format .16f so users can see exactly what their sum values are. --- vic/drivers/shared_image/src/vic_init.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index e89484358..9ef0f5be6 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1196,7 +1196,7 @@ vic_init(void) if (sum <= 0) { sprint_location(locstr, &(local_domain.locations[i])); log_err("Root zone depths must sum to a value greater " - "than 0 (sum = %.2f) - Type: %zd.\n%s", sum, j, + "than 0 (sum = %.16f) - Type: %zd.\n%s", sum, j, locstr); } sum = 0; @@ -1205,10 +1205,10 @@ vic_init(void) } if (!assert_close_double(sum, 1.0, 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Root zone fractions sum to more than 1 (%f), " - "normalizing fractions. If the sum is large, " - "check your vegetation parameter file.\n%s", - sum, locstr); + log_warn("Sum of root zone fractions != 1.0 (%.16f) at " + "grid cell %zd. Normalizing fractions. If the " + "sum is large, check your vegetation parameter " + "file.\n%s", sum, i, locstr); for (k = 0; k < options.ROOT_ZONES; k++) { veg_con[i][vidx].zone_fract[k] /= sum; } @@ -1245,8 +1245,9 @@ vic_init(void) // readjust Cvs to sum to 1.0 if (!assert_close_double(Cv_sum[i], 1., 0., AREA_SUM_ERROR_THRESH)) { sprint_location(locstr, &(local_domain.locations[i])); - log_warn("Cv != 1.0 (%f) at grid cell %zd. Adjusting fractions " - "...\n%s", Cv_sum[i], i, locstr); + log_warn("Sum of veg tile area fractions != 1.0 (%.16f) at grid " + "cell %zd. Adjusting fractions ...\n%s", Cv_sum[i], i, + locstr); for (j = 0; j < options.NVEGTYPES; j++) { vidx = veg_con_map[i].vidx[j]; if (vidx != NODATA_VEG) { From 970691c75d91f5ad4af51570ea562a8c3ccfcaad Mon Sep 17 00:00:00 2001 From: ted Date: Sat, 10 Mar 2018 18:45:25 -0700 Subject: [PATCH 292/294] Updated check on nveg. --- vic/drivers/shared_image/src/vic_init.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vic/drivers/shared_image/src/vic_init.c b/vic/drivers/shared_image/src/vic_init.c index 90059ecd5..8301a3f2b 100644 --- a/vic/drivers/shared_image/src/vic_init.c +++ b/vic/drivers/shared_image/src/vic_init.c @@ -1137,9 +1137,15 @@ vic_init(void) } } // check the number of nonzero veg tiles - if (k > local_domain.locations[i].nveg) { + if (k > local_domain.locations[i].nveg + 1) { sprint_location(locstr, &(local_domain.locations[i])); - log_err("Number of veg tiles with nonzero area (%zu) > nveg " + log_err("Number of veg tiles with nonzero area (%zu) > nveg + 1 " + "(%zu).\n%s", k, local_domain.locations[i].nveg, + locstr); + } + else if (k < local_domain.locations[i].nveg) { + sprint_location(locstr, &(local_domain.locations[i])); + log_err("Number of veg tiles with nonzero area (%zu) < nveg " "(%zu).\n%s", k, local_domain.locations[i].nveg, locstr); } From 0aed9a1f92ad9cc7f033d10e575bb1ed7ec5847f Mon Sep 17 00:00:00 2001 From: Ted Bohn Date: Wed, 25 Apr 2018 13:30:11 -0700 Subject: [PATCH 293/294] Feature/clean up esoil (#777) * 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. --- docs/Development/ReleaseNotes.md | 4 + vic/drivers/shared_all/src/initialize_soil.c | 3 +- .../shared_all/src/print_library_shared.c | 8 +- vic/drivers/shared_all/src/put_data.c | 38 ++++----- vic/vic_run/include/vic_def.h | 3 +- vic/vic_run/src/arno_evap.c | 22 ++--- vic/vic_run/src/canopy_evap.c | 78 ++++++++--------- vic/vic_run/src/func_surf_energy_bal.c | 84 ++++++------------- 8 files changed, 107 insertions(+), 133 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index 0e544b05d..a2e47bfdb 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -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)) diff --git a/vic/drivers/shared_all/src/initialize_soil.c b/vic/drivers/shared_all/src/initialize_soil.c index 6b9761f92..8850fb3bd 100644 --- a/vic/drivers/shared_all/src/initialize_soil.c +++ b/vic/drivers/shared_all/src/initialize_soil.c @@ -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; } } diff --git a/vic/drivers/shared_all/src/print_library_shared.c b/vic/drivers/shared_all/src/print_library_shared.c index be48bd09d..22002cb27 100644 --- a/vic/drivers/shared_all/src/print_library_shared.c +++ b/vic/drivers/shared_all/src/print_library_shared.c @@ -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); } @@ -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", diff --git a/vic/drivers/shared_all/src/put_data.c b/vic/drivers/shared_all/src/put_data.c index 90b163607..a94ec9845 100644 --- a/vic/drivers/shared_all/src/put_data.c +++ b/vic/drivers/shared_all/src/put_data.c @@ -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; @@ -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 * @@ -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; @@ -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; diff --git a/vic/vic_run/include/vic_def.h b/vic/vic_run/include/vic_def.h index e6ea48473..a78dbc15d 100644 --- a/vic/vic_run/include/vic_def.h +++ b/vic/vic_run/include/vic_def.h @@ -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; /****************************************************************************** diff --git a/vic/vic_run/src/arno_evap.c b/vic/vic_run/src/arno_evap.c index 7b3ed3a32..3f4db87e9 100644 --- a/vic/vic_run/src/arno_evap.c +++ b/vic/vic_run/src/arno_evap.c @@ -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; @@ -115,7 +115,7 @@ arno_evap(layer_data_struct *layer, /**********************************************************************/ if (tmp >= max_infil) { - evap = Epot; + esoil = Epot; } else { /********************************************************************/ @@ -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; } /***********************************************************************/ @@ -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); } diff --git a/vic/vic_run/src/canopy_evap.c b/vic/vic_run/src/canopy_evap.c index 8f6689497..ac4e0d568 100644 --- a/vic/vic_run/src/canopy_evap.c +++ b/vic/vic_run/src/canopy_evap.c @@ -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; @@ -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); } @@ -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); @@ -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, @@ -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; @@ -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 && @@ -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]) { @@ -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; @@ -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; } @@ -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); @@ -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++) { @@ -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; } } } diff --git a/vic/vic_run/src/func_surf_energy_bal.c b/vic/vic_run/src/func_surf_energy_bal.c index 1fe7ef4ca..9d51ef818 100644 --- a/vic/vic_run/src/func_surf_energy_bal.c +++ b/vic/vic_run/src/func_surf_energy_bal.c @@ -203,7 +203,7 @@ func_surf_energy_bal(double Ts, double T1_plus; double D1_minus; double D1_plus; - double *transp = NULL; + double SurfRad; double Ra_bare[3]; double tmp_wind[3]; double tmp_height; @@ -366,12 +366,6 @@ func_surf_energy_bal(double Ts, TMean = Ts; - transp = calloc(options.Nlayer, sizeof(*transp)); - check_alloc_status(transp, "Memory allocation error."); - for (i = 0; i < options.Nlayer; i++) { - transp[i] = 0.; - } - /********************************************** Compute Surface Temperature at Half Time Step **********************************************/ @@ -749,66 +743,42 @@ func_surf_energy_bal(double Ts, Should evapotranspiration be active when the ground is only partially covered with snow???? - - Use Arno Evap in the exposed soil portion, and/or - if LAI is zero. *************************************************/ - if (VEG && !SNOWING && veg_var->fcanopy > 0) { - Evap = canopy_evap(layer, veg_var, true, - veg_class, Wdew, delta_t, NetBareRad, vpd, - NetShortBare, Tair, Ra_veg[1], elevation, rainfall, - Wmax, Wcr, Wpwp, frost_fract, root, dryFrac, - shortwave, Catm, CanopLayerBnd); - if (veg_var->fcanopy < 1) { - for (i = 0; i < options.Nlayer; i++) { - transp[i] = layer[i].evap; - layer[i].evap = 0.; - } + for (i = 0; i < options.Nlayer; i++) { + layer[i].transp = 0; + layer[i].esoil = 0; + } + Evap = 0.; + if (!SNOWING) { + if (VEG && veg_var->fcanopy > 0) { + Evap = canopy_evap(layer, veg_var, true, veg_class, Wdew, + delta_t, NetBareRad, vpd, NetShortBare, + Tair, Ra_veg[1], elevation, rainfall, + Wmax, Wcr, Wpwp, frost_fract, root, + dryFrac, shortwave, Catm, CanopLayerBnd); Evap *= veg_var->fcanopy; - Evap += (1 - veg_var->fcanopy) * - arno_evap(layer, surf_atten * NetBareRad, Tair, vpd, - depth[0], max_moist * depth[0] * MM_PER_M, - elevation, b_infilt, Ra_used[0], delta_t, - resid_moist[0], frost_fract); for (i = 0; i < options.Nlayer; i++) { - layer[i].evap = veg_var->fcanopy * transp[i] + - (1 - veg_var->fcanopy) * layer[i].evap; - if (layer[i].evap > 0.) { - layer[i].bare_evap_frac = 1 - - (veg_var->fcanopy * - transp[i]) / layer[i].evap; - } - else { - layer[i].bare_evap_frac = 0.; - } + layer[i].transp *= veg_var->fcanopy; } - veg_var->throughfall = - (1 - - veg_var->fcanopy) * rainfall + veg_var->fcanopy * - veg_var->throughfall; - veg_var->canopyevap *= veg_var->fcanopy; - veg_var->Wdew *= veg_var->fcanopy; + SurfRad = surf_atten * NetBareRad; } else { - for (i = 0; i < options.Nlayer; i++) { - layer[i].bare_evap_frac = 0.; - } + SurfRad = NetBareRad; } - } - else if (!SNOWING) { - Evap = arno_evap(layer, NetBareRad, Tair, vpd, - depth[0], max_moist * depth[0] * MM_PER_M, - elevation, b_infilt, Ra_used[0], delta_t, - resid_moist[0], frost_fract); + Evap += (1 - veg_var->fcanopy) * + arno_evap(layer, SurfRad, Tair, vpd, + depth[0], max_moist * depth[0] * MM_PER_M, + elevation, b_infilt, Ra_used[0], delta_t, + resid_moist[0], frost_fract); for (i = 0; i < options.Nlayer; i++) { - layer[i].bare_evap_frac = 1; + layer[i].esoil *= (1 - veg_var->fcanopy); + layer[i].evap = layer[i].transp + layer[i].esoil; } + veg_var->throughfall = (1 - veg_var->fcanopy) * rainfall + + veg_var->fcanopy * veg_var->throughfall; + veg_var->canopyevap *= veg_var->fcanopy; + veg_var->Wdew *= veg_var->fcanopy; } - else { - Evap = 0.; - } - - free(transp); /********************************************************************** Compute the Latent Heat Flux from the Surface and Covering Vegetation From aef57cc1a313d928c6a7f6e6e17b4de9acc322c7 Mon Sep 17 00:00:00 2001 From: Joe Hamman Date: Fri, 27 Apr 2018 09:53:18 -0700 Subject: [PATCH 294/294] cleanup release notes for 5.1 rc1 release (#789) --- docs/Development/ReleaseNotes.md | 101 +++++++++++++++++-------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/docs/Development/ReleaseNotes.md b/docs/Development/ReleaseNotes.md index a2e47bfdb..851395ee9 100644 --- a/docs/Development/ReleaseNotes.md +++ b/docs/Development/ReleaseNotes.md @@ -15,77 +15,84 @@ To check which release of VIC you are running: ------------------------------ -## VIC 5.1.0 +## VIC 5.1.0 rc1 -**Release date: (Unreleased)** + + + +**Release date: (April 27, 2018)** + +Source code is available here: [![VIC.5.1.0](https://img.shields.io/badge/VIC-5.1.0-blue.svg)](https://github.com/UW-Hydro/VIC/releases/tag/VIC.5.1.0) + +This is a minor update from VIC 5.0.1. The VIC 5.1.0 includes new features, such as a new streamflow routing extension and extended parallelization using OpenMP. The release also includes a number of bug fixes for the CESM driver. See the VIC Github page for more details on the changes included in this release. #### Model enhancement: 1. Improved calculation of drainage between soil layers ([GH#656](https://github.com/UW-Hydro/VIC/pull/656)) - Drainage from upper layer to adjacent lower layer is calculated according to Brook & Corey curve (where drainage rate is a function of upper-layer soil moisture). In previous versions, a simple numerical solution is applied which uses the timestep-beginning upper-layer soil moisture to calculate drainage rate, and assume this constant rate over the entire timestep. This can cause unreasonably large drainage if the curve has a steep shape and when soil moisture is high. Now, the current version uses exact integral (instead of numerical solution) for layer drainage calculation. + Drainage from upper layer to adjacent lower layer is calculated according to Brook & Corey curve (where drainage rate is a function of upper-layer soil moisture). In previous versions, a simple numerical solution is applied which uses the timestep-beginning upper-layer soil moisture to calculate drainage rate, and assume this constant rate over the entire timestep. This can cause unreasonably large drainage if the curve has a steep shape and when soil moisture is high. Now, the current version uses exact integral (instead of numerical solution) for layer drainage calculation. 2. Fixes for the CESM driver - [GH#642](https://github.com/UW-Hydro/VIC/pull/642) + 1. [GH#642](https://github.com/UW-Hydro/VIC/pull/642) - 1. Using correct fill value datatypes in MPI Gather steps - 2. Updated state file name time step to be period-ending rather than period-beginning - 3. Set the state file name to the RASM case ID - 4. Removed decimal point for missing values for unsigned integers - 5. Create dummy forcings when initializing the model (so that there is forcing data for the first time step) - 6. Changed pressure units from kPa to Pa - 7. Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` - 8. Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` + - Using correct fill value datatypes in MPI Gather steps + - Updated state file name time step to be period-ending rather than period-beginning + - Set the state file name to the RASM case ID + - Removed decimal point for missing values for unsigned integers + - Create dummy forcings when initializing the model (so that there is forcing data for the first time step) + - Changed pressure units from kPa to Pa + - Fixed bug that prevented using the correct local domain grid cells in `cesm_put_data.c` + - Changed reference temperature units from Celsius to Kelvin in `cesm_put_data.c` - [GH#695](https://github.com/UW-Hydro/VIC/pull/695) + 1. [GH#695](https://github.com/UW-Hydro/VIC/pull/695) - 1. Fix sign for latent heat fluxes passed from VIC to the coupler - 2. Fix sign for longwave radiation passed from VIC to the coupler + - Fix sign for latent heat fluxes passed from VIC to the coupler + - Fix sign for longwave radiation passed from VIC to the coupler - [GH#696](https://github.com/UW-Hydro/VIC/pull/696) + 1. [GH#696](https://github.com/UW-Hydro/VIC/pull/696) - Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. + - Changes names of CESM driver functions `trim` and `advance_time` to `trimstr` and `advance_vic_time`, respectively, to avoid conflicts with WRF functions with the same names when compiling RFR case. - [GH#702](https://github.com/UW-Hydro/VIC/pull/702) + 1. [GH#702](https://github.com/UW-Hydro/VIC/pull/702) - Fixes Julian day for the first timestep in the dmy struct for the CESM driver. + - Fixes Julian day for the first timestep in the dmy struct for the CESM driver. - [GH#710](https://github.com/UW-Hydro/VIC/pull/710) + 1. [GH#710](https://github.com/UW-Hydro/VIC/pull/710) - Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. + - Refactor the cesm_put_data.c routine in the CESM driver to use values from out_data directly, rather than computing them separately in cesm_put_data.c. - [GH#716](https://github.com/UW-Hydro/VIC/pull/716) + 1. [GH#716](https://github.com/UW-Hydro/VIC/pull/716) - Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. + - Fixes initialization of coupler fields and calculates temperature and upwelling longwave to pass to WRF during initialization. - [GH#718](https://github.com/UW-Hydro/VIC/pull/718) + 1. [GH#718](https://github.com/UW-Hydro/VIC/pull/718) - Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. + - Updates the cesm_put_data.c routine in the CESM driver to pass gridcell-averaged albedo to the coupler. - [GH#726](https://github.com/UW-Hydro/VIC/pull/726) + 1. [GH#726](https://github.com/UW-Hydro/VIC/pull/726) - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. + - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for evap passed to the coupler. - [GH#732](https://github.com/UW-Hydro/VIC/pull/732) + 1. [GH#732](https://github.com/UW-Hydro/VIC/pull/732) - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). + - Updates the cesm_put_data.c routine in the CESM driver to include the correct units for sensible heat flux and updates the rofliq calculation to be correct (previously only OUT_BASEFLOW was being divided by global_param.dt). - [GH#734](https://github.com/UW-Hydro/VIC/pull/734) + 1. [GH#734](https://github.com/UW-Hydro/VIC/pull/734) - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. + - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for turbulent heat fluxes and evaporation. Previously we had switched the signs to agree with the image driver and they should instead be in accordance with the sign conventions for coupled models, which differ from those of land surface models. Also, eliminate populating the `l2x_Sl_ram1` field with aero_resist to agree with the VIC 4 implementation in RASM. - [GH#739](https://github.com/UW-Hydro/VIC/pull/739) + 1. [GH#739](https://github.com/UW-Hydro/VIC/pull/739) - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). + - Updates the cesm_put_data.c routine in the CESM driver to include the correct signs for the wind stresses and fixes a bug in calculating friction velocity (previously it was missing a square root). - [GH#744](https://github.com/UW-Hydro/VIC/pull/744) + 1. [GH#744](https://github.com/UW-Hydro/VIC/pull/744) - Updates the cesm_interface_c.c routine to include missing timers and the VIC RUN timer in the CESM driver. + - Updates the cesm_interface_c.c routine to include missing timers and the VIC RUN timer in the CESM driver. - [GH#746](https://github.com/UW-Hydro/VIC/pull/746) + 1. [GH#746](https://github.com/UW-Hydro/VIC/pull/746) - Updates the cesm_interface_c.c routine in the CESM driver to populate the nrecs, endyear, endmonth and endday fields in the global_param struct to make them available to vic_finalize for timing tables (specifically the secs/day columns). + - Updates the cesm_interface_c.c routine in the CESM driver to populate the nrecs, endyear, endmonth and endday fields in the global_param struct to make them available to vic_finalize for timing tables (specifically the secs/day columns). 3. Speed up NetCDF operations in the image/CESM drivers ([GH#684](https://github.com/UW-Hydro/VIC/pull/684)) @@ -113,27 +120,27 @@ To check which release of VIC you are running: 9. Moved MAX_ITER_GRND_CANOPY, which controls the maximum number of ground-canopy iterations in CLOSE_ENERGY mode for vegetation types with an overstory, to the parameters struct ([GH#771](https://github.com/UW-Hydro/VIC/pull/771)) - Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. + Previously this was set in the surface_fluxes.c numerics routine for ground-canopy iterations, which meant that that routine had to be altered to change the maximum number of iterations. It has now been moved to the parameters struct so that it can be overriden in the constants file. 10. Updated new snow density function by adding a cap to new snow density that is set in the parameters struct by the parameter SNOW_NEW_SNOW_DENS_MAX ([GH#776](https://github.com/UW-Hydro/VIC/pull/776)) - Previously the change in cold content of the snowpack term (deltaCC in the snow_data_struct) would get unreasonably large if the Hedstrom and Pomeroy 1998 equation used to calculate snow density, which depends only on air temperature, was calculated with air temperatures above about 2 deg C. We use this term to calculate the ground flux from the snowpack and snow depth, which resulted in extremely small snow depths and unreasonably large ground fluxes from the snowpack (and thus changes in snowpack cold content). Now there is a cap on new snow density with the new parameter SNOW_NEW_SNOW_DENS_MAX as well as a snow depth below which we disregard the ground flux from the snowpack (1.e-8). + Previously the change in cold content of the snowpack term (deltaCC in the snow_data_struct) would get unreasonably large if the Hedstrom and Pomeroy 1998 equation used to calculate snow density, which depends only on air temperature, was calculated with air temperatures above about 2 deg C. We use this term to calculate the ground flux from the snowpack and snow depth, which resulted in extremely small snow depths and unreasonably large ground fluxes from the snowpack (and thus changes in snowpack cold content). Now there is a cap on new snow density with the new parameter SNOW_NEW_SNOW_DENS_MAX as well as a snow depth below which we disregard the ground flux from the snowpack (1.e-8). 10. Miscellaneous clean-up: [GH#723](https://github.com/UW-Hydro/VIC/pull/723) - 1. Added support for veg_hist forcings (non-climatological) in image mode - 2. Fixed erroneous allocation of extra veg tile in image mode - 3. Simplified looping over veg tiles and bands in vic_run() and prepare_full_energy() - 4. Replaced lengthy data structures with local pointers in vic_run() - 5. Simplified out_prec, out_rain, and Melt arrays - 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. + - Added support for veg_hist forcings (non-climatological) in image mode + - Fixed erroneous allocation of extra veg tile in image mode + - Simplified looping over veg tiles and bands in vic_run() and prepare_full_energy() + - Replaced lengthy data structures with local pointers in vic_run() + - Simplified out_prec, out_rain, and Melt arrays + - Updated names of variables and options for LAI and FCANOPY in documentation to match their new names in the code + - 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. + - 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: