18 character(len=500),
public :: varmap_file =
"NULL"
19 character(len=500),
public :: atm_files_input_grid(6) =
"NULL"
23 character(len=500),
public :: atm_core_files_input_grid(7) =
"NULL"
24 character(len=500),
public :: atm_tracer_files_input_grid(6) =
"NULL"
25 character(len=500),
public :: data_dir_input_grid =
"NULL"
26 character(len=500),
public :: fix_dir_target_grid =
"NULL"
27 character(len=500),
public :: mosaic_file_input_grid =
"NULL"
28 character(len=500),
public :: mosaic_file_target_grid =
"NULL"
29 character(len=500),
public :: nst_files_input_grid =
"NULL"
30 character(len=500),
public :: grib2_file_input_grid =
"NULL"
31 character(len=500),
public :: geogrid_file_input_grid =
"NULL"
34 character(len=500),
public :: orog_dir_input_grid =
"NULL"
35 character(len=500),
public :: orog_files_input_grid(6) =
"NULL"
36 character(len=500),
public :: orog_dir_target_grid =
"NULL"
37 character(len=500),
public :: orog_files_target_grid(6) =
"NULL"
38 character(len=500),
public :: sfc_files_input_grid(6) =
"NULL"
39 character(len=500),
public :: vcoord_file_target_grid =
"NULL"
40 character(len=500),
public :: thomp_mp_climo_file=
"NULL"
41 character(len=15),
public :: cres_target_grid =
"NULL"
42 character(len=500),
public :: atm_weight_file=
"NULL"
43 character(len=25),
public :: input_type=
"restart"
57 character(len=20),
public :: external_model=
"GFS"
59 integer,
parameter,
public :: max_tracers=100
60 integer,
public :: num_tracers
61 integer,
public :: num_tracers_input
63 logical,
allocatable,
public :: read_from_input(:)
66 character(len=20),
public :: tracers(max_tracers)=
"NULL"
72 character(len=20),
public :: tracers_input(max_tracers)=
"NULL"
77 character(len=20),
allocatable,
public :: missing_var_methods(:)
79 character(len=20),
allocatable,
public :: chgres_var_names(:)
81 character(len=20),
allocatable,
public :: field_var_names(:)
83 character(len=500),
public :: wam_parm_file=
"msis21.parm"
85 integer,
public :: cycle_year = -999
86 integer,
public :: cycle_mon = -999
87 integer,
public :: cycle_day = -999
88 integer,
public :: cycle_hour = -999
89 integer,
public :: regional = 0
91 integer,
public :: halo_bndy = 0
92 integer,
public :: halo_blend = 0
94 integer,
public :: nsoill_out = 4
97 logical,
public :: convert_atm = .false.
98 logical,
public :: convert_nst = .false.
99 logical,
public :: convert_sfc = .false.
100 logical,
public :: wam_cold_start = .false.
104 logical,
public :: vgtyp_from_climo = .true.
108 logical,
public :: sotyp_from_climo = .true.
113 logical,
public :: vgfrc_from_climo = .true.
118 logical,
public :: minmax_vgfrc_from_climo = .true.
122 logical,
public :: lai_from_climo = .true.
125 logical,
public :: tg3_from_soil = .false.
128 logical,
public :: use_thomp_mp_climo=.false.
130 real,
allocatable,
public :: drysmc_input(:)
131 real,
allocatable,
public :: drysmc_target(:)
132 real,
allocatable,
public :: maxsmc_input(:)
133 real,
allocatable,
public :: maxsmc_target(:)
134 real,
allocatable,
public :: refsmc_input(:)
135 real,
allocatable,
public :: refsmc_target(:)
136 real,
allocatable,
public :: wltsmc_input(:)
137 real,
allocatable,
public :: wltsmc_target(:)
138 real,
allocatable,
public :: bb_target(:)
139 real,
allocatable,
public :: satpsi_target(:)
140 real(kind=esmf_kind_r4),
allocatable,
public :: missing_var_values(:)
158 character(len=*),
intent(in),
optional :: filename
159 character(len=250),
allocatable :: filename_to_use
161 integer :: is, ie, ierr
163 namelist /config/ varmap_file, &
164 mosaic_file_target_grid, &
165 fix_dir_target_grid, &
166 orog_dir_target_grid, &
167 orog_files_target_grid, &
168 mosaic_file_input_grid, &
169 orog_dir_input_grid, &
170 orog_files_input_grid, &
171 nst_files_input_grid, &
172 sfc_files_input_grid, &
173 atm_files_input_grid, &
174 atm_core_files_input_grid, &
175 atm_tracer_files_input_grid, &
176 grib2_file_input_grid, &
177 geogrid_file_input_grid, &
178 data_dir_input_grid, &
179 vcoord_file_target_grid, &
180 cycle_year, cycle_mon, cycle_day, &
181 cycle_hour, convert_atm, &
182 convert_nst, convert_sfc, &
187 minmax_vgfrc_from_climo, &
188 lai_from_climo, tg3_from_soil, &
189 regional, input_type, &
192 atm_weight_file, tracers, &
199 print*,
"- READ SETUP NAMELIST"
201 if (present(filename))
then
202 filename_to_use = filename
204 filename_to_use =
"./fort.41"
207 open(41, file=trim(filename_to_use), iostat=ierr)
208 if (ierr /= 0) call
error_handler(
"OPENING SETUP NAMELIST.", ierr)
209 read(41, nml=config, iostat=ierr)
210 if (ierr /= 0) call
error_handler(
"READING SETUP NAMELIST.", ierr)
215 orog_dir_target_grid = trim(orog_dir_target_grid) //
'/'
216 orog_dir_input_grid = trim(orog_dir_input_grid) //
'/'
223 ie = index(orog_files_target_grid(1),
"_oro_") - 1
229 cres_target_grid = orog_files_target_grid(1)(is:ie)
231 if (.not. convert_sfc .and. .not. convert_atm)
then
232 call
error_handler(
"MUST CONVERT EITHER AN ATM OR SFC FILE.", 1)
243 if (regional > 0)
then
244 print*,
"- PROCESSING A REGIONAL NEST WITH A BOUNDARY HALO OF ",halo_bndy
245 print*,
"- PROCESSING A REGIONAL NEST WITH A BLENDING HALO OF ",halo_blend
252 do is = 1, max_tracers
253 if (trim(tracers(is)) ==
"NULL")
exit
254 num_tracers = num_tracers + 1
255 print*,
"- TRACER NAME IN OUTPUT FILE ", trim(tracers(is))
258 num_tracers_input = 0
259 do is = 1, max_tracers
260 if (trim(tracers_input(is)) ==
"NULL")
exit
261 num_tracers_input = num_tracers_input + 1
262 print*,
"- TRACER NAME IN INPUT FILE ", trim(tracers_input(is))
269 if( wam_cold_start )
then
271 do is = 1, num_tracers
272 if(trim(tracers(is)) ==
"spo" ) ierr = ierr - 1
273 if(trim(tracers(is)) ==
"spo2" ) ierr = ierr - 1
274 if(trim(tracers(is)) ==
"spo3" ) ierr = ierr - 1
277 print*,
"-ERROR: spo, spo2, and spo3 should be in tracers namelist"
280 print*,
"- WAM COLDSTART OPTION IS TURNED ON."
287 select case (trim(input_type))
289 print*,
'- INPUT DATA FROM FV3 TILED RESTART FILES.'
291 print*,
'- INPUT DATA FROM FV3 TILED HISTORY FILES.'
292 case (
"gaussian_nemsio")
293 print*,
'- INPUT DATA FROM FV3 GAUSSIAN NEMSIO FILE.'
294 case (
"gfs_gaussian_nemsio")
295 print*,
'- INPUT DATA FROM SPECTRAL GFS GAUSSIAN NEMSIO FILE.'
297 print*,
'- INPUT DATA FROM SPECTRAL GFS SIGIO/SFCIO FILE.'
298 case (
"gaussian_netcdf")
299 print*,
'- INPUT DATA FROM FV3 GAUSSIAN NETCDF FILE.'
301 print*,
'- INPUT DATA FROM A GRIB2 FILE'
310 if (trim(input_type) ==
"grib2")
then
311 if (trim(grib2_file_input_grid) ==
"NULL" .or. trim(grib2_file_input_grid) ==
"")
then
312 call
error_handler(
"FOR GRIB2 DATA, PLEASE PROVIDE GRIB2_FILE_INPUT_GRID", 1)
320 if (trim(input_type) ==
"grib2")
then
321 if (.not. any((/
character(4)::
"GFS",
"NAM",
"RAP",
"HRRR",
"RRFS"/)==trim(external_model))) then
322 call
error_handler(
"KNOWN SUPPORTED external_model INPUTS ARE GFS, NAM, RAP, HRRR, AND RRFS. " // &
323 "IF YOU WISH TO PROCESS GRIB2 DATA FROM ANOTHER MODEL, YOU MAY ATTEMPT TO DO SO AT YOUR OWN RISK. " // &
324 "ONE WAY TO DO THIS IS PROVIDE NAM FOR external_model AS IT IS A RELATIVELY STRAIGHT-" // &
325 "FORWARD REGIONAL GRIB2 FILE. YOU MAY ALSO COMMENT OUT THIS ERROR MESSAGE IN " // &
326 "program_setup.f90 LINE 389. NO GUARANTEE IS PROVIDED THAT THE CODE WILL WORK OR "// &
327 "THAT THE RESULTING DATA WILL BE CORRECT OR WORK WITH THE ATMOSPHERIC MODEL.", 1)
336 if (trim(input_type) ==
"grib2" .and. trim(external_model)==
"HRRR")
then
337 if (trim(geogrid_file_input_grid) ==
"NULL" .or. trim(grib2_file_input_grid) ==
"")
then
338 print*,
"HRRR DATA DOES NOT CONTAIN SOIL TYPE INFORMATION. WITHOUT"
339 print*,
"GEOGRID_FILE_INPUT_GRID SPECIFIED, SOIL MOISTURE INTERPOLATION MAY BE LESS ACCURATE."
343 if (trim(thomp_mp_climo_file) /=
"NULL")
then
344 use_thomp_mp_climo=.true.
345 print*,
"- WILL PROCESS CLIMO THOMPSON MP TRACERS FROM FILE: ", trim(thomp_mp_climo_file)
380 integer :: istat, k, nvars
381 character(len=500) :: line
382 character(len=20),
allocatable :: var_type(:)
384 if (trim(input_type) ==
"grib2")
then
386 print*,
"OPEN VARIABLE MAPPING FILE: ", trim(varmap_file)
387 open(14, file=trim(varmap_file), form=
'formatted', iostat=istat)
392 num_tracers_input = 0
397 read(14,
'(A)', iostat=istat) line
400 if ( trim(line) .eq.
'' ) cycle
403 if ( nvars == 0) call
error_handler(
"VARMAP FILE IS EMPTY.", -1)
405 allocate(chgres_var_names(nvars))
406 allocate(field_var_names(nvars))
407 allocate(missing_var_methods(nvars))
408 allocate(missing_var_values(nvars))
409 allocate(read_from_input(nvars))
410 allocate(var_type(nvars))
412 read_from_input(:) = .true.
415 read(14, *, iostat=istat) chgres_var_names(k), field_var_names(k) , &
416 missing_var_methods(k), missing_var_values(k), var_type(k)
417 if (istat /= 0) call
error_handler(
"READING VARIABLE MAPPING FILE", istat)
418 if(trim(var_type(k))==
'T')
then
419 num_tracers_input = num_tracers_input + 1
420 tracers_input(num_tracers_input)=chgres_var_names(k)
421 if ((trim(chgres_var_names(k)) ==
"ice_aero" .or. trim(chgres_var_names(k)) ==
"liq_aero") .and. &
422 trim(thomp_mp_climo_file) .ne.
"NULL" .and. trim(input_type) ==
"grib2")
then
423 call
error_handler(
"VARMAP TABLE CONTAINS TRACER ENTRIES FOR THOMPSON AEROSOLS liq_aero or "// &
424 "ice_aero. REMOVE THESE ENTRIES OR REMOVE THE NAMELIST ENTRY FOR "// &
425 "thomp_mp_climo_file AND TRY AGAIN.",1)
430 num_tracers = num_tracers_input
446 subroutine get_var_cond(var_name,this_miss_var_method,this_miss_var_value, &
447 this_field_var_name, loc)
450 character(len=20),
intent(in) :: var_name
452 character(len=20),
optional,
intent(out) :: this_miss_var_method, &
454 real(esmf_kind_r4),
optional,
intent(out):: this_miss_var_value
456 integer,
optional,
intent(out) :: loc
458 integer :: i, tmp(size(missing_var_methods))
463 where(chgres_var_names==var_name) tmp=1
465 i = maxloc(merge(1.,0.,chgres_var_names == var_name),dim=1)
467 if (maxval(tmp).eq.0)
then
468 print*,
"WARNING: NO ENTRY FOR ", trim(var_name),
" IN VARMAP TABLE. WILL SKIP " // &
469 "VARIABLE IF NOT FOUND IN EXTERNAL MODEL FILE"
471 if(present(this_miss_var_method)) this_miss_var_method =
"skip"
472 if(present(this_miss_var_value)) this_miss_var_value = -9999.9_esmf_kind_r4
473 if(present(this_field_var_name)) this_field_var_name =
"NULL"
474 if(present(loc)) loc = 9999
476 if(present(this_miss_var_method)) this_miss_var_method = missing_var_methods(i)
477 if(present(this_miss_var_value)) this_miss_var_value = missing_var_values(i)
478 if(present(this_field_var_name)) this_field_var_name = field_var_names(i)
479 if(present(loc)) loc = i
521 integer,
intent(in) :: localpet
523 integer,
parameter :: num_statsgo = 16
524 real,
parameter :: smlow_statsgo = 0.5
525 real,
parameter :: smhigh_statsgo = 6.0
528 integer,
parameter :: num_zobler = 9
529 real,
parameter :: smlow_zobler = 0.5
530 real,
parameter :: smhigh_zobler = 6.0
532 integer :: num_soil_cats
534 real :: bb_statsgo(num_statsgo)
535 real :: maxsmc_statsgo(num_statsgo)
536 real :: satdk_statsgo(num_statsgo)
537 real :: satpsi_statsgo(num_statsgo)
539 real :: bb_zobler(num_zobler)
540 real :: maxsmc_zobler(num_zobler)
541 real :: satdk_zobler(num_zobler)
542 real :: satpsi_zobler(num_zobler)
544 real,
allocatable :: bb(:)
545 real :: smlow, smhigh
546 real,
allocatable :: satdk(:)
547 real,
allocatable :: satpsi(:)
548 real,
allocatable :: satdw(:)
551 data bb_statsgo /4.05, 4.26, 4.74, 5.33, 5.33, 5.25, &
552 6.77, 8.72, 8.17, 10.73, 10.39, 11.55, &
553 5.25, -9.99, 4.05, 4.26/
555 data maxsmc_statsgo /0.395, 0.421, 0.434, 0.476, 0.476, 0.439, &
556 0.404, 0.464, 0.465, 0.406, 0.468, 0.457, &
557 0.464, -9.99, 0.200, 0.421/
559 data satdk_statsgo /1.7600e-4, 1.4078e-5, 5.2304e-6, 2.8089e-6, 2.8089e-6, &
560 3.3770e-6, 4.4518e-6, 2.0348e-6, 2.4464e-6, 7.2199e-6, &
561 1.3444e-6, 9.7384e-7, 3.3770e-6, -9.99, 1.4078e-5, &
564 data satpsi_statsgo /0.0350, 0.0363, 0.1413, 0.7586, 0.7586, 0.3548, &
565 0.1349, 0.6166, 0.2630, 0.0977, 0.3236, 0.4677, &
566 0.3548, -9.99, 0.0350, 0.0363/
568 data bb_zobler /4.26, 8.72, 11.55, 4.74, 10.73, 8.17, &
571 data maxsmc_zobler /0.421, 0.464, 0.468, 0.434, 0.406, 0.465, &
574 data satdk_zobler /1.41e-5, 0.20e-5, 0.10e-5, 0.52e-5, 0.72e-5, &
575 0.25e-5, 0.45e-5, 0.34e-5, 1.41e-5/
577 data satpsi_zobler /0.040, 0.620, 0.470, 0.140, 0.100, 0.260, &
584 select case (trim(input_type))
586 print*,
'- INPUT GRID USED ZOBLER SOIL TYPES.'
587 num_soil_cats = num_zobler
589 print*,
'- INPUT GRID USED STATSGO SOIL TYPES.'
590 num_soil_cats = num_statsgo
593 allocate(maxsmc_input(num_soil_cats))
594 allocate(wltsmc_input(num_soil_cats))
595 allocate(drysmc_input(num_soil_cats))
596 allocate(refsmc_input(num_soil_cats))
597 allocate(bb(num_soil_cats))
598 allocate(satdk(num_soil_cats))
599 allocate(satpsi(num_soil_cats))
600 allocate(satdw(num_soil_cats))
602 select case (trim(input_type))
605 smhigh = smhigh_zobler
606 maxsmc_input = maxsmc_zobler
609 satpsi = satpsi_zobler
611 smlow = smlow_statsgo
612 smhigh = smhigh_statsgo
613 maxsmc_input = maxsmc_statsgo
615 satdk = satdk_statsgo
616 satpsi = satpsi_statsgo
620 bb, satpsi, satdw, refsmc_input, drysmc_input, wltsmc_input)
622 deallocate(bb, satdk, satpsi, satdw)
624 if (localpet == 0) print*,
'maxsmc input grid ',maxsmc_input
625 if (localpet == 0) print*,
'wltsmc input grid ',wltsmc_input
631 print*,
'- TARGET GRID USEING STATSGO SOIL TYPES.'
633 num_soil_cats = num_statsgo
635 allocate(maxsmc_target(num_soil_cats))
636 allocate(wltsmc_target(num_soil_cats))
637 allocate(drysmc_target(num_soil_cats))
638 allocate(refsmc_target(num_soil_cats))
639 allocate(bb_target(num_soil_cats))
640 allocate(satpsi_target(num_soil_cats))
641 allocate(satdk(num_soil_cats))
642 allocate(satdw(num_soil_cats))
644 smlow = smlow_statsgo
645 smhigh = smhigh_statsgo
646 maxsmc_target = maxsmc_statsgo
647 bb_target = bb_statsgo
648 satdk = satdk_statsgo
649 satpsi_target = satpsi_statsgo
652 bb_target, satpsi_target, satdw, refsmc_target, drysmc_target, wltsmc_target)
654 deallocate(satdk, satdw)
656 if (localpet == 0) print*,
'maxsmc target grid ',maxsmc_target
657 if (localpet == 0) print*,
'wltsmc input grid ',wltsmc_target
678 maxsmc, bb, satpsi, satdw, refsmc, drysmc, wltsmc)
682 integer,
intent(in) :: num_soil_cats
684 real,
intent(in) :: smlow, smhigh
685 real,
intent(in) :: bb(num_soil_cats)
686 real,
intent(in) :: maxsmc(num_soil_cats)
687 real,
intent(in) :: satdk(num_soil_cats)
688 real,
intent(in) :: satpsi(num_soil_cats)
690 real,
intent(out) :: satdw(num_soil_cats)
691 real,
intent(out) :: refsmc(num_soil_cats)
692 real,
intent(out) :: drysmc(num_soil_cats)
693 real,
intent(out) :: wltsmc(num_soil_cats)
705 do i = 1, num_soil_cats
707 if (maxsmc(i) > 0.0)
then
709 satdw(i) = bb(i)*satdk(i)*(satpsi(i)/maxsmc(i))
710 refsmc1 = maxsmc(i)*(5.79e-9/satdk(i)) **(1.0/(2.0*bb(i)+3.0))
711 refsmc(i) = refsmc1 + (maxsmc(i)-refsmc1) / smhigh
712 wltsmc1 = maxsmc(i) * (200.0/satpsi(i))**(-1.0/bb(i))
713 wltsmc(i) = wltsmc1 - smlow * wltsmc1
720 drysmc(i) = wltsmc(i)
subroutine, public calc_soil_params_driver(localpet)
Driver routine to compute soil parameters for each soil type.
subroutine to_lower(strIn)
Convert from upper to lowercase.
subroutine, public read_setup_namelist(filename)
Reads program configuration namelist.
subroutine error_handler(string, rc)
General error handler.
This module contains code to read the setup namelist file, handle the varmap file for GRIB2 data...
subroutine, public read_varmap
Reads the variable mapping table, which is required for initializing with GRIB2 data.
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.
subroutine calc_soil_params(num_soil_cats, smlow, smhigh, satdk, maxsmc, bb, satpsi, satdw, refsmc, drysmc, wltsmc)
Compute soil parameters.