From f939e07ba45397bbc697f83cedbcbb19ad4c2256 Mon Sep 17 00:00:00 2001 From: "K. Jennings" <32177682+SnowHydrology@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:15:43 -0400 Subject: [PATCH 1/6] return and bmi_failure flags for energymodule error --- bmi/bmi_noahowp.f90 | 7 ++++++- src/DomainType.f90 | 4 ++++ src/EnergyModule.f90 | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/bmi/bmi_noahowp.f90 b/bmi/bmi_noahowp.f90 index dfbeec87..d26aaef1 100644 --- a/bmi/bmi_noahowp.f90 +++ b/bmi/bmi_noahowp.f90 @@ -269,7 +269,12 @@ function noahowp_update(this) result (bmi_status) integer :: bmi_status call advance_in_time(this%model) - bmi_status = BMI_SUCCESS + if (this%model%domain%error_flag /= 0) then + bmi_status = BMI_FAILURE + return + else + bmi_status = BMI_SUCCESS + end if end function noahowp_update ! Advance the model until the given time. diff --git a/src/DomainType.f90 b/src/DomainType.f90 index 12f4d2b4..8e399b26 100644 --- a/src/DomainType.f90 +++ b/src/DomainType.f90 @@ -31,6 +31,8 @@ module DomainType integer :: croptype ! crop type integer :: isltyp ! soil type integer :: IST ! surface type 1-soil; 2-lake + integer :: error_flag ! flag for energy balance error (0 = no error, 1 = longwave < 0) + real, allocatable, dimension(:) :: zsoil ! depth of layer-bottom from soil surface real, allocatable, dimension(:) :: dzsnso ! snow/soil layer thickness [m] real, allocatable, dimension(:) :: zsnso ! depth of snow/soil layer-bottom @@ -93,6 +95,7 @@ subroutine InitDefault(this) this%croptype = huge(1) this%isltyp = huge(1) this%IST = huge(1) + this%error_flag = huge(1) end subroutine InitDefault @@ -116,6 +119,7 @@ subroutine InitTransfer(this, namelist) this%croptype = namelist%croptype this%isltyp = namelist%isltyp this%IST = namelist%sfctyp + this%error_flag = 0 ! model initializes with no errors this%start_datetime = date_to_unix(namelist%startdate) ! returns seconds-since-1970-01-01 this%end_datetime = date_to_unix(namelist%enddate) diff --git a/src/EnergyModule.f90 b/src/EnergyModule.f90 index 7eff19a3..22c7577a 100644 --- a/src/EnergyModule.f90 +++ b/src/EnergyModule.f90 @@ -300,12 +300,13 @@ SUBROUTINE EnergyMain (domain, levels, options, parameters, forcing, energy, wat FIRE = forcing%LWDN + energy%FIRA IF(FIRE <=0.) THEN + domain%error_flag = 1 WRITE(*,*) 'emitted longwave <0; skin T may be wrong due to inconsistent' WRITE(*,*) 'input of SHDFAC with LAI' WRITE(*,*) domain%ILOC, domain%JLOC, 'SHDFAC=',parameters%FVEG,'parameters%VAI=',parameters%VAI,'TV=',energy%TV,'TG=',energy%TG WRITE(*,*) 'LWDN=',forcing%LWDN,'energy%FIRA=',energy%FIRA,'water%SNOWH=',water%SNOWH WRITE(*,*) 'Exiting ...' - STOP + RETURN END IF ! Compute a net emissivity From be6a6396bf62cac70399981223385e024fcc7aff Mon Sep 17 00:00:00 2001 From: Steve Drake Date: Mon, 13 May 2024 12:08:06 -0700 Subject: [PATCH 2/6] Changed STOP to RETURN with signature changes up call stack --- bmi/bmi_noahowp.f90 | 10 +-- driver/AsciiReadModule.f90 | 55 ++++++++++------ driver/NoahModularDriver.f90 | 16 +++++ src/DateTimeUtilsModule.f90 | 22 ++++--- src/DomainType.f90 | 4 ++ src/EnergyModule.f90 | 15 +++-- src/ErrorCheckModule.f90 | 30 ++++++++- src/ParametersRead.f90 | 117 +++++++++++++++++++++++------------ src/ParametersType.f90 | 28 +++++++-- src/RunModule.f90 | 34 ++++++++-- src/UtilitiesModule.f90 | 73 +++++++++++++++------- 11 files changed, 294 insertions(+), 110 deletions(-) diff --git a/bmi/bmi_noahowp.f90 b/bmi/bmi_noahowp.f90 index d26aaef1..beb47a06 100644 --- a/bmi/bmi_noahowp.f90 +++ b/bmi/bmi_noahowp.f90 @@ -196,12 +196,14 @@ function noahowp_initialize(this, config_file) result (bmi_status) character (len=*), intent(in) :: config_file integer :: bmi_status + bmi_status = BMI_SUCCESS if (len(config_file) > 0) then call initialize_from_file(this%model, config_file) else !call initialize_from_defaults(this%model) end if - bmi_status = BMI_SUCCESS + bmi_status = this%model%domain%error_flag + end function noahowp_initialize ! BMI finalizer. @@ -267,14 +269,14 @@ end function noahowp_time_units function noahowp_update(this) result (bmi_status) class (bmi_noahowp), intent(inout) :: this integer :: bmi_status + bmi_status = BMI_SUCCESS call advance_in_time(this%model) - if (this%model%domain%error_flag /= 0) then + if (this%model%domain%error_flag == BMI_FAILURE) then bmi_status = BMI_FAILURE return - else - bmi_status = BMI_SUCCESS end if + end function noahowp_update ! Advance the model until the given time. diff --git a/driver/AsciiReadModule.f90 b/driver/AsciiReadModule.f90 index 57df6d6a..66cc3aa1 100644 --- a/driver/AsciiReadModule.f90 +++ b/driver/AsciiReadModule.f90 @@ -1,16 +1,19 @@ module AsciiReadModule use UtilitiesModule + use ErrorCheckModule implicit none contains - subroutine open_forcing_file(filename) + subroutine open_forcing_file(filename, error_flag) implicit none character*256, intent(in) :: filename + integer, intent(out) :: error_flag + character(len=256) :: error_string !--------------------------------------------------------------------- ! local variables @@ -22,23 +25,25 @@ subroutine open_forcing_file(filename) ! Check if the specified file exists inquire(file = trim(filename), exist = lexist) if (.not. lexist) then - write(*,'(/," ***** Problem *****")') - write(*,'(" ***** File ''", A, "'' does not exist.")') trim(filename) - write(*,'(" ***** Check the forcing file specified as a command-line argument",/)') - stop ": ERROR EXIT" + error_flag = NOM_FAILURE + write(error_string,'(A,A,A)') "AsciiReadModule.f90:open_forcing_file(): File: ",trim(filename), " does not exist. Check the forcing file specified as a command-line argument" + call log_message(error_flag, error_string) + return endif ! Open the forcing file open(10, file = trim(filename), form = 'formatted', action = 'read', iostat = ierr) if (ierr /= 0) then - write(*,'("Problem opening file ''", A, "''")') trim(filename) - stop ": ERROR EXIT" + error_flag = NOM_FAILURE + write(error_string,'(A,A,A)') "ReadModule.f90:open_forcing_file(): Problem opening file: ",trim(filename) + call log_message(error_flag, error_string) + return endif end subroutine open_forcing_file subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & - u, v, sfctmp, spechumd, sfcprs, swrad, lwrad, pcprate, ierr) + u, v, sfctmp, spechumd, sfcprs, swrad, lwrad, pcprate, ierr, error_flag) implicit none @@ -55,6 +60,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & real, intent(out) :: lwrad real, intent(out) :: pcprate integer, intent(out) :: ierr + integer, intent(out) :: error_flag real, intent(out) :: u real, intent(out) :: v @@ -66,6 +72,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & integer :: hour integer :: minute character(len=12) :: readdate + character(len=256):: error_string real :: read_windspeed real :: read_winddir real :: read_temperature @@ -166,10 +173,11 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & return endif - if (ierr /= 0) then - write(*,'("Error reading from data file.")') - ierr = 2 - return + if (ierr /= 0) then + error_flag = NOM_FAILURE + write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): Error reading from data file." + call log_message(error_flag, error_string) + return endif write(readdate,'(I4.4,4I2.2)') year, month, day, hour, minute @@ -185,7 +193,10 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & before = fdata ( readdate, read_windspeed, read_winddir, read_temperature, read_humidity, read_pressure, read_swrad, read_lwrad, read_rain ) cycle READLOOP else - stop "Logic problem" + error_flag = NOM_FAILURE + write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): Logic problem." + call log_message(error_flag, error_string) + return endif enddo READLOOP @@ -216,8 +227,11 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & else if (before%readdate < nowdate .and. nowdate < after%readdate) then - call geth_idts(nowdate, before%readdate, idts) - call geth_idts(after%readdate, before%readdate, idts2) + call geth_idts(nowdate, before%readdate, idts, error_flag) + call geth_idts(after%readdate, before%readdate, idts2, error_flag) + if (error_flag == NOM_FAILURE) then + return + endif if (idts2*60 /= forcing_timestep) then print*, 'forcing_timestep = ', forcing_timestep @@ -226,7 +240,10 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & print*, 'idts = ', idts print*,' after%readdate = ', after%readdate print*, 'idts2 = ', idts2 - stop "IDTS PROBLEM" + error_flag = NOM_FAILURE + write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): IDTS PROBLEM." + call log_message(error_flag, error_string) + return endif fraction = real(idts2-idts)/real(idts2) @@ -250,8 +267,10 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & rhf = rhf * 1.E-2 else - print*, 'nowdate = "'//nowdate//'"' - stop "Problem in the logic of read_forcing_text." + error_flag = NOM_FAILURE + write(error_string,'(A,A,A)') "AsciiReadModule.f90:read_forcing_text(): date: ", nowdate, ". Problem in the logic of read_forcing_text." + call log_message(error_flag, error_string) + return endif ! Below commented out KSJ 2021-06-09 diff --git a/driver/NoahModularDriver.f90 b/driver/NoahModularDriver.f90 index a86ef930..02562169 100644 --- a/driver/NoahModularDriver.f90 +++ b/driver/NoahModularDriver.f90 @@ -29,6 +29,14 @@ program model_driver print*, "Initializing..." call get_command_argument(1, arg) status = m%initialize(arg) + if (status == BMI_FAILURE) then +#ifdef NGEN_ACTIVE + return status ! if NGEN +#else + print*, "Stopping program." + stop +#endif + end if !--------------------------------------------------------------------- ! Run the model with BMI @@ -43,6 +51,14 @@ program model_driver print*, "Running..." do while (current_time < end_time) status = m%update() ! run the model one time step + if (status == BMI_FAILURE) then +#ifdef NGEN_ACTIVE + return status ! if NGEN +#else + print*, "Stopping program." + stop +#endif + end if status = m%get_current_time(current_time) ! update current_time end do diff --git a/src/DateTimeUtilsModule.f90 b/src/DateTimeUtilsModule.f90 index f394b6c8..3b1a091f 100644 --- a/src/DateTimeUtilsModule.f90 +++ b/src/DateTimeUtilsModule.f90 @@ -3,6 +3,8 @@ module DateTimeUtilsModule + use ErrorCheckModule + implicit none public @@ -879,14 +881,15 @@ double precision function date_to_unix (date) character (len=*), intent (in) :: date double precision :: u_day, i_day, days integer :: sec, min, hour, day, month, year, error + character(len=256) :: error_string call parse_date (date, year, month, day, hour, min, sec, error) if (error /= 0) then date_to_unix = -9999.99 - print*, 'error in date_to_unix -- date, year, month, day, hour, min, sec, error:' - print*, date, year, month, day, hour, min, sec, error - stop !return + write(error_string,'(A,A,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4)') "DateTimeUtilsModule.f90:date_to_unix(): date: ",date," year: ",year," month: ",month," day: ",day," hour: ",hour," min: ",min," sec: ",sec, " Error: ",error + call log_message(NOM_FAILURE, error_string) + return end if u_day = julian_date (1, 1, 1970) @@ -959,7 +962,7 @@ integer function julian_date (day, month, year) end function julian_date - subroutine get_utime_list (start_datetime, end_datetime, dt, times) + subroutine get_utime_list (start_datetime, end_datetime, dt, times, error_flag) ! makes a list of data times in secs since 1970-1-1 corresponding to requested period ! reports end-of-timestep points implicit none @@ -967,15 +970,18 @@ subroutine get_utime_list (start_datetime, end_datetime, dt, times) real*8, intent (in) :: start_datetime, end_datetime real, intent (in) :: dt real*8, allocatable, intent (out) :: times(:) + integer, intent (out) :: error_flag !local integer :: t, ntimes real*8 :: utime + character(len=256) :: error_string if(abs(mod(end_datetime - start_datetime, dt)) > 1e-5) then - print*, 'start and end datetimes are not an even multiple of dt -- check dates in namelist' - print*, 'end_datetime, start_datetime, dt, mod:', end_datetime, start_datetime, dt, mod(end_datetime-start_datetime, dt) - stop - end if + error_flag = NOM_FAILURE + write(error_string,'(A,G8.3,A,G8.3,A,G8.3,A,G8.3)') "DateTimeUtilsModule.f90:get_utime_list(): start and end datetimes are not an even multiple of dt -- check dates in namelist: end_datetime: ",end_datetime," start_datetime: ",start_datetime," dt: ",dt," mod: ", mod(end_datetime-start_datetime, dt) + call log_message(error_flag, error_string) + return + endif ntimes = int((end_datetime - start_datetime)/dt) + 1 allocate (times(ntimes)) diff --git a/src/DomainType.f90 b/src/DomainType.f90 index 8e399b26..58767fa3 100644 --- a/src/DomainType.f90 +++ b/src/DomainType.f90 @@ -2,6 +2,7 @@ module DomainType use NamelistRead, only: namelist_type use DateTimeUtilsModule +use ErrorCheckModule implicit none save @@ -122,6 +123,9 @@ subroutine InitTransfer(this, namelist) this%error_flag = 0 ! model initializes with no errors this%start_datetime = date_to_unix(namelist%startdate) ! returns seconds-since-1970-01-01 this%end_datetime = date_to_unix(namelist%enddate) + if (this%start_datetime < 0 .OR. this%end_datetime < 0) then + this%error_flag = NOM_FAILURE + endif end subroutine InitTransfer diff --git a/src/EnergyModule.f90 b/src/EnergyModule.f90 index 22c7577a..4632be47 100644 --- a/src/EnergyModule.f90 +++ b/src/EnergyModule.f90 @@ -2,6 +2,7 @@ module EnergyModule use LevelsType use DomainType + use ErrorCheckModule use OptionsType use ParametersType use WaterType @@ -45,6 +46,7 @@ SUBROUTINE EnergyMain (domain, levels, options, parameters, forcing, energy, wat REAL :: D_RSURF ! Reduced vapor diffusivity in soil for computing RSURF (SZ09) REAL :: FIRE !emitted IR (w/m2) + CHARACTER(len=256) :: error_string !--------------------------------------------------------------------- ! Initialize the the fluxes from the vegetated fraction @@ -300,12 +302,13 @@ SUBROUTINE EnergyMain (domain, levels, options, parameters, forcing, energy, wat FIRE = forcing%LWDN + energy%FIRA IF(FIRE <=0.) THEN - domain%error_flag = 1 - WRITE(*,*) 'emitted longwave <0; skin T may be wrong due to inconsistent' - WRITE(*,*) 'input of SHDFAC with LAI' - WRITE(*,*) domain%ILOC, domain%JLOC, 'SHDFAC=',parameters%FVEG,'parameters%VAI=',parameters%VAI,'TV=',energy%TV,'TG=',energy%TG - WRITE(*,*) 'LWDN=',forcing%LWDN,'energy%FIRA=',energy%FIRA,'water%SNOWH=',water%SNOWH - WRITE(*,*) 'Exiting ...' + domain%error_flag = NOM_FAILURE + write(error_string,101) 'EnergyModule.f90:EnergyMain(): emitted longwave <0; skin T & + may be wrong due to inconsistent input of SHDFAC with LAI. ILOC=', & + domain%ILOC, ', JLOC=',domain%JLOC, ', SHDFAC=',parameters%FVEG,', & + parameters%VAI=',parameters%VAI,', TV=',energy%TV,', TG=',energy%TG +101 format(A,I10,A,I10,A,F8.3,A,F8.3,A,F8.3,A,F8.3) + call log_message(domain%error_flag, trim(error_string)) RETURN END IF diff --git a/src/ErrorCheckModule.f90 b/src/ErrorCheckModule.f90 index f3306965..33ef516a 100644 --- a/src/ErrorCheckModule.f90 +++ b/src/ErrorCheckModule.f90 @@ -1,12 +1,15 @@ module ErrorCheckModule - ! General error checking routins - + ! General error checking routines implicit none + integer, parameter, public :: NOM_SUCCESS = 0 + integer, parameter, public :: NOM_FAILURE = 1 + integer, parameter, public :: NOM_MESSAGE = 2 private public:: sys_abort public:: is_within_bound + public:: log_message interface is_within_bound module procedure is_within_bound_int @@ -32,6 +35,29 @@ subroutine sys_abort(err, message) end subroutine sys_abort + subroutine log_message(err, message) + + ! log information, typically an error + + implicit none + + integer, intent(in) :: err ! error code + character(*), intent(in) :: message ! message + + ! If error, write the error. If message, write message unless NGEN_QUIET + if(err==NOM_FAILURE)then + write(*, '(A,I2,A)') ' Error Code: ', err, ', Message: '//trim(message) + call flush(6) + endif +#ifndef NGEN_QUIET + if(err==NOM_MESSAGE)then + write(*, '(A,I2,A)') ' Error Code: ', err, ', Message: '//trim(message) + call flush(6) + endif +#endif + + end subroutine log_message + function is_within_bound_int(var, lower_bound, upper_bound) result(withinbound) ! check if a integer value is within specified bounds diff --git a/src/ParametersRead.f90 b/src/ParametersRead.f90 index 0f04f0c6..0169cb0c 100644 --- a/src/ParametersRead.f90 +++ b/src/ParametersRead.f90 @@ -1,5 +1,7 @@ MODULE ParametersRead +use ErrorCheckModule + ! Parameter table read routines: ! Adapted from the original module_sf_noahmplsm.F module with several modifications ! 1. made _TABLE variables public. @@ -309,17 +311,20 @@ MODULE ParametersRead CONTAINS - SUBROUTINE read_veg_parameters(param_dir, noahowp_table, DATASET_IDENTIFIER) + SUBROUTINE read_veg_parameters(param_dir, noahowp_table, & + DATASET_IDENTIFIER, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table character(len=*), intent(in) :: DATASET_IDENTIFIER + integer, intent(out):: error_flag integer :: ierr integer :: IK,IM logical :: file_named integer :: NVEG character(len=256) :: VEG_DATASET_DESCRIPTION + character(len=256) :: error_string integer :: ISURBAN integer :: ISWATER @@ -451,7 +456,10 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, DATASET_IDENTIFIER) end if if (ierr /= 0) then - call handle_err(ierr, "ParametersRead.f90: read_veg_parameters: Cannot find file MPTABLE.TBL") + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_veg_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif if ( trim(DATASET_IDENTIFIER) == "USGS" ) then @@ -461,8 +469,10 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, DATASET_IDENTIFIER) read(15,modis_veg_categories) read(15,modis_veg_parameters) else - write(*,'("WARNING: DATASET_IDENTIFIER = ''", A, "''")') trim(DATASET_IDENTIFIER) - call handle_err(ierr, 'ParametersRead.f90: read_veg_parameters: Unrecognized DATASET_IDENTIFIER in subroutine read_VEG_PARAMETERS') + error_flag = NOM_FAILURE + write(error_string,'(A,A)') "ParametersRead.f90:read_veg_parameters(): Unrecognized DATASET_IDENTIFIER: ", trim(DATASET_IDENTIFIER) + call log_message(error_flag, error_string) + return endif close(15) @@ -569,17 +579,20 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, DATASET_IDENTIFIER) END SUBROUTINE read_veg_parameters - SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, soil_class_name) + SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, & + soil_class_name, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: soil_table character(len=*), intent(in) :: general_table character(len=*), intent(in) :: soil_class_name + integer, intent(out):: error_flag integer :: IERR character(len=20) :: SLTYPE integer :: ITMP, NUM_SLOPE, LC integer :: iLine ! loop index - character(len=256) :: message + !character(len=256) :: message + character(len=256) :: error_string logical :: file_named @@ -619,10 +632,13 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, soil_class open(21, form='formatted',status='old',iostat=ierr) end if - if (ierr/=0) then - write(message,fmt='(A)') 'ParametersRead.f90: read_soil_parameters: failure opening SOILPARM.TBL' - call handle_err(ierr, message) - end if + if (ierr /= 0) then + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_soil_parameters(): failure opening SOILPARM.TBL" + call log_message(error_flag, error_string) + return + endif + do iLine = 1,100 READ (21,*) SLTYPE @@ -655,8 +671,11 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, soil_class end if if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_soil_parameters: failure opening GENPARM.TBL') - end if + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_soil_parameters(): failure opening GENPARM.TBL" + call log_message(error_flag, error_string) + return + endif read (22,*) read (22,*) @@ -698,12 +717,14 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, soil_class END SUBROUTINE read_soil_parameters - SUBROUTINE read_rad_parameters(param_dir, noahowp_table) + SUBROUTINE read_rad_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + integer, intent(out):: error_flag integer :: ierr logical :: file_named + character(len=256) :: error_string real :: ALBICE(MBAND),ALBLAK(MBAND),OMEGAS(MBAND),BETADS,BETAIS,EG(2) real :: ALBSAT_VIS(MSC) @@ -731,7 +752,10 @@ SUBROUTINE read_rad_parameters(param_dir, noahowp_table) end if if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_rad_parameters: Cannot find file MPTABLE.TBL') + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_rad_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif read(15,rad_parameters) @@ -750,12 +774,14 @@ SUBROUTINE read_rad_parameters(param_dir, noahowp_table) end subroutine read_rad_parameters - subroutine read_global_parameters(param_dir, noahowp_table) + subroutine read_global_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + integer, intent(out):: error_flag integer :: ierr logical :: file_named + character(len=256) :: error_string real :: CO2,O2,TIMEAN,FSATMX,Z0SNO,SSI,SNOW_RET_FAC,SNOW_EMIS,& SWEMX,TAU0,GRAIN_GROWTH,EXTRA_GROWTH,DIRT_SOOT,& @@ -800,7 +826,10 @@ subroutine read_global_parameters(param_dir, noahowp_table) end if if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_global_parameters: Cannot find file MPTABLE.TBL') + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_global_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif read(15,global_parameters) @@ -831,12 +860,14 @@ subroutine read_global_parameters(param_dir, noahowp_table) END SUBROUTINE read_global_parameters - SUBROUTINE read_crop_parameters(param_dir, noahowp_table) + SUBROUTINE read_crop_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + integer, intent(out):: error_flag integer :: ierr logical :: file_named + character(len=256) :: error_string integer :: DEFAULT_CROP integer, dimension(NCROP) :: PLTDAY @@ -979,8 +1010,11 @@ SUBROUTINE read_crop_parameters(param_dir, noahowp_table) open(15, status='old', form='formatted', action='read', iostat=ierr) end if - if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_crop_parameters: Cannot find file MPTABLE.TBL') + if (ierr /= 0) then + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_crop_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif read(15,crop_parameters) @@ -1126,12 +1160,14 @@ SUBROUTINE read_crop_parameters(param_dir, noahowp_table) END SUBROUTINE read_crop_parameters - SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table) + SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table integer :: ierr + integer, intent(out):: error_flag logical :: file_named + character(len=256) :: error_string real :: IRR_FRAC ! irrigation Fraction integer :: IRR_HAR ! number of days before harvest date to stop irrigation @@ -1163,8 +1199,11 @@ SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table) open(15, status='old', form='formatted', action='read', iostat=ierr) end if - if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_irrigation_parameters: Cannot find file MPTABLE.TBL') + if (ierr /= 0) then + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_irrigation_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif read(15,irrigation_parameters) @@ -1182,12 +1221,15 @@ SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table) END SUBROUTINE read_irrigation_parameters - SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table) + SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table integer :: ierr + integer, intent(out):: error_flag + logical :: file_named + character(len=256) :: error_string real, dimension(MAX_SOILTYP) :: TDSMC_FAC integer, dimension(MAX_SOILTYP) :: TD_DEPTH real, dimension(MAX_SOILTYP) :: TD_DC @@ -1222,9 +1264,13 @@ SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table) else open(15, status='old', form='formatted', action='read', iostat=ierr) end if - if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_tiledrain_parameters: Cannot find file MPTABLE.TBL') + if (ierr /= 0) then + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_tiledrain_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif + read(15,tiledrain_parameters) close(15) TDSMCFAC_TABLE = TDSMC_FAC @@ -1243,12 +1289,14 @@ SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table) END SUBROUTINE read_tiledrain_parameters - SUBROUTINE read_optional_parameters(param_dir, noahowp_table) + SUBROUTINE read_optional_parameters(param_dir, noahowp_table, error_flag) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table integer :: ierr logical :: file_named + integer, intent(out):: error_flag + character(len=256) :: error_string namelist / optional_parameters / & sr2006_theta_1500t_a, sr2006_theta_1500t_b, sr2006_theta_1500t_c, & @@ -1277,7 +1325,10 @@ SUBROUTINE read_optional_parameters(param_dir, noahowp_table) end if if (ierr /= 0) then - call handle_err(ierr, 'ParametersRead.f90: read_optional_parameters: Cannot find file MPTABLE.TBL') + error_flag = NOM_FAILURE + write(error_string,'(A)') "ParametersRead.f90:read_optional_parameters(): Cannot find file MPTABLE.TBL" + call log_message(error_flag, error_string) + return endif read(15,optional_parameters) @@ -1285,16 +1336,4 @@ SUBROUTINE read_optional_parameters(param_dir, noahowp_table) END SUBROUTINE read_optional_parameters - - SUBROUTINE handle_err(err,message) - implicit none - integer, intent(in) :: err ! error code - character(*),intent(in) :: message ! error message - if(err/=0)then - write(*,*) 'FATAL ERROR: '//trim(message) - call flush(6) - stop - endif - END SUBROUTINE handle_err - END MODULE ParametersRead diff --git a/src/ParametersType.f90 b/src/ParametersType.f90 index f57a2ff0..8c248d3e 100644 --- a/src/ParametersType.f90 +++ b/src/ParametersType.f90 @@ -2,6 +2,7 @@ module ParametersType use NamelistRead, only: namelist_type use ParametersRead +use ErrorCheckModule implicit none save @@ -196,22 +197,37 @@ subroutine InitDefault(this) end subroutine InitDefault - subroutine paramRead(this, namelist) + subroutine paramRead(this, namelist, error_flag) implicit none class(parameters_type) :: this class(namelist_type), intent(in) :: namelist + integer, intent(out):: error_flag ! local variables integer :: ix character(len=50) :: dataset_identifier !dataset_identifier = "MODIFIED_IGBP_MODIS_NOAH" ! This can be in namelist !call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, dataset_identifier) - call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table, namelist%soil_class_name) - call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, namelist%veg_class_name) - !call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table) - call read_rad_parameters(namelist%parameter_dir, namelist%noahowp_table) - call read_global_parameters(namelist%parameter_dir, namelist%noahowp_table) + call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table, namelist%soil_class_name, error_flag) + if (error_flag == NOM_FAILURE) then + return + end if + + call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, namelist%veg_class_name, error_flag) + if (error_flag == NOM_FAILURE) then + return + end if + + call read_rad_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) + if (error_flag == NOM_FAILURE) then + return + end if + + call read_global_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) + if (error_flag == NOM_FAILURE) then + return + end if !--------------------------------------------------------------------- ! transfer to structure diff --git a/src/RunModule.f90 b/src/RunModule.f90 index cb357b84..36374778 100644 --- a/src/RunModule.f90 +++ b/src/RunModule.f90 @@ -18,8 +18,10 @@ module RunModule use EnergyModule use WaterModule use DateTimeUtilsModule + use ErrorCheckModule implicit none + type :: noahowp_type type(namelist_type) :: namelist type(levels_type) :: levels @@ -60,12 +62,18 @@ SUBROUTINE initialize_from_file (model, config_filename) call domain%Init(namelist) call domain%InitTransfer(namelist) + if (domain%error_flag == NOM_FAILURE) then + return + end if call options%Init() call options%InitTransfer(namelist) call parameters%Init(namelist) - call parameters%paramRead(namelist) + call parameters%paramRead(namelist, model%domain%error_flag) + if (model%domain%error_flag == NOM_FAILURE) then + return + end if call forcing%Init(namelist) call forcing%InitTransfer(namelist) @@ -195,7 +203,10 @@ SUBROUTINE initialize_from_file (model, config_filename) !--- set a time vector for simulation --- !--------------------------------------------------------------------- ! --- AWW: calculate start and end utimes & records for requested station data read period --- - call get_utime_list (domain%start_datetime, domain%end_datetime, domain%dt, domain%sim_datetimes) ! makes unix-time list for desired records (end-of-timestep) + call get_utime_list (domain%start_datetime, domain%end_datetime, domain%dt, domain%sim_datetimes, domain%error_flag) ! makes unix-time list for desired records (end-of-timestep) + if (domain%error_flag == NOM_FAILURE) then + return + end if domain%ntime = size (domain%sim_datetimes) !print *, "---------"; !print *, 'Simulation startdate = ', domain%startdate, ' enddate = ', domain%enddate, ' dt(sec) = ', domain%dt, ' ntimes = ', domain%ntime ! YYYYMMDD dates @@ -208,7 +219,10 @@ SUBROUTINE initialize_from_file (model, config_filename) ! Nextgen forcing is being used (https://github.com/NOAA-OWP/ngen) !--------------------------------------------------------------------- #ifndef NGEN_FORCING_ACTIVE - call open_forcing_file(namelist%forcing_filename) + call open_forcing_file(namelist%forcing_filename, model%domain%error_flag) + if (model%domain%error_flag == NOM_FAILURE) then + return + end if #endif !--------------------------------------------------------------------- @@ -246,6 +260,9 @@ SUBROUTINE advance_in_time(model) type (noahowp_type), intent (inout) :: model call solve_noahowp(model) + if (model%domain%error_flag == NOM_FAILURE) then + return + end if model%domain%itime = model%domain%itime + 1 ! increment the integer time by 1 model%domain%time_dbl = dble(model%domain%time_dbl + model%domain%dt) ! increment model time in seconds by DT @@ -283,13 +300,19 @@ SUBROUTINE solve_noahowp(model) forcing_timestep = domain%dt #ifndef NGEN_FORCING_ACTIVE call read_forcing_text(iunit, domain%nowdate, forcing_timestep, & - forcing%UU, forcing%VV, forcing%SFCTMP, forcing%Q2, forcing%SFCPRS, forcing%SOLDN, forcing%LWDN, forcing%PRCP, ierr) + forcing%UU, forcing%VV, forcing%SFCTMP, forcing%Q2, forcing%SFCPRS, forcing%SOLDN, forcing%LWDN, forcing%PRCP, ierr, domain%error_flag) + if (domain%error_flag == NOM_FAILURE) then + return + end if #endif !--------------------------------------------------------------------- ! call the main utility routines !--------------------------------------------------------------------- call UtilitiesMain (domain%itime, domain, forcing, energy) + if (domain%error_flag == NOM_FAILURE) then + return + end if !--------------------------------------------------------------------- ! call the main forcing routines @@ -308,6 +331,9 @@ SUBROUTINE solve_noahowp(model) !--------------------------------------------------------------------- call EnergyMain (domain, levels, options, parameters, forcing, energy, water) + if (domain%error_flag == NOM_FAILURE) then + return + end if !--------------------------------------------------------------------- ! call the main water routines (canopy + snow + soil water components) diff --git a/src/UtilitiesModule.f90 b/src/UtilitiesModule.f90 index 6af6cb15..5c4a5ff7 100644 --- a/src/UtilitiesModule.f90 +++ b/src/UtilitiesModule.f90 @@ -9,6 +9,7 @@ module UtilitiesModule use DomainType use EnergyType + use ErrorCheckModule use ForcingType implicit none @@ -28,25 +29,33 @@ SUBROUTINE UtilitiesMain (itime, domain, forcing, energy) idt = itime * (domain%dt / 60) ! calculate current 'nowdate' from start date + integer length of run to current time - call geth_newdate(domain%startdate, idt, & ! in - domain%nowdate) ! out + call geth_newdate(domain%startdate, idt, & ! in + domain%nowdate, domain%error_flag) ! out + if (domain%error_flag == NOM_FAILURE) then + return + end if ! calculate current declination of direct solar radiation input call calc_declin(domain%nowdate(1:4)//"-"//domain%nowdate(5:6)//"-"//domain%nowdate(7:8)//"_"//domain%nowdate(9:10)//":"//domain%nowdate(11:12)//":00", & ! in domain%lat, domain%lon, domain%terrain_slope, domain%azimuth,& ! in - energy%cosz, energy%cosz_horiz,forcing%yearlen, forcing%julian) ! out + energy%cosz, energy%cosz_horiz,forcing%yearlen, forcing%julian, domain%error_flag) ! out + if (domain%error_flag == NOM_FAILURE) then + return + end if + END SUBROUTINE UtilitiesMain ! calculate current 'nowdate' from start date + integer length of run to current time - subroutine geth_newdate (odate, idt, & ! in - ndate) ! out + subroutine geth_newdate (odate, idt, & ! in + ndate, error_flag) ! out IMPLICIT NONE character (len=*), intent(in) :: odate ! start date integer, intent(in) :: idt ! change in time (in minutes) character (len=*), intent(out) :: ndate ! current + integer, intent(out) :: error_flag ! ------------------------ local variables --------------------------- integer :: nlen ! length of "ndate" string @@ -75,7 +84,8 @@ subroutine geth_newdate (odate, idt, & ! in integer :: ifrc logical :: opass ! logical for whether odate components pass their checks character (len=10) :: hfrc - character (len=1) :: sp + character (len=1) :: sp + character (len=256):: error_string logical :: punctuated ! logical for whether the date string has hyphens to separate logical :: idtdy ! logical for whether idt has units of days @@ -209,8 +219,10 @@ subroutine geth_newdate (odate, idt, & ! in ! If opass = false, then cancel the run if (.not.opass) then - write(*,*) 'Crazy ODATE: ', odate(1:olen), olen - call abort() + error_flag = NOM_FAILURE + write(error_string,'(A,A)') "UtilitiesModule.f90:geth_newdate(): Crazy ODATE: ",odate(1:olen) + call log_message(error_flag, trim(error_string)) + return end if ! Date Checks are completed. Continue. @@ -258,10 +270,10 @@ subroutine geth_newdate (odate, idt, & ! in nsec = 0 nfrac = 0 else - write(*,'(''GETH_NEWDATE: Strange length for ODATE: '', i3)') & - olen - write(*,*) odate(1:olen) - call abort() + error_flag = NOM_FAILURE + write(error_string,'(A,I3)') "UtilitiesModule.f90:geth_newdate(): Strange length for ODATE: ",olen + call log_message(error_flag, trim(error_string)) + return end if if (idt >= 0) then @@ -407,7 +419,10 @@ subroutine geth_newdate (odate, idt, & ! in 8 format(i4,i2.2,i2.2) else - stop "DATELEN PROBLEM" + error_flag = NOM_FAILURE + write(error_string,'(A)') "UtilitiesModule.f90:geth_newdate(): DATELEN PROBLEM" + call log_message(error_flag, trim(error_string)) + return end if endif @@ -415,18 +430,20 @@ end subroutine geth_newdate ! calculate integer day of year for current time ! AW: not sure this is ever called in the code at present - subroutine geth_idts (newdate, olddate, idt) + subroutine geth_idts (newdate, olddate, idt, error_flag) implicit none character (len=*) , intent(in) :: newdate ! current date of run character (len=*) , intent(in) :: olddate ! first day of current year integer , intent(out) :: idt ! integer day of year + integer , intent(out) :: error_flag ! ------------------------ local variables --------------------------- character(len=24) :: ndate character(len=24) :: odate character (len=24) :: tdate + character (len=256):: error_string integer :: olen ! length of olddate integer :: nlen ! length of newdate integer :: yrnew ! year associated with "ndate" @@ -456,8 +473,10 @@ subroutine geth_idts (newdate, olddate, idt) olen = len(olddate) nlen = len(newdate) if (nlen /= olen) then - write(*,'("GETH_IDTS: NLEN /= OLEN: ", A, 3x, A)') newdate(1:nlen), olddate(1:olen) - call abort + error_flag = NOM_FAILURE + write(error_string,'(A,A,2x,A)') "UtilitiesModule.f90:geth_idts(): NLEN /= OLEN: ",newdate(1:nlen), olddate(1:olen) + call log_message(error_flag, trim(error_string)) + return endif if (olddate > newdate) then @@ -673,13 +692,17 @@ subroutine geth_idts (newdate, olddate, idt) end if if (.not. npass) then - print*, 'Screwy NDATE: ', ndate(1:nlen) - call abort() + error_flag = NOM_FAILURE + write(error_string,'(A,A)') "UtilitiesModule.f90:geth_idts(): Screwy NDATE: ",ndate(1:nlen) + call log_message(error_flag, trim(error_string)) + return end if if (.not. opass) then - print*, 'Screwy ODATE: ', odate(1:olen) - call abort() + error_flag = NOM_FAILURE + write(error_string,'(A,A)') "UtilitiesModule.f90:geth_idts(): Screwy ODATE: ",odate(1:olen) + call log_message(error_flag, trim(error_string)) + return end if ! Date Checks are completed. Continue. @@ -807,7 +830,7 @@ end function nmdays SUBROUTINE calc_declin (nowdate, & ! in latitude, longitude, slope, azimuth, & ! in - cosz, cosz_horiz, yearlen, julian) ! out + cosz, cosz_horiz, yearlen, julian, error_flag) ! out !--------------------------------------------------------------------- IMPLICIT NONE !--------------------------------------------------------------------- @@ -822,6 +845,7 @@ SUBROUTINE calc_declin (nowdate, & ! in real, intent(out) :: cosz_horiz ! cosine of solar zenith angle for flat ground integer, intent(out) :: yearlen ! year length real, intent(out) :: JULIAN ! julian day + integer, intent(out) :: error_flag ! ------------------------ local variables --------------------------- REAL, PARAMETER :: DEGRAD = 3.14159265/180. ! convert degrees to radians @@ -866,7 +890,10 @@ SUBROUTINE calc_declin (nowdate, & ! in endif ! Determine the Julian time (floating-point day of year) - call geth_idts(nowdate(1:10), nowdate(1:4)//"-01-01", iday) + call geth_idts(nowdate(1:10), nowdate(1:4)//"-01-01", iday, error_flag) + if (error_flag == NOM_FAILURE) then + return + endif read(nowdate(12:13), *) ihour read(nowdate(15:16), *) iminute read(nowdate(18:19), *) isecond @@ -922,4 +949,4 @@ SUBROUTINE calc_declin (nowdate, & ! in END SUBROUTINE calc_declin -end module UtilitiesModule \ No newline at end of file +end module UtilitiesModule From 0f4dc8c9b512be4a821f371cfd8285177207b044 Mon Sep 17 00:00:00 2001 From: Steve Drake Date: Mon, 13 May 2024 22:03:24 -0700 Subject: [PATCH 3/6] Replaced STOP and sys_abort() with RETURN up call stack --- src/ErrorCheckModule.f90 | 18 ----- src/NamelistRead.f90 | 160 ++++++++++++++++++++------------------- src/RunModule.f90 | 5 +- 3 files changed, 85 insertions(+), 98 deletions(-) diff --git a/src/ErrorCheckModule.f90 b/src/ErrorCheckModule.f90 index 33ef516a..3481b525 100644 --- a/src/ErrorCheckModule.f90 +++ b/src/ErrorCheckModule.f90 @@ -7,7 +7,6 @@ module ErrorCheckModule integer, parameter, public :: NOM_MESSAGE = 2 private - public:: sys_abort public:: is_within_bound public:: log_message @@ -18,23 +17,6 @@ module ErrorCheckModule contains - subroutine sys_abort(err, message) - - ! terminate the program if error is detected (err is non-zero) - - implicit none - - integer, intent(in) :: err ! error code - character(*), intent(in) :: message ! error message - - if(err/=0)then - write(*, '(A)') 'FATAL ERROR: '//trim(message) - call flush(6) - stop - endif - - end subroutine sys_abort - subroutine log_message(err, message) ! log information, typically an error diff --git a/src/NamelistRead.f90 b/src/NamelistRead.f90 index d175c4e6..302b2f65 100644 --- a/src/NamelistRead.f90 +++ b/src/NamelistRead.f90 @@ -1,7 +1,6 @@ module NamelistRead -use ErrorCheckModule, only: sys_abort -use ErrorCheckModule, only: is_within_bound +use ErrorCheckModule implicit none save @@ -77,11 +76,12 @@ module NamelistRead contains - subroutine ReadNamelist(this, namelist_file) + subroutine ReadNamelist(this, namelist_file, error_flag) class(namelist_type) :: this ! Optional namelist_file path/filename to read character(len=*), intent (in), optional :: namelist_file + integer, intent (out) :: error_flag integer :: ierr character(len=480) :: line @@ -101,6 +101,7 @@ subroutine ReadNamelist(this, namelist_file) character(len=256) :: general_table character(len=256) :: noahowp_table character(len=256) :: soil_class_name + character(len=256) :: error_string real :: lat real :: lon real :: terrain_slope @@ -227,48 +228,48 @@ subroutine ReadNamelist(this, namelist_file) ! read namelist !--------------------------------------------------------------------- ierr = 0 + error_flag = NOM_SUCCESS if( trim(namelist_file) .ne. '' ) then open(30, file=namelist_file, form="formatted", status='old', iostat=ierr) - if(ierr /= 0) then; write(*,'(A)') 'ERROR: user specified namelist file not found: '//trim(namelist_file); stop; end if - !print*, 'Reading namelist: ', trim(namelist_file) + if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: user specified namelist file not found: '//trim(namelist_file); call log_message(error_flag, error_string); return; end if else open(30, file='./namelist.input', form="formatted", status='old', iostat=ierr) - if(ierr /= 0) then; write(*,'(A)') 'ERROR: default namelist file not found: ./namelist.input'; stop; end if - !print*, 'No namelist filename supplied -- attempting to read namelist.input (default)' + if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: default namelist file not found: ./namelist.input'; call log_message(error_flag, error_string); return; end if endif read(30, timing, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, parameters, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, location, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, forcing, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, model_options, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, structure, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if !--------------------------------------------------------------------- ! Check model option validity, part 2 !--------------------------------------------------------------------- - if (.not. is_within_bound(precip_phase_option, 1, 7)) then; call sys_abort(1,'model options: precip_phase_option should be 1-7'); end if - if (.not. is_within_bound(runoff_option, 1, 8)) then; call sys_abort(1,'model options: runoff_option should be 1-8'); end if - if (.not. is_within_bound(drainage_option, 1, 8)) then; call sys_abort(1,'model options: drainage_option should be 1-8'); end if - if (.not. is_within_bound(frozen_soil_option ,1, 2)) then; call sys_abort(1,'model options: frozen_soil_option should be 1-2'); end if - if (.not. is_within_bound(dynamic_vic_option ,1, 3)) then; call sys_abort(1,'model options: dynamic_vic_option should be 1-3'); end if - if (.not. is_within_bound(dynamic_veg_option ,1, 9)) then; call sys_abort(1,'model options: dynamic_veg_option should be 1-9'); end if - if (.not. is_within_bound(snow_albedo_option ,1, 2)) then; call sys_abort(1,'model options: snow_albedo_option should be 1-2'); end if - if (.not. is_within_bound(radiative_transfer_option,1, 3)) then; call sys_abort(1,'model options: radiative_transfer_option should be 1-3'); end if - if (.not. is_within_bound(sfc_drag_coeff_option, 1, 2)) then; call sys_abort(1,'model options: sfc_drag_coeff_option should be 1-3'); end if - if (.not. is_within_bound(canopy_stom_resist_option, 1, 2)) then; call sys_abort(1,'model options: sfc_drag_coeff_option should be 1-2'); end if - if (.not. is_within_bound(snowsoil_temp_time_option, 1, 3)) then; call sys_abort(1,'model options: snowsoil_temp_time_option should be 1-3'); end if - if (.not. is_within_bound(soil_temp_boundary_option, 1, 2)) then; call sys_abort(1,'model options: soil_temp_boundary_option should be 1-2'); end if - if (.not. is_within_bound(supercooled_water_option, 1, 2)) then; call sys_abort(1,'model options: supercooled_water_option should be 1-2'); end if - if (.not. is_within_bound(stomatal_resistance_option, 1, 3)) then; call sys_abort(1,'model options: stomatal_resistance_option should be 1-3'); end if - if (.not. is_within_bound(evap_srfc_resistance_option, 1, 4)) then; call sys_abort(1,'model options: evap_srfc_resistance_option should be 1-4'); end if - if (.not. is_within_bound(subsurface_option, 1, 3)) then; call sys_abort(1,'model options: subsurface_option should be 1-3'); end if + if (.not. is_within_bound(precip_phase_option, 1, 7)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: precip_phase_option should be 1-7'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(runoff_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: runoff_option should be 1-8'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(drainage_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: drainage_option should be 1-8'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(frozen_soil_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: frozen_soil_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(dynamic_vic_option ,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: dynamic_vic_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(dynamic_veg_option ,1, 9)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: dynamic_veg_option should be 1-9'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(snow_albedo_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: snow_albedo_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(radiative_transfer_option,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: radiative_transfer_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(sfc_drag_coeff_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: sfc_drag_coeff_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(canopy_stom_resist_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: canopy_stom_resist_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(snowsoil_temp_time_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: snowsoil_temp_time_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(soil_temp_boundary_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: soil_temp_boundary_option should be 1-2'; call log_message(error_flag, error_string); return;end if + if (.not. is_within_bound(supercooled_water_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: supercooled_water_option should be 1-2'; call log_message(error_flag, error_string); return;end if + if (.not. is_within_bound(stomatal_resistance_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: stomatal_resistance_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(evap_srfc_resistance_option, 1, 4)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: evap_srfc_resistance_option should be 1-4'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(subsurface_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: subsurface_option should be 1-3'; call log_message(error_flag, error_string); return; end if + ! after reading # of soil layers, allocate local arrays and read soil structure info allocate (zsoil ( 1:nsoil)) ! depth of layer-bottom from soil surface @@ -283,7 +284,7 @@ subroutine ReadNamelist(this, namelist_file) ! read remaining group from namelist read(30, initial_values) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; write(*,'(A)') 'ERROR: invalid line in namelist: '//trim(line); stop; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if close(30) ! calculate total soil depth and populate array for depth of layer-bottom from soil surface @@ -294,64 +295,65 @@ subroutine ReadNamelist(this, namelist_file) zsoil(iz) = -1. * sum(dzsnso(1:iz)) end do else - write(*,'(A)') 'ERROR: required entry dzsnso not found in namelist'; stop + error_flag=NOM_FAILURE; + write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return end if !--------------------------------------------------------------------- ! transfer values to namelist data structure !--------------------------------------------------------------------- - if(dt /= realMissing) then; this%dt = dt; else; write(*,'(A)') 'ERROR: required entry dt not found in namelist'; stop; end if - if(startdate /= stringMissing) then; this%startdate = startdate; else; write(*,'(A)') 'ERROR: required entry startdate not found in namelist'; stop; end if - if(enddate /= stringMissing) then; this%enddate = enddate; else; write(*,'(A)') 'ERROR: required entry enddate not found in namelist'; stop; end if - if(forcing_filename /= stringMissing) then; this%forcing_filename = forcing_filename; else; write(*,'(A)') 'ERROR: required entry forcing_filename not found in namelist'; stop; end if - if(output_filename /= stringMissing) then; this%output_filename = output_filename; else; write(*,'(A)') 'ERROR: required entry output_filename not found in namelist'; stop; end if - if(parameter_dir /= stringMissing) then; this%parameter_dir = parameter_dir; else; write(*,'(A)') 'ERROR: required entry parameter_dir not found in namelist'; stop; end if - if(soil_table /= stringMissing) then; this%soil_table = soil_table; else; write(*,'(A)') 'ERROR: required entry soil_table not found in namelist'; stop; end if - if(general_table /= stringMissing) then; this%general_table = general_table; else; write(*,'(A)') 'ERROR: required entry general_table not found in namelist'; stop; end if - if(noahowp_table /= stringMissing) then; this%noahowp_table = noahowp_table; else; write(*,'(A)') 'ERROR: required entry noahowp_table not found in namelist'; stop; end if - if(soil_class_name /= stringMissing) then; this%soil_class_name = soil_class_name; else; write(*,'(A)') 'ERROR: required entry soil_class_name not found in namelist'; stop; end if - if(veg_class_name /= stringMissing) then; this%veg_class_name = veg_class_name; else; write(*,'(A)') 'ERROR: required entry veg_class_name not found in namelist'; stop; end if + if(dt /= realMissing) then; this%dt = dt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dt not found in namelist'; call log_message(error_flag, error_string); return; end if + if(startdate /= stringMissing) then; this%startdate = startdate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry startdate not found in namelist'; call log_message(error_flag, error_string); return; end if + if(enddate /= stringMissing) then; this%enddate = enddate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry enddate not found in namelist'; call log_message(error_flag, error_string); return; end if + if(forcing_filename /= stringMissing) then; this%forcing_filename = forcing_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry forcing_filename not found in namelist'; call log_message(error_flag, error_string); return; end if + if(output_filename /= stringMissing) then; this%output_filename = output_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry output_filename not found in namelist'; call log_message(error_flag, error_string); return; end if + if(parameter_dir /= stringMissing) then; this%parameter_dir = parameter_dir; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry parameter_dir not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_table /= stringMissing) then; this%soil_table = soil_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(general_table /= stringMissing) then; this%general_table = general_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry general_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(noahowp_table /= stringMissing) then; this%noahowp_table = noahowp_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry noahowp_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_class_name /= stringMissing) then; this%soil_class_name = soil_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if + if(veg_class_name /= stringMissing) then; this%veg_class_name = veg_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry veg_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if - if(lat /= realMissing) then; this%lat = lat; else; write(*,'(A)') 'ERROR: required entry lat not found in namelist'; stop; end if - if(lon /= realMissing) then; this%lon = lon; else; write(*,'(A)') 'ERROR: required entry lon not found in namelist'; stop; end if - if(terrain_slope /= realMissing) then; this%terrain_slope = terrain_slope; else; write(*,'(A)') 'ERROR: required entry terrain_slope not found in namelist'; stop; end if - if(azimuth /= realMissing) then; this%azimuth = azimuth; else; write(*,'(A)') 'ERROR: required entry azimuth not found in namelist'; stop; end if - if(zref /= realMissing) then; this%ZREF = ZREF; else; write(*,'(A)') 'ERROR: required entry ZREF not found in namelist'; stop; end if - if(rain_snow_thresh /= realMissing) then; this%rain_snow_thresh = rain_snow_thresh; else; write(*,'(A)') 'ERROR: required entry rain_snow_thresh not found in namelist'; stop; end if + if(lat /= realMissing) then; this%lat = lat; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry lat not found in namelist'; call log_message(error_flag, error_string); return; end if + if(lon /= realMissing) then; this%lon = lon; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry lon not found in namelist'; call log_message(error_flag, error_string); return; end if + if(terrain_slope /= realMissing) then; this%terrain_slope = terrain_slope; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry terrain_slope not found in namelist'; call log_message(error_flag, error_string); return; end if + if(azimuth /= realMissing) then; this%azimuth = azimuth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry azimuth not found in namelist'; call log_message(error_flag, error_string); return; end if + if(zref /= realMissing) then; this%ZREF = ZREF; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry ZREF not found in namelist'; call log_message(error_flag, error_string); return; end if + if(rain_snow_thresh /= realMissing) then; this%rain_snow_thresh = rain_snow_thresh; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry rain_snow_thresh not found in namelist'; call log_message(error_flag, error_string); return; end if - if(isltyp /= integerMissing) then; this%isltyp = isltyp; else; write(*,'(A)') 'ERROR: required entry isltyp not found in namelist'; stop; end if - if(nsoil /= integerMissing) then; this%nsoil = nsoil; else; write(*,'(A)') 'ERROR: required entry nsoil not found in namelist'; stop; end if - if(nsnow /= integerMissing) then; this%nsnow = nsnow; else; write(*,'(A)') 'ERROR: required entry nsnow not found in namelist'; stop; end if - if(nveg /= integerMissing) then; this%nveg = nveg; else; write(*,'(A)') 'ERROR: required entry nveg not found in namelist'; stop; end if - if(soil_depth /= integerMissing) then; this%soil_depth = soil_depth; else; write(*,'(A)') 'ERROR: required entry soil_depth not found in namelist'; stop; end if - if(vegtyp /= integerMissing) then; this%vegtyp = vegtyp; else; write(*,'(A)') 'ERROR: required entry vegtyp not found in namelist'; stop; end if - if(croptype /= integerMissing) then; this%croptype = croptype; else; write(*,'(A)') 'ERROR: required entry croptype not found in namelist'; stop; end if - if(sfctyp /= integerMissing) then; this%sfctyp = sfctyp; else; write(*,'(A)') 'ERROR: required entry sfctyp not found in namelist'; stop; end if - if(soilcolor /= integerMissing) then; this%soilcolor = soilcolor; else; write(*,'(A)') 'ERROR: required entry soilcolor not found in namelist'; stop; end if + if(isltyp /= integerMissing) then; this%isltyp = isltyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry isltyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nsoil /= integerMissing) then; this%nsoil = nsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nsoil not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nsnow /= integerMissing) then; this%nsnow = nsnow; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nsnow not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nveg /= integerMissing) then; this%nveg = nveg; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nveg not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_depth /= integerMissing) then; this%soil_depth = soil_depth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_depth not found in namelist'; call log_message(error_flag, error_string); return; end if + if(vegtyp /= integerMissing) then; this%vegtyp = vegtyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry vegtyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(croptype /= integerMissing) then; this%croptype = croptype; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry croptype not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sfctyp /= integerMissing) then; this%sfctyp = sfctyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sfctyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soilcolor /= integerMissing) then; this%soilcolor = soilcolor; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soilcolor not found in namelist'; call log_message(error_flag, error_string); return; end if - if(zsoil(1) /= realMissing) then; this%zsoil = zsoil; else; write(*,'(A)') 'ERROR: required entry zsoil not found in namelist'; stop; end if - if(dzsnso(1) /= realMissing) then; this%dzsnso = dzsnso; else; write(*,'(A)') 'ERROR: required entry dzsnso not found in namelist'; stop; end if - if(sice(1) /= realMissing) then; this%sice = sice; else; write(*,'(A)') 'ERROR: required entry sice not found in namelist'; stop; end if - if(sh2o(1) /= realMissing) then; this%sh2o = sh2o; else; write(*,'(A)') 'ERROR: required entry sh2o not found in namelist'; stop; end if - if(zwt /= realMissing) then; this%zwt = zwt; else; write(*,'(A)') 'ERROR: required entry zwt not found in namelist'; stop; end if + if(zsoil(1) /= realMissing) then; this%zsoil = zsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry zsoil not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dzsnso(1) /= realMissing) then; this%dzsnso = dzsnso; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sice(1) /= realMissing) then; this%sice = sice; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sice not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sh2o(1) /= realMissing) then; this%sh2o = sh2o; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sh2o not found in namelist'; call log_message(error_flag, error_string); return; end if + if(zwt /= realMissing) then; this%zwt = zwt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry zwt not found in namelist'; call log_message(error_flag, error_string); return; end if - if(precip_phase_option /= integerMissing) then; this%precip_phase_option = precip_phase_option; else; write(*,'(A)') 'ERROR: required entry precip_phase_option not found in namelist'; stop; end if - if(runoff_option /= integerMissing) then; this%runoff_option = runoff_option; else; write(*,'(A)') 'ERROR: required entry runoff_option not found in namelist'; stop; end if - if(drainage_option /= integerMissing) then; this%drainage_option = drainage_option; else; write(*,'(A)') 'ERROR: required entry drainage_option not found in namelist'; stop; end if - if(frozen_soil_option /= integerMissing) then; this%frozen_soil_option = frozen_soil_option; else; write(*,'(A)') 'ERROR: required entry frozen_soil_option not found in namelist'; stop; end if - if(dynamic_vic_option /= integerMissing) then; this%dynamic_vic_option = dynamic_vic_option; else; write(*,'(A)') 'ERROR: required entry dynamic_vic_option not found in namelist'; stop; end if - if(dynamic_veg_option /= integerMissing) then; this%dynamic_veg_option = dynamic_veg_option; else; write(*,'(A)') 'ERROR: required entry dynamic_veg_option not found in namelist'; stop; end if - if(snow_albedo_option /= integerMissing) then; this%snow_albedo_option = snow_albedo_option; else; write(*,'(A)') 'ERROR: required entry snow_albedo_option not found in namelist'; stop; end if - if(radiative_transfer_option /= integerMissing) then; this%radiative_transfer_option = radiative_transfer_option; else; write(*,'(A)') 'ERROR: required entry radiative_transfer_option not found in namelist'; stop; end if - if(sfc_drag_coeff_option /= integerMissing) then; this%sfc_drag_coeff_option = sfc_drag_coeff_option; else; write(*,'(A)') 'ERROR: required entry sfc_drag_coeff_option not found in namelist'; stop; end if - if(crop_model_option /= integerMissing) then; this%crop_model_option = crop_model_option; else; write(*,'(A)') 'ERROR: required entry crop_model_option not found in namelist'; stop; end if - if(canopy_stom_resist_option /= integerMissing) then; this%canopy_stom_resist_option = canopy_stom_resist_option; else; write(*,'(A)') 'ERROR: required entry canopy_stom_resist_option not found in namelist'; stop; end if - if(snowsoil_temp_time_option /= integerMissing) then; this%snowsoil_temp_time_option = snowsoil_temp_time_option; else; write(*,'(A)') 'ERROR: required entry snowsoil_temp_time_option not found in namelist'; stop; end if - if(soil_temp_boundary_option /= integerMissing) then; this%soil_temp_boundary_option = soil_temp_boundary_option; else; write(*,'(A)') 'ERROR: required entry soil_temp_boundary_option not found in namelist'; stop; end if - if(supercooled_water_option /= integerMissing) then; this%supercooled_water_option = supercooled_water_option; else; write(*,'(A)') 'ERROR: required entry supercooled_water_option not found in namelist'; stop; end if - if(stomatal_resistance_option /= integerMissing) then; this%stomatal_resistance_option = stomatal_resistance_option; else; write(*,'(A)') 'ERROR: required entry stomatal_resistance_option not found in namelist'; stop; end if - if(evap_srfc_resistance_option /= integerMissing) then; this%evap_srfc_resistance_option = evap_srfc_resistance_option; else; write(*,'(A)') 'ERROR: required entry evap_srfc_resistance_option not found in namelist'; stop; end if - if(subsurface_option /= integerMissing) then; this%subsurface_option = subsurface_option; else; write(*,'(A)') 'ERROR: required entry subsurface_option not found in namelist'; stop; end if + if(precip_phase_option /= integerMissing) then; this%precip_phase_option = precip_phase_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry precip_phase_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(runoff_option /= integerMissing) then; this%runoff_option = runoff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry runoff_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(drainage_option /= integerMissing) then; this%drainage_option = drainage_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry drainage_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(frozen_soil_option /= integerMissing) then; this%frozen_soil_option = frozen_soil_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry frozen_soil_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dynamic_vic_option /= integerMissing) then; this%dynamic_vic_option = dynamic_vic_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dynamic_vic_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dynamic_veg_option /= integerMissing) then; this%dynamic_veg_option = dynamic_veg_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dynamic_veg_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(snow_albedo_option /= integerMissing) then; this%snow_albedo_option = snow_albedo_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry snow_albedo_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(radiative_transfer_option /= integerMissing) then; this%radiative_transfer_option = radiative_transfer_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry radiative_transfer_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sfc_drag_coeff_option /= integerMissing) then; this%sfc_drag_coeff_option = sfc_drag_coeff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sfc_drag_coeff_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(crop_model_option /= integerMissing) then; this%crop_model_option = crop_model_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry crop_model_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(canopy_stom_resist_option /= integerMissing) then; this%canopy_stom_resist_option = canopy_stom_resist_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry canopy_stom_resist_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(snowsoil_temp_time_option /= integerMissing) then; this%snowsoil_temp_time_option = snowsoil_temp_time_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry snowsoil_temp_time_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_temp_boundary_option /= integerMissing) then; this%soil_temp_boundary_option = soil_temp_boundary_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_temp_boundary_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(supercooled_water_option /= integerMissing) then; this%supercooled_water_option = supercooled_water_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry supercooled_water_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(stomatal_resistance_option /= integerMissing) then; this%stomatal_resistance_option = stomatal_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry stomatal_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(evap_srfc_resistance_option /= integerMissing) then; this%evap_srfc_resistance_option = evap_srfc_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry evap_srfc_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(subsurface_option /= integerMissing) then; this%subsurface_option = subsurface_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry subsurface_option not found in namelist'; call log_message(error_flag, error_string); return; end if ! store missing values as well this%integerMissing = integerMissing diff --git a/src/RunModule.f90 b/src/RunModule.f90 index 36374778..57b2b3e1 100644 --- a/src/RunModule.f90 +++ b/src/RunModule.f90 @@ -55,7 +55,10 @@ SUBROUTINE initialize_from_file (model, config_filename) !--------------------------------------------------------------------- ! initialize !--------------------------------------------------------------------- - call namelist%ReadNamelist(config_filename) + call namelist%ReadNamelist(config_filename,domain%error_flag) + if (domain%error_flag == NOM_FAILURE) then + return + end if call levels%Init call levels%InitTransfer(namelist) From 989ba81baabdd7dee347ec790e38a179ac303877 Mon Sep 17 00:00:00 2001 From: Steve Drake Date: Tue, 14 May 2024 07:56:56 -0700 Subject: [PATCH 4/6] Commented out unused SUBROUTINE parse() to eliminate stop statement --- src/DateTimeUtilsModule.f90 | 60 ++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/DateTimeUtilsModule.f90 b/src/DateTimeUtilsModule.f90 index 3b1a091f..cfc2a543 100644 --- a/src/DateTimeUtilsModule.f90 +++ b/src/DateTimeUtilsModule.f90 @@ -63,42 +63,42 @@ module DateTimeUtilsModule !********************************************************************** - subroutine parse (str, delims, args, nargs) +! subroutine parse (str, delims, args, nargs) ! Parses the string 'str' into arguments args(1), ..., args(nargs) based on ! the delimiters contained in the string 'delims'. Preceding a delimiter in ! 'str' by a backslash (\) makes this particular instance not a delimiter. ! The integer output variable nargs contains the number of arguments found. - character (len=*) :: str, delims - character (len=len_trim(str)) :: strsav - character (len=*), dimension (:) :: args - integer :: i, k, na, nargs, lenstr - - strsav = str - call compact (str) - na = size (args) - do i = 1, na - args (i) = ' ' - end do - nargs = 0 - lenstr = len_trim (str) - if (lenstr == 0) return - k = 0 - - do - if (len_trim(str) == 0) exit - nargs = nargs + 1 - if(nargs .gt. size(args)) then - print *,'Number of predictors larger than expected, check nPredict' - stop - end if - call split (str, delims, args(nargs)) - call removebksl (args(nargs)) - end do - str = strsav - - end subroutine parse +! character (len=*) :: str, delims +! character (len=len_trim(str)) :: strsav +! character (len=*), dimension (:) :: args +! integer :: i, k, na, nargs, lenstr + +! strsav = str +! call compact (str) +! na = size (args) +! do i = 1, na +! args (i) = ' ' +! end do +! nargs = 0 +! lenstr = len_trim (str) +! if (lenstr == 0) return +! k = 0 + +! do +! if (len_trim(str) == 0) exit +! nargs = nargs + 1 +! if(nargs .gt. size(args)) then +! print *,'Number of predictors larger than expected, check nPredict' +! stop +! end if +! call split (str, delims, args(nargs)) +! call removebksl (args(nargs)) +! end do +! str = strsav + +! end subroutine parse !********************************************************************** From 4c8a0864f3dece7bfccd372a8b68f2a561da491f Mon Sep 17 00:00:00 2001 From: Steve Drake Date: Tue, 11 Jun 2024 11:08:33 -0700 Subject: [PATCH 5/6] initial changes removing error_flag from call signatures --- err_flag_info.txt | 20 ++++++++++++++++++++ src/DomainType.f90 | 2 +- src/ErrorCheckModule.f90 | 5 +++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 err_flag_info.txt diff --git a/err_flag_info.txt b/err_flag_info.txt new file mode 100644 index 00000000..58ccdfa7 --- /dev/null +++ b/err_flag_info.txt @@ -0,0 +1,20 @@ +./ParametersRead.f90: SUBROUTINE read_rad_parameters(param_dir, noahowp_table, error_flag) +./ParametersRead.f90: subroutine read_global_parameters(param_dir, noahowp_table, error_flag) +./ParametersRead.f90: SUBROUTINE read_crop_parameters(param_dir, noahowp_table, error_flag) +./ParametersRead.f90: SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table, error_flag) +./ParametersRead.f90: SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table, error_flag) +./ParametersRead.f90: SUBROUTINE read_optional_parameters(param_dir, noahowp_table, error_flag) +./RunModule.f90: call namelist%ReadNamelist(config_filename,domain%error_flag) +./RunModule.f90: call parameters%paramRead(namelist, model%domain%error_flag) +./RunModule.f90: call get_utime_list (domain%start_datetime, domain%end_datetime, domain%dt, domain%sim_datetimes, domain%error_flag) ! makes unix-time list for desired records (end-of-timestep) +./RunModule.f90: call open_forcing_file(namelist%forcing_filename, model%domain%error_flag) +./NamelistRead.f90: subroutine ReadNamelist(this, namelist_file, error_flag) +./UtilitiesModule.f90: subroutine geth_idts (newdate, olddate, idt, error_flag) +./UtilitiesModule.f90: call geth_idts(nowdate(1:10), nowdate(1:4)//"-01-01", iday, error_flag) +./DateTimeUtilsModule.f90: subroutine get_utime_list (start_datetime, end_datetime, dt, times, error_flag) +./ParametersType.f90: subroutine paramRead(this, namelist, error_flag) +./ParametersType.f90: call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table, namelist%soil_class_name, error_flag) +./ParametersType.f90: call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, namelist%veg_class_name, error_flag) +./ParametersType.f90: call read_rad_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) +./ParametersType.f90: call read_global_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) +./EnergyModule.f90: call log_message(domain%error_flag, trim(error_string)) diff --git a/src/DomainType.f90 b/src/DomainType.f90 index 58767fa3..85f14305 100644 --- a/src/DomainType.f90 +++ b/src/DomainType.f90 @@ -32,7 +32,7 @@ module DomainType integer :: croptype ! crop type integer :: isltyp ! soil type integer :: IST ! surface type 1-soil; 2-lake - integer :: error_flag ! flag for energy balance error (0 = no error, 1 = longwave < 0) +! integer :: error_flag ! flag for energy balance error (0 = no error, 1 = longwave < 0) real, allocatable, dimension(:) :: zsoil ! depth of layer-bottom from soil surface real, allocatable, dimension(:) :: dzsnso ! snow/soil layer thickness [m] diff --git a/src/ErrorCheckModule.f90 b/src/ErrorCheckModule.f90 index 3481b525..078449ac 100644 --- a/src/ErrorCheckModule.f90 +++ b/src/ErrorCheckModule.f90 @@ -2,11 +2,14 @@ module ErrorCheckModule ! General error checking routines implicit none + integer, parameter, public :: NOM_SUCCESS = 0 integer, parameter, public :: NOM_FAILURE = 1 integer, parameter, public :: NOM_MESSAGE = 2 private + + type, public :: error_type public:: is_within_bound public:: log_message @@ -15,6 +18,8 @@ module ErrorCheckModule module procedure is_within_bound_real end interface +end error_type + contains subroutine log_message(err, message) From 5fcfeedca805b0c1f4d956aafe96fd28f9a577ee Mon Sep 17 00:00:00 2001 From: Steve Drake Date: Fri, 14 Jun 2024 16:24:40 -0700 Subject: [PATCH 6/6] Introduce ErrorType to return error to calling program --- bmi/bmi_noahowp.f90 | 7 +- driver/AsciiReadModule.f90 | 28 +++---- run/Makefile | 1 + src/DateTimeUtilsModule.f90 | 16 ++-- src/DomainType.f90 | 14 ++-- src/EnergyModule.f90 | 10 ++- src/ErrorCheckModule.f90 | 21 +++-- src/ErrorType.f90 | 44 ++++++++++ src/Makefile | 3 +- src/NamelistRead.f90 | 156 ++++++++++++++++++------------------ src/ParametersRead.f90 | 65 +++++++-------- src/ParametersType.f90 | 11 ++- src/RunModule.f90 | 47 +++++++---- src/UtilitiesModule.f90 | 37 +++++---- test/Makefile | 1 + 15 files changed, 264 insertions(+), 197 deletions(-) create mode 100644 src/ErrorType.f90 diff --git a/bmi/bmi_noahowp.f90 b/bmi/bmi_noahowp.f90 index beb47a06..033e342d 100644 --- a/bmi/bmi_noahowp.f90 +++ b/bmi/bmi_noahowp.f90 @@ -202,7 +202,7 @@ function noahowp_initialize(this, config_file) result (bmi_status) else !call initialize_from_defaults(this%model) end if - bmi_status = this%model%domain%error_flag + bmi_status = this%model%error%error_flag end function noahowp_initialize @@ -272,10 +272,7 @@ function noahowp_update(this) result (bmi_status) bmi_status = BMI_SUCCESS call advance_in_time(this%model) - if (this%model%domain%error_flag == BMI_FAILURE) then - bmi_status = BMI_FAILURE - return - end if + bmi_status = this%model%error%error_flag end function noahowp_update diff --git a/driver/AsciiReadModule.f90 b/driver/AsciiReadModule.f90 index 66cc3aa1..850207ea 100644 --- a/driver/AsciiReadModule.f90 +++ b/driver/AsciiReadModule.f90 @@ -4,16 +4,17 @@ module AsciiReadModule use ErrorCheckModule implicit none + character(len=*), PARAMETER :: moduleName='AsciiReadModule' + private :: moduleName contains - subroutine open_forcing_file(filename, error_flag) + subroutine open_forcing_file(filename) implicit none character*256, intent(in) :: filename - integer, intent(out) :: error_flag - character(len=256) :: error_string + character(len=*), PARAMETER :: subroutineName = 'open_forcing_file' !--------------------------------------------------------------------- ! local variables @@ -26,7 +27,7 @@ subroutine open_forcing_file(filename, error_flag) inquire(file = trim(filename), exist = lexist) if (.not. lexist) then error_flag = NOM_FAILURE - write(error_string,'(A,A,A)') "AsciiReadModule.f90:open_forcing_file(): File: ",trim(filename), " does not exist. Check the forcing file specified as a command-line argument" + write(error_string,'(A,A,A)') 'AsciiReadModule'//' - '//subroutineName//'(): File: ',trim(filename), ' does not exist. Check the forcing file specified as a command-line argument.' call log_message(error_flag, error_string) return endif @@ -35,7 +36,7 @@ subroutine open_forcing_file(filename, error_flag) open(10, file = trim(filename), form = 'formatted', action = 'read', iostat = ierr) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A,A,A)') "ReadModule.f90:open_forcing_file(): Problem opening file: ",trim(filename) + write(error_string,'(A,A,A)') 'AsciiReadModule'//' - '//subroutineName//'(): Problem opening file: ',trim(filename) call log_message(error_flag, error_string) return endif @@ -43,7 +44,7 @@ subroutine open_forcing_file(filename, error_flag) end subroutine open_forcing_file subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & - u, v, sfctmp, spechumd, sfcprs, swrad, lwrad, pcprate, ierr, error_flag) + u, v, sfctmp, spechumd, sfcprs, swrad, lwrad, pcprate, ierr) implicit none @@ -60,7 +61,6 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & real, intent(out) :: lwrad real, intent(out) :: pcprate integer, intent(out) :: ierr - integer, intent(out) :: error_flag real, intent(out) :: u real, intent(out) :: v @@ -72,7 +72,6 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & integer :: hour integer :: minute character(len=12) :: readdate - character(len=256):: error_string real :: read_windspeed real :: read_winddir real :: read_temperature @@ -117,6 +116,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & real, parameter :: eps = 0.622 character(len=1024) :: string + character(len=*), PARAMETER :: subroutineName = 'read_forcing_text' ! Flag to tell us whether this is the first time this subroutine is called, in which case ! we need to seek forward to the data. @@ -175,7 +175,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & endif if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): Error reading from data file." + write(error_string,'(A)') 'AsciiReadModule'//' - '//subroutineName//'(): Error reading from data file.' call log_message(error_flag, error_string) return endif @@ -194,7 +194,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & cycle READLOOP else error_flag = NOM_FAILURE - write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): Logic problem." + write(error_string,'(A)') 'AsciiReadModule'//' - '//subroutineName//'(): Logic problem.' call log_message(error_flag, error_string) return endif @@ -227,8 +227,8 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & else if (before%readdate < nowdate .and. nowdate < after%readdate) then - call geth_idts(nowdate, before%readdate, idts, error_flag) - call geth_idts(after%readdate, before%readdate, idts2, error_flag) + call geth_idts(nowdate, before%readdate, idts) + call geth_idts(after%readdate, before%readdate, idts2) if (error_flag == NOM_FAILURE) then return endif @@ -241,7 +241,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & print*,' after%readdate = ', after%readdate print*, 'idts2 = ', idts2 error_flag = NOM_FAILURE - write(error_string,'(A)') "AsciiReadModule.f90:read_forcing_text(): IDTS PROBLEM." + write(error_string,'(A)') 'AsciiReadModule'//' - '//subroutineName//'(): IDTS PROBLEM.' call log_message(error_flag, error_string) return endif @@ -268,7 +268,7 @@ subroutine read_forcing_text(iunit, nowdate, forcing_timestep, & else error_flag = NOM_FAILURE - write(error_string,'(A,A,A)') "AsciiReadModule.f90:read_forcing_text(): date: ", nowdate, ". Problem in the logic of read_forcing_text." + write(error_string,'(A,A,A)') 'AsciiReadModule'//' - '//subroutineName//'(): date: ', nowdate, '. Problem in the logic of read_forcing_text.' call log_message(error_flag, error_string) return endif diff --git a/run/Makefile b/run/Makefile index ce0caeba..de17c55c 100644 --- a/run/Makefile +++ b/run/Makefile @@ -7,6 +7,7 @@ include ../user_build_options OBJS = \ ../src/ErrorCheckModule.o \ + ../src/ErrorType.o \ ../src/NamelistRead.o \ ../src/ParametersRead.o \ ../src/LevelsType.o \ diff --git a/src/DateTimeUtilsModule.f90 b/src/DateTimeUtilsModule.f90 index cfc2a543..0fa92764 100644 --- a/src/DateTimeUtilsModule.f90 +++ b/src/DateTimeUtilsModule.f90 @@ -6,6 +6,8 @@ module DateTimeUtilsModule use ErrorCheckModule implicit none + character(len=*), PARAMETER :: moduleName='DateTimeUtilsModule' + private :: moduleName public integer, parameter :: kr4 = selected_real_kind (6, 37)! single precision real @@ -881,14 +883,15 @@ double precision function date_to_unix (date) character (len=*), intent (in) :: date double precision :: u_day, i_day, days integer :: sec, min, hour, day, month, year, error - character(len=256) :: error_string + character(len=*), PARAMETER :: subroutineName = 'date_to_unix' call parse_date (date, year, month, day, hour, min, sec, error) if (error /= 0) then + error_flag = NOM_FAILURE date_to_unix = -9999.99 - write(error_string,'(A,A,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4)') "DateTimeUtilsModule.f90:date_to_unix(): date: ",date," year: ",year," month: ",month," day: ",day," hour: ",hour," min: ",min," sec: ",sec, " Error: ",error - call log_message(NOM_FAILURE, error_string) + write(error_string,'(A,A,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4,A,I4)') moduleName//" - "//subroutineName//"(): date: ",date," year: ",year," month: ",month," day: ",day," hour: ",hour," min: ",min," sec: ",sec, " Error: ",error + call log_message(error_flag, error_string) return end if @@ -962,7 +965,7 @@ integer function julian_date (day, month, year) end function julian_date - subroutine get_utime_list (start_datetime, end_datetime, dt, times, error_flag) + subroutine get_utime_list (start_datetime, end_datetime, dt, times) ! makes a list of data times in secs since 1970-1-1 corresponding to requested period ! reports end-of-timestep points implicit none @@ -970,15 +973,14 @@ subroutine get_utime_list (start_datetime, end_datetime, dt, times, error_flag) real*8, intent (in) :: start_datetime, end_datetime real, intent (in) :: dt real*8, allocatable, intent (out) :: times(:) - integer, intent (out) :: error_flag !local integer :: t, ntimes real*8 :: utime - character(len=256) :: error_string + character(len=*), PARAMETER :: subroutineName = 'get_utime_list' if(abs(mod(end_datetime - start_datetime, dt)) > 1e-5) then error_flag = NOM_FAILURE - write(error_string,'(A,G8.3,A,G8.3,A,G8.3,A,G8.3)') "DateTimeUtilsModule.f90:get_utime_list(): start and end datetimes are not an even multiple of dt -- check dates in namelist: end_datetime: ",end_datetime," start_datetime: ",start_datetime," dt: ",dt," mod: ", mod(end_datetime-start_datetime, dt) + write(error_string,'(A,G8.3,A,G8.3,A,G8.3,A,G8.3)') moduleName//" - "//subroutineName//"(): start and end datetimes are not an even multiple of dt -- check dates in namelist: end_datetime: ",end_datetime," start_datetime: ",start_datetime," dt: ",dt," mod: ", mod(end_datetime-start_datetime, dt) call log_message(error_flag, error_string) return endif diff --git a/src/DomainType.f90 b/src/DomainType.f90 index 85f14305..b57edad4 100644 --- a/src/DomainType.f90 +++ b/src/DomainType.f90 @@ -32,7 +32,6 @@ module DomainType integer :: croptype ! crop type integer :: isltyp ! soil type integer :: IST ! surface type 1-soil; 2-lake -! integer :: error_flag ! flag for energy balance error (0 = no error, 1 = longwave < 0) real, allocatable, dimension(:) :: zsoil ! depth of layer-bottom from soil surface real, allocatable, dimension(:) :: dzsnso ! snow/soil layer thickness [m] @@ -96,7 +95,6 @@ subroutine InitDefault(this) this%croptype = huge(1) this%isltyp = huge(1) this%IST = huge(1) - this%error_flag = huge(1) end subroutine InitDefault @@ -120,11 +118,17 @@ subroutine InitTransfer(this, namelist) this%croptype = namelist%croptype this%isltyp = namelist%isltyp this%IST = namelist%sfctyp - this%error_flag = 0 ! model initializes with no errors this%start_datetime = date_to_unix(namelist%startdate) ! returns seconds-since-1970-01-01 + if (this%start_datetime < 0) then + error_flag = NOM_FAILURE + error_string = 'DomainType - InitTransfer(): Invalid start time' + return + endif this%end_datetime = date_to_unix(namelist%enddate) - if (this%start_datetime < 0 .OR. this%end_datetime < 0) then - this%error_flag = NOM_FAILURE + if (this%end_datetime < 0) then + error_flag = NOM_FAILURE + error_string = 'DomainType - InitTransfer(): Invalid end time' + return endif end subroutine InitTransfer diff --git a/src/EnergyModule.f90 b/src/EnergyModule.f90 index 4632be47..6fdc46a7 100644 --- a/src/EnergyModule.f90 +++ b/src/EnergyModule.f90 @@ -14,6 +14,8 @@ module EnergyModule use EtFluxModule use SnowSoilTempModule implicit none + character(len=*), PARAMETER :: moduleName='EnergyModule' + private :: moduleName contains @@ -46,7 +48,7 @@ SUBROUTINE EnergyMain (domain, levels, options, parameters, forcing, energy, wat REAL :: D_RSURF ! Reduced vapor diffusivity in soil for computing RSURF (SZ09) REAL :: FIRE !emitted IR (w/m2) - CHARACTER(len=256) :: error_string + CHARACTER(len=*), PARAMETER :: subroutineName = 'EnergyMain' !--------------------------------------------------------------------- ! Initialize the the fluxes from the vegetated fraction @@ -302,13 +304,13 @@ SUBROUTINE EnergyMain (domain, levels, options, parameters, forcing, energy, wat FIRE = forcing%LWDN + energy%FIRA IF(FIRE <=0.) THEN - domain%error_flag = NOM_FAILURE - write(error_string,101) 'EnergyModule.f90:EnergyMain(): emitted longwave <0; skin T & + error_flag = NOM_FAILURE + write(error_string,101) moduleName//' - '//subroutineName//'(): emitted longwave <0; skin T & may be wrong due to inconsistent input of SHDFAC with LAI. ILOC=', & domain%ILOC, ', JLOC=',domain%JLOC, ', SHDFAC=',parameters%FVEG,', & parameters%VAI=',parameters%VAI,', TV=',energy%TV,', TG=',energy%TG 101 format(A,I10,A,I10,A,F8.3,A,F8.3,A,F8.3,A,F8.3) - call log_message(domain%error_flag, trim(error_string)) + call log_message(error_flag, trim(error_string)) RETURN END IF diff --git a/src/ErrorCheckModule.f90 b/src/ErrorCheckModule.f90 index 078449ac..7032a361 100644 --- a/src/ErrorCheckModule.f90 +++ b/src/ErrorCheckModule.f90 @@ -7,18 +7,14 @@ module ErrorCheckModule integer, parameter, public :: NOM_FAILURE = 1 integer, parameter, public :: NOM_MESSAGE = 2 - private - - type, public :: error_type - public:: is_within_bound - public:: log_message + integer :: error_flag + character(len=256) :: error_string interface is_within_bound module procedure is_within_bound_int module procedure is_within_bound_real end interface -end error_type contains @@ -45,6 +41,19 @@ subroutine log_message(err, message) end subroutine log_message +! Save state of error_flag and error_string to members of another object. + subroutine save_error_state(err, message) + implicit none + + integer, intent(out) :: err ! error code + character(*), intent(out) :: message ! message + + err = error_flag + message = error_string + + end subroutine save_error_state + + function is_within_bound_int(var, lower_bound, upper_bound) result(withinbound) ! check if a integer value is within specified bounds diff --git a/src/ErrorType.f90 b/src/ErrorType.f90 new file mode 100644 index 00000000..3694fe39 --- /dev/null +++ b/src/ErrorType.f90 @@ -0,0 +1,44 @@ +module ErrorType + +use ErrorCheckModule + +implicit none +save +private + +type, public :: error_type + + integer :: error_flag ! error flag + character(len=256) :: error_string ! error string + + contains + + procedure, public :: Init + procedure, private :: InitDefault + +end type error_type + +contains + + subroutine Init(this) + + class(error_type) :: this + + call this%InitDefault() + + end subroutine Init + + + subroutine InitDefault(this) + + class(error_type) :: this + + error_flag = NOM_SUCCESS ! ModuleErrorCheck variable + error_string = 'EMPTY' + + this%error_flag = error_flag ! ModelType variable + this%error_string = error_string + + end subroutine InitDefault + +end module ErrorType diff --git a/src/Makefile b/src/Makefile index e4cca0ea..014ac9ad 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,7 @@ F90FLAGS := -cpp ${F90FLAGS} OBJS = ErrorCheckModule.o \ NamelistRead.o \ + ErrorType.o \ ParametersRead.o \ LevelsType.o \ DomainType.o \ @@ -105,7 +106,7 @@ EnergyModule.o: OptionsType.o LevelsType.o DomainType.o ParametersType.o EnergyT ForcingType.o WaterType.o ThermalPropertiesModule.o ShortwaveRadiationModule.o \ PrecipHeatModule.o EtFluxModule.o SnowSoilTempModule.o UtilitiesModule.o: DomainType.o ForcingType.o EnergyType.o -RunModule.o: OptionsType.o LevelsType.o DomainType.o ParametersType.o EnergyType.o \ +RunModule.o: OptionsType.o LevelsType.o DomainType.o ParametersType.o EnergyType.o ErrorType.o \ ForcingType.o WaterType.o NamelistRead.o ../driver/AsciiReadModule.o \ ../driver/OutputModule.o UtilitiesModule.o ForcingModule.o InterceptionModule.o \ EnergyModule.o WaterModule.o DateTimeUtilsModule.o diff --git a/src/NamelistRead.f90 b/src/NamelistRead.f90 index 302b2f65..cdbd2f71 100644 --- a/src/NamelistRead.f90 +++ b/src/NamelistRead.f90 @@ -5,6 +5,8 @@ module NamelistRead implicit none save private +character(len=*), PARAMETER :: moduleName='NamelistRead' +private :: moduleName type, public :: namelist_type @@ -76,12 +78,11 @@ module NamelistRead contains - subroutine ReadNamelist(this, namelist_file, error_flag) + subroutine ReadNamelist(this, namelist_file) class(namelist_type) :: this ! Optional namelist_file path/filename to read character(len=*), intent (in), optional :: namelist_file - integer, intent (out) :: error_flag integer :: ierr character(len=480) :: line @@ -101,7 +102,6 @@ subroutine ReadNamelist(this, namelist_file, error_flag) character(len=256) :: general_table character(len=256) :: noahowp_table character(len=256) :: soil_class_name - character(len=256) :: error_string real :: lat real :: lon real :: terrain_slope @@ -169,6 +169,7 @@ subroutine ReadNamelist(this, namelist_file, error_flag) integer :: integerMissing real :: realMissing character(len=12) :: stringMissing + character(len=*), PARAMETER :: subroutineName = 'ReadNamelist' ! ----------------------------------------------------------------------------------------------- ! ! initialize all namelist variables to missing values to allow for checking after namelist read ! @@ -228,47 +229,46 @@ subroutine ReadNamelist(this, namelist_file, error_flag) ! read namelist !--------------------------------------------------------------------- ierr = 0 - error_flag = NOM_SUCCESS if( trim(namelist_file) .ne. '' ) then open(30, file=namelist_file, form="formatted", status='old', iostat=ierr) - if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: user specified namelist file not found: '//trim(namelist_file); call log_message(error_flag, error_string); return; end if + if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: user specified namelist file not found: '//trim(namelist_file); call log_message(error_flag, error_string); return; end if else open(30, file='./namelist.input', form="formatted", status='old', iostat=ierr) - if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: default namelist file not found: ./namelist.input'; call log_message(error_flag, error_string); return; end if + if(ierr /= 0) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: default namelist file not found: ./namelist.input'; call log_message(error_flag, error_string); return; end if endif read(30, timing, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, parameters, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, location, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, forcing, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, model_options, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if read(30, structure, iostat=ierr) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if !--------------------------------------------------------------------- ! Check model option validity, part 2 !--------------------------------------------------------------------- - if (.not. is_within_bound(precip_phase_option, 1, 7)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: precip_phase_option should be 1-7'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(runoff_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: runoff_option should be 1-8'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(drainage_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: drainage_option should be 1-8'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(frozen_soil_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: frozen_soil_option should be 1-2'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(dynamic_vic_option ,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: dynamic_vic_option should be 1-3'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(dynamic_veg_option ,1, 9)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: dynamic_veg_option should be 1-9'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(snow_albedo_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: snow_albedo_option should be 1-2'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(radiative_transfer_option,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: radiative_transfer_option should be 1-3'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(sfc_drag_coeff_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: sfc_drag_coeff_option should be 1-3'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(canopy_stom_resist_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: canopy_stom_resist_option should be 1-2'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(snowsoil_temp_time_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: snowsoil_temp_time_option should be 1-3'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(soil_temp_boundary_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: soil_temp_boundary_option should be 1-2'; call log_message(error_flag, error_string); return;end if - if (.not. is_within_bound(supercooled_water_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: supercooled_water_option should be 1-2'; call log_message(error_flag, error_string); return;end if - if (.not. is_within_bound(stomatal_resistance_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: stomatal_resistance_option should be 1-3'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(evap_srfc_resistance_option, 1, 4)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: evap_srfc_resistance_option should be 1-4'; call log_message(error_flag, error_string); return; end if - if (.not. is_within_bound(subsurface_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): model options: subsurface_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(precip_phase_option, 1, 7)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: precip_phase_option should be 1-7'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(runoff_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: runoff_option should be 1-8'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(drainage_option, 1, 8)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: drainage_option should be 1-8'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(frozen_soil_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: frozen_soil_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(dynamic_vic_option ,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: dynamic_vic_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(dynamic_veg_option ,1, 9)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: dynamic_veg_option should be 1-9'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(snow_albedo_option ,1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: snow_albedo_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(radiative_transfer_option,1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: radiative_transfer_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(sfc_drag_coeff_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: sfc_drag_coeff_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(canopy_stom_resist_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: canopy_stom_resist_option should be 1-2'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(snowsoil_temp_time_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: snowsoil_temp_time_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(soil_temp_boundary_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: soil_temp_boundary_option should be 1-2'; call log_message(error_flag, error_string); return;end if + if (.not. is_within_bound(supercooled_water_option, 1, 2)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: supercooled_water_option should be 1-2'; call log_message(error_flag, error_string); return;end if + if (.not. is_within_bound(stomatal_resistance_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: stomatal_resistance_option should be 1-3'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(evap_srfc_resistance_option, 1, 4)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: evap_srfc_resistance_option should be 1-4'; call log_message(error_flag, error_string); return; end if + if (.not. is_within_bound(subsurface_option, 1, 3)) then; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): model options: subsurface_option should be 1-3'; call log_message(error_flag, error_string); return; end if ! after reading # of soil layers, allocate local arrays and read soil structure info @@ -284,7 +284,7 @@ subroutine ReadNamelist(this, namelist_file, error_flag) ! read remaining group from namelist read(30, initial_values) - if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if + if (ierr/=0) then; backspace(30); read(30,fmt='(A)') line; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: invalid line in namelist: '//trim(line); call log_message(error_flag, error_string); return; end if close(30) ! calculate total soil depth and populate array for depth of layer-bottom from soil surface @@ -296,64 +296,64 @@ subroutine ReadNamelist(this, namelist_file, error_flag) end do else error_flag=NOM_FAILURE; - write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return end if !--------------------------------------------------------------------- ! transfer values to namelist data structure !--------------------------------------------------------------------- - if(dt /= realMissing) then; this%dt = dt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dt not found in namelist'; call log_message(error_flag, error_string); return; end if - if(startdate /= stringMissing) then; this%startdate = startdate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry startdate not found in namelist'; call log_message(error_flag, error_string); return; end if - if(enddate /= stringMissing) then; this%enddate = enddate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry enddate not found in namelist'; call log_message(error_flag, error_string); return; end if - if(forcing_filename /= stringMissing) then; this%forcing_filename = forcing_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry forcing_filename not found in namelist'; call log_message(error_flag, error_string); return; end if - if(output_filename /= stringMissing) then; this%output_filename = output_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry output_filename not found in namelist'; call log_message(error_flag, error_string); return; end if - if(parameter_dir /= stringMissing) then; this%parameter_dir = parameter_dir; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry parameter_dir not found in namelist'; call log_message(error_flag, error_string); return; end if - if(soil_table /= stringMissing) then; this%soil_table = soil_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_table not found in namelist'; call log_message(error_flag, error_string); return; end if - if(general_table /= stringMissing) then; this%general_table = general_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry general_table not found in namelist'; call log_message(error_flag, error_string); return; end if - if(noahowp_table /= stringMissing) then; this%noahowp_table = noahowp_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry noahowp_table not found in namelist'; call log_message(error_flag, error_string); return; end if - if(soil_class_name /= stringMissing) then; this%soil_class_name = soil_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if - if(veg_class_name /= stringMissing) then; this%veg_class_name = veg_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry veg_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dt /= realMissing) then; this%dt = dt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry dt not found in namelist'; call log_message(error_flag, error_string); return; end if + if(startdate /= stringMissing) then; this%startdate = startdate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry startdate not found in namelist'; call log_message(error_flag, error_string); return; end if + if(enddate /= stringMissing) then; this%enddate = enddate; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry enddate not found in namelist'; call log_message(error_flag, error_string); return; end if + if(forcing_filename /= stringMissing) then; this%forcing_filename = forcing_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry forcing_filename not found in namelist'; call log_message(error_flag, error_string); return; end if + if(output_filename /= stringMissing) then; this%output_filename = output_filename; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry output_filename not found in namelist'; call log_message(error_flag, error_string); return; end if + if(parameter_dir /= stringMissing) then; this%parameter_dir = parameter_dir; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry parameter_dir not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_table /= stringMissing) then; this%soil_table = soil_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry soil_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(general_table /= stringMissing) then; this%general_table = general_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry general_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(noahowp_table /= stringMissing) then; this%noahowp_table = noahowp_table; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry noahowp_table not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_class_name /= stringMissing) then; this%soil_class_name = soil_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry soil_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if + if(veg_class_name /= stringMissing) then; this%veg_class_name = veg_class_name; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry veg_class_name not found in namelist'; call log_message(error_flag, error_string); return; end if - if(lat /= realMissing) then; this%lat = lat; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry lat not found in namelist'; call log_message(error_flag, error_string); return; end if - if(lon /= realMissing) then; this%lon = lon; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry lon not found in namelist'; call log_message(error_flag, error_string); return; end if - if(terrain_slope /= realMissing) then; this%terrain_slope = terrain_slope; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry terrain_slope not found in namelist'; call log_message(error_flag, error_string); return; end if - if(azimuth /= realMissing) then; this%azimuth = azimuth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry azimuth not found in namelist'; call log_message(error_flag, error_string); return; end if - if(zref /= realMissing) then; this%ZREF = ZREF; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry ZREF not found in namelist'; call log_message(error_flag, error_string); return; end if - if(rain_snow_thresh /= realMissing) then; this%rain_snow_thresh = rain_snow_thresh; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry rain_snow_thresh not found in namelist'; call log_message(error_flag, error_string); return; end if + if(lat /= realMissing) then; this%lat = lat; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry lat not found in namelist'; call log_message(error_flag, error_string); return; end if + if(lon /= realMissing) then; this%lon = lon; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry lon not found in namelist'; call log_message(error_flag, error_string); return; end if + if(terrain_slope /= realMissing) then; this%terrain_slope = terrain_slope; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry terrain_slope not found in namelist'; call log_message(error_flag, error_string); return; end if + if(azimuth /= realMissing) then; this%azimuth = azimuth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry azimuth not found in namelist'; call log_message(error_flag, error_string); return; end if + if(zref /= realMissing) then; this%ZREF = ZREF; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry ZREF not found in namelist'; call log_message(error_flag, error_string); return; end if + if(rain_snow_thresh /= realMissing) then; this%rain_snow_thresh = rain_snow_thresh; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry rain_snow_thresh not found in namelist'; call log_message(error_flag, error_string); return; end if - if(isltyp /= integerMissing) then; this%isltyp = isltyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry isltyp not found in namelist'; call log_message(error_flag, error_string); return; end if - if(nsoil /= integerMissing) then; this%nsoil = nsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nsoil not found in namelist'; call log_message(error_flag, error_string); return; end if - if(nsnow /= integerMissing) then; this%nsnow = nsnow; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nsnow not found in namelist'; call log_message(error_flag, error_string); return; end if - if(nveg /= integerMissing) then; this%nveg = nveg; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry nveg not found in namelist'; call log_message(error_flag, error_string); return; end if - if(soil_depth /= integerMissing) then; this%soil_depth = soil_depth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_depth not found in namelist'; call log_message(error_flag, error_string); return; end if - if(vegtyp /= integerMissing) then; this%vegtyp = vegtyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry vegtyp not found in namelist'; call log_message(error_flag, error_string); return; end if - if(croptype /= integerMissing) then; this%croptype = croptype; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry croptype not found in namelist'; call log_message(error_flag, error_string); return; end if - if(sfctyp /= integerMissing) then; this%sfctyp = sfctyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sfctyp not found in namelist'; call log_message(error_flag, error_string); return; end if - if(soilcolor /= integerMissing) then; this%soilcolor = soilcolor; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soilcolor not found in namelist'; call log_message(error_flag, error_string); return; end if + if(isltyp /= integerMissing) then; this%isltyp = isltyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry isltyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nsoil /= integerMissing) then; this%nsoil = nsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry nsoil not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nsnow /= integerMissing) then; this%nsnow = nsnow; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry nsnow not found in namelist'; call log_message(error_flag, error_string); return; end if + if(nveg /= integerMissing) then; this%nveg = nveg; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry nveg not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_depth /= integerMissing) then; this%soil_depth = soil_depth; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry soil_depth not found in namelist'; call log_message(error_flag, error_string); return; end if + if(vegtyp /= integerMissing) then; this%vegtyp = vegtyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry vegtyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(croptype /= integerMissing) then; this%croptype = croptype; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry croptype not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sfctyp /= integerMissing) then; this%sfctyp = sfctyp; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry sfctyp not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soilcolor /= integerMissing) then; this%soilcolor = soilcolor; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry soilcolor not found in namelist'; call log_message(error_flag, error_string); return; end if - if(zsoil(1) /= realMissing) then; this%zsoil = zsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry zsoil not found in namelist'; call log_message(error_flag, error_string); return; end if - if(dzsnso(1) /= realMissing) then; this%dzsnso = dzsnso; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return; end if - if(sice(1) /= realMissing) then; this%sice = sice; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sice not found in namelist'; call log_message(error_flag, error_string); return; end if - if(sh2o(1) /= realMissing) then; this%sh2o = sh2o; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sh2o not found in namelist'; call log_message(error_flag, error_string); return; end if - if(zwt /= realMissing) then; this%zwt = zwt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry zwt not found in namelist'; call log_message(error_flag, error_string); return; end if + if(zsoil(1) /= realMissing) then; this%zsoil = zsoil; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry zsoil not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dzsnso(1) /= realMissing) then; this%dzsnso = dzsnso; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry dzsnso not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sice(1) /= realMissing) then; this%sice = sice; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry sice not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sh2o(1) /= realMissing) then; this%sh2o = sh2o; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry sh2o not found in namelist'; call log_message(error_flag, error_string); return; end if + if(zwt /= realMissing) then; this%zwt = zwt; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry zwt not found in namelist'; call log_message(error_flag, error_string); return; end if - if(precip_phase_option /= integerMissing) then; this%precip_phase_option = precip_phase_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry precip_phase_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(runoff_option /= integerMissing) then; this%runoff_option = runoff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry runoff_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(drainage_option /= integerMissing) then; this%drainage_option = drainage_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry drainage_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(frozen_soil_option /= integerMissing) then; this%frozen_soil_option = frozen_soil_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry frozen_soil_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(dynamic_vic_option /= integerMissing) then; this%dynamic_vic_option = dynamic_vic_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dynamic_vic_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(dynamic_veg_option /= integerMissing) then; this%dynamic_veg_option = dynamic_veg_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry dynamic_veg_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(snow_albedo_option /= integerMissing) then; this%snow_albedo_option = snow_albedo_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry snow_albedo_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(radiative_transfer_option /= integerMissing) then; this%radiative_transfer_option = radiative_transfer_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry radiative_transfer_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(sfc_drag_coeff_option /= integerMissing) then; this%sfc_drag_coeff_option = sfc_drag_coeff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry sfc_drag_coeff_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(crop_model_option /= integerMissing) then; this%crop_model_option = crop_model_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry crop_model_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(canopy_stom_resist_option /= integerMissing) then; this%canopy_stom_resist_option = canopy_stom_resist_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry canopy_stom_resist_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(snowsoil_temp_time_option /= integerMissing) then; this%snowsoil_temp_time_option = snowsoil_temp_time_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry snowsoil_temp_time_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(soil_temp_boundary_option /= integerMissing) then; this%soil_temp_boundary_option = soil_temp_boundary_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry soil_temp_boundary_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(supercooled_water_option /= integerMissing) then; this%supercooled_water_option = supercooled_water_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry supercooled_water_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(stomatal_resistance_option /= integerMissing) then; this%stomatal_resistance_option = stomatal_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry stomatal_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(evap_srfc_resistance_option /= integerMissing) then; this%evap_srfc_resistance_option = evap_srfc_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry evap_srfc_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if - if(subsurface_option /= integerMissing) then; this%subsurface_option = subsurface_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') 'NamelistRead.f90:ReadNamelist(): ERROR: required entry subsurface_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(precip_phase_option /= integerMissing) then; this%precip_phase_option = precip_phase_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry precip_phase_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(runoff_option /= integerMissing) then; this%runoff_option = runoff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry runoff_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(drainage_option /= integerMissing) then; this%drainage_option = drainage_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry drainage_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(frozen_soil_option /= integerMissing) then; this%frozen_soil_option = frozen_soil_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry frozen_soil_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dynamic_vic_option /= integerMissing) then; this%dynamic_vic_option = dynamic_vic_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry dynamic_vic_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(dynamic_veg_option /= integerMissing) then; this%dynamic_veg_option = dynamic_veg_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry dynamic_veg_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(snow_albedo_option /= integerMissing) then; this%snow_albedo_option = snow_albedo_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry snow_albedo_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(radiative_transfer_option /= integerMissing) then; this%radiative_transfer_option = radiative_transfer_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry radiative_transfer_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(sfc_drag_coeff_option /= integerMissing) then; this%sfc_drag_coeff_option = sfc_drag_coeff_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry sfc_drag_coeff_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(crop_model_option /= integerMissing) then; this%crop_model_option = crop_model_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry crop_model_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(canopy_stom_resist_option /= integerMissing) then; this%canopy_stom_resist_option = canopy_stom_resist_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry canopy_stom_resist_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(snowsoil_temp_time_option /= integerMissing) then; this%snowsoil_temp_time_option = snowsoil_temp_time_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry snowsoil_temp_time_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(soil_temp_boundary_option /= integerMissing) then; this%soil_temp_boundary_option = soil_temp_boundary_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry soil_temp_boundary_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(supercooled_water_option /= integerMissing) then; this%supercooled_water_option = supercooled_water_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry supercooled_water_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(stomatal_resistance_option /= integerMissing) then; this%stomatal_resistance_option = stomatal_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry stomatal_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(evap_srfc_resistance_option /= integerMissing) then; this%evap_srfc_resistance_option = evap_srfc_resistance_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry evap_srfc_resistance_option not found in namelist'; call log_message(error_flag, error_string); return; end if + if(subsurface_option /= integerMissing) then; this%subsurface_option = subsurface_option; else; error_flag=NOM_FAILURE; write(error_string,'(A)') moduleName//' - '//subroutineName//'(): ERROR: required entry subsurface_option not found in namelist'; call log_message(error_flag, error_string); return; end if ! store missing values as well this%integerMissing = integerMissing diff --git a/src/ParametersRead.f90 b/src/ParametersRead.f90 index 0169cb0c..fb6c3607 100644 --- a/src/ParametersRead.f90 +++ b/src/ParametersRead.f90 @@ -9,6 +9,8 @@ MODULE ParametersRead ! 3. replace error handle routine ("wrf_error_fatal") with "handle_err" implicit none + character(len=*), PARAMETER :: moduleName='ParametersRead' + private :: moduleName save @@ -311,20 +313,18 @@ MODULE ParametersRead CONTAINS - SUBROUTINE read_veg_parameters(param_dir, noahowp_table, & - DATASET_IDENTIFIER, error_flag) + SUBROUTINE read_veg_parameters(param_dir, noahowp_table, DATASET_IDENTIFIER) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table character(len=*), intent(in) :: DATASET_IDENTIFIER - integer, intent(out):: error_flag + character(len=*), PARAMETER :: subroutineName = 'read_veg_parameters' integer :: ierr integer :: IK,IM logical :: file_named integer :: NVEG character(len=256) :: VEG_DATASET_DESCRIPTION - character(len=256) :: error_string integer :: ISURBAN integer :: ISWATER @@ -457,7 +457,7 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, & if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_veg_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -470,8 +470,9 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, & read(15,modis_veg_parameters) else error_flag = NOM_FAILURE - write(error_string,'(A,A)') "ParametersRead.f90:read_veg_parameters(): Unrecognized DATASET_IDENTIFIER: ", trim(DATASET_IDENTIFIER) + write(error_string,'(A,A)') moduleName//' - '//subroutineName//'(): Unrecognized DATASET_IDENTIFIER: ', trim(DATASET_IDENTIFIER) call log_message(error_flag, error_string) + close(15) return endif close(15) @@ -580,19 +581,17 @@ SUBROUTINE read_veg_parameters(param_dir, noahowp_table, & END SUBROUTINE read_veg_parameters SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, & - soil_class_name, error_flag) + soil_class_name) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: soil_table character(len=*), intent(in) :: general_table character(len=*), intent(in) :: soil_class_name - integer, intent(out):: error_flag + character(len=*), PARAMETER :: subroutineName = 'read_soil_parameters' integer :: IERR character(len=20) :: SLTYPE integer :: ITMP, NUM_SLOPE, LC integer :: iLine ! loop index - !character(len=256) :: message - character(len=256) :: error_string logical :: file_named @@ -634,7 +633,7 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, & if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_soil_parameters(): failure opening SOILPARM.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): failure opening SOILPARM.TBL' call log_message(error_flag, error_string) return endif @@ -672,7 +671,7 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, & if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_soil_parameters(): failure opening GENPARM.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): failure opening GENPARM.TBL' call log_message(error_flag, error_string) return endif @@ -717,14 +716,13 @@ SUBROUTINE read_soil_parameters(param_dir, soil_table, general_table, & END SUBROUTINE read_soil_parameters - SUBROUTINE read_rad_parameters(param_dir, noahowp_table, error_flag) + SUBROUTINE read_rad_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table - integer, intent(out):: error_flag + character(len=*), PARAMETER :: subroutineName = 'read_rad_parameters' integer :: ierr logical :: file_named - character(len=256) :: error_string real :: ALBICE(MBAND),ALBLAK(MBAND),OMEGAS(MBAND),BETADS,BETAIS,EG(2) real :: ALBSAT_VIS(MSC) @@ -753,7 +751,7 @@ SUBROUTINE read_rad_parameters(param_dir, noahowp_table, error_flag) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_rad_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -774,14 +772,13 @@ SUBROUTINE read_rad_parameters(param_dir, noahowp_table, error_flag) end subroutine read_rad_parameters - subroutine read_global_parameters(param_dir, noahowp_table, error_flag) + subroutine read_global_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table - integer, intent(out):: error_flag + character(len=*), PARAMETER :: subroutineName = 'read_global_parameters' integer :: ierr logical :: file_named - character(len=256) :: error_string real :: CO2,O2,TIMEAN,FSATMX,Z0SNO,SSI,SNOW_RET_FAC,SNOW_EMIS,& SWEMX,TAU0,GRAIN_GROWTH,EXTRA_GROWTH,DIRT_SOOT,& @@ -827,7 +824,7 @@ subroutine read_global_parameters(param_dir, noahowp_table, error_flag) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_global_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -860,14 +857,13 @@ subroutine read_global_parameters(param_dir, noahowp_table, error_flag) END SUBROUTINE read_global_parameters - SUBROUTINE read_crop_parameters(param_dir, noahowp_table, error_flag) + SUBROUTINE read_crop_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table - integer, intent(out):: error_flag + character(len=*), PARAMETER :: subroutineName = 'read_crop_parameters' integer :: ierr logical :: file_named - character(len=256) :: error_string integer :: DEFAULT_CROP integer, dimension(NCROP) :: PLTDAY @@ -1012,7 +1008,7 @@ SUBROUTINE read_crop_parameters(param_dir, noahowp_table, error_flag) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_crop_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -1160,14 +1156,13 @@ SUBROUTINE read_crop_parameters(param_dir, noahowp_table, error_flag) END SUBROUTINE read_crop_parameters - SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table, error_flag) + SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + character(len=*), PARAMETER :: subroutineName = 'read_irrigation_parameters' integer :: ierr - integer, intent(out):: error_flag logical :: file_named - character(len=256) :: error_string real :: IRR_FRAC ! irrigation Fraction integer :: IRR_HAR ! number of days before harvest date to stop irrigation @@ -1201,7 +1196,7 @@ SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table, error_flag) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_irrigation_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -1221,15 +1216,14 @@ SUBROUTINE read_irrigation_parameters(param_dir, noahowp_table, error_flag) END SUBROUTINE read_irrigation_parameters - SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table, error_flag) + SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + character(len=*), PARAMETER :: subroutineName = 'read_tiledrain_parameters' integer :: ierr - integer, intent(out):: error_flag logical :: file_named - character(len=256) :: error_string real, dimension(MAX_SOILTYP) :: TDSMC_FAC integer, dimension(MAX_SOILTYP) :: TD_DEPTH real, dimension(MAX_SOILTYP) :: TD_DC @@ -1266,7 +1260,7 @@ SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table, error_flag) end if if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_tiledrain_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif @@ -1289,14 +1283,13 @@ SUBROUTINE read_tiledrain_parameters(param_dir, noahowp_table, error_flag) END SUBROUTINE read_tiledrain_parameters - SUBROUTINE read_optional_parameters(param_dir, noahowp_table, error_flag) + SUBROUTINE read_optional_parameters(param_dir, noahowp_table) implicit none character(len=*), intent(in) :: param_dir character(len=*), intent(in) :: noahowp_table + character(len=*), PARAMETER :: subroutineName = 'read_optional_parameters' integer :: ierr logical :: file_named - integer, intent(out):: error_flag - character(len=256) :: error_string namelist / optional_parameters / & sr2006_theta_1500t_a, sr2006_theta_1500t_b, sr2006_theta_1500t_c, & @@ -1326,7 +1319,7 @@ SUBROUTINE read_optional_parameters(param_dir, noahowp_table, error_flag) if (ierr /= 0) then error_flag = NOM_FAILURE - write(error_string,'(A)') "ParametersRead.f90:read_optional_parameters(): Cannot find file MPTABLE.TBL" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): Cannot find file MPTABLE.TBL' call log_message(error_flag, error_string) return endif diff --git a/src/ParametersType.f90 b/src/ParametersType.f90 index 8c248d3e..57b498ae 100644 --- a/src/ParametersType.f90 +++ b/src/ParametersType.f90 @@ -197,11 +197,10 @@ subroutine InitDefault(this) end subroutine InitDefault - subroutine paramRead(this, namelist, error_flag) + subroutine paramRead(this, namelist) implicit none class(parameters_type) :: this class(namelist_type), intent(in) :: namelist - integer, intent(out):: error_flag ! local variables integer :: ix character(len=50) :: dataset_identifier @@ -209,22 +208,22 @@ subroutine paramRead(this, namelist, error_flag) !dataset_identifier = "MODIFIED_IGBP_MODIS_NOAH" ! This can be in namelist !call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, dataset_identifier) - call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table, namelist%soil_class_name, error_flag) + call read_soil_parameters(namelist%parameter_dir, namelist%soil_table, namelist%general_table, namelist%soil_class_name) if (error_flag == NOM_FAILURE) then return end if - call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, namelist%veg_class_name, error_flag) + call read_veg_parameters(namelist%parameter_dir, namelist%noahowp_table, namelist%veg_class_name) if (error_flag == NOM_FAILURE) then return end if - call read_rad_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) + call read_rad_parameters(namelist%parameter_dir, namelist%noahowp_table) if (error_flag == NOM_FAILURE) then return end if - call read_global_parameters(namelist%parameter_dir, namelist%noahowp_table, error_flag) + call read_global_parameters(namelist%parameter_dir, namelist%noahowp_table) if (error_flag == NOM_FAILURE) then return end if diff --git a/src/RunModule.f90 b/src/RunModule.f90 index 57b2b3e1..d8479319 100644 --- a/src/RunModule.f90 +++ b/src/RunModule.f90 @@ -10,6 +10,7 @@ module RunModule use WaterType use ForcingType use EnergyType + use ErrorType use AsciiReadModule use OutputModule use UtilitiesModule @@ -31,6 +32,7 @@ module RunModule type(water_type) :: water type(forcing_type) :: forcing type(energy_type) :: energy + type(error_type) :: error end type noahowp_type contains @@ -50,13 +52,17 @@ SUBROUTINE initialize_from_file (model, config_filename) parameters => model%parameters, & water => model%water, & forcing => model%forcing, & - energy => model%energy) + energy => model%energy, & + error => model%error) !--------------------------------------------------------------------- ! initialize !--------------------------------------------------------------------- - call namelist%ReadNamelist(config_filename,domain%error_flag) - if (domain%error_flag == NOM_FAILURE) then + call error%Init() + + call namelist%ReadNamelist(config_filename) + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if @@ -65,7 +71,8 @@ SUBROUTINE initialize_from_file (model, config_filename) call domain%Init(namelist) call domain%InitTransfer(namelist) - if (domain%error_flag == NOM_FAILURE) then + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if @@ -73,8 +80,9 @@ SUBROUTINE initialize_from_file (model, config_filename) call options%InitTransfer(namelist) call parameters%Init(namelist) - call parameters%paramRead(namelist, model%domain%error_flag) - if (model%domain%error_flag == NOM_FAILURE) then + call parameters%paramRead(namelist) + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if @@ -206,8 +214,9 @@ SUBROUTINE initialize_from_file (model, config_filename) !--- set a time vector for simulation --- !--------------------------------------------------------------------- ! --- AWW: calculate start and end utimes & records for requested station data read period --- - call get_utime_list (domain%start_datetime, domain%end_datetime, domain%dt, domain%sim_datetimes, domain%error_flag) ! makes unix-time list for desired records (end-of-timestep) - if (domain%error_flag == NOM_FAILURE) then + call get_utime_list (domain%start_datetime, domain%end_datetime, domain%dt, domain%sim_datetimes) ! makes unix-time list for desired records (end-of-timestep) + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if domain%ntime = size (domain%sim_datetimes) @@ -222,8 +231,9 @@ SUBROUTINE initialize_from_file (model, config_filename) ! Nextgen forcing is being used (https://github.com/NOAA-OWP/ngen) !--------------------------------------------------------------------- #ifndef NGEN_FORCING_ACTIVE - call open_forcing_file(namelist%forcing_filename, model%domain%error_flag) - if (model%domain%error_flag == NOM_FAILURE) then + call open_forcing_file(namelist%forcing_filename) + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if #endif @@ -263,7 +273,8 @@ SUBROUTINE advance_in_time(model) type (noahowp_type), intent (inout) :: model call solve_noahowp(model) - if (model%domain%error_flag == NOM_FAILURE) then + if (error_flag == NOM_FAILURE) then + call save_error_state(model%error%error_flag, model%error%error_string) return end if @@ -287,7 +298,8 @@ SUBROUTINE solve_noahowp(model) parameters => model%parameters, & water => model%water, & forcing => model%forcing, & - energy => model%energy) + energy => model%energy, & + error => model%error) ! Compute the current UNIX datetime domain%curr_datetime = domain%sim_datetimes(domain%itime) ! use end-of-timestep datetimes because initial var values are being written @@ -303,8 +315,9 @@ SUBROUTINE solve_noahowp(model) forcing_timestep = domain%dt #ifndef NGEN_FORCING_ACTIVE call read_forcing_text(iunit, domain%nowdate, forcing_timestep, & - forcing%UU, forcing%VV, forcing%SFCTMP, forcing%Q2, forcing%SFCPRS, forcing%SOLDN, forcing%LWDN, forcing%PRCP, ierr, domain%error_flag) - if (domain%error_flag == NOM_FAILURE) then + forcing%UU, forcing%VV, forcing%SFCTMP, forcing%Q2, forcing%SFCPRS, forcing%SOLDN, forcing%LWDN, forcing%PRCP, ierr) + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if #endif @@ -313,7 +326,8 @@ SUBROUTINE solve_noahowp(model) ! call the main utility routines !--------------------------------------------------------------------- call UtilitiesMain (domain%itime, domain, forcing, energy) - if (domain%error_flag == NOM_FAILURE) then + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if @@ -334,7 +348,8 @@ SUBROUTINE solve_noahowp(model) !--------------------------------------------------------------------- call EnergyMain (domain, levels, options, parameters, forcing, energy, water) - if (domain%error_flag == NOM_FAILURE) then + if (error_flag == NOM_FAILURE) then + call save_error_state(error%error_flag, error%error_string) return end if diff --git a/src/UtilitiesModule.f90 b/src/UtilitiesModule.f90 index 5c4a5ff7..34c6cde4 100644 --- a/src/UtilitiesModule.f90 +++ b/src/UtilitiesModule.f90 @@ -12,6 +12,8 @@ module UtilitiesModule use ErrorCheckModule use ForcingType implicit none + character(len=*), PARAMETER :: moduleName='UtilitiesModule' + private :: moduleName contains @@ -30,17 +32,17 @@ SUBROUTINE UtilitiesMain (itime, domain, forcing, energy) ! calculate current 'nowdate' from start date + integer length of run to current time call geth_newdate(domain%startdate, idt, & ! in - domain%nowdate, domain%error_flag) ! out - if (domain%error_flag == NOM_FAILURE) then + domain%nowdate) ! out + if (error_flag == NOM_FAILURE) then return end if ! calculate current declination of direct solar radiation input call calc_declin(domain%nowdate(1:4)//"-"//domain%nowdate(5:6)//"-"//domain%nowdate(7:8)//"_"//domain%nowdate(9:10)//":"//domain%nowdate(11:12)//":00", & ! in domain%lat, domain%lon, domain%terrain_slope, domain%azimuth,& ! in - energy%cosz, energy%cosz_horiz,forcing%yearlen, forcing%julian, domain%error_flag) ! out + energy%cosz, energy%cosz_horiz,forcing%yearlen, forcing%julian) ! out - if (domain%error_flag == NOM_FAILURE) then + if (error_flag == NOM_FAILURE) then return end if @@ -48,14 +50,13 @@ END SUBROUTINE UtilitiesMain ! calculate current 'nowdate' from start date + integer length of run to current time subroutine geth_newdate (odate, idt, & ! in - ndate, error_flag) ! out + ndate) ! out IMPLICIT NONE character (len=*), intent(in) :: odate ! start date integer, intent(in) :: idt ! change in time (in minutes) character (len=*), intent(out) :: ndate ! current - integer, intent(out) :: error_flag ! ------------------------ local variables --------------------------- integer :: nlen ! length of "ndate" string @@ -85,7 +86,7 @@ subroutine geth_newdate (odate, idt, & ! in logical :: opass ! logical for whether odate components pass their checks character (len=10) :: hfrc character (len=1) :: sp - character (len=256):: error_string + character (len=*), PARAMETER :: subroutineName = 'geth_newdate' logical :: punctuated ! logical for whether the date string has hyphens to separate logical :: idtdy ! logical for whether idt has units of days @@ -220,7 +221,7 @@ subroutine geth_newdate (odate, idt, & ! in ! If opass = false, then cancel the run if (.not.opass) then error_flag = NOM_FAILURE - write(error_string,'(A,A)') "UtilitiesModule.f90:geth_newdate(): Crazy ODATE: ",odate(1:olen) + write(error_string,'(A,A)') moduleName//' - '//subroutineName//'(): Crazy ODATE: ',odate(1:olen) call log_message(error_flag, trim(error_string)) return end if @@ -271,7 +272,7 @@ subroutine geth_newdate (odate, idt, & ! in nfrac = 0 else error_flag = NOM_FAILURE - write(error_string,'(A,I3)') "UtilitiesModule.f90:geth_newdate(): Strange length for ODATE: ",olen + write(error_string,'(A,I3)') moduleName//' - '//subroutineName//'(): Strange length for ODATE: ',olen call log_message(error_flag, trim(error_string)) return end if @@ -420,7 +421,7 @@ subroutine geth_newdate (odate, idt, & ! in else error_flag = NOM_FAILURE - write(error_string,'(A)') "UtilitiesModule.f90:geth_newdate(): DATELEN PROBLEM" + write(error_string,'(A)') moduleName//' - '//subroutineName//'(): DATELEN PROBLEM' call log_message(error_flag, trim(error_string)) return end if @@ -430,20 +431,19 @@ end subroutine geth_newdate ! calculate integer day of year for current time ! AW: not sure this is ever called in the code at present - subroutine geth_idts (newdate, olddate, idt, error_flag) + subroutine geth_idts (newdate, olddate, idt) implicit none character (len=*) , intent(in) :: newdate ! current date of run character (len=*) , intent(in) :: olddate ! first day of current year integer , intent(out) :: idt ! integer day of year - integer , intent(out) :: error_flag ! ------------------------ local variables --------------------------- character(len=24) :: ndate character(len=24) :: odate character (len=24) :: tdate - character (len=256):: error_string + character (len=*), PARAMETER :: subroutineName = 'geth_idts' integer :: olen ! length of olddate integer :: nlen ! length of newdate integer :: yrnew ! year associated with "ndate" @@ -474,7 +474,7 @@ subroutine geth_idts (newdate, olddate, idt, error_flag) nlen = len(newdate) if (nlen /= olen) then error_flag = NOM_FAILURE - write(error_string,'(A,A,2x,A)') "UtilitiesModule.f90:geth_idts(): NLEN /= OLEN: ",newdate(1:nlen), olddate(1:olen) + write(error_string,'(A,A,2x,A)') moduleName//' - '//subroutineName//'(): NLEN /= OLEN: ',newdate(1:nlen), olddate(1:olen) call log_message(error_flag, trim(error_string)) return endif @@ -693,14 +693,14 @@ subroutine geth_idts (newdate, olddate, idt, error_flag) if (.not. npass) then error_flag = NOM_FAILURE - write(error_string,'(A,A)') "UtilitiesModule.f90:geth_idts(): Screwy NDATE: ",ndate(1:nlen) + write(error_string,'(A,A)') moduleName//' - '//subroutineName//'(): Screwy NDATE: ',ndate(1:nlen) call log_message(error_flag, trim(error_string)) return end if if (.not. opass) then error_flag = NOM_FAILURE - write(error_string,'(A,A)') "UtilitiesModule.f90:geth_idts(): Screwy ODATE: ",odate(1:olen) + write(error_string,'(A,A)') moduleName//' - '//subroutineName//'(): Screwy ODATE: ',odate(1:olen) call log_message(error_flag, trim(error_string)) return end if @@ -830,7 +830,7 @@ end function nmdays SUBROUTINE calc_declin (nowdate, & ! in latitude, longitude, slope, azimuth, & ! in - cosz, cosz_horiz, yearlen, julian, error_flag) ! out + cosz, cosz_horiz, yearlen, julian) ! out !--------------------------------------------------------------------- IMPLICIT NONE !--------------------------------------------------------------------- @@ -845,7 +845,6 @@ SUBROUTINE calc_declin (nowdate, & ! in real, intent(out) :: cosz_horiz ! cosine of solar zenith angle for flat ground integer, intent(out) :: yearlen ! year length real, intent(out) :: JULIAN ! julian day - integer, intent(out) :: error_flag ! ------------------------ local variables --------------------------- REAL, PARAMETER :: DEGRAD = 3.14159265/180. ! convert degrees to radians @@ -890,7 +889,7 @@ SUBROUTINE calc_declin (nowdate, & ! in endif ! Determine the Julian time (floating-point day of year) - call geth_idts(nowdate(1:10), nowdate(1:4)//"-01-01", iday, error_flag) + call geth_idts(nowdate(1:10), nowdate(1:4)//"-01-01", iday) if (error_flag == NOM_FAILURE) then return endif diff --git a/test/Makefile b/test/Makefile index 6afddc54..9a9b4ef7 100644 --- a/test/Makefile +++ b/test/Makefile @@ -7,6 +7,7 @@ include ../user_build_options OBJS = \ ../src/ErrorCheckModule.o \ + ../src/ErrorType.o \ ../src/NamelistRead.o \ ../src/ParametersRead.o \ ../src/LevelsType.o \