diff --git a/INSTALL.md b/INSTALL.md index 0755725..775c1f6 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,14 +1,25 @@ -# Installation instructions +# Installation and example instructions -1. Clone the online github repository either from the main git repo source (https://github.com/NOAA-OWP/snow17.git) or your fork of it. - cmd: `clone [github source]` +1. Clone the online GitHub repository either from the main git repo source (https://github.com/NOAA-OWP/snow17.git) or your fork of it -- e.g., `git clone https://github.com/NOAA-OWP/snow17.git` 2. Change directory to the build directory: `cd snow17/build/` -3. Copy `Makefile` to `Makefile.local` and edit the local version to update the compiler and paths if necessary to match the resources on your system. -4. Run `make -f Makefile.local` to compile the program and generate the executable, which will be found in `snow17/bin/` -5. There is a test case in the `snow17/test_cases/` directory. To run it, first cd to the directory and unpack the example: `tar -xzvf ex1.tgz`. -6. cd into `ex1/run/` directory and run the shell script (`./runSnow17.csh`) or type `../../../bin/snow17.exe namelist.HHWM8` into your command line -7. Check the example output in `snow17/test_cases/ex1//output/` +3. Copy `Makefile` to `Makefile.local` (`cp Makefile Makefile.local`) and edit the local version to update the compiler and paths if necessary to match the resources on your system. +4. Run `make -f MakefileLocal` to compile the program and generate the executable, which will be found in `snow17/bin/` +5. There is a test case in the `snow17/test_cases/` directory. To run it, first cd to the directory (`cd ../test_cases/`) and unpack the example: `tar -xzvf ex1.tgz`. +6. `cd ex1/run/` to get to the run directory and then execute the shell script (`./runSnow17.csh`) or type `../../../bin/snow17.exe namelist.bmi.HHWM8` into your command line +7. Check the example in the output folder (`cd ../output/`) +TL;DR: +``` +git clone https://github.com/NOAA-OWP/snow17.git +cd snow17/build/ +cp Makefile MakefileLocal # edit to match your compiler and system resources +make -f MakefileLocal +cd ../test_cases/ +tar -xzvf ex1.tgz +cd ex1/run/ +./runSnow17.csh # or ../../../bin/snow17.exe namelist.bmi.HHWM8 +cd ../output/ # to view output data +``` Note that the ex1/ example is part of the repo. The unpacked directory and test contents will not be included in a push back to the online repo. To the program for other purposes, create new input files and output directories outside of the `snow17/` repository directory, and link to the executable in `snow17/bin/`. diff --git a/README.md b/README.md index a23c89f..a63772a 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,15 @@ Snow17 is a snow accumulation and melt model that has been used by the National Weather Service since the late 1970s for operational streamflow forecasting. It is a temperature-index model that was first described in Anderson (1973) before being incorporated into the NWS River Forecasting System (NWSRFS) and more recently the NWS Community Hydrologic Prediction System (CHPS). The version of the Snow17 model maintained in this directory is formulated from original NWS FORTRAN code to be compatible with -the NextGen simulation and forecasting framework. +the [Next Generation Water Resources Modeling Framework](https://github.com/NOAA-OWP/ngen) (NextGen). - - **Technology stack**: The model code is written in FORTRAN with a driver that incorporates Basic Model Interface (BMI) commands to enable Snow17 to be run as a module within the NextGen framework. - is intended as standalone or as a module in a framework or other ecosystem. It has been compiled using gnu, pgi and intel compilers. - - **Status**: Beta (runs but has not been extensively tested; validates against the orginal repository version listed below, which has been extensively used)) - - **Links**: This code was adapted from source code included in https://github.com/NCAR/NWS_hydro_models -- a version used in federally-funded streamflow forecasting research at NCAR. The original source code for that effort was obtained from the NWS Office of Hydrology around 2013. The code has since been copied and adapted into other research repositories. + - **Technology stack**: The model code is written in Fortran with a driver that incorporates [Basic Model Interface](https://csdms.colorado.edu/wiki/BMI) (BMI) commands to enable Snow17 to be run in standalone mode or as a module within the NextGen framework (or other BMI-based systems). It has been compiled using GNU, PGI, and Intel compilers. + - **Status**: Beta (runs but has not been extensively tested; validates against the orginal repository version listed below, which has been extensively used) + - **Links**: This code was adapted from source code included in https://github.com/NCAR/NWS_hydro_models -- a version used in federally funded streamflow forecasting research at NCAR. The original source code for that effort was obtained from the NWS Office of Hydrology around 2013. The code has since been copied and adapted into other research repositories. ## Dependencies -TBA: Describe any dependencies that must be installed for this software to work. -This includes programming languages, databases or other storage mechanisms, build tools, frameworks, and so forth. -If specific versions of other software are required, or known not to work, call that out. +There are no current dependencies except for a Fortran-compatible compiler (e.g., GFortran) ## Installation @@ -27,21 +24,20 @@ TBA: If the software is configurable, describe it in detail, either here or in ## How to test the software -Run the included test case example -- see INSTALL.md +Run the included test case example -- see the [INSTALL](INSTALL.md) document. ## Known issues The restart capability has not been implemented, but will be shortly. -The software has so far only been tested with the gfortran compiler (on Cheyenne at NCAR) +The software has so far only been tested with the GFortran compiler (on Cheyenne at NCAR) ## Getting help -Currently, questions may be sent to Andy Wood (andywood@ucar.edu). If there are concerns or bug fixes, etc., please file an issue in this repository's Issue Tracker. ## Getting involved -We encourage community involvement in code development. For more info, please check out our CONTRIBUTING document. +We encourage community involvement in code development. For more info, please check out our [CONTRIBUTING](CONTRIBUTING.md) document. ---- @@ -56,37 +52,4 @@ We encourage community involvement in code development. For more info, please ch If you wish to use or adapt the code in this repository, please make sure that your new repository credits this one as the original source of the code. ### References - - Anderson, E. A., 1973: National Weather Service River Forecast System-Snow Accumulation and Ablation Model. NOAA Tech. Memo. NWS Hydro-17, U.S. National Weather Service. [Avail- able from Office of Hydrologic Development, NOAA/NWS, 1325 East–West Highway, Silver Spring, MD 20910.] - -### Related projects - -### Books, papers, talks, or other sources that have meaningful impact or influence on this project - - ----- ----- - -#### OWP Open Source Project Template Instructions - -1. Create a new project. -2. [Copy these files into the new project](#installation) -3. Update the README, replacing the contents below as prescribed. -4. Add any libraries, assets, or hard dependencies whose source code will be included - in the project's repository to the _Exceptions_ section in the [TERMS](TERMS.md). - - If no exceptions are needed, remove that section from TERMS. -5. If working with an existing code base, answer the questions on the [open source checklist](opensource-checklist.md) -6. Delete these instructions and everything up to the _Project Title_ from the README. -7. Write some great software and tell people about it. - -> Keep the README fresh! It's the first thing people see and will make the initial impression. - -## Installation - -To install all of the template files, run the following script from the root of your project's directory: - -``` -bash -c "$(curl -s https://raw.githubusercontent.com/NOAA-OWP/owp-open-source-project-template/open_source_template.sh)" -``` - ----- - + - Anderson, E. A., 1973: National Weather Service River Forecast System-Snow Accumulation and Ablation Model. NOAA Tech. Memo. NWS Hydro-17, U.S. National Weather Service. [Avail- able from Office of Hydrologic Development, NOAA/NWS, 1325 East–West Highway, Silver Spring, MD 20910.] \ No newline at end of file diff --git a/build/Makefile b/build/Makefile index 919433d..16479e6 100644 --- a/build/Makefile +++ b/build/Makefile @@ -45,9 +45,9 @@ endif # --- Define flags ifeq "$(FC)" "gfortran" - FLAGS_DEBUG = -static -Wall -g -ffree-line-length-none -cpp -fcheckall - FLAGS = -O3 -fdefault-real-8 -fno-align-commons -ffree-line-length-none -cpp -fcheckall - FLAGS2 = -O3 -fdefault-real-8 -fno-align-commons -ffree-line-length-none -cpp -fcheckall + FLAGS_DEBUG = -static -Wall -g -ffree-line-length-none -cpp -fcheck=all + FLAGS = -O3 -fdefault-real-8 -fno-align-commons -ffree-line-length-none -cpp -fcheck=all + FLAGS2 = -O3 -fdefault-real-8 -fno-align-commons -ffree-line-length-none -cpp -fcheck=all endif ifeq "$(FC)" "ifort" diff --git a/doc/Screenshot.png b/doc/Screenshot.png deleted file mode 100644 index 3300f40..0000000 Binary files a/doc/Screenshot.png and /dev/null differ diff --git a/src/bmi/bmi_snow17.f90 b/src/bmi/bmi_snow17.f90 index b557e4e..c91f4a3 100644 --- a/src/bmi/bmi_snow17.f90 +++ b/src/bmi/bmi_snow17.f90 @@ -98,7 +98,7 @@ module bmi_snow17_module ! Exchange items integer, parameter :: input_item_count = 2 - integer, parameter :: output_item_count = 4 + integer, parameter :: output_item_count = 6 character (len=BMI_MAX_VAR_NAME), target, & dimension(input_item_count) :: input_items character (len=BMI_MAX_VAR_NAME), target, & @@ -155,10 +155,12 @@ function snow17_output_var_names(this, names) result (bmi_status) character (*), pointer, intent(out) :: names(:) integer :: bmi_status - output_items(1) = 'precip_scf' ! precip after scf scaling (mm) - output_items(2) = 'sneqv' ! snow water equivalent (mm) - output_items(3) = 'snowh' ! snow height (mm) - output_items(4) = 'raim' ! rain plus snowmelt (mm/s) + output_items(1) = 'tair' ! tair (degC) + output_items(2) = 'precip' ! precip (mm/s) + output_items(3) = 'precip_scf' ! precip after scf scaling (mm/s) + output_items(4) = 'sneqv' ! snow water equivalent (mm) + output_items(5) = 'snowh' ! snow height (mm) + output_items(6) = 'raim' ! precipitation (liquid) plus snowmelt (mm/s) names => output_items bmi_status = BMI_SUCCESS @@ -193,7 +195,7 @@ function snow17_start_time(this, time) result (bmi_status) double precision, intent(out) :: time integer :: bmi_status - !time = 0.d0 ! time relative to start time (s) == 0 + !time = 0.d0 ! time relative to start time (s) == 0 time = dble(this%model%runinfo%start_datetime) ! using unix time (s) bmi_status = BMI_SUCCESS @@ -206,7 +208,7 @@ function snow17_end_time(this, time) result (bmi_status) integer :: bmi_status !time = dble(this%model%runinfo%ntimes * this%model%runinfo%dt) ! time relative to start time (s) - time = dble(this%model%runinfo%end_datetime) ! using unix time (s) + time = dble(this%model%runinfo%end_datetime) ! using unix time (s) bmi_status = BMI_SUCCESS end function snow17_end_time @@ -217,7 +219,7 @@ function snow17_current_time(this, time) result (bmi_status) double precision, intent(out) :: time integer :: bmi_status - !time = dble(this%model%runinfo%time_dbl) ! time from start of run (s) + !time = dble(this%model%runinfo%time_dbl) ! time from start of run (s) time = dble(this%model%runinfo%curr_datetime) ! unix time (s) bmi_status = BMI_SUCCESS end function snow17_current_time @@ -255,34 +257,23 @@ end function snow17_update function snow17_update_until(this, time) result (bmi_status) class (bmi_snow17), intent(inout) :: this double precision, intent(in) :: time + ! local variables integer :: bmi_status - double precision :: n_steps_real - integer :: n_steps, i, s + double precision :: tmp_time + integer :: s - ! new code to work with unix time convention ! check to see if desired time to advance to is earlier than current time (can't go backwards) if (time < this%model%runinfo%curr_datetime) then bmi_status = BMI_FAILURE return end if ! otherwise try to advance to end time - do while ( time < this%model%runinfo%end_datetime ) + tmp_time = time + do while ( tmp_time < this%model%runinfo%end_datetime ) s = this%update() + tmp_time = this%model%runinfo%curr_datetime end do - ! original code working with time run convention from 0 to n*dt end_time - !if (time < this%model%runinfo%time_dbl) then - ! bmi_status = BMI_FAILURE - ! return - !end if - - !n_steps_real = (time - this%model%runinfo%time_dbl) / this%model%runinfo%dt - !n_steps = floor(n_steps_real) - !do i = 1, n_steps - ! s = this%update() - !end do - ! call update_frac(this, n_steps_real - dble(n_steps)) ! NOT IMPLEMENTED - bmi_status = BMI_SUCCESS end function snow17_update_until @@ -294,8 +285,8 @@ function snow17_var_grid(this, name, grid) result (bmi_status) integer :: bmi_status select case(name) - case('tair', 'precip', & ! input vars - 'precip_scf', 'sneqv', 'snowh', 'raim') ! output vars + case('tair', 'precip', & ! input/output vars (can pass forc to output) + 'precip_scf', 'sneqv', 'snowh', 'raim') ! output vars grid = 0 bmi_status = BMI_SUCCESS case default @@ -565,7 +556,7 @@ function snow17_var_type(this, name, type) result (bmi_status) integer :: bmi_status select case(name) - case('tair', 'precip', & ! input vars + case('tair', 'precip', & ! input/output vars 'precip_scf', 'sneqv', 'snowh', 'raim') ! output vars type = "real" bmi_status = BMI_SUCCESS @@ -584,13 +575,13 @@ function snow17_var_units(this, name, units) result (bmi_status) select case(name) case("precip") - units = "mm" + units = "mm/s" bmi_status = BMI_SUCCESS case("tair") - units = "C" + units = "degC" bmi_status = BMI_SUCCESS case("precip_scf") - units = "mm" + units = "mm/s" bmi_status = BMI_SUCCESS case("sneqv") units = "mm" @@ -599,7 +590,7 @@ function snow17_var_units(this, name, units) result (bmi_status) units = "mm" bmi_status = BMI_SUCCESS case("raim") - units = "mm" + units = "mm/s" bmi_status = BMI_SUCCESS case default units = "-" @@ -613,25 +604,28 @@ function snow17_var_itemsize(this, name, size) result (bmi_status) character (len=*), intent(in) :: name integer, intent(out) :: size integer :: bmi_status + + ! note: the combined variables are used assuming ngen is interacting with the + ! catchment-averaged result if snowbands are used select case(name) case("precip") - size = sizeof(this%model%forcing%precip_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%forcing%precip(1)) ! 'sizeof' in gcc & ifort bmi_status = BMI_SUCCESS case("tair") - size = sizeof(this%model%forcing%tair_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%forcing%tair(1)) bmi_status = BMI_SUCCESS case("precip_scf") - size = sizeof(this%model%forcing%precip_scf_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%forcing%precip_scf_comb) bmi_status = BMI_SUCCESS case("sneqv") - size = sizeof(this%model%modelvar%sneqv_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%modelvar%sneqv_comb) bmi_status = BMI_SUCCESS case("snowh") - size = sizeof(this%model%modelvar%snowh_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%modelvar%snowh_comb) bmi_status = BMI_SUCCESS case("raim") - size = sizeof(this%model%modelvar%raim_comb) ! 'sizeof' in gcc & ifort + size = sizeof(this%model%modelvar%raim_comb) bmi_status = BMI_SUCCESS case default size = -1 @@ -701,10 +695,10 @@ function snow17_get_float(this, name, dest) result (bmi_status) select case(name) case("precip") - dest(1) = this%model%forcing%precip_comb + dest(1) = this%model%forcing%precip(1) bmi_status = BMI_SUCCESS case("tair") - dest(1) = this%model%forcing%tair_comb + dest(1) = this%model%forcing%tair(1) bmi_status = BMI_SUCCESS case("precip_scf") dest(1) = this%model%forcing%precip_scf_comb @@ -872,24 +866,27 @@ function snow17_set_float(this, name, src) result (bmi_status) real, intent(in) :: src(:) integer :: bmi_status + ! NOTE: if run in a vector (snowband mode), this code will need revising + ! to set the basin average (ie, restart capability) + select case(name) case("precip") - this%model%forcing%precip_comb = src(1) + this%model%forcing%precip(1) = src(1) bmi_status = BMI_SUCCESS case("tair") - this%model%forcing%tair_comb = src(1) + this%model%forcing%tair(1) = src(1) bmi_status = BMI_SUCCESS case("precip_scf") - this%model%forcing%precip_scf_comb = src(1) + this%model%forcing%precip_scf(1) = src(1) bmi_status = BMI_SUCCESS case("sneqv") - this%model%modelvar%sneqv_comb = src(1) + this%model%modelvar%sneqv(1) = src(1) bmi_status = BMI_SUCCESS case("snowh") - this%model%modelvar%snowh_comb = src(1) + this%model%modelvar%snowh(1) = src(1) bmi_status = BMI_SUCCESS case("raim") - this%model%modelvar%raim_comb = src(1) + this%model%modelvar%raim(1) = src(1) bmi_status = BMI_SUCCESS case default bmi_status = BMI_FAILURE diff --git a/src/driver/driver_bmi.f90 b/src/driver/driver_bmi.f90 index d870029..181a314 100644 --- a/src/driver/driver_bmi.f90 +++ b/src/driver/driver_bmi.f90 @@ -66,11 +66,10 @@ program multi_driver print*, 'Running model => start: ', start_datehr, ' end: ', end_datehr, ' timesteps: ', int((end_time - current_time)/dt) print*,'----' - ! loop through while current time <= end time ( + ! loop through timesteps and update model while current time <= end time ( do while (current_time .le. end_time) - !print*, 'Current time:', current_time status = m%update() ! run the model one time step - status = m%get_current_time(current_time) ! update current_time + status = m%get_current_time(current_time) ! get updated current_time end do !--------------------------------------------------------------------- diff --git a/src/driver/noah-owp-modular.lnk b/src/driver/noah-owp-modular.lnk deleted file mode 120000 index 6363b3b..0000000 --- a/src/driver/noah-owp-modular.lnk +++ /dev/null @@ -1 +0,0 @@ -/glade/u/home/andywood/profdev/ngen/noahmp/noah-owp-modular/ \ No newline at end of file diff --git a/src/share/forcingType.f90 b/src/share/forcingType.f90 index 6d58a2e..23792df 100644 --- a/src/share/forcingType.f90 +++ b/src/share/forcingType.f90 @@ -9,10 +9,10 @@ module forcingType type, public :: forcing_type ! atmospheric inputs & outputs (surface meteorology) - real, dimension(:), allocatable :: tair ! surface air temperature [K] + real, dimension(:), allocatable :: tair ! surface air temperature [degC] real, dimension(:), allocatable :: precip ! total input precipitation [mm/s] real, dimension(:), allocatable :: precip_scf ! total input precipitation with SCF applied [mm/s] - real, dimension(:), allocatable :: pa ! snow17 surface pressure (Pa) + real, dimension(:), allocatable :: pa ! snow17 surface pressure [Pa] real :: precip_comb, precip_scf_comb, tair_comb ! areally averaged forcings across HRUs contains diff --git a/src/share/ioModule.f90 b/src/share/ioModule.f90 index 31405e8..65e3469 100644 --- a/src/share/ioModule.f90 +++ b/src/share/ioModule.f90 @@ -507,52 +507,32 @@ SUBROUTINE write_snow17_output(namelist, runinfo, parameters, forcing, modelvar, ! ==== WRITE output for current area simulation ==== ! Note: write order should match header written by open_and_init_output_files() - 32 FORMAT(I4.4, 3(1x,I2.2), 6(F10.3)) + !32 FORMAT(I4.4, 3(1x,I2.2), F10.3, 2(F15.10), 2(F10.3), F15.10) ! if writing pcp & raim as rates + 32 FORMAT(I4.4, 3(1x,I2.2), 6(F10.3)) ! if writing them as depths ! if user setting is to write out information for each snowband, open the individual files if (namelist%output_hrus == 1 .and. runinfo%n_hrus > 1) then - write(runinfo%output_fileunits(n_curr_hru+1), 32, iostat=ierr) runinfo%curr_yr, runinfo%curr_mo, runinfo%curr_dy, runinfo%curr_hr, & - forcing%tair(n_curr_hru), forcing%precip(n_curr_hru), forcing%precip(n_curr_hru)*parameters%scf(n_curr_hru), & - modelvar%sneqv(n_curr_hru)*1000., modelvar%snowh(n_curr_hru), modelvar%raim(n_curr_hru) + ! writing precip & raim vars as depths (mm) not rates for ease of comparison w/ SWE + write(runinfo%output_fileunits(n_curr_hru+1), 32, iostat=ierr) runinfo%curr_yr, runinfo%curr_mo, & + runinfo%curr_dy, runinfo%curr_hr, & + forcing%tair(n_curr_hru), forcing%precip(n_curr_hru)*runinfo%dt, & + forcing%precip_scf(n_curr_hru)*runinfo%dt, & + modelvar%sneqv(n_curr_hru)*1000., modelvar%snowh(n_curr_hru), modelvar%raim(n_curr_hru)*runinfo%dt if(ierr /= 0) then - print*, 'ERROR writing output information for basin average'; stop + print*, 'ERROR writing output information for sub-unit ', n_curr_hru; stop endif end if ! IF case for writing HRU-specific output to file (not including states) ! ==== if all snowbands have been run, sum across snowbands with weighting for snowband area ==== - - ! initialize for timestep - forcing%tair_comb = 0.0 - forcing%precip_comb = 0.0 - forcing%precip_scf_comb = 0.0 - modelvar%sneqv_comb = 0.0 - modelvar%snowh_comb = 0.0 - modelvar%raim_comb = 0.0 - + if (n_curr_hru .eq. runinfo%n_hrus) then - do nh=1, runinfo%n_hrus - forcing%tair_comb = forcing%tair_comb + forcing%tair(nh) * parameters%hru_area(nh) - forcing%precip_comb = forcing%precip_comb + forcing%precip(nh) * parameters%hru_area(nh) - forcing%precip_scf_comb = forcing%precip_scf_comb + forcing%precip(nh) * parameters%hru_area(nh) * parameters%scf(nh) - modelvar%sneqv_comb = modelvar%sneqv_comb + modelvar%sneqv(nh) * parameters%hru_area(nh) - modelvar%snowh_comb = modelvar%snowh_comb + modelvar%snowh(nh) * parameters%hru_area(nh) - modelvar%raim_comb = modelvar%raim_comb + modelvar%raim(nh) * parameters%hru_area(nh) - end do - - ! take average of weighted sum of HRU areas - forcing%tair_comb = forcing%tair_comb / parameters%total_area - forcing%precip_comb = forcing%precip_comb / parameters%total_area - forcing%precip_scf_comb = forcing%precip_scf_comb / parameters%total_area - modelvar%sneqv_comb = modelvar%sneqv_comb / parameters%total_area - modelvar%snowh_comb = modelvar%snowh_comb / parameters%total_area - modelvar%raim_comb = modelvar%raim_comb / parameters%total_area - - ! -- write out combined file that is similar to each area file, but add flow variable in CFS units - write(runinfo%output_fileunits(1), 32, iostat=ierr) runinfo%curr_yr, runinfo%curr_mo, runinfo%curr_dy, runinfo%curr_hr, & - forcing%tair_comb, forcing%precip_comb, forcing%precip_scf_comb, & - modelvar%sneqv_comb*1000.0, modelvar%snowh_comb, modelvar%raim_comb + ! -- write out combined file that is similar to each sub-unit area file + write(runinfo%output_fileunits(1), 32, iostat=ierr) runinfo%curr_yr, runinfo%curr_mo, & + runinfo%curr_dy, runinfo%curr_hr, & + forcing%tair_comb, forcing%precip_comb*runinfo%dt, forcing%precip_scf_comb*runinfo%dt, & + modelvar%sneqv_comb*1000.0, modelvar%snowh_comb, modelvar%raim_comb*runinfo%dt if(ierr /= 0) then - print*, 'ERROR writing output information for sub-unit ', n_curr_hru; stop + print*, 'ERROR writing output information for basin average'; stop endif endif diff --git a/src/share/modelVarType.f90 b/src/share/modelVarType.f90 index c573741..4dff325 100644 --- a/src/share/modelVarType.f90 +++ b/src/share/modelVarType.f90 @@ -8,13 +8,13 @@ module modelVarType type, public :: modelvar_type ! main model states and flux variable - real, dimension(:), allocatable :: sneqv ! snow water equivalent (unit) - real, dimension(:), allocatable :: snowh ! snow height - real, dimension(:), allocatable :: snow ! snow (?) -- seems same as snowh but used in snow19() - real, dimension(:), allocatable :: raim ! rain and melt output + real, dimension(:), allocatable :: sneqv ! snow water equivalent (mm) + real, dimension(:), allocatable :: snowh ! snow height (mm) + real, dimension(:), allocatable :: snow ! snow (?) -- seems same as snowh but used in snow19() (mm) + real, dimension(:), allocatable :: raim ! rain and melt output (mm/s) ! other states and carryover variables - real, dimension(:), allocatable :: tprev + real, dimension(:), allocatable :: tprev ! stores previous timestep temperature (degC) real, dimension(:,:), allocatable :: cs ! 19-element vector per HRU used in snow19: (n_hrus, 19) ! areally-averaged variables for output diff --git a/src/share/parametersType.f90 b/src/share/parametersType.f90 index 45ca44d..c6756f8 100644 --- a/src/share/parametersType.f90 +++ b/src/share/parametersType.f90 @@ -53,20 +53,17 @@ subroutine initParams(this, namelist) allocate(this%plwhc(n_hrus)) allocate(this%daygm(n_hrus)) - ! - !Reversed the row and column for this `adc' array such that + ! Reversed the row and column for this `adc' array such that ! we can pass a slice of the array to other subroutines in ! a contiguous memory. Otherwise, we will receive warnings ! at runtime about creation of a temporary array and the performance ! is impaired. The reason is that ! Fortran stores arrays as 'column major'. - ! - !allocate(this%adc(n_hrus, 11)) !=> runtime warning ! 11 points (0.0 to 1.0 in 0.1 increments) - ! - allocate(this%adc(11,n_hrus)) ! 11 points (0.0 to 1.0 in 0.1 increments) + + allocate(this%adc(11, n_hrus)) ! 11 points (0.0 to 1.0 in 0.1 increments) ! assign defaults (if any) - this%total_area = huge(1.0) + this%total_area = huge(1.0) end subroutine initParams diff --git a/src/share/runInfoType.f90 b/src/share/runInfoType.f90 index e79d170..dbe5384 100644 --- a/src/share/runInfoType.f90 +++ b/src/share/runInfoType.f90 @@ -10,7 +10,7 @@ module runInfoType type, public :: runinfo_type ! time-space information about the model run - integer :: n_hrus ! number of HRU areas in parameter files + integer :: n_hrus ! number of HRU areas in parameter files character(len=10) :: start_datehr ! Start date of the model run ( YYYYMMDDHH ) character(len=10) :: end_datehr ! End date of the model run ( YYYYMMDDHH ) character(len=10) :: curr_datehr ! Current date of the model run ( YYYYMMDDHH ) diff --git a/src/share/runSnow17.f90 b/src/share/runSnow17.f90 index b5ae74e..f658af4 100644 --- a/src/share/runSnow17.f90 +++ b/src/share/runSnow17.f90 @@ -92,7 +92,6 @@ SUBROUTINE initialize_from_file (model, config_file) END SUBROUTINE initialize_from_file - ! == Move the model ahead one time step ================================================================ SUBROUTINE advance_in_time(model) type (snow17_type), intent (inout) :: model @@ -119,6 +118,7 @@ SUBROUTINE solve_snow17(model) ! local parameters integer :: nh ! counter for snowbands + real :: prcp_mm ! precip as a depth (for input to snow17) (mm) associate(namelist => model%namelist, & runinfo => model%runinfo, & @@ -134,14 +134,26 @@ SUBROUTINE solve_snow17(model) call read_areal_forcing(namelist, parameters, runinfo, forcing) #endif + !--------------------------------------------------------------------- + ! initialize basin-average variables + !--------------------------------------------------------------------- + forcing%tair_comb = 0.0 + forcing%precip_comb = 0.0 + forcing%precip_scf_comb = 0.0 + modelvar%sneqv_comb = 0.0 + modelvar%snowh_comb = 0.0 + modelvar%raim_comb = 0.0 + !--------------------------------------------------------------------- ! call the main snow17 state update routine in loop over spatial sub-units !--------------------------------------------------------------------- do nh=1, runinfo%n_hrus + prcp_mm = forcing%precip(nh)*runinfo%dt ! convert prcp input to a depth per timestep (mm) + call exsnow19(int(runinfo%dt), int(runinfo%dt/3600), runinfo%curr_dy, runinfo%curr_mo, runinfo%curr_yr, & ! SNOW17 INPUT AND OUTPUT VARIABLES - forcing%precip(nh), forcing%tair(nh), modelvar%raim(nh), modelvar%sneqv(nh), modelvar%snow(nh), modelvar%snowh(nh), & + prcp_mm, forcing%tair(nh), modelvar%raim(nh), modelvar%sneqv(nh), modelvar%snow(nh), modelvar%snowh(nh), & ! SNOW17 PARAMETERS !ALAT,SCF,MFMAX,MFMIN,UADJ,SI,NMF,TIPM,MBASE,PXTEMP,PLWHC,DAYGM,ELEV,PA,ADC parameters%latitude(nh), parameters%scf(nh), parameters%mfmax(nh), parameters%mfmin(nh), & @@ -149,7 +161,28 @@ SUBROUTINE solve_snow17(model) parameters%pxtemp(nh), parameters%plwhc(nh), parameters%daygm(nh), parameters%elev(nh), forcing%pa(nh), & parameters%adc(:,nh), & ! SNOW17 CARRYOVER VARIABLES - modelvar%cs(:,nh), modelvar%tprev(nh) ) + modelvar%cs(:,nh), modelvar%tprev(nh) ) + + ! convert raim output to a rate (mm/s) + modelvar%raim(nh) = modelvar%raim(nh) / runinfo%dt + + ! update basin-averaged variables + forcing%tair_comb = forcing%tair_comb + forcing%tair(nh) * parameters%hru_area(nh) + forcing%precip_comb = forcing%precip_comb + forcing%precip(nh) * parameters%hru_area(nh) + forcing%precip_scf_comb = forcing%precip_scf_comb + forcing%precip_scf(nh) * parameters%hru_area(nh) + modelvar%sneqv_comb = modelvar%sneqv_comb + modelvar%sneqv(nh) * parameters%hru_area(nh) + modelvar%snowh_comb = modelvar%snowh_comb + modelvar%snowh(nh) * parameters%hru_area(nh) + modelvar%raim_comb = modelvar%raim_comb + modelvar%raim(nh) * parameters%hru_area(nh) + + ! ==== if all snowbands have been run, sum across snowbands with weighting for snowband area ==== + if (nh .eq. runinfo%n_hrus) then + forcing%tair_comb = forcing%tair_comb / parameters%total_area + forcing%precip_comb = forcing%precip_comb / parameters%total_area + forcing%precip_scf_comb = forcing%precip_scf_comb / parameters%total_area + modelvar%sneqv_comb = modelvar%sneqv_comb / parameters%total_area + modelvar%snowh_comb = modelvar%snowh_comb / parameters%total_area + modelvar%raim_comb = modelvar%raim_comb / parameters%total_area + end if !--------------------------------------------------------------------- ! add results to output file if NGEN_OUTPUT_ACTIVE is undefined diff --git a/test_cases/ex1.tgz b/test_cases/ex1.tgz index b3f53d3..4df14a9 100644 Binary files a/test_cases/ex1.tgz and b/test_cases/ex1.tgz differ diff --git a/test_cases/ex1/input/params/snow17_params.HHWM8.txt b/test_cases/ex1/input/params/snow17_params.HHWM8.txt deleted file mode 100644 index 098c997..0000000 --- a/test_cases/ex1/input/params/snow17_params.HHWM8.txt +++ /dev/null @@ -1,26 +0,0 @@ -hru_id HHWM8IL HHWM8IU -hru_area 2994.7 1271.3 -latitude 47.78 47.78 -elev 1612.50 2153.35 -scf 2.15177 1.86124 -mfmax 0.930472 0.754924 -mfmin 0.137 0.160 -uadj 0.003103 0.208042 -si 1515.00 1515.00 -pxtemp 0.713424 0.220934 -nmf 0.150 0.150 -tipm 0.200 0.050 -mbase 0.000 0.000 -plwhc 0.030 0.030 -daygm 0.300 0.200 -adc1 0.050 0.050 -adc2 0.090 0.090 -adc3 0.160 0.160 -adc4 0.310 0.310 -adc5 0.540 0.540 -adc6 0.740 0.740 -adc7 0.840 0.840 -adc8 0.890 0.890 -adc9 0.930 0.930 -adc10 0.970 0.970 -adc11 1.000 1.000 diff --git a/test_cases/ex1/run/namelist.bmi.HHWM8 b/test_cases/ex1/run/namelist.bmi.HHWM8 deleted file mode 100644 index 16f76b0..0000000 --- a/test_cases/ex1/run/namelist.bmi.HHWM8 +++ /dev/null @@ -1,26 +0,0 @@ -&SNOW17_CONTROL -! === run control file for snow17bmi v. 1.x === - -! -- basin config and path information -main_id = "HHWM8" ! basin label or gage id -n_hrus = 2 ! number of sub-areas in model -forcing_root = "../input/forcing/forcing.snow17bmi." -output_root = "../output/output.snow17bmi." -snow17_param_file = "../input/params/snow17_params.HHWM8.txt" -output_hrus = 1 ! output HRU results? (1=yes; 0=no) - -! -- run period information -start_datehr = 1970010112 ! start date time, backward looking (check) -end_datehr = 2015123112 ! end date time -model_timestep = 86400 ! in seconds (86400 seconds = 1 day) - -! -- state start/write flags and files -warm_start_run = 0 ! is this run started from a state file? (no=0 yes=1) -write_states = 1 ! write restart/state files for 'warm_start' runs (no=0 yes=1) - -! -- filenames only needed if warm_start_run = 1 -snow_state_in_root = "../state/snow17_states." ! input state filename root - -! -- filenames only needed if write_states = 1 -snow_state_out_root = "../state/snow17_states." ! output states filename root -/ diff --git a/test_cases/ex1/run/runSnow17.csh b/test_cases/ex1/run/runSnow17.csh deleted file mode 100755 index 13fef4f..0000000 --- a/test_cases/ex1/run/runSnow17.csh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/csh -# A. Wood, 2016; updated May 2022 for snow only version using BMI - -# Run general distributed snow17 code, which loops over lumped code version for multiple model areas and -# writes an additional combined (basin mean) output file - -# To run the snow17/sac model, just execute this script (or else the command below) - -../../../bin/snow17.exe namelist.bmi.HHWM8 diff --git a/test_cases/ex1/state/README b/test_cases/ex1/state/README deleted file mode 100644 index 6de873b..0000000 --- a/test_cases/ex1/state/README +++ /dev/null @@ -1,2 +0,0 @@ -state file output contains states for all days in the run, arranges one row per day -state file input has same format, and can contain any number of dates