diff --git a/developer_tests/namelist/test_read_variable_namelist.f90 b/developer_tests/namelist/test_read_variable_namelist.f90 index 47b93b48ea..7fbfe456be 100644 --- a/developer_tests/namelist/test_read_variable_namelist.f90 +++ b/developer_tests/namelist/test_read_variable_namelist.f90 @@ -3,13 +3,22 @@ program test_read_variable_namelist use utilities_mod, only : find_namelist_in_file, check_namelist_read use mpi_utilities_mod, only : initialize_mpi_utilities, & finalize_mpi_utilities -use types_mod, only : vtablenamelength +use types_mod, only : r8, vtablenamelength +use verify_variables_mod, only : verify_variables implicit none -character(len=vtablenamelength) :: state_variables(20, 3) - -integer :: iunit, io +integer, parameter :: nrows = 5 ! - Hard Coded +integer, parameter :: ncols = 3 ! - 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) namelist /model_nml/ & state_variables @@ -22,6 +31,14 @@ 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 finalize_mpi_utilities() -end program test_read_variable_namelist +end program test_read_variable_namelist \ No newline at end of file diff --git a/developer_tests/namelist/work/input.nml b/developer_tests/namelist/work/input.nml index 7a94f7cb9a..7bc589e521 100644 --- a/developer_tests/namelist/work/input.nml +++ b/developer_tests/namelist/work/input.nml @@ -1,4 +1,36 @@ &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 = 'theta', 'QTY_POTENTIAL_TEMPERATURE', +! 'rho', 'QTY_DENSITY', +! 'uReconstructZonal', 'QTY_U_WIND_COMPONENT', +! 'uReconstructMeridional','QTY_V_WIND_COMPONENT', +! 'w', 'QTY_VERTICAL_VELOCITY', +! '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' / &utilities_nml @@ -8,6 +40,8 @@ &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' 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' diff --git a/developer_tests/namelist/work/test_read_variable_namelist b/developer_tests/namelist/work/test_read_variable_namelist new file mode 100755 index 0000000000..46f65b7d8b Binary files /dev/null and b/developer_tests/namelist/work/test_read_variable_namelist differ diff --git a/developer_tests/namelist/work/verify_variables_mod.f90 b/developer_tests/namelist/work/verify_variables_mod.f90 new file mode 100644 index 0000000000..41ece90243 --- /dev/null +++ b/developer_tests/namelist/work/verify_variables_mod.f90 @@ -0,0 +1,164 @@ +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 + +implicit none + +private +public :: verify_variables + +character(len=256), parameter :: source = "$URL$" +character(len=32 ), parameter :: revision = "$Revision$" +character(len=128), parameter :: revdate = "$Date$" +character(len=512) :: string1 +character(len=512) :: string2 + +contains + +!----------------------------------------------------------------------- +! 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_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) + +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 + +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. + +ngood = 0 + +MyLoop : do i = 1, nrows + + varname = trim(state_variables(ncols * i - (ncols - 1))) + dartstr = trim(state_variables(ncols * i - (ncols - 2))) + + if ( table(i,1) == ' ' .and. table(i,2) == ' ') 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) + endif + + + if (present(default_vars)) check_obs = default_vars + + ! 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 + endif + + ! All good to here - fill the output variables + ngood = ngood + 1 + + var_names(ngood) = varname + + table(i,1) = trim(varname) + table(i,2) = trim(dartstr) + + ! Check to see if other columns variables are present from default + + if (ncols == 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))) + + ! 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) + CASE (5) + 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), & + ', ', 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) + call error_handler(E_MSG,routine,string1,source,revision,revdate) + END SELECT + endif +enddo MyLoop + +! check to see if temp and salinity are both in the state otherwise you will not +! be able to interpolate in XXX subroutine +if ( any(var_qtys == QTY_SALINITY) ) then + ! check to see that temperature is also in the variable list + if ( .not. any(var_qtys == QTY_POTENTIAL_TEMPERATURE) ) then + write(string1,'(A)') 'in order to compute temperature you need to have both ' + write(string2,'(A)') 'QTY_SALINITY and QTY_POTENTIAL_TEMPERATURE in the model state' + call error_handler(E_ERR,routine,string1,source,revision,revdate, text2=string2) + endif +endif + +end subroutine verify_variables +!----------------------------------------------------------------------- +!----------------------------------------------------------------------- +end module verify_variables_mod