Skip to content

Commit

Permalink
Tweak verify_variables parameters NCAR#448
Browse files Browse the repository at this point in the history
Changed verify_variables to not read state_variables as a list, then output a table. Instead, it reads state_variables as a table. Also simplified structure and removed logic for alternate 5 row input.
  • Loading branch information
Benjamin-Gunn committed Sep 17, 2023
1 parent 4f1c859 commit a125327
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 111 deletions.
28 changes: 11 additions & 17 deletions developer_tests/namelist/test_read_variable_namelist.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ program test_read_variable_namelist

implicit none

integer, parameter :: nrows = 5 ! - Hard Coded
integer, parameter :: ncols = 3 ! - Hard Coded
character(len=vtablenamelength) :: state_variables(nrows * ncols)
integer, parameter :: nrows = 3 ! - Hard Coded
integer, parameter :: ncols = 5 ! - Hard Coded

character(len=vtablenamelength) :: state_variables(nrows, ncols)

integer :: iunit, io, ngood
integer :: var_qtys(nrows)
character(len=vtablenamelength) :: table(nrows, ncols)
character(len=vtablenamelength) :: var_names(nrows)
logical :: var_update(nrows)
real(r8) :: var_ranges(nrows, 2)
integer :: var_qtys(ncols)
character(len=vtablenamelength) :: var_names(ncols)
logical :: var_update(ncols)
real(r8) :: var_ranges(ncols, 2)

namelist /model_nml/ &
state_variables
Expand All @@ -31,13 +30,8 @@ program test_read_variable_namelist

print*, "Hello World!"

call verify_variables(state_variables, ngood, table, var_names, &
var_qtys, var_update, var_ranges)!, .false.)

!print*, state_variables, ngood, table, var_names, &
! var_qtys, var_update, var_ranges

print*, var_qtys
call verify_variables(state_variables, ngood, var_names, &
var_qtys, var_update, var_ranges)

call finalize_mpi_utilities()

Expand Down
36 changes: 11 additions & 25 deletions developer_tests/namelist/work/input.nml
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
&model_nml
! 3 column working. Output good.
!
! state_variables = 'SALT_CUR ', 'QTY_SALINITY ', 'UPDATE',
! 'TEMP_CUR ', 'QTY_POTENTIAL_TEMPERATURE', 'UPDATE',
! 'UVEL_CUR ', 'QTY_U_CURRENT_COMPONENT ', 'UPDATE',
! 'VVEL_CUR ', 'QTY_V_CURRENT_COMPONENT ', 'UPDATE',
! 'PSURF_CUR', 'QTY_SEA_SURFACE_PRESSURE ', 'UPDATE'

! 2 column working. Output good.
state_variables = 'SALT_CUR ', 'QTY_SALINITY ', 'UPDATE',
'TEMP_CUR ', 'QTY_POTENTIAL_TEMPERATURE', 'UPDATE',
'UVEL_CUR ', 'QTY_U_CURRENT_COMPONENT ', 'UPDATE',
'VVEL_CUR ', 'QTY_V_CURRENT_COMPONENT ', 'UPDATE',
'PSURF_CUR', 'QTY_SEA_SURFACE_PRESSURE ', 'UPDATE'
!
! state_variables = 'theta', 'QTY_POTENTIAL_TEMPERATURE',
! 'rho', 'QTY_DENSITY',
Expand All @@ -17,20 +13,9 @@
! 'qv', 'QTY_VAPOR_MIXING_RATIO',
! 'surface_pressure', 'QTY_SURFACE_PRESSURE'
!

! 5 column working, with .false. default_vars flag? Output good, exept no default_vars, var_qtys breaks?
!
state_variables = 'SH2O', 'QTY_SOIL_LIQUID_WATER', '0.0', 'NA', 'NOUPDATE',
'SUBSURFACE_FLUX', 'QTY_SUBSURFACE', '0.0', 'NA', 'NOUPDATE',
'OVERLAND_FLUX', 'QTY_OVERLAND_FLOW', '0.0', 'NA', 'NOUPDATE'


! Alternate 5 column not working as expected! Defult output good, everything else broken!
!
! state_variables = 'U', 'QTY_U_WIND_COMPONENT', 'TYPE_U', 'UPDATE', '999',
! 'V', 'QTY_V_WIND_COMPONENT', 'TYPE_V', 'UPDATE', '999',
! 'U10', 'QTY_U_WIND_COMPONENT', 'TYPE_U10', 'UPDATE', '999',
! 'V10', 'QTY_V_WIND_COMPONENT', 'TYPE_V10', 'UPDATE', '999'
! state_variables = 'SH2O', 'QTY_SOIL_LIQUID_WATER', '0.0', 'NA', 'NOUPDATE',
! 'SUBSURFACE_FLUX', 'QTY_SUBSURFACE', '0.0', 'NA', 'NOUPDATE',
! 'OVERLAND_FLUX', 'QTY_OVERLAND_FLOW', '0.0', 'NA', 'NOUPDATE'
/

&utilities_nml
Expand All @@ -40,8 +25,9 @@

&preprocess_nml
input_obs_kind_mod_file = '../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90'
quantity_files = '../../../assimilation_code/modules/observations/land_quantities_mod.f90',
'../../../assimilation_code/modules/observations/default_quantities_mod.f90'
quantity_files = '../../../assimilation_code/modules/observations/land_quantities_mod.f90',
'../../../assimilation_code/modules/observations/default_quantities_mod.f90'
'../../../assimilation_code/modules/observations/atmosphere_quantities_mod.f90'
output_obs_kind_mod_file = '../../../assimilation_code/modules/observations/obs_kind_mod.f90'
input_obs_def_mod_file = '../../../observations/forward_operators/DEFAULT_obs_def_mod.F90'
output_obs_def_mod_file = '../../../observations/forward_operators/obs_def_mod.f90'
Expand Down
Binary file modified developer_tests/namelist/work/test_read_variable_namelist
Binary file not shown.
110 changes: 41 additions & 69 deletions developer_tests/namelist/work/verify_variables_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ module verify_variables_mod
use types_mod, only : r8, MISSING_R8
use utilities_mod, only : error_handler, E_ERR, E_MSG, do_output, to_upper
use netcdf_utilities_mod, only : NF90_MAX_NAME
use obs_kind_mod, only : QTY_TEMPERATURE, QTY_SALINITY, QTY_DRY_LAND, &
QTY_U_CURRENT_COMPONENT,QTY_V_CURRENT_COMPONENT, &
QTY_SEA_SURFACE_HEIGHT, QTY_SEA_SURFACE_PRESSURE, &
QTY_POTENTIAL_TEMPERATURE, QTY_SEA_SURFACE_ANOMALY, &
get_index_for_quantity, get_name_for_quantity
use obs_kind_mod, only : QTY_SALINITY, QTY_POTENTIAL_TEMPERATURE, get_index_for_quantity

implicit none

Expand All @@ -26,122 +22,98 @@ module verify_variables_mod
! Subroutine for verifying state variables.
! - state_variables: list of state variables from namelist
! - ngood: amount of state variable rows validated
! - table: 2D string array of state variables
! - var_names: array of NetCDF variable names
! - var_qtys: array of DART QUANTITY
! - var_update: array of UPDATE flags (optional)
! - var_qtys (kind_list): array of DART QUANTITY
! - var_update (update_var): array of UPDATE flags (optional,)
! - var_ranges: 2D array of ranges (optional)
! - default_vars: flag to check DART QUANTITY (optional, default = true)
!-----------------------------------------------------------------------
subroutine verify_variables(state_variables, ngood, table, var_names, &
var_qtys, var_update, var_ranges, default_vars)
subroutine verify_variables(state_variables, ngood, var_names, &
var_qtys, var_update, var_ranges)

character(len=*), intent(inout) :: state_variables(:)
character(len=*), intent(inout) :: state_variables(:,:)
integer, intent(out) :: ngood
character(len=*), intent(out) :: table(:,:)
character(len=*), intent(out) :: var_names(:)
integer, intent(out) :: var_qtys(:) ! - kind_list
logical, optional, intent(out) :: var_update(:) ! - update_var, optional
real(r8), optional, intent(out) :: var_ranges(:,:) ! - optional
logical, optional, intent(in) :: default_vars ! - optional

integer, intent(out) :: var_qtys(:)
logical, optional, intent(out) :: var_update(:)
real(r8), optional, intent(out) :: var_ranges(:,:)

character(len=*), parameter :: routine = 'verify_variables'

integer :: io, i, nrows, ncols
real(r8) :: minvalue, maxvalue
logical :: check_obs
character(len=NF90_MAX_NAME) :: varname, dartstr, minvalstring, maxvalstring, update

nrows = size(table,1)
ncols = size(table) / size(table,1)
check_obs = .true.
nrows = size(state_variables,1)
ncols = size(state_variables) / size(state_variables,1)

ngood = 0

MyLoop : do i = 1, nrows
MyLoop : do i = 1, ncols

varname = trim(state_variables(ncols * i - (ncols - 1)))
dartstr = trim(state_variables(ncols * i - (ncols - 2)))
varname = trim(state_variables(1, i))
dartstr = trim(state_variables(2, i))

if ( table(i,1) == ' ' .and. table(i,2) == ' ') exit MyLoop ! Found end of list.
if ( state_variables(1, i) == ' ' .and. state_variables(2, i) == ' ') exit MyLoop ! Found end of list.

if ( table(i,1) == ' ' .or. table(i,2) == ' ') then
string1 = 'model_nml:state_variables not fully specified'
call error_handler(E_ERR,routine,string1,source,revision,revdate)
if ( state_variables(1, i) == ' ' .or. state_variables(2, i) == ' ') then
string1 = 'model_nml:state_variables not fully specified'
call error_handler(E_ERR,routine,string1,source,revision,revdate)
endif

! All good to here - fill the output variables
ngood = ngood + 1

if (present(default_vars)) check_obs = default_vars
var_names(ngood) = varname

! The internal DART routines check if the variable name is valid.

if (check_obs) then
var_qtys(i) = get_index_for_quantity(dartstr)
if( var_qtys(i) < 0 ) then
write(string1,'(''there is no obs_kind <'',a,''> in obs_kind_mod.f90'')') trim(dartstr)
write(string2,'(A)') 'Hint: set default_vars as false if using non default state_variables'
call error_handler(E_ERR,routine,string1,source,revision,revdate, text2=string2)
endif
var_qtys(ngood) = get_index_for_quantity(dartstr)
if( var_qtys(i) < 0 ) then
write(string1,'(''there is no obs_kind <'',a,''> in obs_kind_mod.f90'')') trim(dartstr)
call error_handler(E_ERR,routine,string1,source,revision,revdate)
endif

! All good to here - fill the output variables
ngood = ngood + 1
! Records false in var_update if string is anything but "UPDATE"

var_names(ngood) = varname
if ( present(var_update) .and. nrows <= 3 )then
update = trim(state_variables(3, i))
call to_upper(update)

table(i,1) = trim(varname)
table(i,2) = trim(dartstr)
var_update(ngood) = .false.
if (update == 'UPDATE') var_update(ngood) = .true.
endif

! Check to see if other columns variables are present from default
! Records the min and max value range in var_ranges

if (ncols == 5) then
if ( present(var_ranges) .and. nrows == 5 ) then
var_ranges(ngood,:) = (/ MISSING_R8, MISSING_R8 /)

minvalstring = trim(state_variables(ncols * i - (ncols - 3)))
maxvalstring = trim(state_variables(ncols * i - (ncols - 4)))
update = trim(state_variables(ncols * i - (ncols - 5)))
minvalstring = trim(state_variables(4, i))
maxvalstring = trim(state_variables(5, i))

! Convert the [min,max] valstrings to numeric values if possible

read(minvalstring,*,iostat=io) minvalue
if (io == 0) var_ranges(ngood,1) = minvalue
table(i,3) = trim(minvalstring)

read(maxvalstring,*,iostat=io) maxvalue
if (io == 0) var_ranges(ngood,2) = maxvalue
table(i,4) = trim(maxvalstring)

call to_upper(update)
table(i,5) = trim(update)

else if (ncols == 3) then
update = trim(state_variables(ncols * i - (ncols - 3)))

call to_upper(update)
table(i,3) = trim(update)
end if

! Records false in var_update if string is anything but "UPDATE"

if ( present(var_update) )then
var_update(ngood) = .false.
if (update == 'UPDATE') var_update(ngood) = .true.
endif

! Record the contents of the DART state vector

if (do_output()) then
SELECT CASE (ncols)
SELECT CASE (nrows)
CASE (5)
write(string1,'(A,I2,10A)') 'variable ',i,' is ',trim(varname), ', ', trim(dartstr), &
write(string1,'(A,I2,10A)') 'variable',i,' is ',trim(varname), ', ', trim(dartstr), &
', ', trim(minvalstring), ', ', trim(maxvalstring), ', ', trim(update)
call error_handler(E_MSG,routine,string1,source,revision,revdate)
CASE (3)
write(string1,'(A,I2,6A)') 'variable ',i,' is ',trim(varname), ', ', trim(dartstr), &
write(string1,'(A,I2,6A)') 'variable',i,' is ',trim(varname), ', ', trim(dartstr), &
', ', trim(update)
call error_handler(E_MSG,routine,string1,source,revision,revdate)
CASE DEFAULT
write(string1,'(A,I2,4A)') 'variable ',i,' is ',trim(varname), ', ', trim(dartstr)
write(string1,'(A,I2,4A)') 'variable',i,' is ',trim(varname), ', ', trim(dartstr)
call error_handler(E_MSG,routine,string1,source,revision,revdate)
END SELECT
endif
Expand Down

0 comments on commit a125327

Please sign in to comment.