12 use utilities,
only : error_handler, to_lower
171 character(len=*),
intent(in),
optional :: filename
172 character(len=250),
allocatable :: filename_to_use
174 integer :: i, is, ie, ierr, myrank
212 if (
present(filename))
then
213 filename_to_use = filename
215 filename_to_use =
"./fort.41"
218 call mpi_comm_rank(mpi_comm_world, myrank, ierr)
220 if (myrank == 0)
then
221 print*,
"- READ SETUP NAMELIST"
222 open(41, file=trim(filename_to_use), iostat=ierr)
223 if (ierr /= 0)
call error_handler(
"OPENING SETUP NAMELIST.", ierr)
224 read(41, nml=config, iostat=ierr)
225 if (ierr /= 0)
call error_handler(
"READING SETUP NAMELIST.", ierr)
229 call mpi_barrier(mpi_comm_world,ierr)
255 call mpi_bcast(
cycle_year,1,mpi_integer,0,mpi_comm_world,ierr)
256 call mpi_bcast(
cycle_mon,1,mpi_integer,0,mpi_comm_world,ierr)
257 call mpi_bcast(
cycle_day,1,mpi_integer,0,mpi_comm_world,ierr)
258 call mpi_bcast(
cycle_hour,1,mpi_integer,0,mpi_comm_world,ierr)
259 call mpi_bcast(
convert_atm,1,mpi_logical,0,mpi_comm_world,ierr)
260 call mpi_bcast(
convert_nst,1,mpi_logical,0,mpi_comm_world,ierr)
261 call mpi_bcast(
convert_sfc,1,mpi_logical,0,mpi_comm_world,ierr)
262 call mpi_bcast(
wam_cold_start,1,mpi_logical,0,mpi_comm_world,ierr)
267 call mpi_bcast(
lai_from_climo,1,mpi_logical,0,mpi_comm_world,ierr)
268 call mpi_bcast(
tg3_from_soil,1,mpi_logical,0,mpi_comm_world,ierr)
269 call mpi_bcast(
regional,1,mpi_integer,0,mpi_comm_world,ierr)
275 call mpi_bcast(
tracers(i),len(
tracers),mpi_character,0,mpi_comm_world,ierr)
278 call mpi_bcast(
halo_bndy,1,mpi_integer,0,mpi_comm_world,ierr)
279 call mpi_bcast(
halo_blend,1,mpi_integer,0,mpi_comm_world,ierr)
280 call mpi_bcast(
nsoill_out,1,mpi_integer,0,mpi_comm_world,ierr)
296 call error_handler(
"CANT DETERMINE CRES FROM OROG FILE.", 1)
302 call error_handler(
"MUST CONVERT EITHER AN ATM OR SFC FILE.", 1)
314 print*,
"- PROCESSING A REGIONAL NEST WITH A BOUNDARY HALO OF ",
halo_bndy
315 print*,
"- PROCESSING A REGIONAL NEST WITH A BLENDING HALO OF ",
halo_blend
323 if (trim(
tracers(is)) ==
"NULL")
exit
325 print*,
"- TRACER NAME IN OUTPUT FILE ", trim(
tracers(is))
332 print*,
"- TRACER NAME IN INPUT FILE ", trim(
tracers_input(is))
342 if(trim(
tracers(is)) ==
"spo" ) ierr = ierr - 1
343 if(trim(
tracers(is)) ==
"spo2" ) ierr = ierr - 1
344 if(trim(
tracers(is)) ==
"spo3" ) ierr = ierr - 1
347 print*,
"-ERROR: spo, spo2, and spo3 should be in tracers namelist"
348 call error_handler(
"WAM TRACER NAMELIST.", ierr)
350 print*,
"- WAM COLDSTART OPTION IS TURNED ON."
359 print*,
'- INPUT DATA FROM FV3 TILED RESTART FILES.'
361 print*,
'- INPUT DATA FROM FV3 TILED HISTORY FILES.'
363 case (
"gaussian_nemsio")
364 print*,
'- INPUT DATA FROM FV3 GAUSSIAN NEMSIO FILE.'
365 case (
"gfs_gaussian_nemsio")
366 print*,
'- INPUT DATA FROM SPECTRAL GFS GAUSSIAN NEMSIO FILE.'
368 print*,
'- INPUT DATA FROM SPECTRAL GFS SIGIO/SFCIO FILE.'
370 case (
"gaussian_netcdf")
371 print*,
'- INPUT DATA FROM FV3 GAUSSIAN NETCDF FILE.'
373 print*,
'- INPUT DATA FROM A GRIB2 FILE'
375 call error_handler(
"UNRECOGNIZED INPUT DATA TYPE.", 1)
384 call error_handler(
"FOR GRIB2 DATA, PLEASE PROVIDE GRIB2_FILE_INPUT_GRID", 1)
393 if (.not. any((/
character(4)::
"GFS",
"NAM",
"RAP",
"HRRR",
"RRFS"/)==trim(
external_model)))
then
394 call error_handler(
"KNOWN SUPPORTED external_model INPUTS ARE GFS, NAM, RAP, HRRR, AND RRFS. " // &
395 "IF YOU WISH TO PROCESS GRIB2 DATA FROM ANOTHER MODEL, YOU MAY ATTEMPT TO DO SO AT YOUR OWN RISK. " // &
396 "ONE WAY TO DO THIS IS PROVIDE NAM FOR external_model AS IT IS A RELATIVELY STRAIGHT-" // &
397 "FORWARD REGIONAL GRIB2 FILE. YOU MAY ALSO COMMENT OUT THIS ERROR MESSAGE IN " // &
398 "program_setup.f90 LINE 389. NO GUARANTEE IS PROVIDED THAT THE CODE WILL WORK OR "// &
399 "THAT THE RESULTING DATA WILL BE CORRECT OR WORK WITH THE ATMOSPHERIC MODEL.", 1)
410 print*,
"HRRR DATA DOES NOT CONTAIN SOIL TYPE INFORMATION. WITHOUT"
411 print*,
"GEOGRID_FILE_INPUT_GRID SPECIFIED, SOIL MOISTURE INTERPOLATION MAY BE LESS ACCURATE."
452 integer :: istat, k, nvars, rc, localpet
453 integer :: idum1(1), idum2(2)
454 character(len=500) :: line
455 character(len=20),
allocatable :: var_type(:)
461 call esmf_vmgetglobal(vm, rc=rc)
462 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
463 call error_handler(
"IN VMGetGlobal", rc)
465 call esmf_vmget(vm, localpet=localpet, rc=rc)
466 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
467 call error_handler(
"IN VMGet", rc)
469 if (localpet == 0)
then
471 print*,
"OPEN VARIABLE MAPPING FILE: ", trim(
varmap_file)
472 open(14, file=trim(
varmap_file), form=
'formatted', iostat=istat)
474 call error_handler(
"OPENING VARIABLE MAPPING FILE", istat)
481 read(14,
'(A)', iostat=istat) line
483 if ( trim(line) .eq.
'' ) cycle
486 if (nvars == 0)
call error_handler(
"VARMAP FILE IS EMPTY.", -1)
492 call esmf_vmbroadcast(vm, idum1, 1, 0, rc=rc)
493 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
494 call error_handler(
"IN VMBroadcast", rc)
506 if (localpet == 0)
then
509 allocate(var_type(nvars))
515 if (istat /= 0)
call error_handler(
"READING VARIABLE MAPPING FILE", istat)
517 if(trim(var_type(k))==
'T')
then
522 call error_handler(
"VARMAP TABLE CONTAINS TRACER ENTRIES FOR THOMPSON AEROSOLS liq_aero or "// &
523 "ice_aero. REMOVE THESE ENTRIES OR REMOVE THE NAMELIST ENTRY FOR "// &
524 "thomp_mp_climo_file AND TRY AGAIN.",1)
538 call esmf_vmbroadcast(vm, idum2, 2, 0, rc=rc)
539 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
540 call error_handler(
"IN VMBroadcast", rc)
546 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
547 call error_handler(
"IN VMBroadcast", rc)
550 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
551 call error_handler(
"IN VMBroadcast", rc)
554 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
555 call error_handler(
"IN VMBroadcast", rc)
558 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
559 call error_handler(
"IN VMBroadcast", rc)
562 if(esmf_logfounderror(rctocheck=rc,msg=esmf_logerr_passthru,line=__line__,file=__file__)) &
563 call error_handler(
"IN VMBroadcast", rc)
580subroutine get_var_cond(var_name,this_miss_var_method,this_miss_var_value, &
581 this_field_var_name, loc)
584 character(len=20),
intent(in) :: var_name
586 character(len=20),
optional,
intent(out) :: this_miss_var_method, &
588 real(esmf_kind_r4),
optional,
intent(out):: this_miss_var_value
590 integer,
optional,
intent(out) :: loc
601 if (maxval(tmp).eq.0)
then
602 print*,
"WARNING: NO ENTRY FOR ", trim(var_name),
" IN VARMAP TABLE. WILL SKIP " // &
603 "VARIABLE IF NOT FOUND IN EXTERNAL MODEL FILE"
605 if(
present(this_miss_var_method)) this_miss_var_method =
"skip"
606 if(
present(this_miss_var_value)) this_miss_var_value = -9999.9_esmf_kind_r4
607 if(
present(this_field_var_name)) this_field_var_name =
"NULL"
608 if(
present(loc)) loc = 9999
612 if(
present(this_field_var_name)) this_field_var_name =
field_var_names(i)
613 if(
present(loc)) loc = i
655 integer,
intent(in) :: localpet
657 integer,
parameter :: num_statsgo = 16
658 real,
parameter :: smlow_statsgo = 0.5
659 real,
parameter :: smhigh_statsgo = 6.0
662 integer,
parameter :: num_zobler = 9
663 real,
parameter :: smlow_zobler = 0.5
664 real,
parameter :: smhigh_zobler = 6.0
666 integer :: num_soil_cats
668 real :: bb_statsgo(num_statsgo)
669 real :: maxsmc_statsgo(num_statsgo)
670 real :: satdk_statsgo(num_statsgo)
671 real :: satpsi_statsgo(num_statsgo)
673 real :: bb_zobler(num_zobler)
674 real :: maxsmc_zobler(num_zobler)
675 real :: satdk_zobler(num_zobler)
676 real :: satpsi_zobler(num_zobler)
678 real,
allocatable :: bb(:)
679 real :: smlow, smhigh
680 real,
allocatable :: satdk(:)
681 real,
allocatable :: satpsi(:)
682 real,
allocatable :: satdw(:)
685 data bb_statsgo /4.05, 4.26, 4.74, 5.33, 5.33, 5.25, &
686 6.77, 8.72, 8.17, 10.73, 10.39, 11.55, &
687 5.25, -9.99, 4.05, 4.26/
689 data maxsmc_statsgo /0.395, 0.421, 0.434, 0.476, 0.476, 0.439, &
690 0.404, 0.464, 0.465, 0.406, 0.468, 0.457, &
691 0.464, -9.99, 0.200, 0.421/
693 data satdk_statsgo /1.7600e-4, 1.4078e-5, 5.2304e-6, 2.8089e-6, 2.8089e-6, &
694 3.3770e-6, 4.4518e-6, 2.0348e-6, 2.4464e-6, 7.2199e-6, &
695 1.3444e-6, 9.7384e-7, 3.3770e-6, -9.99, 1.4078e-5, &
698 data satpsi_statsgo /0.0350, 0.0363, 0.1413, 0.7586, 0.7586, 0.3548, &
699 0.1349, 0.6166, 0.2630, 0.0977, 0.3236, 0.4677, &
700 0.3548, -9.99, 0.0350, 0.0363/
702 data bb_zobler /4.26, 8.72, 11.55, 4.74, 10.73, 8.17, &
705 data maxsmc_zobler /0.421, 0.464, 0.468, 0.434, 0.406, 0.465, &
708 data satdk_zobler /1.41e-5, 0.20e-5, 0.10e-5, 0.52e-5, 0.72e-5, &
709 0.25e-5, 0.45e-5, 0.34e-5, 1.41e-5/
711 data satpsi_zobler /0.040, 0.620, 0.470, 0.140, 0.100, 0.260, &
720 print*,
'- INPUT GRID USED ZOBLER SOIL TYPES.'
721 num_soil_cats = num_zobler
723 print*,
'- INPUT GRID USED STATSGO SOIL TYPES.'
724 num_soil_cats = num_statsgo
731 allocate(bb(num_soil_cats))
732 allocate(satdk(num_soil_cats))
733 allocate(satpsi(num_soil_cats))
734 allocate(satdw(num_soil_cats))
739 smhigh = smhigh_zobler
743 satpsi = satpsi_zobler
745 smlow = smlow_statsgo
746 smhigh = smhigh_statsgo
749 satdk = satdk_statsgo
750 satpsi = satpsi_statsgo
756 deallocate(bb, satdk, satpsi, satdw)
758 if (localpet == 0) print*,
'maxsmc input grid ',
maxsmc_input
759 if (localpet == 0) print*,
'wltsmc input grid ',
wltsmc_input
765 print*,
'- TARGET GRID USEING STATSGO SOIL TYPES.'
767 num_soil_cats = num_statsgo
775 allocate(satdk(num_soil_cats))
776 allocate(satdw(num_soil_cats))
778 smlow = smlow_statsgo
779 smhigh = smhigh_statsgo
782 satdk = satdk_statsgo
788 deallocate(satdk, satdw)
790 if (localpet == 0) print*,
'maxsmc target grid ',
maxsmc_target
812 maxsmc, bb, satpsi, satdw, refsmc, drysmc, wltsmc)
816 integer,
intent(in) :: num_soil_cats
818 real,
intent(in) :: smlow, smhigh
819 real,
intent(in) :: bb(num_soil_cats)
820 real,
intent(in) :: maxsmc(num_soil_cats)
821 real,
intent(in) :: satdk(num_soil_cats)
822 real,
intent(in) :: satpsi(num_soil_cats)
824 real,
intent(out) :: satdw(num_soil_cats)
825 real,
intent(out) :: refsmc(num_soil_cats)
826 real,
intent(out) :: drysmc(num_soil_cats)
827 real,
intent(out) :: wltsmc(num_soil_cats)
839 do i = 1, num_soil_cats
841 if (maxsmc(i) > 0.0)
then
843 satdw(i) = bb(i)*satdk(i)*(satpsi(i)/maxsmc(i))
844 refsmc1 = maxsmc(i)*(5.79e-9/satdk(i)) **(1.0/(2.0*bb(i)+3.0))
845 refsmc(i) = refsmc1 + (maxsmc(i)-refsmc1) / smhigh
846 wltsmc1 = maxsmc(i) * (200.0/satpsi(i))**(-1.0/bb(i))
847 wltsmc(i) = wltsmc1 - smlow * wltsmc1
854 drysmc(i) = wltsmc(i)
This module contains code to read the setup namelist file, handle the varmap file for GRIB2 data,...
character(len=500), public geogrid_file_input_grid
Name of "geogrid" file, which contains static surface fields on the input grid.
real(kind=esmf_kind_r4), dimension(:), allocatable, public missing_var_values
If input GRIB2 record is missing, the variable is set to this value.
real, dimension(:), allocatable, public drysmc_input
Air dry soil moisture content input grid.
character(len=500), dimension(6), public sfc_files_input_grid
File names containing input surface data.
integer, public num_tracers_input
Number of atmospheric tracers in input file.
character(len=500), public orog_dir_input_grid
Directory containing the input grid orography files.
integer, parameter, public max_tracers
Maximum number of atmospheric tracers processed.
logical, dimension(:), allocatable, public read_from_input
When false, variable was not read from GRIB2 input file.
character(len=500), dimension(6), public atm_tracer_files_input_grid
File names of input atmospheric restart tracer files.
real, dimension(:), allocatable, public refsmc_input
Reference soil moisture content input grid (onset of soil moisture stress).
character(len=500), public grib2_file_input_grid
REQUIRED.
character(len=500), dimension(6), public orog_files_target_grid
Target grid orography files.
subroutine, public read_setup_namelist(filename)
Reads program configuration namelist.
character(len=500), dimension(6), public orog_files_input_grid
Input grid orography files.
subroutine calc_soil_params(num_soil_cats, smlow, smhigh, satdk, maxsmc, bb, satpsi, satdw, refsmc, drysmc, wltsmc)
Compute soil parameters.
real, dimension(:), allocatable, public wltsmc_target
Plant wilting point soil moisture content target grid.
integer, public regional
For regional target grids.
real, dimension(:), allocatable, public refsmc_target
Reference soil moisture content target grid (onset of soil moisture stress).
character(len=500), public wam_parm_file
Full path to msis21.parm for WAM initialization.
logical, public tg3_from_soil
If false, use lowest level soil temperature for the base soil temperature instead of using data from ...
real, dimension(:), allocatable, public wltsmc_input
Plant wilting point soil moisture content input grid.
character(len=500), dimension(7), public atm_core_files_input_grid
File names of input atmospheric restart core files.
character(len=20), dimension(max_tracers), public tracers
Name of each atmos tracer to be processed.
integer, public num_tracers
Number of atmospheric tracers to be processed.
character(len=500), public nst_files_input_grid
File name of input nst data.
character(len=20), dimension(:), allocatable, public field_var_names
The GRIB2 variable name in the varmap table.
logical, public use_thomp_mp_climo
When true, read and process Thompson MP climatological tracers.
character(len=500), public orog_dir_target_grid
Directory containing the target grid orography files.
character(len=20), dimension(:), allocatable, public chgres_var_names
Varmap table variable name as recognized by this program.
integer, public halo_blend
Number of row/cols of blending halo, where model tendencies and lateral boundary tendencies are appli...
logical, public lai_from_climo
If false, interpolate leaf area index from the input data to the target grid instead of using data fr...
character(len=500), public thomp_mp_climo_file
Path/name to the Thompson MP climatology file.
character(len=500), public mosaic_file_target_grid
Target grid mosaic file.
logical, public vgfrc_from_climo
If false, interpolate vegetation fraction from the input data to the target grid instead of using dat...
subroutine, public read_varmap
Reads the variable mapping table, which is required for initializing with GRIB2 data.
character(len=500), public mosaic_file_input_grid
Input grid mosaic file.
real, dimension(:), allocatable, public maxsmc_target
Maximum soil moisture content target grid.
logical, public wam_cold_start
When true, cold start for whole atmosphere model.
integer, public cycle_mon
Cycle month.
logical, public convert_sfc
Convert sfc data when true.
subroutine, public get_var_cond(var_name, this_miss_var_method, this_miss_var_value, this_field_var_name, loc)
Search the variable mapping table to find conditions for handling missing variables.
integer, public halo_bndy
Number of row/cols of lateral halo, where pure lateral bndy conditions are applied (regional target g...
real, dimension(:), allocatable, public maxsmc_input
Maximum soil moisture content input grid.
character(len=20), dimension(:), allocatable, public missing_var_methods
Method to replace missing GRIB2 input records.
integer, public cycle_day
Cycle day.
integer, public nsoill_out
Number of soil levels desired in the output data.
real, dimension(:), allocatable, public bb_target
Soil 'b' parameter, target grid.
character(len=15), public cres_target_grid
Target grid resolution, i.e., C768.
real, dimension(:), allocatable, public drysmc_target
Air dry soil moisture content target grid.
subroutine, public calc_soil_params_driver(localpet)
Driver routine to compute soil parameters for each soil type.
character(len=500), public varmap_file
REQUIRED.
character(len=500), dimension(6), public atm_files_input_grid
File names of input atmospheric data.
character(len=20), dimension(max_tracers), public tracers_input
Name of each atmos tracer record in the input file.
integer, public cycle_hour
Cycle hour.
logical, public convert_atm
Convert atmospheric data when true.
real, dimension(:), allocatable, public satpsi_target
Saturated soil potential, target grid.
character(len=500), public atm_weight_file
File containing pre-computed weights to horizontally interpolate atmospheric fields.
character(len=500), public data_dir_input_grid
Directory containing input atm or sfc files.
character(len=500), public fix_dir_target_grid
Directory containing target grid pre-computed fixed data (ex: soil type).
logical, public sotyp_from_climo
If false, interpolate soil type from the input data to the target grid instead of using data from sta...
logical, public vgtyp_from_climo
If false, interpolate vegetation type from the input data to the target grid instead of using data fr...
character(len=25), public input_type
Input data type:
character(len=20), public external_model
The model that the input data is derived from.
logical, public convert_nst
Convert nst data when true.
character(len=500), public vcoord_file_target_grid
Vertical coordinate definition file.
logical, public minmax_vgfrc_from_climo
If false, interpolate min/max vegetation fraction from the input data to the target grid instead of u...
integer, public cycle_year
Cycle year.