From 72711368a8b93e7e8523baf4cf2bd4ae0ded8587 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 11 Aug 2022 20:56:55 +0000 Subject: [PATCH 01/58] Issue 886 --- ...odule_sf_noahmp_glacier.f90 => module_sf_noahmp_glacier.F90} | 2 +- physics/{module_sf_noahmplsm.f90 => module_sf_noahmplsm.F90} | 2 +- physics/noahmpdrv.meta | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename physics/{module_sf_noahmp_glacier.f90 => module_sf_noahmp_glacier.F90} (99%) rename physics/{module_sf_noahmplsm.f90 => module_sf_noahmplsm.F90} (99%) diff --git a/physics/module_sf_noahmp_glacier.f90 b/physics/module_sf_noahmp_glacier.F90 similarity index 99% rename from physics/module_sf_noahmp_glacier.f90 rename to physics/module_sf_noahmp_glacier.F90 index ee57e336f..40202a827 100644 --- a/physics/module_sf_noahmp_glacier.f90 +++ b/physics/module_sf_noahmp_glacier.F90 @@ -1,5 +1,5 @@ #define CCPP -!> \file module_sf_noahmp_glacier.f90 +!> \file module_sf_noahmp_glacier.F90 !! This file contains the NoahMP Glacier scheme. !>\ingroup NoahMP_LSM diff --git a/physics/module_sf_noahmplsm.f90 b/physics/module_sf_noahmplsm.F90 similarity index 99% rename from physics/module_sf_noahmplsm.f90 rename to physics/module_sf_noahmplsm.F90 index 652db602d..57e047c3e 100644 --- a/physics/module_sf_noahmplsm.f90 +++ b/physics/module_sf_noahmplsm.F90 @@ -1,5 +1,5 @@ #define CCPP -!> \file module_sf_noahmplsm.f90 +!> \file module_sf_noahmplsm.F90 !! This file contains the NoahMP land surface model. !>\ingroup NoahMP_LSM diff --git a/physics/noahmpdrv.meta b/physics/noahmpdrv.meta index 9ad9092ec..ddf16f65d 100644 --- a/physics/noahmpdrv.meta +++ b/physics/noahmpdrv.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = noahmpdrv type = scheme - dependencies = funcphys.f90,machine.F,sfc_diff.f,module_sf_noahmp_glacier.f90,module_sf_noahmplsm.f90,noahmp_tables.f90,set_soilveg.f + dependencies = funcphys.f90,machine.F,sfc_diff.f,module_sf_noahmp_glacier.F90,module_sf_noahmplsm.F90,noahmp_tables.f90,set_soilveg.f ######################################################################## [ccpp-arg-table] From 8329e07281c33832c0fd334b7c023f2bf9177e5b Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 11 Aug 2022 22:24:11 +0000 Subject: [PATCH 02/58] Issue 764 --- physics/drag_suite.F90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/physics/drag_suite.F90 b/physics/drag_suite.F90 index 09ee621bd..ec8bf2f5e 100644 --- a/physics/drag_suite.F90 +++ b/physics/drag_suite.F90 @@ -7,6 +7,11 @@ module drag_suite contains +!>\brief This subroutine initializes the GFS_ogwd GFS Orographic Gravity Wave Drag scheme. +!! +!> \section arg_table_drag_suite_init Argument Table +!! \htmlinclude drag_suite_init.html +!! subroutine drag_suite_init(gwd_opt, errmsg, errflg) integer, intent(in) :: gwd_opt From a282821eb995c7780b066af5f34b55f50119144d Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 11 Aug 2022 22:39:14 +0000 Subject: [PATCH 03/58] Issue 672 --- physics/GFS_phys_time_vary.fv3.F90 | 5 +++-- physics/GFS_phys_time_vary.fv3.meta | 8 ++++++++ physics/gcycle.F90 | 13 +++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 3c5a5af9b..3cfa9e956 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -713,7 +713,7 @@ subroutine GFS_phys_time_vary_timestep_init ( imfdeepcnv, cal_pre, random_clds, nscyc, ntoz, h2o_phys, iaerclm, iccn, clstp, & jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & - jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, & + jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, fn_nml, & imap, jmap, prsl, seed0, rann, nthrds, nx, ny, nsst, tile_num, nlunit, lsoil, lsoil_lsm,& kice, ialb, isot, ivegsrc, input_nml_file, use_ufo, nst_anl, frac_grid, fhcyc, phour, & lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, & @@ -754,6 +754,7 @@ subroutine GFS_phys_time_vary_timestep_init ( integer, intent(in) :: nthrds, nx, ny, nsst, tile_num, nlunit, lsoil integer, intent(in) :: lsoil_lsm, kice, ialb, isot, ivegsrc character(len=*), intent(in) :: input_nml_file(:) + character(len=*), intent(in) :: fn_nml logical, intent(in) :: use_ufo, nst_anl, frac_grid real(kind_phys), intent(in) :: fhcyc, phour, lakefrac(:), min_seaice, min_lakeice, & xlat_d(:), xlon_d(:), landfrac(:) @@ -894,7 +895,7 @@ subroutine GFS_phys_time_vary_timestep_init ( !> - Call gcycle() to repopulate specific time-varying surface properties for AMIP/forecast runs if (nscyc > 0) then if (mod(kdt,nscyc) == 1) THEN - call gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, & + call gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, & input_nml_file, lsoil, lsoil_lsm, kice, idate, ialb, isot, ivegsrc, & use_ufo, nst_anl, fhcyc, phour, landfrac, lakefrac, min_seaice, min_lakeice,& frac_grid, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, tsfc, & diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index f37235975..ce350a7b2 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -1285,6 +1285,14 @@ type = real kind = kind_phys intent = inout +[fn_nml] + standard_name = filename_of_namelist + long_name = namelist filename + units = none + dimensions = () + type = character + kind = len=* + intent = in [imap] standard_name = map_of_block_column_number_to_global_i_index long_name = map of local index ix to global index i for this block diff --git a/physics/gcycle.F90 b/physics/gcycle.F90 index 5f4f959c6..7e301c480 100644 --- a/physics/gcycle.F90 +++ b/physics/gcycle.F90 @@ -15,7 +15,7 @@ module gcycle_mod !>\ingroup mod_GFS_phys_time_vary !! This subroutine repopulates specific time-varying surface properties for !! atmospheric forecast runs. - subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, & + subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, & input_nml_file, lsoil, lsoil_lsm, kice, idate, ialb, isot, ivegsrc, & use_ufo, nst_anl, fhcyc, phour, landfrac, lakefrac, min_seaice, min_lakeice, & frac_grid, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, tsfc, & @@ -31,6 +31,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, integer, intent(in) :: me, nthrds, nx, ny, isc, jsc, nsst, & tile_num, nlunit, lsoil, lsoil_lsm, kice integer, intent(in) :: idate(:), ialb, isot, ivegsrc + character(len = 64), intent(in) :: fn_nml character(len=*), intent(in) :: input_nml_file(:) logical, intent(in) :: use_ufo, nst_anl, frac_grid real(kind=kind_phys), intent(in) :: fhcyc, phour, landfrac(:), lakefrac(:), & @@ -210,13 +211,13 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, enddo ! #ifndef INTERNAL_FILE_NML - inquire (file=trim(Model%fn_nml),exist=exists) + inquire (file=trim(fn_nml),exist=exists) if (.not. exists) then - write(6,*) 'gcycle:: namelist file: ',trim(Model%fn_nml),' does not exist' + write(6,*) 'gcycle:: namelist file: ',trim(fn_nml),' does not exist' stop else - open (unit=Model%nlunit, file=trim(Model%fn_nml), action='READ', status='OLD', iostat=ios) - rewind (Model%nlunit) + open (unit=nlunit, file=trim(fn_nml), action='READ', status='OLD', iostat=ios) + rewind (nlunit) endif #endif CALL SFCCYCLE (9998, npts, max(lsoil,lsoil_lsm), sig1t, fhcyc, & @@ -233,7 +234,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, min_ice, ialb, isot, ivegsrc, & trim(tile_num_ch), i_indx, j_indx) #ifndef INTERNAL_FILE_NML - close (Model%nlunit) + close (nlunit) #endif ! if ( nsst > 0 ) then From 7c37906f8997a1e7311c74a4a3cee66908c54ab9 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Fri, 12 Aug 2022 16:43:44 -0600 Subject: [PATCH 04/58] Cleanup to radiation_aerosols. Related to #923. Made changes to made radiation_aerosols.f ccpp compliant --- physics/GFS_phys_time_vary.fv3.F90 | 5 +- physics/GFS_phys_time_vary.fv3.meta | 7 + physics/GFS_rad_time_vary.fv3.F90 | 2 +- physics/GFS_rad_time_vary.scm.F90 | 2 +- physics/GFS_rrtmg_pre.F90 | 17 +- physics/GFS_rrtmg_pre.meta | 23 +- physics/GFS_rrtmg_setup.F90 | 60 +++-- physics/GFS_rrtmg_setup.meta | 51 ++++ physics/GFS_rrtmgp_setup.F90 | 21 +- physics/GFS_rrtmgp_setup.meta | 44 ++++ physics/GFS_time_vary_pre.scm.F90 | 2 +- physics/physparam.f | 17 -- physics/radiation_aerosols.f | 345 +++++++++++++++++++--------- physics/rrtmgp_aerosol_optics.F90 | 12 +- physics/rrtmgp_aerosol_optics.meta | 21 ++ 15 files changed, 455 insertions(+), 174 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 3cfa9e956..2803212b7 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -35,7 +35,6 @@ module GFS_phys_time_vary !--- variables needed for calculating 'sncovr' use namelist_soilveg, only: salp_data, snupx use set_soilveg_mod, only: set_soilveg - use physparam, only : iaermdl ! --- needed for Noah MP init use noahmp_tables, only: laim_table,saim_table,sla_table, & @@ -68,7 +67,7 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !! @{ subroutine GFS_phys_time_vary_init ( & - me, master, ntoz, h2o_phys, iaerclm, iccn, iflip, im, levs, & + me, master, ntoz, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & nx, ny, idate, xlat_d, xlon_d, & jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & @@ -87,7 +86,7 @@ subroutine GFS_phys_time_vary_init ( implicit none ! Interface variables - integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs + integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs, iaermdl logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhour diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index ce350a7b2..36ac38ab9 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -44,6 +44,13 @@ dimensions = () type = logical intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = in [iccn] standard_name = control_for_ice_cloud_condensation_nuclei_forcing long_name = flag for IN and CCN forcing for morrison gettelman microphysics diff --git a/physics/GFS_rad_time_vary.fv3.F90 b/physics/GFS_rad_time_vary.fv3.F90 index 8dd070b12..24d18d3f7 100644 --- a/physics/GFS_rad_time_vary.fv3.F90 +++ b/physics/GFS_rad_time_vary.fv3.F90 @@ -20,7 +20,7 @@ subroutine GFS_rad_time_vary_timestep_init ( imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) - use physparam, only: ipsd0, ipsdlim, iaerflg + use physparam, only: ipsd0, ipsdlim use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 diff --git a/physics/GFS_rad_time_vary.scm.F90 b/physics/GFS_rad_time_vary.scm.F90 index d7d4cda26..db1e7e290 100644 --- a/physics/GFS_rad_time_vary.scm.F90 +++ b/physics/GFS_rad_time_vary.scm.F90 @@ -20,7 +20,7 @@ subroutine GFS_rad_time_vary_timestep_init ( imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) - use physparam, only: ipsd0, ipsdlim, iaerflg + use physparam, only: ipsd0, ipsdlim use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index c75278a33..b4b69d447 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -33,7 +33,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & lmfdeep2, fhswr, fhlwr, solhr, sup, con_eps, epsm1, fvirt, & rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, slmsk, & prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, pert_clds, & - sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, icloud, & !inputs from here and above + sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, icloud, & + iaermdl, iaerflg, & !inputs from here and above coszen, coszdg, effrl_inout, effri_inout, effrs_inout, & clouds1, clouds2, clouds3, clouds4, clouds5, qci_conv, & !in/out from here and above kd, kt, kb, mtopa, mbota, raddt, tsfg, tsfa, de_lgth, alb1d, delp, dz, & !output from here and below @@ -43,7 +44,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & aero_dir_fdb, smoke_ext, dust_ext, & - spp_wts_rad, spp_rad, rrfs_smoke_band, errmsg, errflg) + spp_wts_rad, spp_rad, rrfs_smoke_band, top_at_1, errmsg, errflg) use machine, only: kind_phys @@ -80,7 +81,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & make_IceNumber, & make_DropletNumber, & make_RainNumber - use physparam, only : iaermdl implicit none integer, intent(in) :: im, levs, lm, lmk, lmp, n_var_lndp, & @@ -100,7 +100,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & imp_physics_mg, imp_physics_wsm6, & imp_physics_nssl, & imp_physics_fer_hires, & - yearlen, icloud + yearlen, icloud, iaermdl, iaerflg integer, intent(in) :: & iovr_rand, & ! Flag for random cloud overlap method @@ -200,7 +200,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & faerlw2,& faerlw3 real(kind=kind_phys), dimension(:,:), intent(out) :: alpha - + logical, intent(out) :: top_at_1 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -257,6 +257,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & errmsg = '' errflg = 0 + ! Vertical ordering + top_at_1 = (prsi(1,1) .lt. prsi(1, lm)) + if (.not. (lsswr .or. lslwr)) return !--- set commonly used integers @@ -634,8 +637,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & call setaer (plvl, plyr, prslk1, tvly, rhly, slmsk, & ! --- inputs tracer1, aer_nm, xlon, xlat, IM, LMK, LMP,& - lsswr,lslwr, & - faersw,faerlw,aerodp) ! --- outputs + lsswr,lslwr,iaermdl,iaerflg,top_at_1, & + faersw,faerlw,aerodp,errflg,errmsg) ! --- outputs ! CCPP do j = 1,NBDSW diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index b98512c7d..e15ca3730 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,module_mp_radar.F90,module_mp_thompson.F90 - dependencies = module_mp_thompson_make_number_concentrations.F90,physcons.F90,physparam.f,radcons.f90,radiation_aerosols.f + dependencies = module_mp_thompson_make_number_concentrations.F90,physparam.f,physcons.F90,radcons.f90,radiation_aerosols.f dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radlw_param.f,radsw_param.f,surface_perturbation.F90,radiation_cloud_overlap.F90 ######################################################################## @@ -205,6 +205,20 @@ dimensions = () type = integer intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = flag_for_aerosol_effects_in_radiation + long_name = flag for aerosol effects to include in radiation + units = flag + dimensions = () + type = integer + intent = in [nssl_ccn_on] standard_name = nssl_ccn_on long_name = CCN activation flag in NSSL micro @@ -1306,6 +1320,13 @@ type = real kind = kind_phys intent = out +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = out [aero_dir_fdb] standard_name = do_smoke_aerosol_direct_feedback long_name = flag for smoke and dust radiation feedback diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 0e2d87feb..ebe34a705 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -4,8 +4,8 @@ !> \defgroup GFS_rrtmg_setup_mod GFS RRTMG Scheme Setup module GFS_rrtmg_setup - use physparam, only : isolar , ictmflg, ico2flg, ioznflg, iaerflg, & - & iaermdl, icldflg, & + use physparam, only : isolar , ictmflg, ico2flg, ioznflg, & + & icldflg, & & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & & isubcsw, isubclw, ivflip , ipsd0, & & iswcliq, & @@ -48,7 +48,8 @@ subroutine GFS_rrtmg_setup_init ( & icliq_sw, crick_proof, ccnorm, & imp_physics, & norad_precip, idate, iflip, & - do_RRTMGP, me, errmsg, errflg) + do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & + aeros_file, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -167,10 +168,12 @@ subroutine GFS_rrtmg_setup_init ( & logical, intent(in) :: norad_precip integer, intent(in) :: idate(:) integer, intent(in) :: iflip - logical, intent(in) :: do_RRTMGP + logical, intent(in) :: do_RRTMGP, lalw1bd integer, intent(in) :: me + character(len=26), intent(in) :: aeros_file character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg + integer, intent(out) :: iaermdl, iaerflg ! Initialize the CCPP error handling variables errmsg = '' @@ -241,7 +244,8 @@ subroutine GFS_rrtmg_setup_init ( & call radinit & ! --- inputs: - & ( si, levr, imp_physics, me ) + & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & + & aeros_file, errmsg, errflg ) ! --- outputs: ! ( none ) @@ -261,8 +265,8 @@ end subroutine GFS_rrtmg_setup_init !! \htmlinclude GFS_rrtmg_setup_timestep_init.html !! subroutine GFS_rrtmg_setup_timestep_init ( & - idate, jdate, deltsw, deltim, lsswr, me, & - slag, sdec, cdec, solcon, errmsg, errflg) + idate, jdate, deltsw, deltim, lsswr, me, iaermdl, & + iaerflg, aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) implicit none @@ -273,6 +277,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & real(kind=kind_phys), intent(in) :: deltim logical, intent(in) :: lsswr integer, intent(in) :: me + integer, intent(in) :: iaermdl, iaerflg + character(len=26), intent(in) :: aeros_file real(kind=kind_phys), intent(out) :: slag real(kind=kind_phys), intent(out) :: sdec real(kind=kind_phys), intent(out) :: cdec @@ -291,8 +297,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & errmsg = '' errflg = 0 - call radupdate(idate,jdate,deltsw,deltim,lsswr,me, & - slag,sdec,cdec,solcon) + call radupdate(idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& + iaerflg, aeros_file, slag,sdec,cdec,solcon,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -322,13 +328,14 @@ end subroutine GFS_rrtmg_setup_finalize ! Private functions - subroutine radinit( si, NLAY, imp_physics, me ) + subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & + aeros_file, errmsg, errflg) !................................... ! --- inputs: -! & ( si, NLAY, imp_physics, me ) +! & ( si, NLAY, imp_physics, me, iaermdl, iaerflg) ! --- outputs: -! ( none ) +! ( errmsg, errflg ) ! ================= subprogram documentation block ================ ! ! ! @@ -435,12 +442,14 @@ subroutine radinit( si, NLAY, imp_physics, me ) implicit none ! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics - + integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg + logical, intent(in) :: lalw1bd real (kind=kind_phys), intent(in) :: si(:) + character(len=26), intent(in) :: aeros_file -! --- outputs: (none, to module variables) - +! --- outputs: (ccpp error handling) + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: ! @@ -525,7 +534,7 @@ subroutine radinit( si, NLAY, imp_physics, me ) call sol_init ( me ) ! --- ... astronomy initialization routine - call aer_init ( NLAY, me ) ! --- ... aerosols initialization routine + call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, errflg, errmsg) ! --- ... aerosols initialization routine call gas_init ( me ) ! --- ... co2 and other gases initialization routine @@ -561,8 +570,9 @@ end subroutine radinit !> \section gen_radupdate General Algorithm !> @{ !----------------------------------- - subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & - & slag,sdec,cdec,solcon) + subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& + & iaerflg, aeros_file, slag,sdec,cdec,solcon, & + & errflg,errmsg) !................................... ! ================= subprogram documentation block ================ ! @@ -630,13 +640,16 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & implicit none ! --- inputs: - integer, intent(in) :: idate(:), jdate(:), me + integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg logical, intent(in) :: lsswr + character(len=26),intent(in) :: aeros_file real (kind=kind_phys), intent(in) :: deltsw, deltim ! --- outputs: real (kind=kind_phys), intent(out) :: slag, sdec, cdec, solcon + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: integer :: iyear, imon, iday, ihour @@ -648,6 +661,11 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & ! !===> ... begin here ! + + ! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Set up time stamp at fcst time and that for green house gases !! (currently co2 only) ! --- ... time stamp at fcst time @@ -703,7 +721,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & !> -# Call module_radiation_aerosols::aer_update(), monthly update, no !! time interpolation if ( lmon_chg ) then - call aer_update ( iyear, imon, me ) + call aer_update ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) endif !> -# Call co2 and other gases update routine: diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index ae0da3a5e..09068b6a6 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -163,6 +163,35 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[lalw1bd] + standard_name = flag_for_longwave_aerosol_band_properties + long_name = flag for band or multiband longwave aerosol properties + units = flag + dimensions = () + type = logical + intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = out +[iaerflg] + standard_name = flag_for_aerosol_effects_in_radiation + long_name = flag for aerosol effects to include in radiation + units = flag + dimensions = () + type = integer + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -227,6 +256,28 @@ dimensions = () type = integer intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = flag_for_aerosol_effects_in_radiation + long_name = flag for aerosol effects to include in radiation + units = flag + dimensions = () + type = integer + intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index f7f657b50..54a40d505 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -8,8 +8,7 @@ module GFS_rrtmgp_setup ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize ! *NOTE* These parameters below are required radiation_****** modules. They are not ! directly used by the RRTMGP routines. - use physparam, only : isolar, ictmflg, ico2flg, ioznflg, iaerflg, & - iaermdl, ivflip + use physparam, only : isolar, ictmflg, ico2flg, ioznflg, ivflip implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize @@ -43,7 +42,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & - norad_precip, idate, iflip, me, errmsg, errflg) + norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -60,15 +59,17 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, & - icliq_sw, iflip, me + icliq_sw, iflip, me logical, intent(in) :: & - crick_proof, ccnorm, norad_precip + crick_proof, ccnorm, norad_precip, lalw1bd integer, intent(in), dimension(:) :: & idate + character(len=26),intent(in) :: aeros_file ! Outputs character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg + integer, intent(out) :: iaermdl, iaerflg ! Initialize the CCPP error handling variables errmsg = '' @@ -128,7 +129,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ! Call initialization routines.. call sol_init ( me ) - call aer_init ( levr, me ) + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, errflg, errmsg) call gas_init ( me ) !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & @@ -150,8 +151,8 @@ end subroutine GFS_rrtmgp_setup_init !> \section arg_table_GFS_rrtmgp_setup_timestep_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! - subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, & - slag, sdec, cdec, solcon, errmsg, errflg) + subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, iaermdl,& + iaerflg, aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) @@ -160,6 +161,8 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, real(kind_phys), intent(in) :: deltim logical, intent(in) :: lsswr integer, intent(in) :: me + integer, intent(in) :: iaermdl, iaerflg + character(len=26), intent(in) :: aeros_file ! Outputs real(kind_phys), intent(out) :: slag @@ -230,7 +233,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, ! Update aerosols... if ( lmon_chg ) then - call aer_update ( iyear, imon, me ) + call aer_update ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg) endif ! Update trace gases (co2 only)... diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 41bf63ac8..ea4fdcb88 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -185,6 +185,13 @@ dimensions = () type = logical intent = in +[lalw1bd] + standard_name = flag_for_longwave_aerosol_band_properties + long_name = flag for band or multiband longwave aerosol properties + units = flag + dimensions = () + type = logical + intent = in [idate] standard_name = date_and_time_at_model_initialization_in_united_states_order long_name = initialization date and time @@ -206,6 +213,28 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = out +[iaerflg] + standard_name = flag_for_aerosol_effects_in_radiation + long_name = flag for aerosol effects to include in radiation + units = flag + dimensions = () + type = integer + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -270,6 +299,21 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/GFS_time_vary_pre.scm.F90 b/physics/GFS_time_vary_pre.scm.F90 index 2bb6b3ceb..17cf09ca9 100644 --- a/physics/GFS_time_vary_pre.scm.F90 +++ b/physics/GFS_time_vary_pre.scm.F90 @@ -122,7 +122,7 @@ subroutine GFS_time_vary_pre_timestep_init (jdat, idat, dtp, nsswr, & else if (w3kindreal == 4) then rinc4(1:5) = 0 call w3difdat(jdat,idat,4,rinc4) - sec = rina4c(4) + sec = rinc4(4) else write(0,*)' FATAL ERROR: Invalid w3kindreal' call abort diff --git a/physics/physparam.f b/physics/physparam.f index 5518c6163..0e6a6f663 100644 --- a/physics/physparam.f +++ b/physics/physparam.f @@ -157,23 +157,6 @@ module physparam !> \name 2.2 For module radiation_aerosols ! ............................................. ! -!> aerosol model scheme control flag -!!\n =0:seasonal global distributed OPAC aerosol climatology -!!\n =1:monthly global distributed GOCART aerosol climatology -!!\n =2: GOCART prognostic aerosol model -!!\n =5: OPAC climatoloy with new band mapping -!!\n Opr GFS=0; Opr CFS=n/a - integer, save :: iaermdl = 0 - -!> aerosol effect control flag -!!\n 3-digit flag 'abc': -!!\n a-stratospheric volcanic aerols -!!\n b-tropospheric aerosols for LW -!!\n c-tropospheric aerosols for SW -!!\n =0:aerosol effect is not included; =1:aerosol effect is included -!!\n Opr GFS/CFS =111; see IAER in run scripts - integer, save :: iaerflg = 0 - !> external aerosols data file: aerosol.dat character, save :: aeros_file*26 ! data aeros_file / 'climaeropac_global.txt ' / diff --git a/physics/radiation_aerosols.f b/physics/radiation_aerosols.f index e7fd3631b..20a456cf4 100644 --- a/physics/radiation_aerosols.f +++ b/physics/radiation_aerosols.f @@ -15,20 +15,20 @@ ! inputs: ! ! ( NLAY, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'aer_update' -- updating aerosol data ! ! inputs: ! ! ( iyear, imon, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'setaer' -- mapping aeros profile, compute aeros opticals ! ! inputs: ! ! (prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, ! ! IMAX,NLAY,NLP1, lsswr,lslwr, ! ! outputs: ! -! (aerosw,aerolw,aerodp) ! +! (aerosw,aerolw,aerodp,errmsg,errflg) ! ! ! ! ! ! external modules referenced: ! @@ -157,8 +157,7 @@ module module_radiation_aerosols ! !........................................! ! - use physparam,only : iaermdl, iaerflg, lalw1bd, aeros_file, & - & ivflip, kind_phys, kind_io4, kind_io8 + use machine, only : kind_phys, kind_io4, kind_io8 use physcons, only : con_pi, con_rd, con_g, con_t0c, con_c, & & con_boltz, con_plnk, con_amd @@ -500,7 +499,8 @@ module module_radiation_aerosols ! !! @{ !----------------------------------- subroutine aer_init & - & ( NLAY, me ) ! --- inputs + & ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, & + & errflg, errmsg) ! --- outputs: ( to module variables ) ! ================================================================== ! @@ -512,7 +512,9 @@ subroutine aer_init & ! NLAY - number of model vertical layers (not used) ! ! me - print message control flag ! ! ! -! outputs: (to module variables) ! +! outputs: (CCPP error handling) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! external module variables: (in physparam) ! ! iaermdl - tropospheric aerosol model scheme flag ! @@ -543,9 +545,12 @@ subroutine aer_init & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: NLAY, me - -! --- output: ( none ) + integer, intent(in) :: NLAY, me, iaermdl, iaerflg + logical, intent(in) :: lalw1bd + character(len=26),intent(in) :: aeros_file +! --- output: + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux @@ -553,6 +558,11 @@ subroutine aer_init & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + kyrstr = 1 kyrend = 1 kyrsav = 1 @@ -566,9 +576,9 @@ subroutine aer_init & if ( me == 0 ) then - call wrt_aerlog ! write aerosol param info to log file + call wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) ! write aerosol param info to log file ! --- inputs: (in scope variables) -! --- outputs: ( none ) +! --- outputs: (CCPP error handling) endif @@ -618,9 +628,9 @@ subroutine aer_init & !> -# Call set_spectrum() to set up spectral one wavenumber solar/IR !! fluxes. - call set_spectrum + call set_spectrum(errflg, errmsg) ! --- inputs: (module constants) -! --- outputs: (in-scope variables) +! --- outputs: (ccpp error handling) !> -# Call clim_aerinit() to invoke tropospheric aerosol initialization. @@ -628,23 +638,26 @@ subroutine aer_init & call clim_aerinit & ! --- inputs: - & ( solfwv, eirfwv, me & + & ( solfwv, eirfwv, me, aeros_file, & ! --- outputs: - & ) + & errflg, errmsg) elseif ( iaermdl==1 .or. iaermdl==2 ) then ! gocart clim/prog scheme call gocart_aerinit & ! --- inputs: - & ( solfwv, eirfwv, me & + & ( solfwv, eirfwv, me, & ! --- outputs: - & ) + & errflg, errmsg) else if ( me == 0 ) then print *,' !!! ERROR in aerosol model scheme selection', & & ' iaermdl =',iaermdl - stop + errflg = 1 + errmsg = 'ERROR(aer_init): aerosol model scheme selected'// & + & 'is invalid' + return endif endif @@ -655,9 +668,9 @@ subroutine aer_init & if ( lavoflg ) then - call set_volcaer + call set_volcaer(errflg, errmsg) ! --- inputs: (module variables) -! --- outputs: (module variables) +! --- outputs: (module variables: ccpp error handling) endif ! end if_lavoflg_block @@ -668,10 +681,10 @@ subroutine aer_init & !> This subroutine writes aerosol parameter configuration to run log file. !-------------------------------- - subroutine wrt_aerlog + subroutine wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) !................................ ! --- inputs: (in scope variables) -! --- outputs: ( none ) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -682,14 +695,14 @@ subroutine wrt_aerlog ! ==================== defination of variables =================== ! ! ! ! external module variables: (in physparam) ! -! iaermdl - aerosol scheme flag: 0:opac-clm; 1:gocart-clim; ! -! 2:gocart-prog; 5:opac-clim+new mapping ! ! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) ! ! lalwflg - toposphere lw aerosol effect: =f:no; =t:yes ! ! laswflg - toposphere sw aerosol effect: =f:no; =t:yes ! ! lavoflg - stratospherer volcanic aeros effect: =f:no; =t:yes ! ! ! -! outputs: ( none ) ! +! outputs: ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! subroutines called: none ! ! ! @@ -697,13 +710,22 @@ subroutine wrt_aerlog ! ! ! ================================================================== ! -! --- inputs: ( none ) -! --- output: ( none ) +! --- inputs: () + integer, intent(in) :: iaermdl, iaerflg + logical, intent(in) :: lalw1bd +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + print *, VTAGAER ! print out version tag if ( iaermdl==0 .or. iaermdl==5 ) then @@ -718,7 +740,10 @@ subroutine wrt_aerlog else print *,' !!! ERROR in selection of aerosol model scheme', & & ' IAER_MDL =',iaermdl - stop + errflg = 1 + errmsg = 'ERROR(wrt_aerlog): Selected aerosol model scheme is'//& + & 'is invalid' + return endif ! end_if_iaermdl_block print *,' IAER=',iaerflg,' LW-trop-aer=',lalwflg, & @@ -765,10 +790,10 @@ end subroutine wrt_aerlog !> This subroutine defines the one wavenumber solar fluxes based on toa !! solar spectral distribution, and define the one wavenumber IR fluxes !! based on black-body emission distribution at a predefined temperature. - subroutine set_spectrum + subroutine set_spectrum(errflg, errmsg) !................................ ! --- inputs: (module constants) -! --- outputs: (in-scope variables) +! --- outputs: (ccpp error handling) ! ================================================================== ! ! ! @@ -789,6 +814,8 @@ subroutine set_spectrum !! (\f$W/m^2\f$) !! - eirfwv(NWVTIR): ir flux(273k) for each individual wavenumber !! (\f$W/m^2\f$) +!! - errflg: CCPP error flag +!! - errmsg: CCPP error message ! ! ! subroutines called: none ! ! ! @@ -802,11 +829,16 @@ subroutine set_spectrum ! --- output: (in-scope variables) ! real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux ! real (kind=kind_phys), dimension(NWVTIR) :: eirfwv ! one wvn ir flux - + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys) :: soltot, tmp1, tmp2, tmp3 integer :: nb, nw, nw1, nw2, nmax, nmin + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 ! !===> ... begin here ! @@ -858,11 +890,12 @@ end subroutine set_spectrum !> The initialization program for stratospheric volcanic aerosols. !----------------------------- - subroutine set_volcaer + subroutine set_volcaer(errflg, errmsg) !............................. -! --- inputs: ( none ) -! --- outputs: (module variables) - +! --- inputs: ( none ) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ================================================================== ! ! ! ! subprogram : set_volcaer ! @@ -878,13 +911,19 @@ subroutine set_volcaer ! --- inputs: (none) -! --- output: (module variables) +! --- output: (CCPP error handling) ! integer :: ivolae(:,:,:) - + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- allocate data space if ( .not. allocated(ivolae) ) then @@ -913,8 +952,8 @@ end subroutine aer_init !!\section gen_clim_aerinit General Algorithm !!@{ subroutine clim_aerinit & - & ( solfwv, eirfwv, me & ! --- inputs - & ) ! --- outputs + & ( solfwv, eirfwv, me, aeros_file, & ! --- inputs + & errflg, errmsg) ! --- outputs ! ================================================================== ! ! ! @@ -926,7 +965,9 @@ subroutine clim_aerinit & ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)! ! me - print message control flag ! ! ! -! outputs: (to module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! external module variables: (in physparam) ! ! iaerflg - abc 3-digit integer aerosol flag (abc:volc,lw,sw) ! @@ -965,8 +1006,10 @@ subroutine clim_aerinit & real (kind=kind_phys), dimension(:) :: eirfwv ! one wvn ir flux integer, intent(in) :: me - -! --- output: ( none ) + character(len=26), intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NAERBND,NCM1) :: & @@ -985,10 +1028,14 @@ subroutine clim_aerinit & ! !===> ... begin here ! +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... invoke tropospheric aerosol initialization !> - call set_aercoef() to invoke tropospheric aerosol initialization. - call set_aercoef + call set_aercoef(aeros_file, errflg, errmsg) ! --- inputs: (in-scope variables, module constants) ! --- outputs: (module variables) @@ -1003,10 +1050,10 @@ subroutine clim_aerinit & !!\section det_set_aercoef General Algorithm !! @{ !-------------------------------- - subroutine set_aercoef + subroutine set_aercoef(aeros_file,errflg, errmsg) !................................ ! --- inputs: (in-scope variables, module constants) -! --- outputs: (module variables) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1025,6 +1072,9 @@ subroutine set_aercoef ! me - integer, select cpu number as print control flag ! ! ! ! outputs: (to the module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! external module variables: (in physparam) ! ! lalwflg - module control flag for lw trop-aer: =f:no; =t:yes ! @@ -1080,7 +1130,10 @@ subroutine set_aercoef ! ================================================================== ! ! ! --- inputs: ( none ) -! --- output: ( none ) + character(len=26),intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: integer, dimension(NAERBND) :: iendwv @@ -1094,6 +1147,11 @@ subroutine set_aercoef ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Reading climatological aerosols optical data from aeros_file, !! including: @@ -1108,7 +1166,10 @@ subroutine set_aercoef print *,' Requested aerosol data file "',aeros_file, & & '" not found!' print *,' *** Stopped in subroutine aero_init !!' - stop + errflg = 1 + errmsg = 'ERROR(set_aercoef): Requested aerosol data file '// & + & aeros_file//' not found' + return endif ! end if_file_exist_block ! --- ... skip monthly global distribution @@ -1712,8 +1773,8 @@ end subroutine clim_aerinit !! @{ !----------------------------------- subroutine aer_update & - & ( iyear, imon, me ) ! --- inputs: -! --- outputs: ( to module variables ) + & ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) ! --- inputs: +! --- outputs: ( CCPP error handling ) ! ================================================================== ! ! ! @@ -1725,7 +1786,9 @@ subroutine aer_update & ! imon - month of the year 1 ! ! me - print message control flag 1 ! ! ! -! outputs: ( none ) ! +! outputs: (CCPP error handling) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! external module variables: (in physparam) ! ! lalwflg - control flag for tropospheric lw aerosol ! @@ -1739,33 +1802,41 @@ subroutine aer_update & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: iyear, imon, me - + integer, intent(in) :: iyear, imon, me, iaermdl + character(len=26),intent(in) :: aeros_file ! --- output: ( none ) - + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ( none ) ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + if ( imon < 1 .or. imon > 12 ) then print *,' ***** ERROR in specifying requested month !!! ', & & 'imon=', imon print *,' ***** STOPPED in subroutinte aer_update !!!' - stop + errflg = 1 + errmsg = 'ERROR(aer_update): Requested month not valid' + return endif !> -# Call trop_update() to update monthly tropospheric aerosol data. if ( lalwflg .or. laswflg ) then if ( iaermdl == 0 .or. iaermdl==5 ) then ! opac-climatology scheme - call trop_update + call trop_update(aeros_file, errflg, errmsg) endif endif !> -# Call volc_update() to update yearly stratospheric volcanic aerosol data. if ( lavoflg ) then - call volc_update + call volc_update(errflg, errmsg) endif @@ -1776,10 +1847,10 @@ subroutine aer_update & !> This subroutine updates the monthly global distribution of aerosol !! profiles in five degree horizontal resolution. !-------------------------------- - subroutine trop_update + subroutine trop_update(aeros_file, errflg, errmsg) !................................ ! --- inputs: (in scope variables, module variables) -! --- outputs: (module variables) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1814,7 +1885,10 @@ subroutine trop_update ! ================================================================== ! ! --- inputs: ( none ) -! --- output: ( none ) + character(len=26),intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! real (kind=kind_io8) :: cmix(NXC), denn, tem @@ -1828,6 +1902,11 @@ subroutine trop_update ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... reading climatological aerosols data inquire (file=aeros_file, exist=file_exist) @@ -1845,7 +1924,10 @@ subroutine trop_update print *,' Requested aerosol data file "',aeros_file, & & '" not found!' print *,' *** Stopped in subroutine trop_update !!' - stop + errflg = 1 + errmsg = 'ERROR(trop_update):Requested aerosol data file '// & + & aeros_file // ' not found.' + return endif ! end if_file_exist_block !$omp parallel do private(i,j,m) @@ -1937,10 +2019,10 @@ end subroutine trop_update !> This subroutine searches historical volcanic data sets to find and !! read in monthly 45-degree lat-zone band of optical depth. !-------------------------------- - subroutine volc_update + subroutine volc_update(errflg, errmsg) !................................ ! --- inputs: (in scope variables, module variables) -! --- outputs: (module variables) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1975,6 +2057,8 @@ subroutine volc_update ! --- output: (module variables) ! integer :: ivolae(:,:,:), kyrstr, kyrend, kyrsav, kmonsav + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: integer :: i, j, k @@ -1985,6 +2069,11 @@ subroutine volc_update ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + kmonsav = imon if ( kyrstr<=iyear .and. iyear<=kyrend ) then ! use previously input data @@ -2039,7 +2128,10 @@ subroutine volc_update print *,' Requested volcanic data file "', & & volcano_file,'" not found!' print *,' *** Stopped in subroutine VOLC_AERINIT !!' - stop + errflg = 1 + errmsg = 'ERROR(volc_update): Requested volcanic data '// & + & 'file '//volcano_file//' not found!' + return endif ! end if_file_exist_block endif ! end if_iyear_block @@ -2093,9 +2185,9 @@ end subroutine aer_update !----------------------------------- subroutine setaer & & ( prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, & ! --- inputs - & IMAX,NLAY,NLP1, lsswr,lslwr, & - & aerosw,aerolw & ! --- outputs - &, aerodp & + & IMAX,NLAY,NLP1, lsswr,lslwr,iaermdl,iaerflg,top_at_1, & + & aerosw,aerolw, & ! --- outputs + & aerodp, errflg, errmsg & & ) ! ================================================================== ! @@ -2132,6 +2224,9 @@ subroutine setaer & ! tau_gocart - 550nm aeros opt depth IMAX*NLAY*MAX_NUM_GRIDCOMP! !! aerodp - vertically integrated optical depth IMAX*NSPC1 ! ! ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! +! ! ! external module variable: (in physparam) ! ! iaerflg - aerosol effect control flag (volc,lw,sw, 3-dig) ! ! laswflg - tropospheric aerosol control flag for sw radiation ! @@ -2140,10 +2235,6 @@ subroutine setaer & ! =f: no lw aeros calc. =t: do lw aeros calc. ! ! lavoflg - control flag for stratospheric vocanic aerosols ! ! =t: add volcanic aerosols to the background aerosols ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! internal module variable: (set by subroutine aer_init) ! ! ivolae - stratosphere volcanic aerosol optical depth (fac 1.e4) ! ! 12*4*10 ! @@ -2154,7 +2245,7 @@ subroutine setaer & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: IMAX, NLAY, NLP1 + integer, intent(in) :: IMAX, NLAY, NLP1, iaermdl, iaerflg real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay @@ -2163,7 +2254,7 @@ subroutine setaer & real (kind=kind_phys), dimension(:,:,:),intent(in):: tracer real (kind=kind_phys), dimension(:,:,:),intent(in):: aerfld - logical, intent(in) :: lsswr, lslwr + logical, intent(in) :: lsswr, lslwr, top_at_1 ! --- outputs: @@ -2171,6 +2262,8 @@ subroutine setaer & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), parameter :: psrfh = 5.0 ! ref press (mb) for upper bound @@ -2192,6 +2285,10 @@ subroutine setaer & !===> ... begin here +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + do m = 1, NF_AESW do j = 1, NBDSW do k = 1, NLAY @@ -2245,7 +2342,7 @@ subroutine setaer & lab_do_IMAX : do i = 1, IMAX - lab_if_flip : if (ivflip == 1) then ! input from sfc to toa + lab_if_flip : if (.not. top_at_1) then ! input from sfc to toa do k = 1, NLAY prsln(k) = log(prsi(i,k)) @@ -2300,10 +2397,10 @@ subroutine setaer & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, & & alon,alat,slmsk, laersw,laerlw, & - & IMAX,NLAY,NLP1, & + & IMAX,NLAY,NLP1,top_at_1, & ! & IMAX,NLAY,NLP1,NSPC1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,errflg,errmsg & & ) ! @@ -2315,7 +2412,7 @@ subroutine setaer & & alon,alat,slmsk,laersw,laerlw, & & IMAX,NLAY,NLP1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,errflg,errmsg & & ) endif ! end if_iaerflg_block @@ -2402,7 +2499,7 @@ subroutine setaer & endif enddo - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc ! --- find lower boundary of stratosphere @@ -2637,7 +2734,7 @@ subroutine setaer & endif ! end if_NLWBND_block endif ! end if_laddlw_block - endif ! end if_ivflip_block + endif ! end if_top_at_1_block endif ! end if_lavoflg_block ! @@ -2680,8 +2777,8 @@ end subroutine setaer subroutine aer_property & & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, & ! --- inputs: & alon,alat,slmsk, laersw,laerlw, & - & IMAX,NLAY,NLP1, & - & aerosw,aerolw,aerodp & ! --- outputs: + & IMAX,NLAY,NLP1,top_at_1, & + & aerosw,aerolw,aerodp,errflg,errmsg & ! --- outputs: & ) ! ================================================================== ! @@ -2724,11 +2821,6 @@ subroutine aer_property & ! NLWBND - total number of actual lw spectral bands computed ! ! NSWLWBD - total number of sw+lw bands computed ! ! ! -! external module variables: (in physparam) ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module variable: (set by subroutine aer_init) ! ! kprfg - aerosols profile index IMXAE*JMXAE ! ! 1:ant 2:arc 3:cnt 4:mar 5:des 6:marme 7:cntme ! @@ -2748,7 +2840,7 @@ subroutine aer_property & ! --- inputs: integer, intent(in) :: IMAX, NLAY, NLP1 ! integer, intent(in) :: IMAX, NLAY, NLP1, NSPC - logical, intent(in) :: laersw, laerlw + logical, intent(in) :: laersw, laerlw, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay, dz, hz @@ -2760,6 +2852,8 @@ subroutine aer_property & real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NCM) :: cmix @@ -2786,6 +2880,11 @@ subroutine aer_property & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Map aerosol data to model grids !! - Map grid in longitude direction, lon from 0 to 355 deg resolution !! - Map grid in latitude direction, lat from 90n to 90s in 5 deg resolution @@ -2811,7 +2910,9 @@ subroutine aer_property & if ( i3 > IMXAE ) then print *,' ERROR! In setclimaer alon>360. ipt =',i, & & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif elseif ( dtmp >= f_zero ) then i1 = i3 @@ -2829,7 +2930,9 @@ subroutine aer_property & if ( i3 < 1 ) then print *,' ERROR! In setclimaer alon< 0. ipt =',i, & & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif endif enddo lab_do_IMXAE @@ -2848,7 +2951,9 @@ subroutine aer_property & if ( j3 >= JMXAE ) then print *,' ERROR! In setclimaer alat<-90. ipt =',i, & & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif elseif ( dtmp >= f_zero ) then j1 = j3 @@ -2866,7 +2971,9 @@ subroutine aer_property & if ( j3 < 1 ) then print *,' ERROR! In setclimaer alat>90. ipt =',i, & & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif endif enddo lab_do_JMXAE @@ -2963,14 +3070,16 @@ subroutine aer_property & dz1(k) = dz (i,k) enddo - lab_if_flip : if (ivflip == 1) then ! input from sfc to toa + lab_if_flip : if (.not. top_at_1) then ! input from sfc to toa if ( prsi(i,1) > 100.0 ) then rps = f_one / prsi(i,1) else print *,' !!! (1) Error in subr radiation_aerosols:', & & ' unrealistic surface pressure =', i,prsi(i,1) - stop + errflg = 1 + errmsg = 'ERROR(aer_property): Unrealistic surface pressure' + return endif ii = 1 @@ -3043,7 +3152,7 @@ subroutine aer_property & !> -# Call radclimaer() to calculate SW/LW aerosol optical properties !! for the corresponding frequency bands. - call radclimaer + call radclimaer(top_at_1) ! --- inputs: (in-scope variables) ! --- outputs: (in-scope variables) @@ -3104,7 +3213,7 @@ subroutine aer_property & !! troposphere, aerosol distribution at each grid point is composed !! from up to six components out of ten different substances. !-------------------------------- - subroutine radclimaer + subroutine radclimaer(top_at_1) !................................ ! --- inputs: (in scope variables) @@ -3140,6 +3249,7 @@ subroutine radclimaer parameter (crt1=30.0, crt2=0.03333) ! --- inputs: + logical, intent(in) :: top_at_1 ! --- outputs: ! --- locals: @@ -3342,7 +3452,7 @@ subroutine radclimaer ! !===> ... smooth profile at domain boundaries ! - if ( ivflip == 0 ) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do ib = 1, NSWLWBD do kk = 2, NLAY @@ -3419,8 +3529,8 @@ end subroutine aer_property !! @{ !----------------------------------- subroutine gocart_aerinit & - & ( solfwv, eirfwv, me & - & ) + & ( solfwv, eirfwv, me, & + & errflg, errmsg) ! ================================================================== ! ! ! @@ -3434,7 +3544,9 @@ subroutine gocart_aerinit & ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)! ! me - print message control flag ! ! ! -! outputs: (to module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! module variables: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! @@ -3460,7 +3572,9 @@ subroutine gocart_aerinit & integer, intent(in) :: me -! --- output: ( none ) +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(kaerbndi,kcm1) :: & @@ -3491,13 +3605,20 @@ subroutine gocart_aerinit & ! !===> ... begin here + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! ! --- ... invoke gocart aerosol initialization if (KCM /= ntrcaerm ) then print *, 'ERROR in # of gocart aer species',KCM - stop 3000 + errflg = 1 + errmsg = 'ERROR(gocart_init): Incorrect # of species' + return endif ! --- ... aloocate and input aerosol optical data @@ -3814,7 +3935,9 @@ subroutine rd_gocart_luts else print *,' Requested luts file ',trim(fin),' not found' print *,' ** Stopped in rd_gocart_luts ** ' - stop 1220 + errflg = 1 + errmsg = 'Requested luts file '//trim(fin)//' not found' + return endif ! end if_file_exist_block iradius = 5 @@ -3876,7 +3999,9 @@ subroutine rd_gocart_luts else print *,' Requested luts file ',trim(fin),' not found' print *,' ** Stopped in rd_gocart_luts ** ' - stop 1222 + errflg = 1 + errmsg = 'Requested luts file '//trim(fin)//' not found' + return endif ! end if_file_exist_block ibeg = radius_lower(ib) - kcm1 @@ -4199,7 +4324,7 @@ subroutine aer_property_gocart & & alon,alat,slmsk, laersw,laerlw, & & imax,nlay,nlp1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,errflg,errmsg & & ) ! ================================================================== ! @@ -4242,11 +4367,6 @@ subroutine aer_property_gocart & ! NLWBND - total number of actual lw spectral bands computed ! ! NSWLWBD - total number of sw+lw bands computed ! ! ! -! external module variables: (in physparam) ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module variable: (set by subroutine aer_init) ! ! ! ! usage: call aer_property_gocart ! @@ -4268,6 +4388,8 @@ subroutine aer_property_gocart & real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(nlay,nswlwbd):: tauae,ssaae,asyae @@ -4281,6 +4403,11 @@ subroutine aer_property_gocart & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + lab_do_IMAXg : do i = 1, IMAX ! --- initialize tauae, ssaae, asyae diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index eb7797125..977594d6c 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -26,18 +26,22 @@ module rrtmgp_aerosol_optics !! subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTracerAer, & nDay, idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - aerodp, sw_optical_props_aerosol, lw_optical_props_aerosol, errmsg, errflg ) + iaermdl, iaerflg, top_at_1, aerodp, sw_optical_props_aerosol, & + lw_optical_props_aerosol, errmsg, errflg ) ! Inputs logical, intent(in) :: & doSWrad, & ! Logical flag for shortwave radiation call - doLWrad ! Logical flag for longwave radiation call + doLWrad, & ! Logical flag for longwave radiation call + top_at_1 ! Logical flag for vertical grid direcetion integer, intent(in) :: & nCol, & ! Number of horizontal grid points nDay, & ! Number of daylit points nLev, & ! Number of vertical layers nTracer, & ! Number of tracers - nTracerAer ! Number of aerosol tracers + nTracerAer, & ! Number of aerosol tracers + iaermdl, & ! Aerosol model scheme flag + iaerflg ! Aerosol effects to include integer,intent(in),dimension(:) :: & idxday ! Indices for daylit points. real(kind_phys), dimension(:), intent(in) :: & @@ -83,7 +87,7 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile call setaer(p_lev*0.01, p_lay*0.01, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & - nLev+1, .true., .true., aerosolssw2, aerosolslw, aerodp) + nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, aerosolssw2, aerosolslw, aerodp, errflg, errmsg) ! Shortwave if (nDay .gt. 0) then diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index f0c37edc0..516943d49 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -21,6 +21,13 @@ dimensions = () type = logical intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -143,6 +150,20 @@ type = real kind = kind_phys intent = in +[iaermdl] + standard_name = flag_for_aerosol_radiation_scheme + long_name = flag for aerosol scheme to use in radiation + units = flag + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = flag_for_aerosol_effects_in_radiation + long_name = flag for aerosol effects to include in radiation + units = flag + dimensions = () + type = integer + intent = in [aerodp] standard_name = atmosphere_optical_thickness_due_to_ambient_aerosol_particles long_name = vertical integrated optical depth for various aerosol species From 11f1ef0351411e6b05160458c7b7ebe60fabf588 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Mon, 15 Aug 2022 12:27:19 -0600 Subject: [PATCH 05/58] Remove dependency on physcons and physparam in radiation_aerosols.f. Provided as ccpp interstitials. --- physics/GFS_rrtmg_pre.F90 | 28 +++-- physics/GFS_rrtmg_pre.meta | 34 +++++-- physics/GFS_rrtmg_setup.F90 | 28 ++--- physics/GFS_rrtmg_setup.meta | 42 +++++++- physics/GFS_rrtmgp_setup.F90 | 8 +- physics/GFS_rrtmgp_setup.meta | 40 ++++++++ physics/physparam.f | 18 ---- physics/radiation_aerosols.f | 158 ++++++++++++++++------------- physics/rrtmgp_aerosol_optics.F90 | 10 +- physics/rrtmgp_aerosol_optics.meta | 24 +++++ 10 files changed, 258 insertions(+), 132 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index b4b69d447..3387e7d40 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -34,7 +34,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, slmsk, & prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, pert_clds, & sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, icloud, & - iaermdl, iaerflg, & !inputs from here and above + iaermdl, iaerflg, con_pi, con_g, & !inputs from here and above coszen, coszdg, effrl_inout, effri_inout, effrs_inout, & clouds1, clouds2, clouds3, clouds4, clouds5, qci_conv, & !in/out from here and above kd, kt, kb, mtopa, mbota, raddt, tsfg, tsfa, de_lgth, alb1d, delp, dz, & !output from here and below @@ -48,8 +48,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & use machine, only: kind_phys - use physparam - use radcons, only: itsfc,ltp, lextop, qmin, & qme5, qme6, epsq, prsmin use funcphys, only: fpvs @@ -130,7 +128,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & real(kind_phys), intent(in) :: spp_wts_rad(:,:) real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp - real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd + real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g real(kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlat, xlon, & coslat, sinlat, tsfc, & @@ -258,7 +256,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & errflg = 0 ! Vertical ordering - top_at_1 = (prsi(1,1) .lt. prsi(1, lm)) + top_at_1 = (prsi(1,1) .lt. prsi(1, LMP)) if (.not. (lsswr .or. lslwr)) return @@ -285,7 +283,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ! variables if ( lextop ) then - if ( ivflip == 1 ) then ! vertical from sfc upward + if (.not. top_at_1) then ! vertical from sfc upward kd = 0 ! index diff between in/out and local kt = 1 ! index diff between lyr and upper bound kb = 0 ! index diff between lyr and lower bound @@ -301,16 +299,16 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & llb = 1 ! local index at toa level lya = 2 ! local index for the 2nd layer from top lyb = 1 ! local index for the top layer - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else kd = 0 - if ( ivflip == 1 ) then ! vertical from sfc upward + if (.not. top_at_1) then ! vertical from sfc upward kt = 1 ! index diff between lyr and upper bound kb = 0 ! index diff between lyr and lower bound else ! vertical from toa downward kt = 0 ! index diff between lyr and upper bound kb = 1 ! index diff between lyr and lower bound - endif ! end if_ivflip_block + endif ! end if_top_at_1_block endif ! end if_lextop_block raddt = min(fhswr, fhlwr) @@ -337,7 +335,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ! lsk = 0 - if (ivflip == 0 .and. lm < levs) lsk = levs - lm + if (top_at_1 .and. lm < levs) lsk = levs - lm ! convert pressure unit from pa to mb do k = 1, LM @@ -366,7 +364,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & enddo enddo ! - if (ivflip == 0) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc if (lsk > 0) then k1 = 1 + kd k2 = k1 + kb @@ -475,7 +473,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & enddo enddo - if (ivflip == 0) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc do i = 1, IM tem1d (i) = QME6 tem2da(i,1) = log( plyr(i,1) ) @@ -605,7 +603,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & dzb(i,1) = hzb(i,1) - hz(i,1) enddo - endif ! end_if_ivflip + endif ! end_if_top_at_1 !> - Call module_radiation_aerosols::setaer(),to setup aerosols !! property profile for radiation. @@ -637,8 +635,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & call setaer (plvl, plyr, prslk1, tvly, rhly, slmsk, & ! --- inputs tracer1, aer_nm, xlon, xlat, IM, LMK, LMP,& - lsswr,lslwr,iaermdl,iaerflg,top_at_1, & - faersw,faerlw,aerodp,errflg,errmsg) ! --- outputs + lsswr, lslwr, iaermdl, iaerflg, top_at_1, con_pi, & + con_rd, con_g, faersw, faerlw, aerodp, errflg, errmsg) ! --- outputs ! CCPP do j = 1,NBDSW diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index e15ca3730..0c2240720 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,module_mp_radar.F90,module_mp_thompson.F90 - dependencies = module_mp_thompson_make_number_concentrations.F90,physparam.f,physcons.F90,radcons.f90,radiation_aerosols.f + dependencies = module_mp_thompson_make_number_concentrations.F90,radcons.f90,radiation_aerosols.f dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radlw_param.f,radsw_param.f,surface_perturbation.F90,radiation_cloud_overlap.F90 ######################################################################## @@ -639,6 +639,30 @@ type = real kind = kind_phys intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in [epsm1] standard_name = ratio_of_dry_air_to_water_vapor_gas_constants_minus_one long_name = (rd/rv) - 1 @@ -671,14 +695,6 @@ type = real kind = kind_phys intent = in -[con_rd] - standard_name = gas_constant_of_dry_air - long_name = ideal gas constant for dry air - units = J kg-1 K-1 - dimensions = () - type = real - kind = kind_phys - intent = in [xlat_d] standard_name = latitude_in_degree long_name = latitude in degree north diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index ebe34a705..8fb417f61 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -4,13 +4,11 @@ !> \defgroup GFS_rrtmg_setup_mod GFS RRTMG Scheme Setup module GFS_rrtmg_setup - use physparam, only : isolar , ictmflg, ico2flg, ioznflg, & - & icldflg, & + use physparam, only : isolar , ictmflg, ico2flg, ioznflg, icldflg, & & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & & isubcsw, isubclw, ivflip , ipsd0, & - & iswcliq, & - & kind_phys - + & iswcliq + use machine, only: kind_phys use radcons, only: ltp, lextop implicit none @@ -49,7 +47,8 @@ subroutine GFS_rrtmg_setup_init ( & imp_physics, & norad_precip, idate, iflip, & do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & - aeros_file, errmsg, errflg) + aeros_file, con_pi, con_t0c, con_c, con_boltz, & + con_plnk, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -170,7 +169,8 @@ subroutine GFS_rrtmg_setup_init ( & integer, intent(in) :: iflip logical, intent(in) :: do_RRTMGP, lalw1bd integer, intent(in) :: me - character(len=26), intent(in) :: aeros_file + character(len=26),intent(in) :: aeros_file + real(kind_phys), intent(in) :: con_pi,con_t0c,con_c,con_boltz,con_plnk character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg integer, intent(out) :: iaermdl, iaerflg @@ -245,7 +245,8 @@ subroutine GFS_rrtmg_setup_init ( & call radinit & ! --- inputs: & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & - & aeros_file, errmsg, errflg ) + & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & + & errmsg, errflg ) ! --- outputs: ! ( none ) @@ -297,8 +298,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & errmsg = '' errflg = 0 - call radupdate(idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& - iaerflg, aeros_file, slag,sdec,cdec,solcon,errflg,errmsg) + call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl,& + iaerflg,aeros_file,slag,sdec,cdec,solcon,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -329,7 +330,7 @@ end subroutine GFS_rrtmg_setup_finalize subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & - aeros_file, errmsg, errflg) + aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, errmsg, errflg) !................................... ! --- inputs: @@ -444,7 +445,7 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & ! --- inputs: integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg logical, intent(in) :: lalw1bd - real (kind=kind_phys), intent(in) :: si(:) + real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, con_boltz, con_plnk character(len=26), intent(in) :: aeros_file ! --- outputs: (ccpp error handling) @@ -534,7 +535,8 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & call sol_init ( me ) ! --- ... astronomy initialization routine - call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, errflg, errmsg) ! --- ... aerosols initialization routine + call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & + con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! --- ... aerosols initialization routine call gas_init ( me ) ! --- ... co2 and other gases initialization routine diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 09068b6a6..6ca7552cc 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_setup type = scheme dependencies = iounitdef.f,module_bfmicrophysics.f,physparam.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f - dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f + dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f,machine.F ######################################################################## [ccpp-arg-table] @@ -171,6 +171,46 @@ type = character kind = len=26 intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_c] + standard_name = speed_of_light_in_vacuum + long_name = speed of light in vacuum + units = m s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_plnk] + standard_name = planck_constant + long_name = Planck constant + units = J s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_boltz] + standard_name = boltzmann_constant + long_name = Boltzmann constant + units = J K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_t0c] + standard_name = temperature_at_zero_celsius + long_name = temperature at 0 degree Celsius + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [lalw1bd] standard_name = flag_for_longwave_aerosol_band_properties long_name = flag for band or multiband longwave aerosol properties diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 54a40d505..b8e5d4fd7 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -42,7 +42,8 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & - norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, errmsg, errflg) + norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, con_pi, & + con_t0c, con_c, con_boltz, con_plnk, errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -55,6 +56,8 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_zhao_carr, & ! Flag for zhao-carr scheme imp_physics_zhao_carr_pdf, & ! Flag for zhao-carr+PDF scheme imp_physics_mg ! Flag for MG scheme + real(kind_phys), intent(in) :: & + con_pi, con_t0c, con_c, con_boltz, con_plnk real(kind_phys), dimension(:), intent(in) :: & si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & @@ -129,7 +132,8 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ! Call initialization routines.. call sol_init ( me ) - call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, errflg, errmsg) + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & + con_c, con_boltz, con_plnk, errflg, errmsg) call gas_init ( me ) !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index ea4fdcb88..028495f14 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -221,6 +221,46 @@ type = character kind = len=26 intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_c] + standard_name = speed_of_light_in_vacuum + long_name = speed of light in vacuum + units = m s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_plnk] + standard_name = planck_constant + long_name = Planck constant + units = J s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_boltz] + standard_name = boltzmann_constant + long_name = Boltzmann constant + units = J K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_t0c] + standard_name = temperature_at_zero_celsius + long_name = temperature at 0 degree Celsius + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [iaermdl] standard_name = flag_for_aerosol_radiation_scheme long_name = flag for aerosol scheme to use in radiation diff --git a/physics/physparam.f b/physics/physparam.f index 0e6a6f663..b6dd84c99 100644 --- a/physics/physparam.f +++ b/physics/physparam.f @@ -119,15 +119,6 @@ module physparam !! \cite fu_et_al_1998 method integer,save :: ilwcice = 3 -! ............................................. ! -!>\name 1.3 Control flag for LW aerosol property - -!> selects 1 band or multi bands for LW aerosol properties -!!\n =.true.:aerosol properties calculated in 1 broad LW band -!!\n =.false.:aerosol properties calculated in all LW bands -!!\n variable names diff in Opr CFS - logical,parameter :: lalw1bd =.false. - !================================================================================== ! Section - 2 - ! values of control flags might be re-set in initialization subroutines @@ -153,15 +144,6 @@ module physparam ! data solar_file / 'solarconstantdata.txt ' / data solar_file / 'solarconstant_noaa_a0.txt ' / -! ............................................. ! -!> \name 2.2 For module radiation_aerosols -! ............................................. ! - -!> external aerosols data file: aerosol.dat - character, save :: aeros_file*26 -! data aeros_file / 'climaeropac_global.txt ' / - data aeros_file / 'aerosol.dat ' / - ! ............................................. ! !> \name 2.3 For module radiation_gases ! ............................................. ! diff --git a/physics/radiation_aerosols.f b/physics/radiation_aerosols.f index 20a456cf4..a96b1d942 100644 --- a/physics/radiation_aerosols.f +++ b/physics/radiation_aerosols.f @@ -32,8 +32,6 @@ ! ! ! ! ! external modules referenced: ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! ! 'module module_radsw_parameters' in 'radsw_xxxx#_param.f' ! ! 'module module_radlw_parameters' in 'radlw_xxxx#_param.f' ! ! 'module module_radlw_cntr_para' in 'radsw_xxxx#_param.f' ! @@ -158,9 +156,6 @@ module module_radiation_aerosols ! !........................................! ! use machine, only : kind_phys, kind_io4, kind_io8 - use physcons, only : con_pi, con_rd, con_g, con_t0c, con_c, & - & con_boltz, con_plnk, con_amd - use module_iounitdef, only : NIAERCM use module_radsw_parameters, only : NBDSW, wvnsw1=>wvnum1, & & NSWSTR, wvnsw2=>wvnum2 @@ -499,9 +494,8 @@ module module_radiation_aerosols ! !! @{ !----------------------------------- subroutine aer_init & - & ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, & - & errflg, errmsg) -! --- outputs: ( to module variables ) + & ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & + & con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! ================================================================== ! ! ! @@ -511,26 +505,26 @@ subroutine aer_init & ! inputs: ! ! NLAY - number of model vertical layers (not used) ! ! me - print message control flag ! +! iaermdl - tropospheric aerosol model scheme flag ! +! =0 opac-clim; =1 gocart-clim, =2 gocart-prognostic ! +! =5 opac-clim new spectral mapping ! +! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! +! =t use 1 broad band optical property ! +! =f use multi bands optical property ! ! ! ! outputs: (CCPP error handling) ! ! errmsg - CCPP error message ! ! errflg - CCPP error flag ! ! ! -! external module variables: (in physparam) ! -! iaermdl - tropospheric aerosol model scheme flag ! -! =0 opac-clim; =1 gocart-clim, =2 gocart-prognostic ! -! =5 opac-clim new spectral mapping ! +! internal module variables: ! ! lalwflg - logical lw aerosols effect control flag ! ! =t compute lw aerosol optical prop ! ! laswflg - logical sw aerosols effect control flag ! ! =t compute sw aerosol optical prop ! ! lavoflg - logical stratosphere volcanic aerosol control flag ! ! =t include volcanic aerosol effect ! -! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! -! =t use 1 broad band optical property ! -! =f use multi bands optical property ! ! ! -! module constants: ! +! internal module constants: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! ! NWVTOT - total num of wave numbers used in sw spectrum ! ! NWVTIR - total num of wave numbers used in the ir region ! @@ -548,6 +542,8 @@ subroutine aer_init & integer, intent(in) :: NLAY, me, iaermdl, iaerflg logical, intent(in) :: lalw1bd character(len=26),intent(in) :: aeros_file + real(kind_phys), intent(in) :: con_pi,con_t0c, con_c, con_boltz, & + & con_plnk ! --- output: integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg @@ -628,14 +624,14 @@ subroutine aer_init & !> -# Call set_spectrum() to set up spectral one wavenumber solar/IR !! fluxes. - call set_spectrum(errflg, errmsg) + call set_spectrum(con_pi, con_t0c, con_c, con_boltz, con_plnk, & + & errflg, errmsg) ! --- inputs: (module constants) ! --- outputs: (ccpp error handling) !> -# Call clim_aerinit() to invoke tropospheric aerosol initialization. if ( iaermdl==0 .or. iaermdl==5 ) then ! opac-climatology scheme - call clim_aerinit & ! --- inputs: & ( solfwv, eirfwv, me, aeros_file, & @@ -682,10 +678,6 @@ subroutine aer_init & !> This subroutine writes aerosol parameter configuration to run log file. !-------------------------------- subroutine wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) -!................................ -! --- inputs: (in scope variables) -! --- outputs: (CCPP error handling) - ! ================================================================== ! ! ! ! subprogram : wrt_aerlog ! @@ -694,11 +686,14 @@ subroutine wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) ! ! ! ==================== defination of variables =================== ! ! ! -! external module variables: (in physparam) ! -! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) ! +! internal module variables: ! ! lalwflg - toposphere lw aerosol effect: =f:no; =t:yes ! ! laswflg - toposphere sw aerosol effect: =f:no; =t:yes ! -! lavoflg - stratospherer volcanic aeros effect: =f:no; =t:yes ! +! lavoflg - stratosphere volcanic aeros effect: =f:no; =t:yes ! +! ! +! inputs: ! +! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) ! +! iaermdl - tropospheric aerosol model scheme flag ! ! ! ! outputs: ! ! errmsg - CCPP error message ! @@ -790,10 +785,8 @@ end subroutine wrt_aerlog !> This subroutine defines the one wavenumber solar fluxes based on toa !! solar spectral distribution, and define the one wavenumber IR fluxes !! based on black-body emission distribution at a predefined temperature. - subroutine set_spectrum(errflg, errmsg) -!................................ -! --- inputs: (module constants) -! --- outputs: (ccpp error handling) + subroutine set_spectrum(con_pi, con_t0c, con_c, con_boltz, & + & con_plnk, errflg, errmsg) ! ================================================================== ! ! ! @@ -805,7 +798,14 @@ subroutine set_spectrum(errflg, errmsg) ! ! ! ==================== defination of variables =================== ! ! ! -!> - inputs: (module constants) +!> - inputs: (CCPP Interstitials) +!! - con_pi: Physical constant (pi) +!! - con_t0c: Physical constant (temperature kelvin at zero celcius) +!! - con_c: Physical constant (speed of light) +!! - con_boltz: Physical constant (Boltzmann constant) +!! - con_plnk: Physical constant (Planck constant) +!! +!> - inputs: (in-scope variables) !! - NWVTOT: total num of wave numbers used in sw spectrum !! - NWVTIR: total num of wave numbers used in the ir region !! @@ -814,6 +814,8 @@ subroutine set_spectrum(errflg, errmsg) !! (\f$W/m^2\f$) !! - eirfwv(NWVTIR): ir flux(273k) for each individual wavenumber !! (\f$W/m^2\f$) +!! +!> - outputs: (CCPP error-handling) !! - errflg: CCPP error flag !! - errmsg: CCPP error message ! ! @@ -825,10 +827,14 @@ subroutine set_spectrum(errflg, errmsg) ! --- inputs: (module constants) ! integer :: NWVTOT, NWVTIR +! --- inputs: (CCPP Interstitials) + real(kind_phys),intent(in) :: con_pi, con_t0c, con_c, con_boltz, & + & con_plnk ! --- output: (in-scope variables) ! real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux ! real (kind=kind_phys), dimension(NWVTIR) :: eirfwv ! one wvn ir flux +! --- output: (CCPP error-handling) integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg ! --- locals: @@ -964,26 +970,17 @@ subroutine clim_aerinit & ! solfwv(NWVTOT) - solar flux for each individual wavenumber (w/m2)! ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)! ! me - print message control flag ! +! aeros_file - external aerosol data file name ! ! ! ! outputs: (CCPP error handling) ! ! errflg - CCPP error flag ! ! errmsg - CCPP error message ! ! ! -! external module variables: (in physparam) ! -! iaerflg - abc 3-digit integer aerosol flag (abc:volc,lw,sw) ! -! a: =0 use background stratospheric aerosol ! -! =1 incl stratospheric vocanic aeros (MINVYR-MAXVYR) ! -! b: =0 no topospheric aerosol in lw radiation ! -! =1 include tropspheric aerosols for lw radiation ! -! c: =0 no topospheric aerosol in sw radiation ! -! =1 include tropspheric aerosols for sw radiation ! +! internal module variables: ! ! lalwflg - logical lw aerosols effect control flag ! ! =t compute lw aerosol optical prop ! ! laswflg - logical sw aerosols effect control flag ! ! =t compute sw aerosol optical prop ! -! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! -! =t use 1 broad band optical property ! -! =f use multi bands optical property ! ! ! ! module constants: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! @@ -1004,7 +1001,6 @@ subroutine clim_aerinit & ! --- inputs: real (kind=kind_phys), dimension(:) :: solfwv ! one wvn sol flux real (kind=kind_phys), dimension(:) :: eirfwv ! one wvn ir flux - integer, intent(in) :: me character(len=26), intent(in) :: aeros_file ! --- output: (CCPP error handling) @@ -1076,7 +1072,7 @@ subroutine set_aercoef(aeros_file,errflg, errmsg) ! errflg - CCPP error flag ! ! errmsg - CCPP error message ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! lalwflg - module control flag for lw trop-aer: =f:no; =t:yes ! ! laswflg - module control flag for sw trop-aer: =f:no; =t:yes ! ! aeros_file- external aerosol data file name ! @@ -1536,7 +1532,7 @@ subroutine optavg ! NSWBND - total number of sw spectral bands ! ! NLWBND - total number of lw spectral bands ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! laswflg - control flag for sw spectral region ! ! lalwflg - control flag for lw spectral region ! ! ! @@ -1773,24 +1769,25 @@ end subroutine clim_aerinit !! @{ !----------------------------------- subroutine aer_update & - & ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) ! --- inputs: -! --- outputs: ( CCPP error handling ) + & ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) ! ================================================================== ! ! ! ! aer_update checks and update time varying climatology aerosol ! ! data sets. ! ! ! -! inputs: size ! -! iyear - 4-digit calender year 1 ! -! imon - month of the year 1 ! -! me - print message control flag 1 ! +! inputs: size ! +! iyear - 4-digit calender year 1 ! +! imon - month of the year 1 ! +! me - print message control flag 1 ! +! iaermdl - tropospheric aerosol model scheme flag 1 ! +! aeros_file - external aerosol data file name len=26 ! ! ! -! outputs: (CCPP error handling) ! -! errmsg - CCPP error message ! +! outputs: (CCPP error handling) len=* ! +! errmsg - CCPP error message 1 ! ! errflg - CCPP error flag ! ! ! -! external module variables: (in physparam) ! +! internal module variables: ! ! lalwflg - control flag for tropospheric lw aerosol ! ! laswflg - control flag for tropospheric sw aerosol ! ! lavoflg - control flag for stratospheric volcanic aerosol ! @@ -1804,7 +1801,7 @@ subroutine aer_update & ! --- inputs: integer, intent(in) :: iyear, imon, me, iaermdl character(len=26),intent(in) :: aeros_file -! --- output: ( none ) +! --- output: (CCPP error-handling) integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg ! --- locals: ( none ) @@ -1848,9 +1845,6 @@ subroutine aer_update & !! profiles in five degree horizontal resolution. !-------------------------------- subroutine trop_update(aeros_file, errflg, errmsg) -!................................ -! --- inputs: (in scope variables, module variables) -! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1864,11 +1858,14 @@ subroutine trop_update(aeros_file, errflg, errmsg) ! inputs: (in-scope variables, module constants) ! ! imon - integer, month of the year ! ! me - integer, print message control flag ! +! inputs: (CCPP Interstitials) ! +! aeros_file - external aerosol data file name ! ! ! ! outputs: (module variables) ! -! ! -! external module variables: (in physparam) ! -! aeros_file - external aerosol data file name ! +! +! outputs: (CCPP error-handling) ! +! errmsg - Error message ! +! errflg - Error flag ! ! ! ! internal module variables: ! ! kprfg ( IMXAE*JMXAE) - aeros profile index ! @@ -1884,7 +1881,7 @@ subroutine trop_update(aeros_file, errflg, errmsg) ! ! ! ================================================================== ! -! --- inputs: ( none ) +! --- inputs: (CCPP Interstitials) character(len=26),intent(in) :: aeros_file ! --- output: (CCPP error handling) integer, intent(out) :: errflg @@ -2046,6 +2043,10 @@ subroutine volc_update(errflg, errmsg) ! kyrsav - integer, the year of data in use in the input file ! ! kmonsav - integer, the month of data in use in the input file ! ! ! +! outputs: (CCPP error-handling) ! +! errmsg - Error message ! +! errflg - Error flag ! +! ! ! subroutines called: none ! ! ! ! usage: call volc_aerinit ! @@ -2057,6 +2058,7 @@ subroutine volc_update(errflg, errmsg) ! --- output: (module variables) ! integer :: ivolae(:,:,:), kyrstr, kyrend, kyrsav, kmonsav +! --- output: (CCPP error-handling) integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg @@ -2186,7 +2188,7 @@ end subroutine aer_update subroutine setaer & & ( prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, & ! --- inputs & IMAX,NLAY,NLP1, lsswr,lslwr,iaermdl,iaerflg,top_at_1, & - & aerosw,aerolw, & ! --- outputs + & con_pi,con_rd,con_g,aerosw,aerolw, & ! --- outputs & aerodp, errflg, errmsg & & ) @@ -2211,6 +2213,12 @@ subroutine setaer & ! NLAY,NLP1-vertical dimensions of arrays 1 ! ! lsswr,lslwr ! ! - logical flags for sw/lw radiation calls 1 ! +! con_pi - Physical constant (pi) ! +! con_t0c - Physical constant (temperature kelvin at zero celcius) ! +! con_c - Physical constant (speed of light) ! +! iaermdl - tropospheric aerosol model scheme flag ! +! iaerflg - aerosol effect control flag ! +! top_at_1 - Vertical ordering convection flag ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -2227,8 +2235,7 @@ subroutine setaer & ! errflg - CCPP error flag ! ! errmsg - CCPP error message ! ! ! -! external module variable: (in physparam) ! -! iaerflg - aerosol effect control flag (volc,lw,sw, 3-dig) ! +! internal module variable: ! ! laswflg - tropospheric aerosol control flag for sw radiation ! ! =f: no sw aeros calc. =t: do sw aeros calc. ! ! lalwflg - tropospheric aerosol control flag for lw radiation ! @@ -2246,7 +2253,7 @@ subroutine setaer & ! --- inputs: integer, intent(in) :: IMAX, NLAY, NLP1, iaermdl, iaerflg - + real (kind=kind_phys), intent(in) :: con_pi, con_rd, con_g real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay real (kind=kind_phys), dimension(:), intent(in) :: xlon, xlat, & @@ -2280,10 +2287,12 @@ subroutine setaer & logical :: laddlw=.false., laerlw=.false. ! --- conversion constants - real (kind=kind_phys), parameter :: rdg = 180.0 / con_pi - real (kind=kind_phys), parameter :: rovg = 0.001 * con_rd / con_g + real (kind=kind_phys) :: rdg + real (kind=kind_phys) :: rovg !===> ... begin here + rdg = 180._kind_phys / con_pi + rovg = 0.001_kind_phys * con_rd / con_g ! Initialize CCPP error handling variables errmsg = '' @@ -2409,7 +2418,7 @@ subroutine setaer & call aer_property_gocart & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer,aerfld, & - & alon,alat,slmsk,laersw,laerlw, & + & alon,alat,slmsk,laersw,laerlw,con_rd, & & IMAX,NLAY,NLP1, & ! --- outputs: & aerosw,aerolw,aerodp,errflg,errmsg & @@ -2804,6 +2813,7 @@ subroutine aer_property & ! IMAX - horizontal dimension of arrays 1 ! ! NLAY,NLP1-vertical dimensions of arrays 1 ! !! NSPC - num of species for optional aod output fields 1 ! +! top_at_1 - vertical ordering flag ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -2816,6 +2826,9 @@ subroutine aer_property & ! (:,:,:,3): asymmetry parameter ! !! aerodp - vertically integrated aer-opt-depth IMAX*NSPC+1 ! ! ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! +! ! ! module parameters and constants: ! ! NSWBND - total number of actual sw spectral bands computed ! ! NLWBND - total number of actual lw spectral bands computed ! @@ -4109,7 +4122,7 @@ subroutine optavg_gocart ! nswbnd - total number of sw spectral bands ! ! nlwbnd - total number of lw spectral bands ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! laswflg - control flag for sw spectral region ! ! lalwflg - control flag for lw spectral region ! ! ! @@ -4321,7 +4334,7 @@ subroutine aer_property_gocart & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer,aerfld, & - & alon,alat,slmsk, laersw,laerlw, & + & alon,alat,slmsk, laersw,laerlw,con_rd, & & imax,nlay,nlp1, & ! --- outputs: & aerosw,aerolw,aerodp,errflg,errmsg & @@ -4350,6 +4363,7 @@ subroutine aer_property_gocart & ! - logical flag for sw/lw aerosol calculations ! ! IMAX - horizontal dimension of arrays 1 ! ! NLAY,NLP1-vertical dimensions of arrays 1 ! +! con_rd - Physical constant (gas constant for dry air) ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -4361,6 +4375,8 @@ subroutine aer_property_gocart & ! (:,:,:,2): single scattering albedo ! ! (:,:,:,3): asymmetry parameter ! ! aerodp - vertically integrated aer-opt-depth IMAX*NSPC+1 ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! module parameters and constants: ! ! NSWBND - total number of actual sw spectral bands computed ! @@ -4376,7 +4392,7 @@ subroutine aer_property_gocart & ! --- inputs: integer, intent(in) :: IMAX, NLAY, NLP1 logical, intent(in) :: laersw, laerlw - + real (kind=kind_phys), intent(in) :: con_rd real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay, dz, hz real (kind=kind_phys), dimension(:), intent(in) :: alon, alat, & diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index 977594d6c..d53f3ffb8 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -26,7 +26,7 @@ module rrtmgp_aerosol_optics !! subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTracerAer, & nDay, idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - iaermdl, iaerflg, top_at_1, aerodp, sw_optical_props_aerosol, & + iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerodp, sw_optical_props_aerosol, & lw_optical_props_aerosol, errmsg, errflg ) ! Inputs @@ -43,7 +43,11 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra iaermdl, & ! Aerosol model scheme flag iaerflg ! Aerosol effects to include integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. + idxday ! Indices for daylit points. + real(kind_phys),intent(in) :: & + con_pi, & ! Physical constant (pi) + con_rd, & ! Physical constant (gas constant for dry-air) + con_g ! Physical constant (gravitational constant) real(kind_phys), dimension(:), intent(in) :: & lon, & ! Longitude lat, & ! Latitude @@ -87,7 +91,7 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile call setaer(p_lev*0.01, p_lay*0.01, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & - nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, aerosolssw2, aerosolslw, aerodp, errflg, errmsg) + nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, aerodp, errflg, errmsg) ! Shortwave if (nDay .gt. 0) then diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index 516943d49..f2fc09be6 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -28,6 +28,30 @@ dimensions = () type = logical intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension From 063e15d3f9380416ae04a76424274380f2316660 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Mon, 15 Aug 2022 12:55:02 -0600 Subject: [PATCH 06/58] bug fix in argument list. --- physics/GFS_rrtmgp_setup.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index b8e5d4fd7..3339d64ae 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -156,7 +156,7 @@ end subroutine GFS_rrtmgp_setup_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, iaermdl,& - iaerflg, aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) + aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) @@ -165,7 +165,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, real(kind_phys), intent(in) :: deltim logical, intent(in) :: lsswr integer, intent(in) :: me - integer, intent(in) :: iaermdl, iaerflg + integer, intent(in) :: iaermdl character(len=26), intent(in) :: aeros_file ! Outputs From 225f5b566a7a96c9782e6dc856f217088106d929 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Mon, 15 Aug 2022 15:10:40 -0600 Subject: [PATCH 07/58] Remove dependency on physcons and physparam in radiation_astronomy.f. Provided as ccpp interstitials. --- physics/GFS_rrtmg_setup.F90 | 50 +++++++++++------------ physics/GFS_rrtmg_setup.meta | 39 ++++++++++++++++++ physics/GFS_rrtmgp_setup.F90 | 23 +++++------ physics/GFS_rrtmgp_setup.meta | 39 ++++++++++++++++++ physics/physparam.f | 19 --------- physics/radiation_astronomy.f | 74 ++++++++++++++++++++--------------- 6 files changed, 159 insertions(+), 85 deletions(-) diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 8fb417f61..1960ff11e 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -4,7 +4,7 @@ !> \defgroup GFS_rrtmg_setup_mod GFS RRTMG Scheme Setup module GFS_rrtmg_setup - use physparam, only : isolar , ictmflg, ico2flg, ioznflg, icldflg, & + use physparam, only : ictmflg, ico2flg, ioznflg, icldflg, & & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & & isubcsw, isubclw, ivflip , ipsd0, & & iswcliq @@ -41,14 +41,14 @@ module GFS_rrtmg_setup !! \htmlinclude GFS_rrtmg_setup_init.html !! subroutine GFS_rrtmg_setup_init ( & - si, levr, ictm, isol, ico2, iaer, ntcw, & + si, levr, ictm, isol, solar_file, ico2, iaer, ntcw, & num_p3d, npdf3d, ntoz, iovr, isubc_sw, isubc_lw, & icliq_sw, crick_proof, ccnorm, & imp_physics, & norad_precip, idate, iflip, & do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & aeros_file, con_pi, con_t0c, con_c, con_boltz, & - con_plnk, errmsg, errflg) + con_plnk, con_solr_2008, con_solr_2002, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -169,8 +169,8 @@ subroutine GFS_rrtmg_setup_init ( & integer, intent(in) :: iflip logical, intent(in) :: do_RRTMGP, lalw1bd integer, intent(in) :: me - character(len=26),intent(in) :: aeros_file - real(kind_phys), intent(in) :: con_pi,con_t0c,con_c,con_boltz,con_plnk + character(len=26),intent(in) :: aeros_file, solar_file + real(kind_phys), intent(in) :: con_pi,con_t0c,con_c,con_boltz,con_plnk,con_solr_2008,con_solr_2002 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg integer, intent(out) :: iaermdl, iaerflg @@ -187,7 +187,6 @@ subroutine GFS_rrtmg_setup_init ( & return end if - isolar = isol ! solar constant control flag ictmflg= ictm ! data ic time/date control flag ico2flg= ico2 ! co2 data source control flag ioznflg= ntoz ! ozone data source control flag @@ -246,7 +245,7 @@ subroutine GFS_rrtmg_setup_init ( & ! --- inputs: & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & - & errmsg, errflg ) + & isol, solar_file, con_solr_2008, con_solr_2002, errmsg, errflg ) ! --- outputs: ! ( none ) @@ -267,7 +266,7 @@ end subroutine GFS_rrtmg_setup_init !! subroutine GFS_rrtmg_setup_timestep_init ( & idate, jdate, deltsw, deltim, lsswr, me, iaermdl, & - iaerflg, aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) + iaerflg, isol, aeros_file, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) implicit none @@ -276,9 +275,10 @@ subroutine GFS_rrtmg_setup_timestep_init ( & integer, intent(in) :: jdate(:) real(kind=kind_phys), intent(in) :: deltsw real(kind=kind_phys), intent(in) :: deltim + real(kind=kind_phys), intent(in) :: con_pi logical, intent(in) :: lsswr integer, intent(in) :: me - integer, intent(in) :: iaermdl, iaerflg + integer, intent(in) :: iaermdl, iaerflg, isol character(len=26), intent(in) :: aeros_file real(kind=kind_phys), intent(out) :: slag real(kind=kind_phys), intent(out) :: sdec @@ -299,7 +299,7 @@ subroutine GFS_rrtmg_setup_timestep_init ( & errflg = 0 call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl,& - iaerflg,aeros_file,slag,sdec,cdec,solcon,errflg,errmsg) + iaerflg,isol,aeros_file,slag,sdec,cdec,solcon,con_pi,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -330,7 +330,8 @@ end subroutine GFS_rrtmg_setup_finalize subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & - aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, errmsg, errflg) + aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, isol, & + solar_file, con_solr_2008, con_solr_2002, errmsg, errflg) !................................... ! --- inputs: @@ -443,10 +444,11 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & implicit none ! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg + integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, isol logical, intent(in) :: lalw1bd - real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, con_boltz, con_plnk - character(len=26), intent(in) :: aeros_file + real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, & + con_boltz, con_plnk, con_solr_2008, con_solr_2002 + character(len=26), intent(in) :: aeros_file, solar_file ! --- outputs: (ccpp error handling) character(len=*), intent(out) :: errmsg @@ -469,7 +471,7 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & & ' May 01 2007' print *, VTAGRAD !print out version tag print *,' - Selected Control Flag settings: ICTMflg=',ictmflg, & - & ' ISOLar =',isolar, ' ICO2flg=',ico2flg,' IAERflg=',iaerflg, & + & ' ISOLar =',isol, ' ICO2flg=',ico2flg,' IAERflg=',iaerflg, & & ' ICLDflg=',icldflg, & & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ioznflg print *,' IVFLIP=',ivflip,' IOVR=',iovrRad, & @@ -533,7 +535,7 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & !! call module_radsw_main::rswinit() ! Initialization - call sol_init ( me ) ! --- ... astronomy initialization routine + call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) ! --- ... astronomy initialization routine call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! --- ... aerosols initialization routine @@ -573,8 +575,8 @@ end subroutine radinit !> @{ !----------------------------------- subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& - & iaerflg, aeros_file, slag,sdec,cdec,solcon, & - & errflg,errmsg) + & iaerflg, isol, aeros_file, slag,sdec,cdec,solcon, & + & con_pi, errflg,errmsg) !................................... ! ================= subprogram documentation block ================ ! @@ -607,7 +609,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! solcon : sun-earth distance adjusted solar constant (w/m2) ! ! ! ! external module variables: ! -! isolar : solar constant cntrl (in module physparam) ! +! iso : solar constant cntrl (in module physparam) ! ! = 0: use the old fixed solar constant in "physcon" ! ! =10: use the new fixed solar constant in "physcon" ! ! = 1: use noaa ann-mean tsi tbl abs-scale with cycle apprx! @@ -642,11 +644,11 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& implicit none ! --- inputs: - integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg + integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg, isol logical, intent(in) :: lsswr character(len=26),intent(in) :: aeros_file - real (kind=kind_phys), intent(in) :: deltsw, deltim + real (kind=kind_phys), intent(in) :: deltsw, deltim, con_pi ! --- outputs: real (kind=kind_phys), intent(out) :: slag, sdec, cdec, solcon @@ -702,12 +704,12 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& !! time interpolation. if (lsswr) then - if ( isolar == 0 .or. isolar == 10 ) then + if ( isol == 0 .or. isol == 10 ) then lsol_chg = .false. elseif ( iyear0 /= iyear ) then lsol_chg = .true. else - lsol_chg = ( isolar==4 .and. lmon_chg ) + lsol_chg = ( isol==4 .and. lmon_chg ) endif iyear0 = iyear @@ -715,7 +717,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! --- inputs: & ( jdate,kyear,deltsw,deltim,lsol_chg, me, & ! --- outputs: - & slag,sdec,cdec,solcon & + & slag,sdec,cdec,solcon,con_pi,errmsg,errflg & & ) endif ! end_if_lsswr_block diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 6ca7552cc..71f1e2ff7 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -37,6 +37,30 @@ dimensions = () type = integer intent = in +[solar_file] + standard_name = solar_constant_file + long_name = external solar constant data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_solr_2008] + standard_name = solar_constant_2008 + long_name = solar constant Tim 2008 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_solr_2002] + standard_name = solar_constant_2002 + long_name= solar constant Liu 2002 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ico2] standard_name = control_for_co2 long_name = prescribed global mean value (old opernl) @@ -310,6 +334,13 @@ dimensions = () type = integer intent = in +[isol] + standard_name = control_for_solar_constant + long_name = use prescribed solar constant + units = flag + dimensions = () + type = integer + intent = in [aeros_file] standard_name = aerosol_data_file long_name = aerosol data file @@ -318,6 +349,14 @@ type = character kind = len=26 intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 3339d64ae..0cec892ba 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -8,7 +8,7 @@ module GFS_rrtmgp_setup ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize ! *NOTE* These parameters below are required radiation_****** modules. They are not ! directly used by the RRTMGP routines. - use physparam, only : isolar, ictmflg, ico2flg, ioznflg, ivflip + use physparam, only : ictmflg, ico2flg, ioznflg, ivflip implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize @@ -43,7 +43,8 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, errmsg, errflg) + con_t0c, con_c, con_boltz, con_plnk, solar_file, con_solr_2008, con_solr_2002, & + errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -57,7 +58,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_zhao_carr_pdf, & ! Flag for zhao-carr+PDF scheme imp_physics_mg ! Flag for MG scheme real(kind_phys), intent(in) :: & - con_pi, con_t0c, con_c, con_boltz, con_plnk + con_pi, con_t0c, con_c, con_boltz, con_plnk, con_solr_2008, con_solr_2002 real(kind_phys), dimension(:), intent(in) :: & si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & @@ -67,7 +68,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, crick_proof, ccnorm, norad_precip, lalw1bd integer, intent(in), dimension(:) :: & idate - character(len=26),intent(in) :: aeros_file + character(len=26),intent(in) :: aeros_file, solar_file ! Outputs character(len=*), intent(out) :: errmsg @@ -88,7 +89,6 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, end if ! Set radiation parameters - isolar = isol ! solar constant control flag ictmflg = ictm ! data ic time/date control flag ico2flg = ico2 ! co2 data source control flag ioznflg = ntoz ! ozone data source control flag @@ -131,7 +131,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, monthd = 0 ! Call initialization routines.. - call sol_init ( me ) + call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) call gas_init ( me ) @@ -156,16 +156,17 @@ end subroutine GFS_rrtmgp_setup_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, iaermdl,& - aeros_file, slag, sdec, cdec, solcon, errmsg, errflg) + aeros_file, isol, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) integer, intent(in) :: jdate(:) real(kind_phys), intent(in) :: deltsw real(kind_phys), intent(in) :: deltim + real(kind_phys), intent(in) :: con_pi logical, intent(in) :: lsswr integer, intent(in) :: me - integer, intent(in) :: iaermdl + integer, intent(in) :: iaermdl,isol character(len=26), intent(in) :: aeros_file ! Outputs @@ -224,15 +225,15 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, ! Update solar forcing... if (lsswr) then - if ( isolar == 0 .or. isolar == 10 ) then + if ( isol == 0 .or. isol == 10 ) then lsol_chg = .false. elseif ( iyear0 /= iyear ) then lsol_chg = .true. else - lsol_chg = ( isolar==4 .and. lmon_chg ) + lsol_chg = ( isol==4 .and. lmon_chg ) endif iyear0 = iyear - call sol_update(jdate, kyear, deltsw, deltim, lsol_chg, me, slag, sdec, cdec, solcon) + call sol_update(jdate, kyear, deltsw, deltim, lsol_chg, me, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) endif ! Update aerosols... diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 028495f14..6e8d296e3 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -101,6 +101,30 @@ dimensions = () type = integer intent = in +[solar_file] + standard_name = solar_constant_file + long_name = external solar constant data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_solr_2008] + standard_name = solar_constant_2008 + long_name = solar constant Tim 2008 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_solr_2002] + standard_name = solar_constant_2002 + long_name= solar constant Liu 2002 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ico2] standard_name = control_for_co2 long_name = prescribed global mean value (old opernl) @@ -354,6 +378,21 @@ dimensions = () type = integer intent = in +[isol] + standard_name = control_for_solar_constant + long_name = use prescribed solar constant + units = flag + dimensions = () + type = integer + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/physparam.f b/physics/physparam.f index b6dd84c99..b84bdd42f 100644 --- a/physics/physparam.f +++ b/physics/physparam.f @@ -125,25 +125,6 @@ module physparam ! (may be adjusted at run time based on namelist input or run condition) !================================================================================== -! ............................................. ! -!>\name 2.1 For module radiation_astronomy -! ............................................. ! - -!> solar constant scheme control flag -!!\n =0:fixed value=1366.0\f$W/m^2\f$(old standard) -!!\n =10:fixed value=1360.8\f$W/m^2\f$(new standard) -!!\n =1:NOAA ABS-scale TSI table (yearly) w 11-yr cycle approx -!!\n =2:NOAA TIM-scale TSI table (yearly) w 11-yr cycle approx -!!\n =3:CMIP5 TIM-scale TSI table (yearly) w 11-yr cycle approx -!!\n =4:CMIP5 TIM-scale TSI table (monthly) w 11-yr cycle approx -!!\n see ISOL in run scripts: Opr GFS=2; Opr CFS=1 - integer, save :: isolar = 0 - -!> external solar constant data table,solarconstant_noaa_a0.txt - character, save :: solar_file*26 -! data solar_file / 'solarconstantdata.txt ' / - data solar_file / 'solarconstant_noaa_a0.txt ' / - ! ............................................. ! !> \name 2.3 For module radiation_gases ! ............................................. ! diff --git a/physics/radiation_astronomy.f b/physics/radiation_astronomy.f index f1651ca84..693274009 100644 --- a/physics/radiation_astronomy.f +++ b/physics/radiation_astronomy.f @@ -21,7 +21,7 @@ ! input: ! ! ( jdate,kyear,deltsw,deltim,lsol_chg, me ) ! ! output: ! -! ( slag,sdec,cdec,solcon ) ! +! ( slag,sdec,cdec,solcon,errmsg,errflg) ! ! ! ! 'coszmn' -- compute cosin of zenith angles ! ! input: ! @@ -29,11 +29,6 @@ ! output: ! ! ( coszen,coszdg ) ! ! ! -! ! -! external modules referenced: ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! -! ! ! program history log: ! ! - a collection of programs to track solar-earth position ! ! may 1977 --- ray orzol (gfdl) created program compjd to ! @@ -93,8 +88,7 @@ !> This module sets up astronomy quantities for solar radiation calculations. module module_radiation_astronomy ! - use physparam, only : isolar, solar_file, kind_phys - use physcons, only : con_solr, con_solr_old, con_pi + use machine, only : kind_phys use module_iounitdef, only : NIRADSF ! implicit none @@ -107,17 +101,17 @@ module module_radiation_astronomy ! & VTAGAST='NCEP-Radiation_astronomy v5.1 Nov 2012 ' ! Parameter constants - real (kind=kind_phys), parameter :: degrad = 180.0/con_pi - real (kind=kind_phys), parameter :: tpi = 2.0 * con_pi - real (kind=kind_phys), parameter :: hpi = 0.5 * con_pi + real (kind=kind_phys) :: degrad + real (kind=kind_phys) :: tpi + real (kind=kind_phys) :: hpi + real (kind=kind_phys) :: pid12 real (kind=kind_phys), parameter :: f12 = 12.0 real (kind=kind_phys), parameter :: f3600 = 3600.0 real (kind=kind_phys), parameter :: czlimt = 0.0001 ! ~ cos(89.99427) - real (kind=kind_phys), parameter :: pid12 = con_pi/f12 ! angle per hour ! real (kind=kind_phys), parameter :: pid12 = (2.0*asin(1.0))/f12 ! Module variable (to be set in module_radiation_astronomy::sol_init): - real (kind=kind_phys), public :: solc0 = con_solr + real (kind=kind_phys), public :: solc0 integer :: isolflg = 10 character(26) :: solar_fname = ' ' @@ -133,7 +127,6 @@ module module_radiation_astronomy real (kind=kind_phys) :: anginc=0.0 ! saved monthly solar constants (isolflg=4 only) real (kind=kind_phys) :: smon_sav(12) - data smon_sav(1:12) / 12*con_solr / ! saved year of data used integer :: iyr_sav =0 @@ -154,7 +147,7 @@ module module_radiation_astronomy !>\section sol_init_gen sol_init General Algorithm !! @{ subroutine sol_init & - & ( me ) ! --- inputs + & ( me, isolar, solar_file, con_solr, con_solr_old, con_pi ) ! --- inputs ! --- outputs: ( none ) ! =================================================================== ! @@ -163,18 +156,16 @@ subroutine sol_init & ! ! ! inputs: ! ! me - print message control flag ! -! ! -! outputs: (to module variable) ! -! ( none ) ! -! ! -! external module variable: (in physparam) ! -! isolar - = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! +! isolar - = 0: use the old fixed solar constant in "GFS_typedefs" ! +! =10: use the new fixed solar constant in "GFS_typedefs" ! ! = 1: use noaa ann-mean tsi tbl abs-scale with cyc apprx ! ! = 2: use noaa ann-mean tsi tbl tim-scale with cyc apprx ! ! = 3: use cmip5 ann-mean tsi tbl tim-scale with cyc apprx! ! = 4: use cmip5 mon-mean tsi tbl tim-scale with cyc apprx! -! solar_file- external solar constant data table ! +! solar_file - external solar constant data table ! +! ! +! outputs: (to module variable) ! +! ( none ) ! ! ! ! internal module variable: ! ! isolflg - internal solar constant scheme control flag ! @@ -191,23 +182,33 @@ subroutine sol_init & implicit none ! --- input: - integer, intent(in) :: me - + integer, intent(in) :: me, isolar + character(len=26), intent(in) :: solar_file + real(kind=kind_phys), intent(in) :: con_solr, con_solr_old, con_pi ! --- output: ( none ) ! --- local: logical :: file_exist + integer :: imonth ! !===> ... begin here ! if ( me == 0 ) print *, VTAGAST !print out version tag + degrad = 180.0/con_pi + tpi = 2.0 * con_pi + hpi = 0.5 * con_pi + pid12 = con_pi/f12 + ! --- initialization isolflg = isolar solc0 = con_solr solar_fname = solar_file iyr_sav = 0 nstp = 6 + do imonth = 1,12 + smon_sav(imonth) = con_solr + enddo if ( isolar == 0 ) then solc0 = con_solr_old @@ -331,7 +332,7 @@ end subroutine sol_init !----------------------------------- subroutine sol_update & & ( jdate,kyear,deltsw,deltim,lsol_chg, me, & ! --- inputs - & slag, sdec, cdec, solcon & ! --- outputs + & slag, sdec, cdec, solcon, con_pi, errmsg, errflg & ! --- outputs & ) ! =================================================================== ! @@ -353,6 +354,8 @@ subroutine sol_update & ! slag - equation of time in radians ! ! sdec, cdec - sin and cos of the solar declination angle ! ! solcon - sun-earth distance adjusted solar constant (w/m2) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! ! ! module variable: ! @@ -386,10 +389,12 @@ subroutine sol_update & integer, intent(in) :: jdate(:), kyear, me logical, intent(in) :: lsol_chg - real (kind=kind_phys), intent(in) :: deltsw, deltim + real (kind=kind_phys), intent(in) :: deltsw, deltim, con_pi ! --- output: real (kind=kind_phys), intent(out) :: slag, sdec, cdec, solcon + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: hrday = 1.0/24.0 ! frc day/hour @@ -408,6 +413,10 @@ subroutine sol_update & ! !===> ... begin here ! +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... forecast time iyear = jdate(1) imon = jdate(2) @@ -430,7 +439,10 @@ subroutine sol_update & inquire (file=solar_fname, exist=file_exist) if ( .not. file_exist ) then print *,' !!! ERROR! Can not find solar constant file!!!' - stop + errflg = 1 + errmsg = "ERROR(radiation_astronomy): solar constant file"//& + & " not found" + return else iyr = iyear @@ -585,7 +597,7 @@ subroutine sol_update & !> -# Call solar() call solar & ! --- inputs: - & ( jd, fjd, & + & ( jd, fjd, con_pi, & ! --- outputs: & r1, dlt, alp & & ) @@ -652,7 +664,7 @@ end subroutine sol_update !! @{ !----------------------------------- subroutine solar & - & ( jd, fjd, & ! --- inputs + & ( jd, fjd, con_pi, & ! --- inputs & r1, dlt, alp & ! --- outputs & ) @@ -684,7 +696,7 @@ subroutine solar & implicit none ! --- inputs: - real (kind=kind_phys), intent(in) :: fjd + real (kind=kind_phys), intent(in) :: fjd, con_pi integer, intent(in) :: jd ! --- outputs: From da57e02e35d74e14993360d3ce4ddcc7aec470cb Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Mon, 15 Aug 2022 16:22:52 -0600 Subject: [PATCH 08/58] Replaced stop statements with ccpp error handling --- physics/GFS_phys_time_vary.fv3.F90 | 2 +- physics/GFS_phys_time_vary.scm.F90 | 2 +- physics/GFS_rrtmg_setup.F90 | 6 +-- physics/GFS_rrtmgp_setup.F90 | 4 +- physics/cires_ugwpv1_oro.F90 | 4 +- physics/lsm_noah.f | 5 +- physics/noahmpdrv.F90 | 2 +- physics/radiation_clouds.f | 30 +++++++---- physics/radiation_gases.f | 87 ++++++++++++++++++++---------- physics/set_soilveg.f | 22 +++++--- physics/sfc_diff.f | 4 +- physics/sflx.f | 36 ++++++++++--- 12 files changed, 138 insertions(+), 66 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 2803212b7..e3d95e5a3 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -288,7 +288,7 @@ subroutine GFS_phys_time_vary_init ( !$OMP section !> - Initialize soil vegetation (needed for sncovr calculation further down) - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) !$OMP end sections diff --git a/physics/GFS_phys_time_vary.scm.F90 b/physics/GFS_phys_time_vary.scm.F90 index c70e3232a..74b34e974 100644 --- a/physics/GFS_phys_time_vary.scm.F90 +++ b/physics/GFS_phys_time_vary.scm.F90 @@ -264,7 +264,7 @@ subroutine GFS_phys_time_vary_init ( endif !> - Initialize soil vegetation (needed for sncovr calculation further down) - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) !> - Call setindxoz() to initialize ozone data if (ntoz > 0) then diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 1960ff11e..331ecbd1e 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -540,9 +540,9 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! --- ... aerosols initialization routine - call gas_init ( me ) ! --- ... co2 and other gases initialization routine + call gas_init ( me, errflg, errmsg ) ! --- ... co2 and other gases initialization routine - call cld_init ( si, NLAY, imp_physics, me) ! --- ... cloud initialization routine + call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! --- ... cloud initialization routine call rlwinit ( me ) ! --- ... lw radiation initialization routine @@ -737,7 +737,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& lco2_chg = .false. endif - call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me ) + call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 0cec892ba..517e88d85 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -134,7 +134,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me ) + call gas_init ( me, errflg, errmsg ) !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& @@ -248,7 +248,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, else lco2_chg = .false. endif - call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me ) + call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/cires_ugwpv1_oro.F90 b/physics/cires_ugwpv1_oro.F90 index 959bbd6c5..7e050fc83 100644 --- a/physics/cires_ugwpv1_oro.F90 +++ b/physics/cires_ugwpv1_oro.F90 @@ -999,7 +999,9 @@ subroutine orogw_v1 (im, km, imx, me, master, dtp, kdt, do_tofd, & ! enddo print * - stop + errflg = 1 + errmsg = 'ERROR(orogw_v1): ' + return endif endif diff --git a/physics/lsm_noah.f b/physics/lsm_noah.f index 7a8e17bf8..d99b9d39d 100644 --- a/physics/lsm_noah.f +++ b/physics/lsm_noah.f @@ -62,7 +62,7 @@ subroutine lsm_noah_init(lsm, lsm_noah, me, isot, ivegsrc, nlunit, end if !--- initialize soil vegetation - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) pores (:) = maxsmc (:) resid (:) = drysmc (:) @@ -544,7 +544,8 @@ subroutine lsm_noah_run & & edir, et, ett, esnow, drip, dew, beta, etp, ssoil, & & flx1, flx2, flx3, runoff1, runoff2, runoff3, & & snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, & - & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax) + & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, & + & errmsg, errflg ) !> - Noah LSM: prepare variables for return to parent model and unit conversion. !> - 6. output (o): diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index a4f5b5226..faa6eb5d7 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -93,7 +93,7 @@ subroutine noahmpdrv_init(lsm, lsm_noahmp, me, isot, ivegsrc, & !--- initialize soil vegetation - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) ! initialize psih and psim diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 16ea93d26..d77b39735 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -16,7 +16,7 @@ ! inputs: ! ! ( si, NLAY, imp_physics, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'radiation_clouds_prop' --- radiation cloud properties ! ! obtained from various cloud schemes ! @@ -278,10 +278,7 @@ module module_radiation_clouds !>\section cld_init General Algorithm !! @{ subroutine cld_init & - & ( si, NLAY, imp_physics, me ) ! --- inputs -! --- outputs: -! ( none ) - + & ( si, NLAY, imp_physics, me, errflg, errmsg ) ! =================================================================== ! ! ! ! abstract: cld_init is an initialization program for cloud-radiation ! @@ -294,8 +291,9 @@ subroutine cld_init & ! imp_physics : MP identifier ! ! me : print control flag ! ! ! -! outputs: (none) ! -! to module variables ! +! outputs: ! +! errflg : CCPP error flag ! +! errmsg : CCPP error message ! ! ! ! external module variables: (in physparam) ! ! icldflg : cloud optical property scheme control flag ! @@ -331,7 +329,9 @@ subroutine cld_init & real (kind=kind_phys), intent(in) :: si(:) -! --- outputs: (none) +! --- outputs: + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: integer :: k, kl, ier @@ -339,14 +339,20 @@ subroutine cld_init & ! !===> ... begin here ! +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- set up module variables if (me == 0) print *, VTAGCLD !print out version tag if ( icldflg == 0 ) then print *,' - Diagnostic Cloud Method has been discontinued' - stop - + errflg = 1 + errmsg = 'ERROR(cld_init): Diagnostic Cloud Method has been '// & + & 'discontinued' + return else if (me == 0) then print *,' - Using Prognostic Cloud Method' @@ -369,6 +375,10 @@ subroutine cld_init & else print *,' !!! ERROR in cloud microphysc specification!!!', & & ' imp_physics (NP3D) =',imp_physics + errflg = 1 + errmsg = 'ERROR(cld_init): cloud mp specification is not'// & + & ' valid' + return stop endif endif diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index 157da8e09..d015c1ac9 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -19,13 +19,13 @@ ! input: ! ! ( me ) ! ! output: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'gas_update' -- read in data and update with time ! ! input: ! ! ( iyear, imon, iday, ihour, loz1st, ldoco2, me ) ! ! output: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'getozn' -- setup climatological ozone profile ! ! input: ! @@ -232,8 +232,7 @@ module module_radiation_gases !! @{ !----------------------------------- subroutine gas_init & - & ( me )! --- inputs: -! --- outputs: ( none ) + & ( me , errflg, errmsg) ! =================================================================== ! ! ! @@ -243,8 +242,8 @@ subroutine gas_init & ! inputs: dimemsion ! ! me - print message control flag 1 ! ! ! -! outputs: (to the module variables) ! -! ( none ) ! +! outputs: (CCPP error handling) ! +! (errflg, errmsg) ! ! ! ! external module variables: (in physparam) ! ! ico2flg - co2 data source control flag ! @@ -285,7 +284,9 @@ subroutine gas_init & ! --- inputs: integer, intent(in) :: me -! --- output: ( none ) +! --- output: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), dimension(IMXCO2,JMXCO2) :: co2dat @@ -301,6 +302,11 @@ subroutine gas_init & ! !===> ... begin here ! + +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + if ( me == 0 ) print *, VTAGGAS ! print out version tag kyrsav = 0 @@ -317,7 +323,10 @@ subroutine gas_init & print *,' - Using climatology ozone distribution' print *,' timeozc=',timeozc, ' is not monthly mean', & & ' - job aborting in subroutin gas_init!!!' - stop + errflg = 1 + errmsg = 'ERROR(gas_init): Climatological o3 distribution '// & + & 'is not monthly mean' + return endif allocate (pkstr(LOZ), o3r(JMR,LOZ,12)) @@ -392,9 +401,10 @@ subroutine gas_init & inquire (file=co2usr_file, exist=file_exist) if ( .not. file_exist ) then - print *,' Can not find user CO2 data file: ',co2usr_file, & - & ' - Stopped in subroutine gas_init !!' - stop + print *,' Can not find user CO2 data file: ',co2usr_file + errflg = 1 + errmsg = 'ERROR(gas_init): Can not find user CO2 data file' + return else close (NICO2CN) open(NICO2CN,file=co2usr_file,form='formatted',status='old') @@ -435,9 +445,10 @@ subroutine gas_init & enddo endif else - print *,' ICO2=',ico2flg,' is not a valid selection', & - & ' - Stoped in subroutine gas_init!!!' - stop + print *,' ICO2=',ico2flg,' is not a valid selection' + errflg = 1 + errmsg = 'ERROR(gas_init): ICO2 is not valid' + return endif ! endif_ico2flg_block close (NICO2CN) @@ -456,9 +467,10 @@ subroutine gas_init & print *,' - Using observed co2 monthly 2-d data' endif else - print *,' ICO2=',ico2flg,' is not a valid selection', & - & ' - Stoped in subroutine gas_init!!!' - stop + print *,' ICO2=',ico2flg,' is not a valid selection' + errflg = 1 + errmsg = 'ERROR(gas_init): ICO2 is not valid' + return endif if ( ictmflg == -2 ) then @@ -466,9 +478,12 @@ subroutine gas_init & if ( .not. file_exist ) then if ( me == 0 ) then print *,' Can not find seasonal cycle CO2 data: ', & - & co2cyc_file,' - Stopped in subroutine gas_init !!' + & co2cyc_file endif - stop + errflg = 1 + errmsg = 'ERROR(gas_init): Can not find seasonal cycle '//& + & 'CO2 data' + return else allocate( co2cyc_sav(IMXCO2,JMXCO2,12) ) @@ -531,8 +546,8 @@ end subroutine gas_init !! @{ !----------------------------------- subroutine gas_update & - & ( iyear, imon, iday, ihour, loz1st, ldoco2, me )! --- inputs -! --- outputs: ( none ) + & ( iyear, imon, iday, ihour, loz1st, ldoco2, me, & + & errflg, errmsg ) ! =================================================================== ! ! ! @@ -549,7 +564,8 @@ subroutine gas_update & ! me - print message control flag 1 ! ! ! ! outputs: (to the module variables) ! -! ( none ) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! external module variables: (in physparam) ! ! ico2flg - co2 data source control flag ! @@ -597,7 +613,9 @@ subroutine gas_update & logical, intent(in) :: loz1st, ldoco2 -! --- output: ( none ) +! --- output: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), dimension(IMXCO2,JMXCO2) :: co2dat, co2ann @@ -614,6 +632,10 @@ subroutine gas_update & ! !===> ... begin here ! +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + !> - Ozone data section if ( ioznflg == 0 ) then @@ -684,8 +706,11 @@ subroutine gas_update & inquire (file=co2gbl_file, exist=file_exist) if ( .not. file_exist ) then print *,' Requested co2 data file "',co2gbl_file, & - & '" not found - Stopped in subroutine gas_update!!' - stop + & '" not found' + errflg = 1 + errmsg = 'ERROR(gas_update): Requested co2 data file not '// & + & 'found' + return else close(NICO2CN) open (NICO2CN,file=co2gbl_file,form='formatted',status='old') @@ -752,9 +777,11 @@ subroutine gas_update & if ( me == 0 ) then print *,' Specified co2 data for year',idyr, & & ' not found !! Need to change namelist ICTM !!' - print *,' *** Stopped in subroutine gas_update !!' endif - stop + errflg = 1 + errmsg = 'ERROR(gas_update): Specified co2 data for year '//& + & 'not found' + return else Lab_if_ictm ! looking for latest available data if ( me == 0 ) then print *,' Requested co2 data for year',idyr, & @@ -778,9 +805,11 @@ subroutine gas_update & if ( .not. file_exist ) then if ( me == 0 ) then print *,' Can not find co2 data source file' - print *,' *** Stopped in subroutine gas_update !!' endif - stop + errflg = 1 + errmsg = 'ERROR(gas_update): Can not find co2 data '// & + & 'source file' + return endif endif Lab_if_ictm endif ! end if_file_exist_block diff --git a/physics/set_soilveg.f b/physics/set_soilveg.f index efef0f24b..37f2c2a73 100644 --- a/physics/set_soilveg.f +++ b/physics/set_soilveg.f @@ -13,11 +13,13 @@ module set_soilveg_mod !> \ingroup Noah_LSM !! This subroutine initializes soil and vegetation. - subroutine set_soilveg(me,isot,ivet,nlunit) + subroutine set_soilveg(me,isot,ivet,nlunit,errmsg,errflg) use namelist_soilveg implicit none integer, intent(in) :: me,isot,ivet,nlunit + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !my begin locals !for 20 igbp veg type and 19 stasgo soil type integer i @@ -385,16 +387,22 @@ subroutine set_soilveg(me,isot,ivet,nlunit) ! CLOSE(59) IF (DEFINED_SOIL .GT. MAX_SOILTYP) THEN - WRITE(0,*) 'Warning: DEFINED_SOIL too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_SOIL too large in '// & + & 'namelist' + return ENDIF IF (DEFINED_VEG .GT. MAX_VEGTYP) THEN - WRITE(0,*) 'Warning: DEFINED_VEG too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_VEG too large in '// & + & 'namelist' + return ENDIF IF (DEFINED_SLOPE .GT. MAX_SLOPETYP) THEN - WRITE(0,*) 'Warning: DEFINED_SLOPE too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_SLOPE too large in '//& + & 'namelist' + return ENDIF SMLOW = SMLOW_DATA diff --git a/physics/sfc_diff.f b/physics/sfc_diff.f index 59c6d2d60..150735106 100644 --- a/physics/sfc_diff.f +++ b/physics/sfc_diff.f @@ -383,7 +383,9 @@ subroutine sfc_diff_run (im,rvrdm1,eps,epsm1,grav, & !intent(in) call znot_t_v7(wind10m, ztmax_wat(i)) ! 10-m wind,m/s, ztmax(m) else if (sfc_z0_type > 0) then write(0,*)'no option for sfc_z0_type=',sfc_z0_type - stop + errflg = 1 + errmsg = 'ERROR(sfc_diff_run): no option for sfc_z0_type' + return endif ! call stability diff --git a/physics/sflx.f b/physics/sflx.f index 026e2b854..cd1adfe75 100644 --- a/physics/sflx.f +++ b/physics/sflx.f @@ -124,7 +124,8 @@ subroutine gfssflx &! --- input & edir, et, ett, esnow, drip, dew, beta, etp, ssoil, & & flx1, flx2, flx3, runoff1, runoff2, runoff3, & & snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, & - & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax) + & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, & + & errmsg, errflg ) ! ===================================================================== ! ! description: ! @@ -328,6 +329,8 @@ subroutine gfssflx &! --- input & runoff1, runoff2, runoff3, rc, pc, rsmin, xlai, rcs, & & rct, rcq, rcsoil, soilw, soilm, smcwlt, smcdry, smcref, & & smcmax + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: ! real (kind=kind_phys) :: df1h, @@ -347,6 +350,10 @@ subroutine gfssflx &! --- input ! !===> ... begin here ! +! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + ! --- ... initialization runoff1 = 0.0 @@ -412,7 +419,7 @@ subroutine gfssflx &! --- input !> - Call redprm() to set the land-surface paramters, !! including soil-type and veg-type dependent parameters. - call redprm + call redprm(errmsg, errflg) if(ivegsrc == 1) then !only igbp type has urban !urban @@ -1673,7 +1680,7 @@ end subroutine penman !> This subroutine internally sets default values or optionally read-in !! via namelist i/o, all soil and vegetation parateters requied for the execusion !! of the Noah LSM. - subroutine redprm + subroutine redprm(errmsg, errflg) !................................... ! --- inputs: ! & ( nsoil, vegtyp, soiltyp, slopetyp, sldpth, zsoil, & @@ -1860,7 +1867,8 @@ subroutine redprm ! & frzx, psisat, slope, snup, salp, bexp, dksat, dwsat, & ! & smcmax, smcwlt, smcref, smcdry, f1, quartz, fxexp, z0, & ! & czil, xlai, csoil, rtdis(nsoil) - + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! integer, intent(out) :: nroot ! --- locals: @@ -1871,20 +1879,30 @@ subroutine redprm ! !===> ... begin here ! +! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + if (soiltyp > defined_soil) then write(*,*) 'warning: too many soil types,soiltyp=',soiltyp, & & 'defined_soil=',defined_soil - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many soil types' + return endif if (vegtyp > defined_veg) then write(*,*) 'warning: too many veg types' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many veg types' + return endif if (slopetyp > defined_slope) then write(*,*) 'warning: too many slope types' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many slope types' + return endif ! --- ... set-up universal parameters (not dependent on soiltyp, vegtyp @@ -1941,7 +1959,9 @@ subroutine redprm if (nroot > nsoil) then write(*,*) 'warning: too many root layers' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many root layers' + return endif ! --- ... calculate root distribution. present version assumes uniform From 1dbed67e964bf108ac4f5c7b8544497fad074973 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Tue, 16 Aug 2022 11:31:22 -0600 Subject: [PATCH 09/58] Replaced all remaing stop statements with ccpp error handling. --- physics/GFS_phys_time_vary.fv3.F90 | 2 +- physics/GFS_rrtmg_setup.F90 | 30 +++++++++++++------------ physics/gcycle.F90 | 14 ++++++++++-- physics/gfdl_cloud_microphys.F90 | 2 +- physics/gfdl_sfc_layer.F90 | 6 ++--- physics/lsm_ruc.F90 | 8 ++++--- physics/m_micro.F90 | 4 +++- physics/module_SF_JSFC.F90 | 23 +++++++++++++++---- physics/module_gfdl_cloud_microphys.F90 | 13 +++++++++-- physics/module_sf_exchcoef.f90 | 13 +++++++++-- physics/module_sf_mynn.F90 | 21 ++++++++++++++--- physics/module_sf_ruclsm.F90 | 29 +++++++++++++++++------- physics/radiation_clouds.f | 1 - physics/radlw_main.F90 | 28 +++++++++++++++++------ physics/radsw_main.F90 | 23 ++++++++++++++----- physics/set_soilveg_ruc.F90 | 20 +++++++++++++---- 16 files changed, 176 insertions(+), 61 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index e3d95e5a3..8ffd56b0e 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -901,7 +901,7 @@ subroutine GFS_phys_time_vary_timestep_init ( tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, & zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, & stype, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, & - xlat_d, xlon_d, slmsk, imap, jmap) + xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg) endif endif diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 331ecbd1e..eb6a94578 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -199,7 +199,9 @@ subroutine GFS_rrtmg_setup_init ( & iaermdl = iaer/1000 ! control flag for aerosol scheme selection if ( iaermdl < 0 .or. (iaermdl>2 .and. iaermdl/=5) ) then print *, ' Error -- IAER flag is incorrect, Abort' - stop 7777 + errflg = 1 + errmsg = 'ERROR(GFS_rrtmg_setup): IAER flag is incorrect' + return endif ! if ( ntcw > 0 ) then @@ -496,7 +498,9 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & else print *,' - ERROR!!! ISUBCLW=',isubclw,' is not a ', & & 'valid option ' - stop + errflg = 1 + errmsg = 'ERROR(GFS_rrtmg_setup): ISUBCLW flag is invalid' + return endif if ( isubcsw == 0 ) then @@ -511,7 +515,9 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & else print *,' - ERROR!!! ISUBCSW=',isubcsw,' is not a ', & & 'valid option ' - stop + errflg = 1 + errmsg = 'ERROR(GFS_rrtmg_setup): ISUBCSW flag is invalid' + return endif if ( isubcsw /= isubclw ) then @@ -535,18 +541,14 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & !! call module_radsw_main::rswinit() ! Initialization - call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) ! --- ... astronomy initialization routine - + call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002,& + con_pi ) ! astronomy initialization routine call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! --- ... aerosols initialization routine - - call gas_init ( me, errflg, errmsg ) ! --- ... co2 and other gases initialization routine - - call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! --- ... cloud initialization routine - - call rlwinit ( me ) ! --- ... lw radiation initialization routine - - call rswinit ( me ) ! --- ... sw radiation initialization routine + con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine + call gas_init ( me, errflg, errmsg ) ! co2 and other gases initialization routine + call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! cloud initialization routine + call rlwinit ( me, errflg, errmsg ) ! lw RRTMG initialization routine + call rswinit ( me, errflg, errmsg ) ! sw RRTMG initialization routine ! return ! diff --git a/physics/gcycle.F90 b/physics/gcycle.F90 index 7e301c480..16e446b27 100644 --- a/physics/gcycle.F90 +++ b/physics/gcycle.F90 @@ -22,7 +22,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, & zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, & stype, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, & - xlat_d, xlon_d, slmsk, imap, jmap) + xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg) ! ! use machine, only: kind_phys, kind_io8 @@ -78,6 +78,9 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, slope(:) integer, intent(in) :: imap(:), jmap(:) + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + ! ! Local variables ! --------------- @@ -104,6 +107,11 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, real(kind=kind_phys) :: sig1t integer :: npts, nb, ix, jx, ls, ios, ll logical :: exists + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! @@ -214,7 +222,9 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, inquire (file=trim(fn_nml),exist=exists) if (.not. exists) then write(6,*) 'gcycle:: namelist file: ',trim(fn_nml),' does not exist' - stop + errflg = 1 + errmsg = 'ERROR(gcycle): namelist file: ',trim(fn_nml),' does not exist.' + return else open (unit=nlunit, file=trim(fn_nml), action='READ', status='OLD', iostat=ios) rewind (nlunit) diff --git a/physics/gfdl_cloud_microphys.F90 b/physics/gfdl_cloud_microphys.F90 index 309cbac92..e2c71c960 100644 --- a/physics/gfdl_cloud_microphys.F90 +++ b/physics/gfdl_cloud_microphys.F90 @@ -63,7 +63,7 @@ subroutine gfdl_cloud_microphys_init (me, master, nlunit, input_nml_file, loguni return endif - call gfdl_cloud_microphys_mod_init(me, master, nlunit, input_nml_file, logunit, fn_nml) + call gfdl_cloud_microphys_mod_init(me, master, nlunit, input_nml_file, logunit, fn_nml, errmsg, errflg) is_initialized = .true. diff --git a/physics/gfdl_sfc_layer.F90 b/physics/gfdl_sfc_layer.F90 index 379c9c856..44e2fa254 100644 --- a/physics/gfdl_sfc_layer.F90 +++ b/physics/gfdl_sfc_layer.F90 @@ -1140,7 +1140,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m land(i) = 0.0 windmks=wind10p(i)*.01 if ( iwavecpl .eq. 1 ) then - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) !Check if Charnock parameter ratio is received in a proper range. if ( alpha(i) .ge. 0.2 .and. alpha(i) .le. 5. ) then znotm = znotm*alpha(i) @@ -1148,7 +1148,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m zoc(i) = -100.*znotm zot(i) = -100* znott else - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) zoc(i) = -100.*znotm zot(i) = -100* znott endif @@ -1785,7 +1785,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m !!! if ( iwavecpl .eq. 1 .and. zoc(i) .le. 0.0 ) then windmks = wind10(i) * 0.01 - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) !Check if Charnock parameter ratio is received in a proper range. if ( alpha(i) .ge. 0.2 .and. alpha(i) .le. 5. ) then znotm = znotm*alpha(i) diff --git a/physics/lsm_ruc.F90 b/physics/lsm_ruc.F90 index 3ca78ad04..48bb281da 100644 --- a/physics/lsm_ruc.F90 +++ b/physics/lsm_ruc.F90 @@ -159,7 +159,7 @@ subroutine lsm_ruc_init (me, master, isot, ivegsrc, nlunit, & endif !--- initialize soil vegetation - call set_soilveg_ruc(me, isot, ivegsrc, nlunit) + call set_soilveg_ruc(me, isot, ivegsrc, nlunit, errmsg, errflg) pores (:) = maxsmc (:) resid (:) = drysmc (:) @@ -1135,7 +1135,8 @@ subroutine lsm_ruc_run & ! inputs & smfrsoil(i,:,j),keepfrsoil(i,:,j), .false., & & shdmin1d(i,j), shdmax1d(i,j), rdlai2d, & & ims,ime, jms,jme, kms,kme, & - & its,ite, jts,jte, kts,kte ) + & its,ite, jts,jte, kts,kte, & + & errmsg, errflg) if(debug_print) then write (0,*)'after LSMRUC for land' write (0,*)'after sneqv(i,j) =',i,j,sneqv_lnd(i,j) @@ -1396,7 +1397,8 @@ subroutine lsm_ruc_run & ! inputs & smfrice(i,:,j),keepfrice(i,:,j), .false., & & shdmin1d(i,j), shdmax1d(i,j), rdlai2d, & & ims,ime, jms,jme, kms,kme, & - & its,ite, jts,jte, kts,kte ) + & its,ite, jts,jte, kts,kte, & + & errmsg, errflg) ! Interstitial evap_ice(i) = qfx_ice(i,j) / rho(i) ! kinematic diff --git a/physics/m_micro.F90 b/physics/m_micro.F90 index 15e30b0a6..200f906ee 100644 --- a/physics/m_micro.F90 +++ b/physics/m_micro.F90 @@ -123,7 +123,9 @@ subroutine m_micro_init(imp_physics, imp_physics_mg, fprcp, gravit, rair, rh2o, mg_ngcons, mg_ngnst) else write(0,*)' fprcp = ',fprcp,' is not a valid option - aborting' - stop + errflg = 1 + errmsg = 'ERROR(m_micro_init): fprcp is not a valid option' + return endif call aer_cloud_init () diff --git a/physics/module_SF_JSFC.F90 b/physics/module_SF_JSFC.F90 index 8d67a81cd..fdf188b96 100644 --- a/physics/module_SF_JSFC.F90 +++ b/physics/module_SF_JSFC.F90 @@ -122,7 +122,7 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & & ,A1U,A1T,A1Q & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM) + & ,ITS,ITE,JTS,JTE,KTS,LM,errmsg,errflg) ! !----------------------------------------------------------------------- ! SUBROUTINE JSFC(NTSD,EPSQ2,HT,DZ & @@ -182,6 +182,8 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & REAL(kind=kfpt),DIMENSION(IMS:IME,JMS:JME),INTENT(OUT) :: CM,CH,STRESS,FFM & & ,FFH,WIND,FM10,FH2 & & ,A1U,A1T,A1Q + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg ! ! REAL(kind=kfpt),DIMENSION(IMS:IME,JMS:JME),INTENT(OUT) :: CHS,CHS2,CQS2 & ! & ,CPM,CT,FLHC,FLQC & @@ -215,6 +217,9 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & ! !---------------------------------------------------------------------- !********************************************************************** + ! Initialize error-handling + errflg = 0 + errmsg = '' !---------------------------------------------------------------------- ! !*** MAKE PREPARATIONS @@ -390,7 +395,8 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & & ,A1U(I,J),A1T(I,J),A1Q(I,J) & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZHK(LMH+1),RIB(I,J)) ! Added Bulk Richardson No. + & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZHK(LMH+1),RIB(I,J) & ! Added Bulk Richardson No. + & ,errmsg, errflg) ! !*** REMOVE SUPERATURATION AT 2M AND 10M ! @@ -454,7 +460,8 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & & ,FFM,FFH,FM10,FH2,A1U,A1T,A1Q & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZSFC,RIB) ! Added Bulk Richardson No. + & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZSFC,RIB & ! Added Bulk Richardson No. + & ,errmsg, errflg) ! **************************************************************** ! * * ! * SURFACE LAYER * @@ -481,6 +488,8 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & REAL(kind=kfpt),INTENT(OUT) :: FFM,FFH,FM10,FH2,A1U,A1T,A1Q ! REAL(kind=kfpt),INTENT(INOUT) :: AKHS,AKMS,QZ0,THZ0,USTAR,UZ0,VZ0,Z0,QS + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !---------------------------------------------------------------------- !*** !*** LOCAL VARIABLES @@ -507,6 +516,10 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & !---------------------------------------------------------------------- !********************************************************************** !---------------------------------------------------------------------- + ! Initialize error-handling + errflg = 0 + errmsg = '' + RDZ=1./ZSL CXCHL=EXCML*RDZ CXCHS=EXCMS*RDZ @@ -701,7 +714,9 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & print*,'PSIH1(1,2),RDZT=',PSIH1(K+1),PSIH1(K+2),RDZT print*,'ZSLU,ZSLT,RLMO,ZU,ZT=',ZSLU,ZSLT,RLMO,ZU,ZT print*,'A,B,DTHV,DU2,RIB=',A,B,DTHV,DU2,RIB - stop + errflg = 1 + errmsg = 'ERROR(SFCDIF): ' + return end if diff --git a/physics/module_gfdl_cloud_microphys.F90 b/physics/module_gfdl_cloud_microphys.F90 index 7f00d9bca..ebd3b93ff 100644 --- a/physics/module_gfdl_cloud_microphys.F90 +++ b/physics/module_gfdl_cloud_microphys.F90 @@ -3575,7 +3575,8 @@ end subroutine setupm !>\ingroup mod_gfdl_cloud_mp !! The subroutine 'gfdl_cloud_microphys_init' initializes the GFDL !! cloud microphysics. -subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, fn_nml) +subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, & + fn_nml, errmsg, errflg) implicit none @@ -3586,6 +3587,8 @@ subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, lo character (len = 64), intent (in) :: fn_nml character (len = *), intent (in) :: input_nml_file(:) + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg integer :: ios logical :: exists @@ -3600,13 +3603,19 @@ subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, lo ! master = (mpp_pe () .eq.mpp_root_pe ()) + ! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + #ifdef INTERNAL_FILE_NML read (input_nml_file, nml = gfdl_cloud_microphysics_nml) #else inquire (file = trim (fn_nml), exist = exists) if (.not. exists) then write (6, *) 'gfdl - mp :: namelist file: ', trim (fn_nml), ' does not exist' - stop + errflg = 1 + errmsg = 'ERROR(gfdl_cloud_microphys_mod_init): namelist file '//trim (fn_nml)//' does not exist' + return else open (unit = nlunit, file = fn_nml, action = 'read' , status = 'old', iostat = ios) endif diff --git a/physics/module_sf_exchcoef.f90 b/physics/module_sf_exchcoef.f90 index 0e3dae80c..6ec9ed835 100644 --- a/physics/module_sf_exchcoef.f90 +++ b/physics/module_sf_exchcoef.f90 @@ -636,7 +636,7 @@ SUBROUTINE znot_t_v8(uref,znott) END SUBROUTINE znot_t_v8 - SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) + SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf,errmsg,errflg) IMPLICIT NONE ! w10m(m/s) : 10-m wind speed @@ -647,8 +647,15 @@ SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) REAL, INTENT(IN) :: w10m INTEGER, INTENT(IN) :: icoef_sf REAL, INTENT(OUT):: znott, znotm + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg real :: zm,zt,windmks, zlev,z10, tmp, zlevt, aaa, zm1,zt1 + + ! Initialize error-handling + errflg = 0 + errmsg = '' + zlev=20.0 zlevt=10.0 z10=10.0 @@ -722,7 +729,9 @@ SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) call znot_t_v8(windmks,zt1) else write(0,*)'stop, icoef_sf must be one of 0,1,2,3,4,5,6,7,8' - stop + errflg = 1 + errmsg = 'ERROR(znot_wind10m): icoef_sf must be one of 0,1,2,3,4,5,6,7,8' + return endif znott=zt1 znotm=zm1 diff --git a/physics/module_sf_mynn.F90 b/physics/module_sf_mynn.F90 index 0d81e145a..a6f32430d 100644 --- a/physics/module_sf_mynn.F90 +++ b/physics/module_sf_mynn.F90 @@ -378,6 +378,10 @@ SUBROUTINE SFCLAY_mynn( & INTEGER :: I,J,K,itf,ktf !----------------------------------------------------------- + ! Initialize error-handling + errflg = 0 + errmsg = '' + IF (debug_code >= 1) THEN write(*,*)"======= printing of constants:" write(*,*)"cp=", cp," g=", g @@ -671,6 +675,9 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & REAL :: FLUXC,VSGD REAL :: restar,VISC,DQG,OLDUST,OLDTST + ! Initialize error-handling + errflg = 0 + errmsg = '' !------------------------------------------------------------------- DO I=its,ite @@ -1179,7 +1186,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ENDIF ELSEIF ( ISFTCFLX .EQ. 4 ) THEN !GFS zt formulation - CALL GFS_zt_wat(ZT_wat(i),ZNTstoch_wat(i),restar,WSPD(i),ZA(i),sfc_z0_type) + CALL GFS_zt_wat(ZT_wat(i),ZNTstoch_wat(i),restar,WSPD(i),ZA(i),sfc_z0_type,errmsg,errflg) ZQ_wat(i)=ZT_wat(i) ENDIF ELSE @@ -2749,14 +2756,20 @@ SUBROUTINE GFS_z0_wat(z0rl_wat,ustar_wat,WSPD,z1,sfc_z0_type,redrag) END SUBROUTINE GFS_z0_wat !-------------------------------------------------------------------- !>\ingroup mynn_sfc - SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type) + SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type,errmsg,errflg) REAL, INTENT(OUT) :: ztmax REAL, INTENT(IN) :: wspd,z1,z0rl_wat,restar INTEGER, INTENT(IN):: sfc_z0_type + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg REAL :: z0,z0max,wind10m,rat,ustar_wat REAL, PARAMETER :: charnock = 0.014, z0s_max=.317e-2 + ! Initialize error-handling + errflg = 0 + errmsg = '' + ! z0 = 0.01 * z0rl_wat !Already converted to meters in the wrapper z0 = z0rl_wat @@ -2786,7 +2799,9 @@ SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type) call znot_t_v7(wind10m, ztmax) ! 10-m wind,m/s, ztmax(m) else if (sfc_z0_type > 0) then write(0,*)'no option for sfc_z0_type=',sfc_z0_type - stop + errflg = 1 + errmsg = 'ERROR(GFS_zt_wat): sfc_z0_type not valid.' + return endif END SUBROUTINE GFS_zt_wat diff --git a/physics/module_sf_ruclsm.F90 b/physics/module_sf_ruclsm.F90 index 0cf820303..f86eb54fe 100644 --- a/physics/module_sf_ruclsm.F90 +++ b/physics/module_sf_ruclsm.F90 @@ -81,7 +81,8 @@ SUBROUTINE LSMRUC( & SMFR3D,KEEPFR3DFLAG, & myj,shdmin,shdmax,rdlai2d, & ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) + its,ite, jts,jte, kts,kte, & + errmsg, errflg) !----------------------------------------------------------------- IMPLICIT NONE !----------------------------------------------------------------- @@ -334,7 +335,6 @@ SUBROUTINE LSMRUC( & KICE, & KWT - REAL, DIMENSION(1:NSL) :: ZSMAIN, & ZSHALF, & DTDZS2 @@ -390,9 +390,14 @@ SUBROUTINE LSMRUC( & INTEGER :: I,J,K,NZS,NZS1,NDDZS INTEGER :: k1,k2 logical :: debug_print - + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !----------------------------------------------------------------- ! + ! Initialize error-handling + errflg = 0 + errmsg = '' + debug_print = .false. ! rovcp = rd/cp @@ -713,7 +718,7 @@ SUBROUTINE LSMRUC( & soilfrac,nscat,shdmin(i,j),shdmax(i,j),mosaic_lu, mosaic_soil,& NLCAT,ILAND,ISOIL,iswater,MYJ,IFOREST,lufrac,VEGFRA(I,J), & EMISSL(I,J),PC(I,J),ZNT(I,J),LAI(I,J),RDLAI2D, & - QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,i,j ) + QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,i,j,errmsg, errflg) !-- update background emissivity for land points, can have vegetation mosaic effect EMISBCK(I,J) = EMISSL(I,J) @@ -6557,7 +6562,8 @@ SUBROUTINE SOILVEGIN ( debug_print, & mosaic_lu, mosaic_soil, & NLCAT,IVGTYP,ISLTYP,iswater,MYJ, & IFOREST,lufrac,vegfrac,EMISS,PC,ZNT,LAI,RDLAI2D,& - QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,I,J) + QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,I,J,& + errmsg, errflg) !************************************************************************ ! Set-up soil and vegetation Parameters in the case when @@ -6819,7 +6825,8 @@ SUBROUTINE SOILVEGIN ( debug_print, & REF, & WILT INTEGER, INTENT ( OUT) :: iforest - + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg ! INTEGER, DIMENSION( 1:(lucats) ) , & ! INTENT ( OUT) :: iforest @@ -6840,7 +6847,11 @@ SUBROUTINE SOILVEGIN ( debug_print, & ! iforest(k)=if1(k) ! enddo - iforest = IFORTBL(IVGTYP) + ! Initialize error-handling + errflg = 0 + errmsg = '' + + iforest = IFORTBL(IVGTYP) IF (debug_print ) THEN print *,'ifortbl(ivgtyp),ivgtyp,laitbl(ivgtyp),z0tbl(ivgtyp)', & @@ -6914,7 +6925,9 @@ SUBROUTINE SOILVEGIN ( debug_print, & if (area.gt.1.) area=1. if (area <= 0.) then print *,'Bad area of grid box', area - stop + errflg = 1 + errmsg = 'ERROR(SOILVEGIN): Bad area of grid box' + return endif IF (debug_print ) THEN diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index d77b39735..dc6535e3d 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -379,7 +379,6 @@ subroutine cld_init & errmsg = 'ERROR(cld_init): cloud mp specification is not'// & & ' valid' return - stop endif endif endif diff --git a/physics/radlw_main.F90 b/physics/radlw_main.F90 index aeb626007..2f51b09f4 100644 --- a/physics/radlw_main.F90 +++ b/physics/radlw_main.F90 @@ -1325,8 +1325,7 @@ end subroutine rrtmg_lw_finalize !!\section rlwinit_gen rlwinit General Algorithm !! @{ subroutine rlwinit & - & ( me ) ! --- inputs -! --- outputs: (none) + & ( me, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1397,7 +1396,9 @@ subroutine rlwinit & ! --- inputs: integer, intent(in) :: me -! --- outputs: none +! --- outputs: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: expeps = 1.e-20 @@ -1409,10 +1410,16 @@ subroutine rlwinit & ! !===> ... begin here ! + ! Initialize error-handling + errflg = 0 + errmsg = '' + if ( iovr<0 .or. iovr>5 ) then print *,' *** Error in specification of cloud overlap flag', & & ' IOVR=',iovr,' in RLWINIT !!' - stop + errflg = 1 + errmsg = 'ERROR(rlwinit): cloud-overlap (iovr) scheme selected not valid.' + return elseif ( (iovr==2 .or. iovr==3) .and. isubclw==0 ) then if (me == 0) then print *,' *** IOVR=',iovr,' is not available for', & @@ -1446,7 +1453,9 @@ subroutine rlwinit & else print *,' *** Error in specification of sub-column cloud ', & & ' control flag isubclw =',isubclw,' !!' - stop + errflg = 1 + errmsg = 'ERROR(rlwinit): sub-column scheme (isubclw) selected not valid.' + return endif endif @@ -1456,7 +1465,10 @@ subroutine rlwinit & & (icldflg == 1 .and. ilwcliq == 0)) then print *,' *** Model cloud scheme inconsistent with LW', & & ' radiation cloud radiative property setup !!' - stop + errflg = 1 + errmsg = 'ERROR(rlwinit): Model cloud scheme inconsistent with LW'//& + & ' radiation cloud radiative property setup' + return endif !> -# Setup default surface emissivity for each band. @@ -7668,7 +7680,9 @@ subroutine cldprmc(nlayers, inflag, iceflag, liqflag, cldfmc, & return elseif(inflag .eq. 1) then - stop 'INFLAG = 1 OPTION NOT AVAILABLE WITH MCICA' + errflg = 1 + errmsg = 'ERROR(rlwinit): INFLAG = 1 OPTION NOT AVAILABLE WITH MCICA' + return ! cwp = ciwpmc(ig,lay) + clwpmc(ig,lay) ! taucmc(ig,lay) = abscld1 * cwp diff --git a/physics/radsw_main.F90 b/physics/radsw_main.F90 index 5d7d62dcc..f6c6b9a1e 100644 --- a/physics/radsw_main.F90 +++ b/physics/radsw_main.F90 @@ -1397,7 +1397,7 @@ end subroutine rrtmg_sw_finalize !! @{ !----------------------------------- subroutine rswinit & - & ( me ) ! --- inputs: + & ( me, errflg, errmsg ) ! --- inputs: ! --- outputs: (none) ! =================== program usage description =================== ! @@ -1457,7 +1457,9 @@ subroutine rswinit & ! --- inputs: integer, intent(in) :: me -! --- outputs: none +! --- outputs: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: expeps = 1.e-20 @@ -1469,10 +1471,16 @@ subroutine rswinit & ! !===> ... begin here ! + ! Initialize error-handling + errflg = 0 + errmsg = '' + if ( iovr<0 .or. iovr>5 ) then print *,' *** Error in specification of cloud overlap flag', & & ' IOVR=',iovr,' in RSWINIT !!' - stop + errflg = 1 + errmsg = 'ERROR(rswinit): cloud-overlap (iovr) scheme selected not valid.' + return endif if (me == 0) then @@ -1505,7 +1513,9 @@ subroutine rswinit & else print *,' *** Error in specification of sub-column cloud ', & & ' control flag isubcsw =',isubcsw,' !!' - stop + errflg = 1 + errmsg = 'ERROR(rswinit): sub-column scheme (isubcsw) selected not valid.' + return endif endif @@ -1515,7 +1525,10 @@ subroutine rswinit & & (icldflg == 1 .and. iswcliq == 0)) then print *,' *** Model cloud scheme inconsistent with SW', & & ' radiation cloud radiative property setup !!' - stop + errflg = 1 + errmsg = 'ERROR(rswinit): Model cloud scheme inconsistent with SW'//& + & ' radiation cloud radiative property setup' + return endif if ( isubcsw==0 .and. iovr>2 ) then diff --git a/physics/set_soilveg_ruc.F90 b/physics/set_soilveg_ruc.F90 index cac4fd1e7..c03e6fc5f 100644 --- a/physics/set_soilveg_ruc.F90 +++ b/physics/set_soilveg_ruc.F90 @@ -17,9 +17,11 @@ module set_soilveg_ruc_mod !>\ingroup lsm_ruc_group !! This subroutine specifies vegetation and soil parameters for a given !! soil and land-use classification. - subroutine set_soilveg_ruc(me,isot,ivet,nlunit) + subroutine set_soilveg_ruc(me,isot,ivet,nlunit,errmsg,errflg) integer, intent(in) :: isot,ivet,nlunit + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg integer me integer i @@ -35,6 +37,10 @@ subroutine set_soilveg_ruc(me,isot,ivet,nlunit) & WLTSMC, QTZ, mosaic_soil, mosaic_lu, & & REFSMCnoah, WLTSMCnoah, MAXSMCnoah + ! Initialize error-handling + errflg = 0 + errmsg = '' + if(ivet.eq.2) then ! Using umd veg classification slope_data =(/0.1, 0.6, 1.0, 0.35, 0.55, 0.8, & @@ -415,15 +421,21 @@ subroutine set_soilveg_ruc(me,isot,ivet,nlunit) IF (DEFINED_SOIL .GT. MAX_SOILTYP) THEN WRITE(0,*) 'Warning: DEFINED_SOIL too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_SOIL too large in namelist' + return ENDIF IF (DEFINED_VEG .GT. MAX_VEGTYP) THEN WRITE(0,*) 'Warning: DEFINED_VEG too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_VEG too large in namelist' + return ENDIF IF (DEFINED_SLOPE .GT. MAX_SLOPETYP) THEN WRITE(0,*) 'Warning: DEFINED_SLOPE too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_SLOPE too large in namelist' + return ENDIF ! if (me == 0) write(6,soil_veg_ruc) From e02f1dde91715f1fcb4937f43ee58d35c0c0db74 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Tue, 16 Aug 2022 18:19:28 +0000 Subject: [PATCH 10/58] Bug fix in html include location. --- physics/drag_suite.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/physics/drag_suite.F90 b/physics/drag_suite.F90 index c1c6fc8f4..5bb90b5e0 100644 --- a/physics/drag_suite.F90 +++ b/physics/drag_suite.F90 @@ -9,8 +9,12 @@ module drag_suite !> \defgroup gfs_drag_suite_mod GSL drag_suite Module !> This module contains the CCPP-compliant GSL orographic gravity wave dray scheme. !> @{ +!! +!> \brief This subroutine initializes the orographic gravity wave drag scheme. +!! !> \section arg_table_drag_suite_init Argument Table -!! \htmlinclude drag_suite_init.html +!! \htmlinclude drag_suite_init.html +!! subroutine drag_suite_init(gwd_opt, errmsg, errflg) integer, intent(in) :: gwd_opt From f885b9cdc92b78765afbdae66c04ca48603607a7 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 17 Aug 2022 10:32:10 -0600 Subject: [PATCH 11/58] Remove dependency on physcons and physparam in radiation_surface.f. Provided as ccpp interstitials. --- CMakeLists.txt | 2 +- physics/GFS_cloud_diagnostics.F90 | 1 - physics/GFS_cloud_diagnostics.meta | 1 + physics/GFS_radiation_surface.F90 | 20 +++++------ physics/GFS_radiation_surface.meta | 31 +++++++++++++++++ physics/GFS_surface_composites_pre.F90 | 1 - physics/GFS_surface_composites_pre.meta | 2 +- physics/physparam.f | 19 ---------- physics/radiation_surface.f | 46 ++++++++++++------------- 9 files changed, 66 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d14778b06..242275411 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,7 +195,7 @@ set_target_properties(ccpp_physics PROPERTIES VERSION ${PROJECT_VERSION} target_include_directories(ccpp_physics PUBLIC $) -target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d NetCDF::NetCDF_Fortran) +target_link_libraries(ccpp_physics PUBLIC w3nco::w3nco_d NetCDF::NetCDF_Fortran) # Define where to install the library install(TARGETS ccpp_physics diff --git a/physics/GFS_cloud_diagnostics.F90 b/physics/GFS_cloud_diagnostics.F90 index 0e3f730e5..01ecd7452 100644 --- a/physics/GFS_cloud_diagnostics.F90 +++ b/physics/GFS_cloud_diagnostics.F90 @@ -3,7 +3,6 @@ module GFS_cloud_diagnostics use machine, only: kind_phys - use physparam, only: icldflg use module_radiation_clouds, only: gethml ! Module parameters (imported directly from radiation_cloud.f) diff --git a/physics/GFS_cloud_diagnostics.meta b/physics/GFS_cloud_diagnostics.meta index dd88bbc46..ded38a1e7 100644 --- a/physics/GFS_cloud_diagnostics.meta +++ b/physics/GFS_cloud_diagnostics.meta @@ -1,6 +1,7 @@ [ccpp-table-properties] name = GFS_cloud_diagnostics type = scheme + dependencies = machine.F ######################################################################## [ccpp-arg-table] diff --git a/physics/GFS_radiation_surface.F90 b/physics/GFS_radiation_surface.F90 index ec7795c10..01c37156d 100644 --- a/physics/GFS_radiation_surface.F90 +++ b/physics/GFS_radiation_surface.F90 @@ -17,14 +17,15 @@ module GFS_radiation_surface !> \section arg_table_GFS_radiation_surface_init Argument Table !! \htmlinclude GFS_radiation_surface_init.html !! - subroutine GFS_radiation_surface_init (me, ialb, iems, errmsg, errflg) + subroutine GFS_radiation_surface_init (me, ialb, iems, semis_file, con_pi, errmsg, errflg) - use physparam, only: ialbflg, iemsflg use module_radiation_surface, only: sfc_init implicit none integer, intent(in) :: me, ialb, iems + character(len=26), intent(in) :: semis_file + real(kind_phys), intent(in) :: con_pi character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -32,16 +33,13 @@ subroutine GFS_radiation_surface_init (me, ialb, iems, errmsg, errflg) errmsg = '' errflg = 0 - ialbflg= ialb ! surface albedo control flag - iemsflg= iems ! surface emissivity control flag - if ( me == 0 ) then print *,'In GFS_radiation_surface_init, before calling sfc_init' print *,'ialb=',ialb,' iems=',iems end if ! Call surface initialization routine - call sfc_init ( me, errmsg, errflg ) + call sfc_init ( me, ialb, iems, semis_file, con_pi, errmsg, errflg ) end subroutine GFS_radiation_surface_init @@ -50,13 +48,13 @@ end subroutine GFS_radiation_surface_init !! \htmlinclude GFS_radiation_surface_run.html !! subroutine GFS_radiation_surface_run ( & - im, frac_grid, lslwr, lsswr, lsm, lsm_noahmp, lsm_ruc, & + ialb, im, frac_grid, lslwr, lsswr, lsm, lsm_noahmp, lsm_ruc, & xlat, xlon, slmsk, lndp_type, n_var_lndp, sfc_alb_pert, & lndp_var_list, lndp_prt_list, landfrac, snodl, snodi, sncovr, & sncovr_ice, fice, zorl, hprime, tsfg, tsfa, tisfc, coszen, & cplice, min_seaice, min_lakeice, lakefrac, use_flake, & alvsf, alnsf, alvwf, alnwf, facsf, facwf, & - semis_lnd, semis_ice, semis_wat, snoalb, use_cice_alb, & + semis_lnd, semis_ice, semis_wat, snoalb, use_cice_alb, con_ttp, & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & albdvis_ice, albdnir_ice, albivis_ice, albinir_ice, & semisbase, semis, sfcalb, sfc_alb_dif, errmsg, errflg) @@ -67,10 +65,10 @@ subroutine GFS_radiation_surface_run ( & implicit none - integer, intent(in) :: im + integer, intent(in) :: im, ialb logical, intent(in) :: frac_grid, lslwr, lsswr, use_cice_alb, cplice integer, intent(in) :: lsm, lsm_noahmp, lsm_ruc, lndp_type, n_var_lndp - real(kind=kind_phys), intent(in) :: min_seaice, min_lakeice + real(kind=kind_phys), intent(in) :: min_seaice, min_lakeice, con_ttp logical, dimension(:), intent(in) :: use_flake real(kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, slmsk, & @@ -184,7 +182,7 @@ subroutine GFS_radiation_surface_run ( & alvsf, alnsf, alvwf, alnwf, facsf, facwf, fice, tisfc, & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & albdvis_ice, albdnir_ice, albivis_ice, albinir_ice, & - IM, sfc_alb_pert, lndp_alb, fracl, fraco, fraci, icy, & ! --- inputs + IM, sfc_alb_pert, lndp_alb, fracl, fraco, fraci, icy, ialb, con_ttp, & ! --- inputs sfcalb ) ! --- outputs !> -# Approximate mean surface albedo from vis- and nir- diffuse values. diff --git a/physics/GFS_radiation_surface.meta b/physics/GFS_radiation_surface.meta index 3fd851a40..8ad848446 100644 --- a/physics/GFS_radiation_surface.meta +++ b/physics/GFS_radiation_surface.meta @@ -28,6 +28,22 @@ dimensions = () type = integer intent = in +[semis_file] + standard_name = surface_emissivity_data_file + long_name = surface emissivity data file for radiation + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -55,6 +71,13 @@ dimensions = () type = integer intent = in +[ialb] + standard_name = control_for_surface_albedo + long_name = flag for using climatology alb, based on sfc type + units = flag + dimensions = () + type = integer + intent = in [frac_grid] standard_name = flag_for_fractional_landmask long_name = flag for fractional grid @@ -380,6 +403,14 @@ dimensions = () type = logical intent = in +[con_ttp] + standard_name = triple_point_temperature_of_water + long_name = triple point temperature of water + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [albdvis_lnd] standard_name = surface_albedo_direct_visible_over_land long_name = direct surface albedo visible band over land diff --git a/physics/GFS_surface_composites_pre.F90 b/physics/GFS_surface_composites_pre.F90 index 734f1965b..a8b0a3112 100644 --- a/physics/GFS_surface_composites_pre.F90 +++ b/physics/GFS_surface_composites_pre.F90 @@ -4,7 +4,6 @@ module GFS_surface_composites_pre use machine, only: kind_phys - use physparam, only : iemsflg implicit none diff --git a/physics/GFS_surface_composites_pre.meta b/physics/GFS_surface_composites_pre.meta index e87af3e28..a0e30055f 100644 --- a/physics/GFS_surface_composites_pre.meta +++ b/physics/GFS_surface_composites_pre.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_surface_composites_pre type = scheme - dependencies = machine.F,physparam.f + dependencies = machine.F ######################################################################## [ccpp-arg-table] diff --git a/physics/physparam.f b/physics/physparam.f index b84bdd42f..880ed47f3 100644 --- a/physics/physparam.f +++ b/physics/physparam.f @@ -211,25 +211,6 @@ module physparam !> shallow convetion flag logical, save :: lsashal =.false. -! ............................................. ! -!>\name 2.5 For module radiation_surface -! ............................................. ! - -!> surface albedo scheme control flag -!!\n =0:vegetation type based climatological albedo scheme -!!\n =1:seasonal albedo derived from MODIS measurements - integer, save :: ialbflg = 0 - -!> surface emissivity scheme control flag -!!\n =0:black-body surface emissivity(=1.0) -!!\n =1:vegetation type based climatology emissivity(<1.0) -!!\n Opr GFS/CFS=1; see IEMS in run scripts - integer, save :: iemsflg = 0 - -!> external sfc emissivity data table: sfc_emissivity_idx.txt - character, save :: semis_file*26 - data semis_file / 'sfc_emissivity_idx.txt ' / - ! ............................................. ! !> \name 2.6 general purpose ! ............................................. ! diff --git a/physics/radiation_surface.f b/physics/radiation_surface.f index 664e7d453..dba4450e2 100644 --- a/physics/radiation_surface.f +++ b/physics/radiation_surface.f @@ -107,9 +107,7 @@ module module_radiation_surface !! \section arg_table_module_radiation_surface !! \htmlinclude module_radiation_surface.html !! - use physparam, only : ialbflg, iemsflg, semis_file, & - & kind_phys - use physcons, only : con_t0c, con_ttp, con_pi, con_tice + use machine, only : kind_phys use module_iounitdef, only : NIRADSF use surface_perturbation, only : ppfbet ! @@ -129,7 +127,7 @@ module module_radiation_surface real (kind=kind_phys), parameter :: f_zero = 0.0 real (kind=kind_phys), parameter :: f_one = 1.0 real (kind=kind_phys), parameter :: epsln = 1.0e-6 - real (kind=kind_phys), parameter :: rad2dg = 180.0 / con_pi + real (kind=kind_phys) :: rad2dg integer, allocatable :: idxems(:,:) ! global surface emissivity index array integer :: iemslw = 1 ! global surface emissivity control flag set up in 'sfc_init' ! @@ -146,7 +144,7 @@ module module_radiation_surface !>\section gen_sfc_init sfc_init General Algorithm !----------------------------------- subroutine sfc_init & - & ( me, errmsg, errflg )! --- inputs/outputs: + & ( me, ialbflg, iemsflg, semis_file, con_pi, errmsg, errflg )! --- inputs/outputs: ! ! =================================================================== ! ! ! @@ -160,11 +158,7 @@ subroutine sfc_init & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control flag ! -! ! -! outputs: (none) to module variables only ! -! ! -! external module variables: ! +! me - print control flag ! ! ialbflg - control flag for surface albedo schemes ! ! =1: use modis based surface albedo ! ! =2: use surface albedo from land model ! @@ -174,13 +168,18 @@ subroutine sfc_init & ! b:=1 use varying climtology sfc emiss (veg based) ! ! =2 use surface emissivity from land model ! ! ! +! outputs: (CCPP error handling) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! +! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs: - integer, intent(in) :: me - + integer, intent(in) :: me, ialbflg, iemsflg + real(kind=kind_phys), intent(in) :: con_pi + character(len=26), intent(in) :: semis_file ! --- outputs: ( none ) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -196,10 +195,13 @@ subroutine sfc_init & errmsg = '' errflg = 0 ! + ! Module + rad2dg = 180.0 / con_pi + if ( me == 0 ) print *, VTAGSFC ! print out version tag !> - Initialization of surface albedo section -!! \n physparam::ialbflg +!! \n GFS_typedefs::ialbflg !! - = 1: using MODIS based land surface albedo for SW !! - = 2: using albedo from land model @@ -224,7 +226,7 @@ subroutine sfc_init & endif ! end if_ialbflg_block !> - Initialization of surface emissivity section -!! \n physparam::iemsflg +!! \n GFS_typedefs::iemsflg !! - = 1: input SFC emissivity type map from "semis_file" !! - = 2: input SFC emissivity from land model @@ -339,8 +341,8 @@ subroutine setalb & & alvsf,alnsf,alvwf,alnwf,facsf,facwf,fice,tisfc, & & lsmalbdvis, lsmalbdnir, lsmalbivis, lsmalbinir, & & icealbdvis, icealbdnir, icealbivis, icealbinir, & - & IMAX, albPpert, pertalb, fracl, fraco, fraci, icy, & - & sfcalb & ! --- outputs: + & IMAX, albPpert, pertalb, fracl, fraco, fraci, icy, ialbflg,& + & con_ttp, sfcalb & ! --- outputs: & ) ! =================================================================== ! @@ -387,6 +389,9 @@ subroutine setalb & ! fice (IMAX) - sea-ice fraction ! ! tisfc (IMAX) - sea-ice surface temperature ! ! IMAX - array horizontal dimension ! +! ialbflg - control flag for surface albedo schemes ! +! =1: use modis based surface albedo ! +! =2: use surface albedo from land model ! ! ! ! outputs: ! ! sfcalb(IMAX,NF_ALBD) ! @@ -395,17 +400,12 @@ subroutine setalb & ! ( :, 3) - uv+vis direct beam albedo ! ! ( :, 4) - uv+vis diffused albedo ! ! ! -! module internal control variables: ! -! ialbflg - =0 use the default climatology surface albedo ! -! =1 use modis retrieved albedo and input snow cover! -! for land areas ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs - integer, intent(in) :: IMAX + integer, intent(in) :: IMAX, ialbflg integer, intent(in) :: lsm, lsm_noahmp, lsm_ruc logical, intent(in) :: use_cice_alb, frac_grid @@ -415,7 +415,7 @@ subroutine setalb & & alvsf, alnsf, alvwf, alnwf, facsf, facwf, fice, tisfc, & & icealbdvis, icealbdnir, icealbivis, icealbinir, & & sncovr, sncovr_ice, snoalb, albPpert ! sfc-perts, mgehne - real (kind=kind_phys), intent(in) :: pertalb ! sfc-perts, mgehne + real (kind=kind_phys), intent(in) :: pertalb, con_ttp! sfc-perts, mgehne real (kind=kind_phys), dimension(:), intent(in) :: & & fracl, fraco, fraci real (kind=kind_phys), dimension(:),intent(inout) :: & From 9f9ed2ab0f4c4ab054b8999697f57beff4af6219 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 17 Aug 2022 13:56:02 -0600 Subject: [PATCH 12/58] Remove dependency on physcons and physparam in radiation_gases.f. Provided as ccpp interstitials. --- physics/GFS_rrtmg_pre.F90 | 13 +-- physics/GFS_rrtmg_pre.meta | 7 ++ physics/GFS_rrtmg_setup.F90 | 85 ++++++++------- physics/GFS_rrtmg_setup.meta | 53 ++++++++++ physics/GFS_rrtmgp_pre.F90 | 10 +- physics/GFS_rrtmgp_pre.meta | 15 +++ physics/GFS_rrtmgp_setup.F90 | 29 +++--- physics/GFS_rrtmgp_setup.meta | 53 ++++++++++ physics/physparam.f | 13 --- physics/radiation_gases.f | 188 ++++++---------------------------- 10 files changed, 228 insertions(+), 238 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 9fd2a092c..57e0b4347 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -45,7 +45,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & aero_dir_fdb, smoke_ext, dust_ext, & - spp_wts_rad, spp_rad, rrfs_smoke_band, top_at_1, errmsg, errflg) + spp_wts_rad, spp_rad, rrfs_smoke_band, top_at_1, ico2, errmsg, errflg) use machine, only: kind_phys @@ -111,7 +111,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & idcor_con, & idcor_hogan, & idcor_oreopoulos, & - rrfs_smoke_band ! Band number for rrfs-smoke dust and smoke + rrfs_smoke_band, & ! Band number for rrfs-smoke dust and smoke + ico2 ! Flag for co2 source used in radiation integer, intent(in) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, ntss3, & ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, ntchm @@ -422,8 +423,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & enddo enddo else ! climatological ozone - call getozn (prslk1, xlat, im, lmk, & ! --- inputs - olyr) ! --- outputs + call getozn (prslk1, xlat, im, lmk, top_at_1, & ! --- inputs + olyr) ! --- outputs endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) @@ -447,8 +448,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & ! --- ... set up non-prognostic gas volume mixing ratioes - call getgases (plvl, xlon, xlat, IM, LMK, & ! --- inputs - gasvmr) ! --- outputs + call getgases (plvl, xlon, xlat, IM, LMK, ico2, top_at_1,& ! --- inputs + con_pi, gasvmr) ! --- outputs !CCPP: re-assign gasvmr(:,:,NF_VGAS) to gasvmr_X(:,:) do k = 1, LMK diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 0c2240720..8fa020ec5 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1343,6 +1343,13 @@ dimensions = () type = logical intent = out +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in [aero_dir_fdb] standard_name = do_smoke_aerosol_direct_feedback long_name = flag for smoke and dust radiation feedback diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index a8d829e12..f83f53f01 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -6,7 +6,7 @@ !> @{ module GFS_rrtmg_setup - use physparam, only : ictmflg, ico2flg, ioznflg, icldflg, & + use physparam, only : icldflg, & & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & & isubcsw, isubclw, ivflip , ipsd0, & & iswcliq @@ -34,7 +34,7 @@ module GFS_rrtmg_setup !> control flag for the first time of reading climatological ozone data !! (set/reset in subroutines radinit/radupdate, it is used only if the - !! control parameter ioznflg=0) + !! control parameter ntoz=0) logical :: loz1st = .true. contains @@ -50,7 +50,8 @@ subroutine GFS_rrtmg_setup_init ( & norad_precip, idate, iflip, & do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & aeros_file, con_pi, con_t0c, con_c, con_boltz, & - con_plnk, con_solr_2008, con_solr_2002, errmsg, errflg) + con_plnk, con_solr_2008, con_solr_2002, co2usr_file,& + co2cyc_file, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -171,7 +172,7 @@ subroutine GFS_rrtmg_setup_init ( & integer, intent(in) :: iflip logical, intent(in) :: do_RRTMGP, lalw1bd integer, intent(in) :: me - character(len=26),intent(in) :: aeros_file, solar_file + character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file, co2cyc_file real(kind_phys), intent(in) :: con_pi,con_t0c,con_c,con_boltz,con_plnk,con_solr_2008,con_solr_2002 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -189,10 +190,6 @@ subroutine GFS_rrtmg_setup_init ( & return end if - ictmflg= ictm ! data ic time/date control flag - ico2flg= ico2 ! co2 data source control flag - ioznflg= ntoz ! ozone data source control flag - if ( ictm==0 .or. ictm==-2 ) then iaerflg = mod(iaer, 100) ! no volcanic aerosols for clim hindcast else @@ -246,12 +243,11 @@ subroutine GFS_rrtmg_setup_init ( & endif call radinit & -! --- inputs: & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & - & isol, solar_file, con_solr_2008, con_solr_2002, errmsg, errflg ) -! --- outputs: -! ( none ) + & isol, solar_file, con_solr_2008, con_solr_2002, & + & co2usr_file, co2cyc_file, ico2, ictm, ntoz, errmsg, errflg ) + if ( me == 0 ) then print *,' Radiation sub-cloud initial seed =',ipsd0, & @@ -268,9 +264,9 @@ end subroutine GFS_rrtmg_setup_init !> \section arg_table_GFS_rrtmg_setup_timestep_init Argument Table !! \htmlinclude GFS_rrtmg_setup_timestep_init.html !! - subroutine GFS_rrtmg_setup_timestep_init ( & - idate, jdate, deltsw, deltim, lsswr, me, iaermdl, & - iaerflg, isol, aeros_file, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) + subroutine GFS_rrtmg_setup_timestep_init (idate, jdate, deltsw, deltim, & + lsswr, me, iaermdl, iaerflg, isol, aeros_file, slag, sdec, cdec, & + solcon, con_pi, co2dat_file, co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) implicit none @@ -282,8 +278,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & real(kind=kind_phys), intent(in) :: con_pi logical, intent(in) :: lsswr integer, intent(in) :: me - integer, intent(in) :: iaermdl, iaerflg, isol - character(len=26), intent(in) :: aeros_file + integer, intent(in) :: iaermdl, iaerflg, isol, ictm, ico2, ntoz + character(len=26), intent(in) :: aeros_file, co2dat_file, co2gbl_file real(kind=kind_phys), intent(out) :: slag real(kind=kind_phys), intent(out) :: sdec real(kind=kind_phys), intent(out) :: cdec @@ -302,8 +298,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & errmsg = '' errflg = 0 - call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl,& - iaerflg,isol,aeros_file,slag,sdec,cdec,solcon,con_pi,errflg,errmsg) + call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl, iaerflg,isol,aeros_file,& + slag,sdec,cdec,solcon,con_pi,co2dat_file,co2gbl_file,ictm,ico2,ntoz,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -335,7 +331,8 @@ end subroutine GFS_rrtmg_setup_finalize subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, isol, & - solar_file, con_solr_2008, con_solr_2002, errmsg, errflg) + solar_file, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & + ico2, ictm, ntoz, errmsg, errflg) !................................... ! --- inputs: @@ -379,11 +376,11 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & ! =2 compute tropspheric aero in multi bands for lw ! ! c:=0 no topospheric aerosol in sw radiation ! ! =1 include tropspheric aerosols for sw ! -! ico2flg : co2 data source control flag ! +! ico2 : co2 data source control flag ! ! =0: use prescribed global mean co2 (old oper) ! ! =1: use observed co2 annual mean value only ! ! =2: use obs co2 monthly data with 2-d variation ! -! ictmflg : =yyyy#, external data ic time/date control flag ! +! ictm : =yyyy#, external data ic time/date control flag ! ! = -2: same as 0, but superimpose seasonal cycle ! ! from climatology data set. ! ! = -1: use user provided external data for the ! @@ -448,11 +445,11 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & implicit none ! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, isol + integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, isol, ico2, ictm, ntoz logical, intent(in) :: lalw1bd real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, & con_boltz, con_plnk, con_solr_2008, con_solr_2002 - character(len=26), intent(in) :: aeros_file, solar_file + character(len=26), intent(in) :: aeros_file, solar_file,co2usr_file, co2cyc_file ! --- outputs: (ccpp error handling) character(len=*), intent(out) :: errmsg @@ -464,7 +461,7 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & ! !> -# Set up control variables and external module variables in !! module physparam - loz1st = (ioznflg == 0) ! first-time clim ozone data read flag + loz1st = (ntoz == 0) ! first-time clim ozone data read flag month0 = 0 iyear0 = 0 monthd = 0 @@ -474,16 +471,16 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & print *,' NEW RADIATION PROGRAM STRUCTURES BECAME OPER. ', & & ' May 01 2007' print *, VTAGRAD !print out version tag - print *,' - Selected Control Flag settings: ICTMflg=',ictmflg, & - & ' ISOLar =',isol, ' ICO2flg=',ico2flg,' IAERflg=',iaerflg, & + print *,' - Selected Control Flag settings: ICTMflg=',ictm, & + & ' ISOLar =',isol, ' ICO2flg=',ico2,' IAERflg=',iaerflg, & & ' ICLDflg=',icldflg, & - & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ioznflg + & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ntoz print *,' IVFLIP=',ivflip,' IOVR=',iovrRad, & & ' ISUBCSW=',isubcsw,' ISUBCLW=',isubclw print *,' LCRICK=',lcrick,' LCNORM=',lcnorm,' LNOPREC=',lnoprec print *,' LTP =',ltp,', add extra top layer =',lextop - if ( ictmflg==0 .or. ictmflg==-2 ) then + if ( ictm==0 .or. ictm==-2 ) then print *,' Data usage is limited by initial condition!' print *,' No volcanic aerosols' endif @@ -544,13 +541,14 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & ! Initialization call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002,& - con_pi ) ! astronomy initialization routine + con_pi ) ! astronomy initialization routine call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine - call gas_init ( me, errflg, errmsg ) ! co2 and other gases initialization routine - call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! cloud initialization routine - call rlwinit ( me, errflg, errmsg ) ! lw RRTMG initialization routine - call rswinit ( me, errflg, errmsg ) ! sw RRTMG initialization routine + con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, & + errflg, errmsg) ! co2 and other gases initialization routine + call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! cloud initialization routine + call rlwinit ( me, errflg, errmsg ) ! lw RRTMG initialization routine + call rswinit ( me, errflg, errmsg ) ! sw RRTMG initialization routine ! return ! @@ -578,8 +576,8 @@ end subroutine radinit !> \section gen_radupdate General Algorithm !----------------------------------- subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& - & iaerflg, isol, aeros_file, slag,sdec,cdec,solcon, & - & con_pi, errflg,errmsg) + iaerflg, isol, aeros_file, slag,sdec,cdec,solcon, con_pi, & + co2dat_file,co2gbl_file, ictm, ico2, ntoz, errflg, errmsg) !................................... ! ================= subprogram documentation block ================ ! @@ -619,7 +617,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! = 2: use noaa ann-mean tsi tbl tim-scale with cycle apprx! ! = 3: use cmip5 ann-mean tsi tbl tim-scale with cycl apprx! ! = 4: use cmip5 mon-mean tsi tbl tim-scale with cycl apprx! -! ictmflg : =yyyy#, external data ic time/date control flag ! +! ictm : =yyyy#, external data ic time/date control flag ! ! = -2: same as 0, but superimpose seasonal cycle ! ! from climatology data set. ! ! = -1: use user provided external data for the ! @@ -647,9 +645,9 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& implicit none ! --- inputs: - integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg, isol + integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg, isol, ictm, ntoz, ico2 logical, intent(in) :: lsswr - character(len=26),intent(in) :: aeros_file + character(len=26),intent(in) :: aeros_file,co2dat_file,co2gbl_file real (kind=kind_phys), intent(in) :: deltsw, deltim, con_pi @@ -684,7 +682,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! --- ... set up time stamp used for green house gases (** currently co2 only) - if ( ictmflg==0 .or. ictmflg==-2 ) then ! get external data at initial condition time + if ( ictm==0 .or. ictm==-2 ) then ! get external data at initial condition time kyear = idate(1) kmon = idate(2) kday = idate(3) @@ -694,7 +692,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& kmon = imon kday = iday khour = ihour - endif ! end if_ictmflg_block + endif ! end if_ictm_block if ( month0 /= imon ) then lmon_chg = .true. @@ -740,7 +738,8 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& lco2_chg = .false. endif - call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me, errflg, errmsg ) + call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 71f1e2ff7..e65795887 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -195,6 +195,22 @@ type = character kind = len=26 intent = in +[co2usr_file] + standard_name = co2_user_data_table_file + long_name = co2 user defined data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2cyc_file] + standard_name = co2_clim_monthly_cycle_data_table_file + long_name = co2 climotological monthly cycle data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in [con_pi] standard_name = pi long_name = ratio of a circle's circumference to its diameter @@ -349,6 +365,43 @@ type = character kind = len=26 intent = in +[co2dat_file] + standard_name = co2_monthly_obs_data_table_file + long_name = co2 monthly observation data table + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2gbl_file] + standard_name = co2_global_annual_mean_data_table_file + long_name = co2 global annual mean data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[ictm] + standard_name = flag_for_initial_time_date_control + long_name = flag for initial conditions and forcing + units = flag + dimensions = () + type = integer + intent = in +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [con_pi] standard_name = pi long_name = ratio of a circle's circumference to its diameter diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 755b977b3..9822aaf74 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -116,14 +116,15 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, minGPpres, maxGPpres, minGPtemp, & maxGPtemp, raddt, p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, qs_lay, q_lay, tv_lay, & relhum, tracer, deltaZ, deltaZc, deltaP, active_gases_array, gas_concentrations, & - tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, errmsg, errflg) + tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, ico2, con_pi, errmsg, errflg) ! Inputs integer, intent(in) :: & nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers nTracers, & ! Number of tracers from model. - i_o3 ! Index into tracer array for ozone + i_o3, & ! Index into tracer array for ozone + ico2 ! Flag for co2 radiation scheme logical, intent(in) :: & lsswr, & ! Call SW radiation? lslwr ! Call LW radiation @@ -141,6 +142,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw con_epsm1, & ! Physical constant: Epsilon (Rd/Rv) minus one con_fvirt, & ! Physical constant: Inverse of epsilon minus one con_epsqs, & ! Physical constant: Minimum saturation mixing-ratio (kg/kg) + con_pi, & ! Physical constant: Pi solhr ! Time in hours after 00z at the current timestep real(kind_phys), dimension(:), intent(in) :: & xlon, & ! Longitude @@ -350,14 +352,14 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw enddo ! OR Use climatological ozone data else - call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, o3_lay) + call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, o3_lay) endif ! ####################################################################################### ! Set gas concentrations for RRTMGP ! ####################################################################################### ! Call getgases(), to set up non-prognostic gas volume mixing ratios (gas_vmr). - call getgases (p_lev/100., xlon, xlat, nCol, nLev, gas_vmr) + call getgases (p_lev/100., xlon, xlat, nCol, nLev, ico2, top_at_1, con_pi, gas_vmr) ! Compute volume mixing-ratios for ozone (mmr) and specific-humidity. vmr_h2o = merge((q_lay/(1-q_lay))*amdw, 0., q_lay .ne. 1.) diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 88face855..86645cb1a 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -252,6 +252,14 @@ type = real kind = kind_phys intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [minGPpres] standard_name = minimum_pressure_in_RRTMGP long_name = minimum pressure allowed in RRTMGP @@ -284,6 +292,13 @@ type = real kind = kind_phys intent = in +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in [raddt] standard_name = time_step_for_radiation long_name = radiation time step diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index baaf2fcdc..935500739 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -9,7 +9,7 @@ module GFS_rrtmgp_setup ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize ! *NOTE* These parameters below are required radiation_****** modules. They are not ! directly used by the RRTMGP routines. - use physparam, only : ictmflg, ico2flg, ioznflg, ivflip + use physparam, only : ivflip implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize @@ -27,7 +27,7 @@ module GFS_rrtmgp_setup is_initialized = .false. ! Control flag for the first time of reading climatological ozone data ! (set/reset in subroutines GFS_rrtmgp_setup_init/GFS_rrtmgp_setup_timestep_init, it is used only if - ! the control parameter ioznflg=0) + ! the control parameter ntoz=0) logical :: loz1st = .true. contains @@ -42,7 +42,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, con_pi, & con_t0c, con_c, con_boltz, con_plnk, solar_file, con_solr_2008, con_solr_2002, & - errmsg, errflg) + co2usr_file, co2cyc_file, errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -66,7 +66,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, crick_proof, ccnorm, norad_precip, lalw1bd integer, intent(in), dimension(:) :: & idate - character(len=26),intent(in) :: aeros_file, solar_file + character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file, co2cyc_file ! Outputs character(len=*), intent(out) :: errmsg @@ -87,9 +87,6 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, end if ! Set radiation parameters - ictmflg = ictm ! data ic time/date control flag - ico2flg = ico2 ! co2 data source control flag - ioznflg = ntoz ! ozone data source control flag ivflip = iflip ! vertical index direction control flag if ( ictm==0 .or. ictm==-2 ) then @@ -123,7 +120,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ' me = ',me endif - loz1st = (ioznflg == 0) ! first-time clim ozone data read flag + loz1st = (ntoz == 0) ! first-time clim ozone data read flag month0 = 0 iyear0 = 0 monthd = 0 @@ -140,7 +137,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, errflg, errmsg ) + call gas_init ( me, co2usr_file, co2cyc_file, ictm, ntoz, ico2, con_pi, errflg, errmsg ) !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& @@ -161,8 +158,9 @@ end subroutine GFS_rrtmgp_setup_init !> \section arg_table_GFS_rrtmgp_setup_timestep_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! - subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, iaermdl,& - aeros_file, isol, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) + subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, & + iaermdl, aeros_file, isol, slag, sdec, cdec, solcon, con_pi, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) @@ -172,8 +170,8 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, real(kind_phys), intent(in) :: con_pi logical, intent(in) :: lsswr integer, intent(in) :: me - integer, intent(in) :: iaermdl,isol - character(len=26), intent(in) :: aeros_file + integer, intent(in) :: iaermdl,isol,ictm,ico2,ntoz + character(len=26), intent(in) :: aeros_file,co2dat_file,co2gbl_file ! Outputs real(kind_phys), intent(out) :: slag @@ -209,7 +207,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, ! Set up time stamp used for green house gases (** currently co2 only) ! get external data at initial condition time - if ( ictmflg==0 .or. ictmflg==-2 ) then + if ( ictm==0 .or. ictm==-2 ) then kyear = idate(1) kmon = idate(2) kday = idate(3) @@ -254,7 +252,8 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, else lco2_chg = .false. endif - call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me, errflg, errmsg ) + call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 6e8d296e3..4f8fe1db4 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -285,6 +285,22 @@ type = real kind = kind_phys intent = in +[co2usr_file] + standard_name = co2_user_data_table_file + long_name = co2 user defined data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2cyc_file] + standard_name = co2_clim_monthly_cycle_data_table_file + long_name = co2 climotological monthly cycle data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in [iaermdl] standard_name = flag_for_aerosol_radiation_scheme long_name = flag for aerosol scheme to use in radiation @@ -371,6 +387,43 @@ type = character kind = len=26 intent = in +[co2dat_file] + standard_name = co2_monthly_obs_data_table_file + long_name = co2 monthly observation data table + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2gbl_file] + standard_name = co2_global_annual_mean_data_table_file + long_name = co2 global annual mean data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[ictm] + standard_name = flag_for_initial_time_date_control + long_name = flag for initial conditions and forcing + units = flag + dimensions = () + type = integer + intent = in +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [iaermdl] standard_name = flag_for_aerosol_radiation_scheme long_name = flag for aerosol scheme to use in radiation diff --git a/physics/physparam.f b/physics/physparam.f index 880ed47f3..0dd53a304 100644 --- a/physics/physparam.f +++ b/physics/physparam.f @@ -153,19 +153,6 @@ module physparam !! variable at initial time) integer, save :: ioznflg = 1 -!> external co2 2d monthly obsv data table: co2historicaldata_2004.txt - character, save :: co2dat_file*26 -!> external co2 global annual mean data tb: co2historicaldata_glob.txt - character, save :: co2gbl_file*26 -!> external co2 user defined data table: co2userdata.txt - character, save :: co2usr_file*26 -!> external co2 clim monthly cycle data tb: co2monthlycyc.txt - character, save :: co2cyc_file*26 - data co2dat_file / 'co2historicaldata_2004.txt' / !year is run-time selected - data co2gbl_file / 'co2historicaldata_glob.txt' / - data co2usr_file / 'co2userdata.txt ' / - data co2cyc_file / 'co2monthlycyc.txt ' / - ! ............................................. ! !>\name 2.4 For module radiation_clouds ! ............................................. ! diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index 01048c5eb..b5eb8ffb9 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -44,7 +44,6 @@ ! external modules referenced: ! ! 'module machine' in 'machine.f' ! ! 'module funcphys' in 'funcphys.f' ! -! 'module physcons' in 'physcons.f ! ! 'module module_iounitdef' in 'iounitdef.f' ! ! ! ! unit used for radiative active gases: ! @@ -141,13 +140,8 @@ !> This module sets up ozone climatological profiles and other constant gas !! profiles, such as co2, ch4, n2o, o2, and those of cfc gases. module module_radiation_gases -! - use physparam, only : ico2flg, ictmflg, ioznflg, ivflip, & - & co2dat_file, co2gbl_file, & - & co2usr_file, co2cyc_file, & - & kind_phys, kind_io4 + use machine, only : kind_phys, kind_io4 use funcphys, only : fpkapx - use physcons, only : con_pi use ozne_def, only : JMR => latsozc, LOZ => levozc, & & blte => blatc, dlte=> dphiozc, & & timeozc => timeozc @@ -168,9 +162,9 @@ module module_radiation_gases integer, parameter :: MINYEAR = 1957 ! earlist year 2D CO2 data available real (kind=kind_phys), parameter :: resco2=15.0 ! horizontal resolution in degree - real (kind=kind_phys), parameter :: raddeg=180.0/con_pi ! rad->deg conversion real (kind=kind_phys), parameter :: prsco2=788.0 ! pressure limitation for 2D CO2 (mb) - real (kind=kind_phys), parameter :: hfpi =0.5*con_pi ! half of pi + real (kind=kind_phys) :: raddeg ! rad->deg conversion + real (kind=kind_phys) :: hfpi ! half of pi real (kind=kind_phys), parameter :: co2vmr_def = 350.0e-6 ! parameter constant for CO2 volume mixing ratio real (kind=kind_phys), parameter :: n2ovmr_def = 0.31e-6 ! parameter constant for N2O volume mixing ratio @@ -230,45 +224,22 @@ module module_radiation_gases !!\param me print message control flag !>\section gas_init_gen gas_init General Algorithm !----------------------------------- - subroutine gas_init & - & ( me , errflg, errmsg) + subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & + & ictmflg, ioznflg, con_pi, errflg, errmsg) ! =================================================================== ! ! ! ! gas_init sets up ozone, co2, etc. parameters. if climatology ozone ! ! then read in monthly ozone data. ! ! ! -! inputs: dimemsion ! -! me - print message control flag 1 ! +! inputs: ! +! me - print message control flag ! +! co2usr_file - external co2 user defined data table ! +! co2cyc_file - external co2 climotology monthly cycle data table ! ! ! ! outputs: (CCPP error handling) ! ! (errflg, errmsg) ! ! ! -! external module variables: (in physparam) ! -! ico2flg - co2 data source control flag ! -! =0: use prescribed co2 global mean value ! -! =1: use input global mean co2 value (co2_glb) ! -! =2: use input 2-d monthly co2 value (co2vmr_sav) ! -! ictmflg - =yyyy#, data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the fcst ! -! time, no extrapolation. ! -! = 0: use data at initial cond time, if not existed! -! then use latest, without extrapolation. ! -! = 1: use data at the forecast time, if not existed! -! then use latest and extrapolate to fcst time.! -! =yyyy0: use yyyy data for the forecast time, no ! -! further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! -! =0: use climatological ozone profile ! -! >0: use interactive ozone profile ! -! ivflip - vertical profile indexing flag ! -! co2usr_file- external co2 user defined data table ! -! co2cyc_file- external co2 climotology monthly cycle data table ! -! ! ! internal module variables: ! ! pkstr, o3r - arrays for climatology ozone data ! ! ! @@ -281,8 +252,9 @@ subroutine gas_init & implicit none ! --- inputs: - integer, intent(in) :: me - + integer, intent(in) :: me, ictmflg, ioznflg, ico2flg + character(len=26),intent(in) :: co2usr_file,co2cyc_file + real(kind=kind_phys), intent(in) :: con_pi ! --- output: character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -306,6 +278,10 @@ subroutine gas_init & errmsg = '' errflg = 0 +! Initiailize module parameters + raddeg = 180.0/con_pi + hfpi = 0.5*con_pi + if ( me == 0 ) print *, VTAGGAS ! print out version tag kyrsav = 0 @@ -541,8 +517,8 @@ end subroutine gas_init !!\param me print message control flag !>\section gen_gas_update gas_update General Algorithm !----------------------------------- - subroutine gas_update & - & ( iyear, imon, iday, ihour, loz1st, ldoco2, me, & + subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & + & me, co2dat_file, co2gbl_file, ictmflg, ico2flg, ioznflg, & & errflg, errmsg ) ! =================================================================== ! @@ -550,52 +526,6 @@ subroutine gas_update & ! gas_update reads in 2-d monthly co2 data set for a specified year. ! ! data are in a 15 degree lat/lon horizontal resolution. ! ! ! -! inputs: dimemsion ! -! iyear - year of the requested data for fcst 1 ! -! imon - month of the year 1 ! -! iday - day of the month 1 ! -! ihour - hour of the day 1 ! -! loz1st - clim ozone 1st time update control flag 1 ! -! ldoco2 - co2 update control flag 1 ! -! me - print message control flag 1 ! -! ! -! outputs: (to the module variables) ! -! errflg - CCPP error flag ! -! errmsg - CCPP error message ! -! ! -! external module variables: (in physparam) ! -! ico2flg - co2 data source control flag ! -! =0: use prescribed co2 global mean value ! -! =1: use input global mean co2 value (co2_glb) ! -! =2: use input 2-d monthly co2 value (co2vmr_sav) ! -! ictmflg - =yyyy#, data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the fcst ! -! time, no extrapolation. ! -! = 0: use data at initial cond time, if not existed! -! then use latest, without extrapolation. ! -! = 1: use data at the forecast time, if not existed! -! then use latest and extrapolate to fcst time.! -! =yyyy0: use yyyy data for the forecast time, no ! -! further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! -! =0: use climatological ozone profile ! -! >0: use interactive ozone profile ! -! ivflip - vertical profile indexing flag ! -! co2dat_file- external co2 2d monthly obsv data table ! -! co2gbl_file- external co2 global annual mean data table ! -! ! -! internal module variables: ! -! co2vmr_sav - monthly co2 volume mixing ratio IMXCO2*JMXCO2*12 ! -! co2cyc_sav - monthly cycle co2 vol mixing ratio IMXCO2*JMXCO2*12 ! -! co2_glb - global annual mean co2 mixing ratio ! -! gco2cyc - global monthly mean co2 variation 12 ! -! k1oz,k2oz,facoz ! -! - climatology ozone parameters 1 ! -! ! ! usage: call gas_update ! ! ! ! subprograms called: none ! @@ -605,8 +535,9 @@ subroutine gas_update & implicit none ! --- inputs: - integer, intent(in) :: iyear, imon, iday, ihour, me - + integer, intent(in) :: iyear,imon,iday,ihour,me,ictmflg,ico2flg + integer, intent(in) :: ioznflg + character(len=26),intent(in) :: co2dat_file, co2gbl_file logical, intent(in) :: loz1st, ldoco2 ! --- output: @@ -760,6 +691,7 @@ subroutine gas_update & ! --- ... set up input data file name + print*,"co2dat_file: ",co2dat_file cfile1 = co2dat_file write(cfile1(19:22),34) idyr 34 format(i4.4) @@ -948,11 +880,8 @@ end subroutine gas_update !!\n (:,:,10) - cfc113 !>\section gen_getgases getgases General Algorithm !----------------------------------- - subroutine getgases & - & ( plvl, xlon, xlat, & ! --- inputs - & IMAX, LMAX, & - & gasdat & ! --- outputs - & ) + subroutine getgases( plvl, xlon, xlat, IMAX, LMAX, ico2flg, & + & top_at_1, con_pi, gasdat) ! =================================================================== ! ! ! ! getgases set up global distribution of radiation absorbing gases ! @@ -960,45 +889,6 @@ subroutine getgases & ! observed values, all other gases are asigned to the climatological ! ! values. ! ! ! -! inputs: ! -! plvl(IMAX,LMAX+1)- pressure at model layer interfaces (mb) ! -! xlon(IMAX) - grid longitude in radians, ok both 0->2pi or ! -! -pi -> +pi arrangements ! -! xlat(IMAX) - grid latitude in radians, default range to ! -! pi/2 -> -pi/2, otherwise see in-line comment ! -! IMAX, LMAX - horiz, vert dimensions for output data ! -! ! -! outputs: ! -! gasdat(IMAX,LMAX,NF_VGAS) - gases volume mixing ratioes ! -! (:,:,1) - co2 ! -! (:,:,2) - n2o ! -! (:,:,3) - ch4 ! -! (:,:,4) - o2 ! -! (:,:,5) - co ! -! (:,:,6) - cfc11 ! -! (:,:,7) - cfc12 ! -! (:,:,8) - cfc22 ! -! (:,:,9) - ccl4 ! -! (:,:,10) - cfc113 ! -! ! -!> - External module variables: (in physparam) -!!\n ico2flg - co2 data source control flag -!!\n =0: use prescribed co2 global mean value -!!\n =1: use input global mean co2 value (co2_glb) -!!\n =2: use input 2-d monthly co2 value (co2vmr_sav) -!!\n ivflip - vertical profile indexing flag -!! -!> - Internal module variables : -!!\n co2vmr_sav - saved monthly co2 concentration from sub gas_update -!!\n co2_glb - saved global annual mean co2 value from gas_update -!!\n gco2cyc - saved global seasonal variation of co2 climatology -!! in 12-month form -!note: for lower atmos co2vmr_sav may have clim monthly deviations ! -! superimposed on init-cond co2 value, while co2_glb only ! -! contains the global mean value, thus needs to add the ! -! monthly dglobal mean deviation gco2cyc at upper atmos. for ! -! ictmflg/=-2, this value will be zero. ! -! ! ! usage: call getgases ! ! ! ! subprograms called: none ! @@ -1008,8 +898,10 @@ subroutine getgases & implicit none ! --- input: - integer, intent(in) :: IMAX, LMAX + integer, intent(in) :: IMAX, LMAX, ico2flg real (kind=kind_phys), intent(in) :: plvl(:,:), xlon(:), xlat(:) + logical, intent(in) :: top_at_1 + real(kind=kind_phys), intent(in) :: con_pi ! --- output: real (kind=kind_phys), intent(out) :: gasdat(:,:,:) @@ -1063,7 +955,7 @@ subroutine getgases & ilon = min( IMXCO2, int( xlon1*tmp + 1 )) ilat = min( JMXCO2, int( xlat1*tmp + 1 )) - if ( ivflip == 0 ) then ! index from toa to sfc + if (top_at_1) then ! index from toa to sfc do k = 1, LMAX if ( plvl(i,k) >= prsco2 ) then gasdat(i,k,1) = co2vmr_sav(ilon,ilat,kmonsav) @@ -1099,11 +991,7 @@ end subroutine getgases !! ratio (g/g) !>\section getozn_gen getozn General Algorithm !----------------------------------- - subroutine getozn & - & ( prslk,xlat, & ! --- inputs - & IMAX, LM, & - & o3mmr & ! --- outputs - & ) + subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, o3mmr) ! =================================================================== ! ! ! @@ -1111,20 +999,6 @@ subroutine getozn & ! ! ! this code is originally written By Shrinivas Moorthi ! ! ! -! inputs: ! -! prslk (IMAX,LM) - exner function = (p/p0)**rocp ! -! xlat (IMAX) - latitude in radians, default to pi/2 -> -pi/2 ! -! range, otherwise see in-line comment ! -! IMAX, LM - horizontal and vertical dimensions ! -! ! -! outputs: ! -! o3mmr (IMAX,LM) - output ozone profile in mass mixing ratio (g/g)! -! ! -! module variables: ! -! k1oz, k2oz - ozone data interpolation indices ! -! facoz - ozone data interpolation factor ! -! ivflip - control flag for direction of vertical index ! -! ! ! usage: call getozn ! ! ! ! =================================================================== ! @@ -1133,7 +1007,7 @@ subroutine getozn & ! --- inputs: integer, intent(in) :: IMAX, LM - + logical, intent(in) :: top_at_1 real (kind=kind_phys), intent(in) :: prslk(:,:), xlat(:) ! --- outputs: @@ -1177,7 +1051,7 @@ subroutine getozn & do l = 1, LM ll = l - if (ivflip == 1) ll = LM -l + 1 + if (.not. top_at_1) ll = LM -l + 1 do i = 1, IMAX wk1(i) = prslk(i,ll) From c0d2d20b4f5c50a9766dc4d4fb5e95c805b7b716 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 18 Aug 2022 11:51:14 -0600 Subject: [PATCH 13/58] Remove dependency on physparam in radlw_main/radsw_main.F90. Provided as ccpp interstitials. --- physics/GFS_radiation_surface.meta | 2 +- physics/GFS_rrtmg_setup.F90 | 74 ++++----- physics/GFS_rrtmg_setup.meta | 39 ++++- physics/radiation_cloud_overlap.F90 | 2 +- physics/radiation_clouds.f | 42 ++--- physics/radlw_datatb.f | 38 ++--- physics/radlw_main.F90 | 169 ++++++++------------ physics/radlw_main.meta | 42 +++++ physics/radlw_param.f | 2 +- physics/radsw_datatb.f | 34 ++-- physics/radsw_main.F90 | 234 +++++++++++----------------- physics/radsw_main.meta | 51 +++++- physics/radsw_param.f | 2 +- 13 files changed, 363 insertions(+), 368 deletions(-) diff --git a/physics/GFS_radiation_surface.meta b/physics/GFS_radiation_surface.meta index 8ad848446..56303f995 100644 --- a/physics/GFS_radiation_surface.meta +++ b/physics/GFS_radiation_surface.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_radiation_surface type = scheme - dependencies = iounitdef.f,machine.F,physparam.f,radiation_surface.f,set_soilveg_ruc.F90,namelist_soilveg_ruc.F90 + dependencies = iounitdef.f,machine.F,radiation_surface.f,set_soilveg_ruc.F90,namelist_soilveg_ruc.F90 ######################################################################## [ccpp-arg-table] diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index f83f53f01..6891b0f24 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -6,10 +6,9 @@ !> @{ module GFS_rrtmg_setup - use physparam, only : icldflg, & - & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & - & isubcsw, isubclw, ivflip , ipsd0, & - & iswcliq + use physparam, only : lcrick , lcnorm , lnoprec, & + & ivflip , ipsd0, & + & iswcliq,iovrRad=>iovr use machine, only: kind_phys use radcons, only: ltp, lextop @@ -44,14 +43,15 @@ module GFS_rrtmg_setup !! subroutine GFS_rrtmg_setup_init ( & si, levr, ictm, isol, solar_file, ico2, iaer, ntcw, & - num_p3d, npdf3d, ntoz, iovr, isubc_sw, isubc_lw, & + num_p3d, npdf3d, ntoz, iovr, & icliq_sw, crick_proof, ccnorm, & imp_physics, & norad_precip, idate, iflip, & do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & aeros_file, con_pi, con_t0c, con_c, con_boltz, & con_plnk, con_solr_2008, con_solr_2002, co2usr_file,& - co2cyc_file, errmsg, errflg) + co2cyc_file, rad_hr_units, inc_minor_gas, ilwcliq, & + iswcliq, isubcsw, isubclw, iswmode, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -128,8 +128,8 @@ subroutine GFS_rrtmg_setup_init ( & ! =1: max/ran overlapping clouds ! ! =2: maximum overlap clouds (mcica only) ! ! =3: decorrelation-length overlap (mcica only) ! -! =4: exponential overlap clouds -! isubc_sw/isubc_lw: sub-column cloud approx control flag (sw/lw rad) ! +! =4: exponential overlap clouds ! +! isubcsw/isubclw: sub-column cloud approx control flag (sw/lw rad) ! ! =0: with out sub-column cloud approximation ! ! =1: mcica sub-col approx. prescribed random seed ! ! =2: mcica sub-col approx. provided random seed ! @@ -161,8 +161,6 @@ subroutine GFS_rrtmg_setup_init ( & integer, intent(in) :: npdf3d integer, intent(in) :: ntoz integer, intent(in) :: iovr - integer, intent(in) :: isubc_sw - integer, intent(in) :: isubc_lw integer, intent(in) :: icliq_sw logical, intent(in) :: crick_proof logical, intent(in) :: ccnorm @@ -170,10 +168,13 @@ subroutine GFS_rrtmg_setup_init ( & logical, intent(in) :: norad_precip integer, intent(in) :: idate(:) integer, intent(in) :: iflip - logical, intent(in) :: do_RRTMGP, lalw1bd - integer, intent(in) :: me - character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file, co2cyc_file - real(kind_phys), intent(in) :: con_pi,con_t0c,con_c,con_boltz,con_plnk,con_solr_2008,con_solr_2002 + logical, intent(in) :: do_RRTMGP, lalw1bd, inc_minor_gas + integer, intent(in) :: me, rad_hr_units, ilwcliq, iswcliq, isubcsw, & + isubclw, iswmode + character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file,& + co2cyc_file + real(kind_phys), intent(in) :: con_pi, con_t0c, con_c, con_boltz, & + con_plnk, con_solr_2008, con_solr_2002 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg integer, intent(out) :: iaermdl, iaerflg @@ -203,28 +204,14 @@ subroutine GFS_rrtmg_setup_init ( & return endif -! if ( ntcw > 0 ) then - icldflg = 1 ! prognostic cloud optical prop scheme -! else -! icldflg = 0 ! no support for diag cloud opt prop scheme -! endif - - iswcliq = icliq_sw ! optical property for liquid clouds for sw - - ! iovr comes from the model. In the RRTMG implementation this is stored in phyrparam.f, - ! it comes in from the host-model and is set here. - ! In GP, iovr is passed directly into the routines. iovrRAD = iovr lcrick = crick_proof ! control flag for eliminating CRICK lcnorm = ccnorm ! control flag for in-cld condensate lnoprec = norad_precip ! precip effect on radiation flag (ferrier microphysics) - isubcsw = isubc_sw ! sub-column cloud approx flag in sw radiation - isubclw = isubc_lw ! sub-column cloud approx flag in lw radiation - ivflip = iflip ! vertical index direction control flag ! --- assign initial permutation seed for mcica cloud-radiation - if ( isubc_sw>0 .or. isubc_lw>0 ) then + if ( isubcsw>0 .or. isubclw>0 ) then ! ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) + ipsd0 ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) endif @@ -235,8 +222,8 @@ subroutine GFS_rrtmg_setup_init ( & print *,' levr=',levr,' ictm=',ictm,' isol=',isol,' ico2=',ico2,& & ' iaermdl=',iaermdl,' iaerflg=',iaerflg print *,' np3d=',num_p3d,' ntoz=',ntoz, & - & ' iovr=',iovr,' isubc_sw=',isubc_sw, & - & ' isubc_lw=',isubc_lw,' icliq_sw=',icliq_sw, & + & ' iovr=',iovr,' isubcsw=',isubcsw, & + & ' isubclw=',isubclw,' icliq_sw=',icliq_sw, & & ' iflip=',iflip,' me=',me print *,' crick_proof=',crick_proof, & & ' ccnorm=',ccnorm,' norad_precip=',norad_precip @@ -246,7 +233,9 @@ subroutine GFS_rrtmg_setup_init ( & & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & & isol, solar_file, con_solr_2008, con_solr_2002, & - & co2usr_file, co2cyc_file, ico2, ictm, ntoz, errmsg, errflg ) + & co2usr_file, co2cyc_file, ico2, ictm, ntoz, rad_hr_units, & + & inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, iovr, & + & iswmode, errmsg, errflg ) if ( me == 0 ) then @@ -332,7 +321,8 @@ end subroutine GFS_rrtmg_setup_finalize subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, isol, & solar_file, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & - ico2, ictm, ntoz, errmsg, errflg) + ico2, ictm, rad_hr_units, ntoz, inc_minor_gas, ilwcliq, iswcliq, & + isubcsw, isubclw, iovr, iswmode, errmsg, errflg) !................................... ! --- inputs: @@ -396,9 +386,6 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & ! ioznflg : ozone data source control flag ! ! =0: use climatological ozone profile ! ! =1: use interactive ozone profile ! -! icldflg : cloud optical property scheme control flag ! -! =0: use diagnostic cloud scheme ! -! =1: use prognostic cloud scheme (default) ! ! imp_physics : cloud microphysics scheme control flag ! ! =99 zhao/carr/sundqvist microphysics scheme ! ! =98 zhao/carr/sundqvist microphysics+pdf cloud&cnvc,cnvw ! @@ -445,8 +432,10 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & implicit none ! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, isol, ico2, ictm, ntoz - logical, intent(in) :: lalw1bd + integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, & + isol, ico2, ictm, ntoz, rad_hr_units, ilwcliq, iswcliq, isubcsw,& + isubclw, iovr, iswmode + logical, intent(in) :: lalw1bd, inc_minor_gas real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, & con_boltz, con_plnk, con_solr_2008, con_solr_2002 character(len=26), intent(in) :: aeros_file, solar_file,co2usr_file, co2cyc_file @@ -472,10 +461,9 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & & ' May 01 2007' print *, VTAGRAD !print out version tag print *,' - Selected Control Flag settings: ICTMflg=',ictm, & - & ' ISOLar =',isol, ' ICO2flg=',ico2,' IAERflg=',iaerflg, & - & ' ICLDflg=',icldflg, & + & ' ISOLar =',isol, ' ICO2flg=',ico2,' IAERflg=',iaerflg, & & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ntoz - print *,' IVFLIP=',ivflip,' IOVR=',iovrRad, & + print *,' IVFLIP=',ivflip,' IOVR=',iovr, & & ' ISUBCSW=',isubcsw,' ISUBCLW=',isubclw print *,' LCRICK=',lcrick,' LCNORM=',lcnorm,' LNOPREC=',lnoprec print *,' LTP =',ltp,', add extra top layer =',lextop @@ -547,8 +535,8 @@ subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, & errflg, errmsg) ! co2 and other gases initialization routine call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! cloud initialization routine - call rlwinit ( me, errflg, errmsg ) ! lw RRTMG initialization routine - call rswinit ( me, errflg, errmsg ) ! sw RRTMG initialization routine + call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, iovr, errflg, errmsg ) ! lw RRTMG initialization routine + call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, iovr, iswmode, errflg, errmsg ) ! sw RRTMG initialization routine ! return ! diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index e65795887..2355b91c2 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -110,20 +110,27 @@ dimensions = () type = integer intent = in -[isubc_sw] +[isubcsw] standard_name = flag_for_sw_clouds_grid_approximation long_name = flag for sw clouds sub-grid approximation units = flag dimensions = () type = integer intent = in -[isubc_lw] +[isubclw] standard_name = flag_for_lw_clouds_sub_grid_approximation long_name = flag for lw clouds sub-grid approximation units = flag dimensions = () type = integer intent = in +[iswmode] + standard_name = flag_for_sw_scattering_choice + long_name = flag for rrtmg shortwave scattering choice + units = flag + dimensions = () + type = integer + intent = in [icliq_sw] standard_name = control_for_shortwave_radiation_liquid_clouds long_name = sw optical property for liquid clouds @@ -211,6 +218,34 @@ type = character kind = len=26 intent = in +[rad_hr_units] + standard_name = flag_for_radiation_heating_rate_units + long_name = flag to control heating rate units + units = count + dimensions = () + type = integer + intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[ilwcliq] + standard_name = flag_for_rrtmg_lw_cloud_optics + long_name = flag for rrtmg longwave cloud optics + units = flag + dimensions = () + type = integer + intent = in +[iswcliq] + standard_name = flag_for_rrtmg_sw_cloud_optics + long_name = flag for rrtmg shortwave cloud optics + units = flag + dimensions = () + type = integer + intent = in [con_pi] standard_name = pi long_name = ratio of a circle's circumference to its diameter diff --git a/physics/radiation_cloud_overlap.F90 b/physics/radiation_cloud_overlap.F90 index d6169b3e5..737b9be61 100644 --- a/physics/radiation_cloud_overlap.F90 +++ b/physics/radiation_cloud_overlap.F90 @@ -4,7 +4,7 @@ !>\defgroup rad_cld_ovr_mod Radiation Cloud Overlap Module !! This module contains the calculation of cloud overlap parameters for both RRTMG and RRTMGP. module module_radiation_cloud_overlap - use physparam, only : kind_phys + use machine, only : kind_phys implicit none public :: cmp_dcorr_lgth diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 4b75cb4c0..ee7922c99 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -173,7 +173,7 @@ !> This module computes cloud related quantities for radiation computations. module module_radiation_clouds ! - use physparam, only : icldflg, iovr, idcor, & + use physparam, only : iovr, idcor, & & lcrick, lcnorm, lnoprec, & & ivflip use physcons, only : con_fvirt, con_ttp, con_rocp, & @@ -287,9 +287,6 @@ subroutine cld_init & ! errmsg : CCPP error message ! ! ! ! external module variables: (in physparam) ! -! icldflg : cloud optical property scheme control flag ! -! =0: abort! diagnostic cloud method discontinued ! -! =1: model use prognostic cloud method ! ! imp_physics : cloud microphysics scheme control flag ! ! =99: zhao/carr/sundqvist microphysics cloud ! ! =98: zhao/carr/sundqvist microphysics cloud+pdfcld! @@ -334,44 +331,33 @@ subroutine cld_init & errmsg = '' errflg = 0 -! --- set up module variables - - if (me == 0) print *, VTAGCLD !print out version tag - - if ( icldflg == 0 ) then - print *,' - Diagnostic Cloud Method has been discontinued' - errflg = 1 - errmsg = 'ERROR(cld_init): Diagnostic Cloud Method has been '// & - & 'discontinued' - return - else - if (me == 0) then - print *,' - Using Prognostic Cloud Method' - if (imp_physics == 99) then + if (me == 0) then + print *, VTAGCLD !print out version tag + print *,' - Using Prognostic Cloud Method' + if (imp_physics == 99) then print *,' --- Zhao/Carr/Sundqvist microphysics' - elseif (imp_physics == 98) then + elseif (imp_physics == 98) then print *,' --- zhao/carr/sundqvist + pdf cloud' - elseif (imp_physics == 11) then + elseif (imp_physics == 11) then print *,' --- GFDL Lin cloud microphysics' - elseif (imp_physics == 8) then + elseif (imp_physics == 8) then print *,' --- Thompson cloud microphysics' - elseif (imp_physics == 6) then + elseif (imp_physics == 6) then print *,' --- WSM6 cloud microphysics' - elseif (imp_physics == 10) then + elseif (imp_physics == 10) then print *,' --- MG cloud microphysics' - elseif (imp_physics == 15) then + elseif (imp_physics == 15) then print *,' --- Ferrier-Aligo cloud microphysics' - elseif (imp_physics == 17) then + elseif (imp_physics == 17) then print *,' --- NSSL cloud microphysics' - else + else print *,' !!! ERROR in cloud microphysc specification!!!', & & ' imp_physics (NP3D) =',imp_physics errflg = 1 errmsg = 'ERROR(cld_init): cloud mp specification is not'// & & ' valid' return - endif - endif + endif endif !> - Compute the top of BL cld (llyr), which is the topmost non diff --git a/physics/radlw_datatb.f b/physics/radlw_datatb.f index f297c8e4c..da0f5eaa3 100644 --- a/physics/radlw_datatb.f +++ b/physics/radlw_datatb.f @@ -66,7 +66,7 @@ module module_radlw_avplank ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NPLNK, NBANDS ! implicit none @@ -747,7 +747,7 @@ end module module_radlw_avplank ! module module_radlw_ref ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys ! implicit none ! @@ -924,7 +924,7 @@ end module module_radlw_ref ! module module_radlw_cldprlw ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NBANDS ! implicit none @@ -1607,7 +1607,7 @@ end module module_radlw_cldprlw ! module module_radlw_kgb01 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG01 ! implicit none @@ -2421,7 +2421,7 @@ end module module_radlw_kgb01 ! module module_radlw_kgb02 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG02 ! implicit none @@ -3278,7 +3278,7 @@ end module module_radlw_kgb02 ! module module_radlw_kgb03 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG03 ! implicit none @@ -10152,7 +10152,7 @@ end module module_radlw_kgb03 ! module module_radlw_kgb04 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG04 ! implicit none @@ -15352,7 +15352,7 @@ end module module_radlw_kgb04 ! module module_radlw_kgb05 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG05 ! implicit none @@ -21849,7 +21849,7 @@ end module module_radlw_kgb05 ! module module_radlw_kgb06 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG06 ! implicit none @@ -22109,7 +22109,7 @@ end module module_radlw_kgb06 ! module module_radlw_kgb07 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG07 ! implicit none @@ -24756,7 +24756,7 @@ end module module_radlw_kgb07 ! module module_radlw_kgb08 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG08 ! implicit none @@ -25553,7 +25553,7 @@ end module module_radlw_kgb08 ! module module_radlw_kgb09 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG09 ! implicit none @@ -28231,7 +28231,7 @@ end module module_radlw_kgb09 ! module module_radlw_kgb10 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG10 ! implicit none @@ -28705,7 +28705,7 @@ end module module_radlw_kgb10 ! module module_radlw_kgb11 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG11 ! implicit none @@ -29404,7 +29404,7 @@ end module module_radlw_kgb11 ! module module_radlw_kgb12 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG12 ! implicit none @@ -30475,7 +30475,7 @@ end module module_radlw_kgb12 ! module module_radlw_kgb13 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG13 ! implicit none @@ -31381,7 +31381,7 @@ end module module_radlw_kgb13 ! module module_radlw_kgb14 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG14 ! implicit none @@ -31605,7 +31605,7 @@ end module module_radlw_kgb14 ! module module_radlw_kgb15 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG15 ! implicit none @@ -32010,7 +32010,7 @@ end module module_radlw_kgb15 ! module module_radlw_kgb16 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG16 ! implicit none diff --git a/physics/radlw_main.F90 b/physics/radlw_main.F90 index 8612e33db..341ca47ed 100644 --- a/physics/radlw_main.F90 +++ b/physics/radlw_main.F90 @@ -79,7 +79,6 @@ ! ! ! external modules referenced: ! ! ! -! 'module physparam' ! ! 'module physcons' ! ! 'mersenne_twister' ! ! ! @@ -278,8 +277,6 @@ !! rrtmg-lw radiation code from aer inc. module rrtmg_lw ! - use physparam, only : ilwrate, ilwrgas, ilwcliq, ilwcice, & - & isubclw, icldflg, iovr, ivflip use physcons, only : con_g, con_cp, con_avgd, con_amd, & & con_amw, con_amo3 use mersenne_twister, only : random_setseed, random_number, & @@ -425,7 +422,8 @@ subroutine rrtmg_lw_run & & gasvmr_cfc12, gasvmr_cfc22, gasvmr_ccl4, & & icseed,aeraod,aerssa,sfemis,sfgtmp, & & dzlyr,delpin,de_lgth,alpha, & - & npts, nlay, nlp1, lprnt, cld_cf, lslwr, & + & npts, nlay, nlp1, lprnt, cld_cf, lslwr, top_at_1, iovr, & + & inc_minor_gas, ilwcliq, ilwcice, isubclw, & & hlwc,topflx,sfcflx,cldtau, & ! --- outputs & HLW0,HLWB,FLXPRF, & ! --- optional & cld_lwp, cld_ref_liq, cld_iwp, cld_ref_ice, & @@ -483,6 +481,27 @@ subroutine rrtmg_lw_run & ! npts : total number of horizontal points ! ! nlay, nlp1 : total number of vertical layers, levels ! ! lprnt : cntl flag for diagnostic print out ! +! inc_minor_gas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! +! =0: do not include rare gases ! +! >0: include all rare gases ! +! ilwcliq - control flag for liq-cloud optical properties ! +! =1: input cld liqp & reliq, hu & stamnes (1993) ! +! =2: not used ! +! ilwcice - control flag for ice-cloud optical properties ! +! =1: input cld icep & reice, ebert & curry (1997) ! +! =2: input cld icep & reice, streamer (1996) ! +! =3: input cld icep & reice, fu (1998) ! +! isubclw - sub-column cloud approximation control flag ! +! =0: no sub-col cld treatment, use grid-mean cld quantities ! +! =1: mcica sub-col, prescribed seeds to get random numbers ! +! =2: mcica sub-col, providing array icseed for random numbers! +! iovr - cloud overlapping control flag ! +! =0: random overlapping clouds ! +! =1: maximum/random overlapping clouds ! +! =2: maximum overlap cloud (used for isubclw>0 only) ! +! =3: decorrelation-length overlap (for isubclw>0 only) ! +! =4: exponential cloud overlap (AER) ! +! =5: exponential-random cloud overlap (AER) ! ! ! ! output variables: ! ! hlwc (npts,nlay): total sky heating rate (k/day or k/sec) ! @@ -508,32 +527,6 @@ subroutine rrtmg_lw_run & ! upfx0 - clear sky upward flux ! ! dnfx0 - clear sky dnward flux ! ! ! -! external module variables: (in physparam) ! -! ilwrgas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! -! ilwcliq - control flag for liq-cloud optical properties ! -! =1: input cld liqp & reliq, hu & stamnes (1993) ! -! =2: not used ! -! ilwcice - control flag for ice-cloud optical properties ! -! =1: input cld icep & reice, ebert & curry (1997) ! -! =2: input cld icep & reice, streamer (1996) ! -! =3: input cld icep & reice, fu (1998) ! -! isubclw - sub-column cloud approximation control flag ! -! =0: no sub-col cld treatment, use grid-mean cld quantities ! -! =1: mcica sub-col, prescribed seeds to get random numbers ! -! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud (used for isubclw>0 only) ! -! =3: decorrelation-length overlap (for isubclw>0 only) ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! -! ivflip - control flag for vertical index direction ! -! =0: vertical index from toa to surface ! -! =1: vertical index from surface to toa ! -! ! ! module parameters, control variables: ! ! nbands - number of longwave spectral bands ! ! maxgas - maximum number of absorbing gaseous ! @@ -605,10 +598,11 @@ subroutine rrtmg_lw_run & ! ====================== end of definitions =================== ! ! --- inputs: - integer, intent(in) :: npts, nlay, nlp1 + integer, intent(in) :: npts, nlay, nlp1, ilwcliq, ilwcice, & + isubclw, iovr integer, intent(in) :: icseed(npts) - logical, intent(in) :: lprnt + logical, intent(in) :: lprnt, inc_minor_gas real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, & & tlvl @@ -631,6 +625,7 @@ subroutine rrtmg_lw_run & real (kind=kind_phys), dimension(:,:,:),intent(in):: & & aeraod, aerssa + logical, intent(in) :: lslwr, top_at_1 ! --- outputs: real (kind=kind_phys), dimension(:,:), intent(inout) :: hlwc @@ -650,7 +645,6 @@ subroutine rrtmg_lw_run & & intent(inout) :: hlw0 type (proflw_type), dimension(:,:), optional, & & intent(inout) :: flxprf - logical, intent(in) :: lslwr ! --- locals: real (kind=kind_phys), dimension(0:nlp1) :: cldfrc @@ -801,7 +795,7 @@ subroutine rrtmg_lw_run & ! layer pressure thickness (in mb), based on the hydrostatic equation ! --- ... and includes a correction to account for h2o in the layer. - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc tem1 = 100.0 * con_g tem2 = 1.0e-20 * 1.0e3 * con_avgd @@ -841,7 +835,7 @@ subroutine rrtmg_lw_run & !! cf22, convert from volume mixing ratio to molec/cm2 based on !! coldry (scaled to 1.0e-20). - if (ilwrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay k1 = nlp1 - k colamt(k,4)=max(temcol(k), coldry(k)*gasvmr_n2o(iplon,k1)) ! n2o @@ -952,7 +946,7 @@ subroutine rrtmg_lw_run & ! --- ... set up col amount for rare gases, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (ilwrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay colamt(k,4)=max(temcol(k), coldry(k)*gasvmr_n2o(iplon,k)) ! n2o colamt(k,5)=max(temcol(k), coldry(k)*gasvmr_ch4(iplon,k)) ! ch4 @@ -1021,7 +1015,7 @@ subroutine rrtmg_lw_run & tem0 = 10.0 * tem2 / (amdw * tem1 * con_g) pwvcm = tem0 * plvl(iplon,1) - endif ! if_ivflip + endif ! top_at_1 !> -# Compute column amount for broadening gases. @@ -1078,6 +1072,7 @@ subroutine rrtmg_lw_run & ! --- inputs: & ( cldfrc,clwp,relw,ciwp,reiw,cda1,cda2,cda3,cda4, & & nlay, nlp1, ipseed(iplon), dz, delgth, iovr, alph, & + & ilwcliq, ilwcice, isubclw, & ! --- outputs: & cldfmc, taucld & & ) @@ -1085,7 +1080,7 @@ subroutine rrtmg_lw_run & ! --- ... save computed layer cloud optical depth for output ! rrtm band-7 is apprx 10mu channel (or use spectral mean of bands 6-8) - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do k = 1, nlay k1 = nlp1 - k cldtau(iplon,k1) = taucld( 7,k) @@ -1094,7 +1089,7 @@ subroutine rrtmg_lw_run & do k = 1, nlay cldtau(iplon,k) = taucld( 7,k) enddo - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else cldfmc = f_zero @@ -1229,7 +1224,7 @@ subroutine rrtmg_lw_run & sfcflx(iplon)%dnfxc = totdflux(0) sfcflx(iplon)%dnfx0 = totdclfl(0) - if (ivflip == 0) then ! output from toa to sfc + if (top_at_1) then ! output from toa to sfc !! --- ... optional fluxes if ( lflxprf ) then @@ -1297,7 +1292,7 @@ subroutine rrtmg_lw_run & enddo endif - endif ! if_ivflip + endif ! if_top_at_1 enddo lab_do_iplon @@ -1315,8 +1310,8 @@ end subroutine rrtmg_lw_run !! spectral band are reduced from 256 g-point intervals to 140. !!\param me print control for parallel process !!\section rlwinit_gen rlwinit General Algorithm - subroutine rlwinit & - & ( me, errflg, errmsg ) + subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & + isubclw, iovr, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1328,17 +1323,9 @@ subroutine rlwinit & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control for parallel process ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in physparam) ! -! ilwrate - heating rate unit selections ! -! =1: output in k/day ! -! =2: output in k/second ! -! ilwrgas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! +! me - print control for parallel process ! +! rad_hr_units - 1 for heating rates in units K/day. 2 for K/s ! +! inc_minor_gas - flag to turn on/off minor gases in rrtmg ! ! ilwcliq - liquid cloud optical properties contrl flag ! ! =0: input cloud opt depth from diagnostic scheme ! ! >0: input cwp,rew, and other cloud content parameters ! @@ -1346,9 +1333,6 @@ subroutine rlwinit & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! icldflg - cloud scheme control flag ! -! =0: diagnostic scheme gives cloud tau, omiga, and g. ! -! =1: prognostic scheme gives cloud liq/ice path, etc. ! ! iovr - clouds vertical overlapping control flag ! ! =0: random overlapping clouds ! ! =1: maximum/random overlapping clouds ! @@ -1357,6 +1341,10 @@ subroutine rlwinit & ! =4: exponential cloud overlap (AER) ! ! =5: exponential-random cloud overlap (AER) ! ! ! +! outputs: ! +! errflg - error flag ! +! errmsg - error message ! +! ! ! ******************************************************************* ! ! original code description ! ! ! @@ -1385,7 +1373,8 @@ subroutine rlwinit & ! ====================== end of description block ================= ! ! --- inputs: - integer, intent(in) :: me + integer, intent(in) :: me, rad_hr_units, ilwcliq, isubclw, iovr + logical, intent(in) :: inc_minor_gas ! --- outputs: character(len=*), intent(out) :: errmsg @@ -1405,27 +1394,10 @@ subroutine rlwinit & errflg = 0 errmsg = '' - if ( iovr<0 .or. iovr>5 ) then - print *,' *** Error in specification of cloud overlap flag', & - & ' IOVR=',iovr,' in RLWINIT !!' - errflg = 1 - errmsg = 'ERROR(rlwinit): cloud-overlap (iovr) scheme selected not valid.' - return - elseif ( (iovr==2 .or. iovr==3) .and. isubclw==0 ) then - if (me == 0) then - print *,' *** IOVR=',iovr,' is not available for', & - & ' ISUBCLW=0 setting!!' - print *,' The program uses maximum/random overlap', & - & ' instead.' - endif - - iovr = 1 - endif - if (me == 0) then print *,' - Using AER Longwave Radiation, Version: ', VTAGLW - if (ilwrgas > 0) then + if (inc_minor_gas) then print *,' --- Include rare gases N2O, CH4, O2, CFCs ', & & 'absorptions in LW' else @@ -1441,27 +1413,9 @@ subroutine rlwinit & elseif ( isubclw == 2 ) then print *,' --- Using MCICA sub-colum clouds approximation ', & & 'with provided input array of permutation seeds' - else - print *,' *** Error in specification of sub-column cloud ', & - & ' control flag isubclw =',isubclw,' !!' - errflg = 1 - errmsg = 'ERROR(rlwinit): sub-column scheme (isubclw) selected not valid.' - return endif endif -!> -# Check cloud flags for consistency. - - if ((icldflg == 0 .and. ilwcliq /= 0) .or. & - & (icldflg == 1 .and. ilwcliq == 0)) then - print *,' *** Model cloud scheme inconsistent with LW', & - & ' radiation cloud radiative property setup !!' - errflg = 1 - errmsg = 'ERROR(rlwinit): Model cloud scheme inconsistent with LW'//& - & ' radiation cloud radiative property setup' - return - endif - !> -# Setup default surface emissivity for each band. semiss0(:) = f_one @@ -1473,7 +1427,7 @@ subroutine rlwinit & fluxfac = pival * 2.0d4 ! fluxfac = 62831.85307179586 ! = 2 * pi * 1.0e4 - if (ilwrate == 1) then + if (rad_hr_units == 1) then ! heatfac = 8.4391 ! heatfac = con_g * 86400. * 1.0e-2 / con_cp ! (in k/day) heatfac = con_g * 864.0 / con_cp ! (in k/day) @@ -1559,8 +1513,8 @@ end subroutine rlwinit !!\section gen_cldprop cldprop General Algorithm subroutine cldprop & & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & ! --- inputs - & nlay, nlp1, ipseed, dz, de_lgth, iovr, alpha, & - & cldfmc, taucld & ! --- outputs + & nlay, nlp1, ipseed, dz, de_lgth, iovr, alpha, ilwcliq, & + & ilwcice, isubclw, cldfmc, taucld & ! --- outputs & ) ! =================== program usage description =================== ! @@ -1660,7 +1614,8 @@ subroutine cldprop & use module_radlw_cldprlw ! --- inputs: - integer, intent(in) :: nlay, nlp1, ipseed, iovr + integer, intent(in) :: nlay, nlp1, ipseed, iovr, ilwcliq, ilwcice,& + isubclw real (kind=kind_phys), dimension(0:nlp1), intent(in) :: cfrac real (kind=kind_phys), dimension(nlay), intent(in) :: cliqp, & @@ -1825,7 +1780,7 @@ subroutine cldprop & endif lab_if_ilwcliq -!> -# if physparam::isubclw > 0, call mcica_subcol() to distribute +!> -# if GFS_typedefs::isubclw > 0, call mcica_subcol() to distribute !! cloud properties to each g-point. if ( isubclw > 0 ) then ! mcica sub-col clouds approx @@ -1841,7 +1796,7 @@ subroutine cldprop & call mcica_subcol & ! --- inputs: - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- output: & lcloudy & & ) @@ -1874,7 +1829,7 @@ end subroutine cldprop !!\param lcloudy sub-colum cloud profile flag array !!\section mcica_subcol_gen mcica_subcol General Algorithm subroutine mcica_subcol & - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & ! --- inputs + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- inputs & lcloudy & ! --- outputs & ) @@ -1889,22 +1844,20 @@ subroutine mcica_subcol & ! for lw and sw, use values differ by the number of g-pts. ! ! dz - real, layer thickness (km) nlay ! ! de_lgth - real, layer cloud decorrelation length (km) 1 ! -! alpha - real, EXP/ER decorrelation parameter nlay ! +! alpha - real, EXP/ER decorrelation parameter nlay ! +! iovr - control flag for cloud overlapping method 1 ! +! =0:random; =1:maximum/random: =2:maximum; =3:decorr ! +! =4:exponential; =5:exponential-random ! ! ! ! output variables: ! ! lcloudy - logical, sub-colum cloud profile flag array ngptlw*nlay! ! ! -! other control flags from module variables: ! -! iovr : control flag for cloud overlapping method ! -! =0:random; =1:maximum/random: =2:maximum; =3:decorr ! -! =4:exponential; =5:exponential-random ! -! ! ! ===================== end of definitions ==================== ! implicit none ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iovr real (kind=kind_phys), dimension(nlay), intent(in) :: cldf, dz real (kind=kind_phys), intent(in) :: de_lgth diff --git a/physics/radlw_main.meta b/physics/radlw_main.meta index 9286c45cb..8dc1db046 100644 --- a/physics/radlw_main.meta +++ b/physics/radlw_main.meta @@ -241,6 +241,48 @@ dimensions = () type = logical intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = flag for cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[ilwcliq] + standard_name = flag_for_rrtmg_lw_cloud_optics + long_name = flag for rrtmg longwave cloud optics + units = flag + dimensions = () + type = integer + intent = in +[ilwcice] + standard_name = flag_for_rrtmg_lw_ice_cloud_optics + long_name = flag for rrtmg longwave ice cloud optics + units = flag + dimensions = () + type = integer + intent = in +[isubclw] + standard_name = flag_for_lw_clouds_sub_grid_approximation + long_name = flag for lw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in [hlwc] standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step_and_radiation_levels long_name = longwave total sky heating rate diff --git a/physics/radlw_param.f b/physics/radlw_param.f index fa7ceecb0..bc2aae224 100644 --- a/physics/radlw_param.f +++ b/physics/radlw_param.f @@ -65,7 +65,7 @@ module module_radlw_parameters ! !! \htmlinclude module_radlw_parameters.html !! - use physparam, only : kind_phys + use machine, only : kind_phys implicit none ! diff --git a/physics/radsw_datatb.f b/physics/radsw_datatb.f index 6d88f1989..e0bb651e9 100644 --- a/physics/radsw_datatb.f +++ b/physics/radsw_datatb.f @@ -73,7 +73,7 @@ module module_radsw_ref ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys ! implicit none ! @@ -217,7 +217,7 @@ module module_radsw_cldprtb ! ! ! ! ************************* end description ************************ ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : nblow, nbhgh ! implicit none @@ -2503,7 +2503,7 @@ module module_radsw_sflux ! ! ! ! ************************* end description ************************ ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NGMAX, NG16, NG17, NG18, NG19,& & NG20, NG21, NG22, NG23, NG24, & & NG25, NG26, NG27, NG28, NG29, & @@ -2838,7 +2838,7 @@ module module_radsw_kgb16 ! ! ! ! ************************ end description ************************ ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG16 ! @@ -4031,7 +4031,7 @@ module module_radsw_kgb17 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG17 ! @@ -8640,7 +8640,7 @@ module module_radsw_kgb18 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG18 ! @@ -10158,7 +10158,7 @@ module module_radsw_kgb19 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG19 ! @@ -11677,7 +11677,7 @@ module module_radsw_kgb20 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG20 ! @@ -12461,7 +12461,7 @@ module module_radsw_kgb21 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG21 ! @@ -16319,7 +16319,7 @@ module module_radsw_kgb22 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG22 ! @@ -16766,7 +16766,7 @@ module module_radsw_kgb23 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG23 ! @@ -17023,7 +17023,7 @@ module module_radsw_kgb24 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG24 ! @@ -18588,7 +18588,7 @@ module module_radsw_kgb25 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG25 ! @@ -18748,7 +18748,7 @@ module module_radsw_kgb26 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG26 ! @@ -18784,7 +18784,7 @@ module module_radsw_kgb27 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG27 ! @@ -19387,7 +19387,7 @@ module module_radsw_kgb28 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG28 ! @@ -21701,7 +21701,7 @@ module module_radsw_kgb29 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG29 ! diff --git a/physics/radsw_main.F90 b/physics/radsw_main.F90 index f24dcff86..cf6c37346 100644 --- a/physics/radsw_main.F90 +++ b/physics/radsw_main.F90 @@ -90,7 +90,6 @@ ! ! ! external modules referenced: ! ! ! -! 'module physparam' ! ! 'module physcons' ! ! 'mersenne_twister' ! ! ! @@ -304,9 +303,6 @@ !! rrtmg-sw radiation code from aer inc. module rrtmg_sw ! - use physparam, only : iswrate, iswrgas, iswcliq, iswcice, & - & isubcsw, icldflg, iovr, ivflip, & - & iswmode use physcons, only : con_g, con_cp, con_avgd, con_amd, & & con_amw, con_amo3 use machine, only : rb => kind_phys, im => kind_io4, & @@ -503,7 +499,8 @@ subroutine rrtmg_sw_run & & sfcalb_uvis_dir, sfcalb_uvis_dif, & & dzlyr,delpin,de_lgth,alpha, & & cosz,solcon,NDAY,idxday, & - & npts, nlay, nlp1, lprnt, & + & npts, nlay, nlp1, lprnt, inc_minor_gas, iswcliq, iswcice, & + & isubcsw, iovr, top_at_1, iswmode, & & cld_cf, lsswr, & & hswc,topflx,sfcflx,cldtau, & ! --- outputs & HSW0,HSWB,FLXPRF,FDNCMP, & ! --- optional @@ -570,6 +567,30 @@ subroutine rrtmg_sw_run & ! npts : number of horizontal points ! ! nlay,nlp1 : vertical layer/lavel numbers ! ! lprnt : logical check print flag ! +! iswcliq - control flag for liq-cloud optical properties ! +! =0: input cloud optical depth, fixed ssa, asy ! +! =1: use hu and stamnes(1993) method for liq cld ! +! =2: use updated coeffs for hu and stamnes scheme ! +! iswcice - control flag for ice-cloud optical properties ! +! *** if iswcliq==0, iswcice is ignored ! +! =1: use ebert and curry (1992) scheme for ice clouds ! +! =2: use streamer v3.0 (2001) method for ice clouds ! +! =3: use fu's method (1996) for ice clouds ! +! iswmode - control flag for 2-stream transfer scheme ! +! =1; delta-eddington (joseph et al., 1976) ! +! =2: pifm (zdunkowski et al., 1980) ! +! =3: discrete ordinates (liou, 1973) ! +! isubcsw - sub-column cloud approximation control flag ! +! =0: no sub-col cld treatment, use grid-mean cld quantities ! +! =1: mcica sub-col, prescribed seeds to get random numbers ! +! =2: mcica sub-col, providing array icseed for random numbers! +! iovr - cloud overlapping control flag ! +! =0: random overlapping clouds ! +! =1: maximum/random overlapping clouds ! +! =2: maximum overlap cloud ! +! =3: decorrelation-length overlap clouds ! +! =4: exponential cloud overlap (AER) ! +! =5: exponential-random cloud overlap (AER) ! ! ! ! output variables: ! ! hswc (npts,nlay): total sky heating rates (k/sec or k/day) ! @@ -604,38 +625,6 @@ subroutine rrtmg_sw_run & ! visbm - downward surface uv+vis direct beam flux ! ! visdf - downward surface uv+vis diffused flux ! ! ! -! external module variables: (in physparam) ! -! iswrgas - control flag for rare gases (ch4,n2o,o2, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! -! iswcliq - control flag for liq-cloud optical properties ! -! =0: input cloud optical depth, fixed ssa, asy ! -! =1: use hu and stamnes(1993) method for liq cld ! -! =2: use updated coeffs for hu and stamnes scheme ! -! iswcice - control flag for ice-cloud optical properties ! -! *** if iswcliq==0, iswcice is ignored ! -! =1: use ebert and curry (1992) scheme for ice clouds ! -! =2: use streamer v3.0 (2001) method for ice clouds ! -! =3: use fu's method (1996) for ice clouds ! -! iswmode - control flag for 2-stream transfer scheme ! -! =1; delta-eddington (joseph et al., 1976) ! -! =2: pifm (zdunkowski et al., 1980) ! -! =3: discrete ordinates (liou, 1973) ! -! isubcsw - sub-column cloud approximation control flag ! -! =0: no sub-col cld treatment, use grid-mean cld quantities ! -! =1: mcica sub-col, prescribed seeds to get random numbers ! -! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud ! -! =3: decorrelation-length overlap clouds ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! -! ivflip - control flg for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module parameters, control variables: ! ! nblow,nbhgh - lower and upper limits of spectral bands ! ! maxgas - maximum number of absorbing gaseous ! @@ -690,11 +679,12 @@ subroutine rrtmg_sw_run & ! ===================== end of definitions ==================== ! ! --- inputs: - integer, intent(in) :: npts, nlay, nlp1, NDAY + integer, intent(in) :: npts, nlay, nlp1, NDAY, iswcliq, iswcice, & + isubcsw, iovr, iswmode integer, dimension(:), intent(in) :: idxday, icseed - logical, intent(in) :: lprnt, lsswr + logical, intent(in) :: lprnt, lsswr, inc_minor_gas, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: & & plvl, tlvl @@ -910,7 +900,7 @@ subroutine rrtmg_sw_run & !> - Prepare atmospheric profile for use in rrtm. ! the vertical index of internal array is from surface to top - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc tem1 = 100.0 * con_g tem2 = 1.0e-20 * 1.0e3 * con_avgd @@ -950,7 +940,7 @@ subroutine rrtmg_sw_run & ! --- ... set up gas column amount, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (iswrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay kk = nlp1 - k colamt(k,4) = max(temcol(k), coldry(k)*gasvmr_n2o(j1,kk)) ! n2o @@ -1047,7 +1037,7 @@ subroutine rrtmg_sw_run & ! --- ... set up gas column amount, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (iswrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay colamt(k,4) = max(temcol(k), coldry(k)*gasvmr_n2o(j1,k)) ! n2o colamt(k,5) = max(temcol(k), coldry(k)*gasvmr_ch4(j1,k)) ! ch4 @@ -1094,7 +1084,7 @@ subroutine rrtmg_sw_run & enddo endif ! end if_iswcliq - endif ! if_ivflip + endif ! if_top_at_1 !> - Compute fractions of clear sky view: !! - random overlapping @@ -1135,7 +1125,8 @@ subroutine rrtmg_sw_run & call cldprop & ! --- inputs: & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & - & zcf1, nlay, ipseed(j1), dz, delgth, alph, & + & zcf1, nlay, ipseed(j1), dz, delgth, alph, iswcliq, iswcice,& + & isubcsw, iovr, & ! --- outputs: & taucw, ssacw, asycw, cldfrc, cldfmc & & ) @@ -1143,7 +1134,7 @@ subroutine rrtmg_sw_run & ! --- ... save computed layer cloud optical depth for output ! rrtm band 10 is approx to the 0.55 mu spectrum - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do k = 1, nlay kk = nlp1 - k cldtau(j1,kk) = taucw(k,10) @@ -1152,7 +1143,7 @@ subroutine rrtmg_sw_run & do k = 1, nlay cldtau(j1,k) = taucw(k,10) enddo - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else ! clear sky column cldfrc(:) = f_zero @@ -1187,9 +1178,9 @@ subroutine rrtmg_sw_run & & ) !> - Call the 2-stream radiation transfer model: -!! - if physparam::isubcsw .le.0, using standard cloud scheme, +!! - if GFS_typedefs::isubcsw .le.0, using standard cloud scheme, !! call spcvrtc(). -!! - if physparam::isubcsw .gt.0, using mcica cloud scheme, +!! - if GFS_typedefs::isubcsw .gt.0, using mcica cloud scheme, !! call spcvrtm(). if ( isubcsw <= 0 ) then ! use standard cloud scheme @@ -1198,7 +1189,7 @@ subroutine rrtmg_sw_run & ! --- inputs: & ( ssolar,cosz1,sntz1,albbm,albdf,sfluxzen,cldfrc, & & zcf1,zcf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & ! --- outputs: & fxupc,fxdnc,fxup0,fxdn0, & & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & @@ -1211,7 +1202,7 @@ subroutine rrtmg_sw_run & ! --- inputs: & ( ssolar,cosz1,sntz1,albbm,albdf,sfluxzen,cldfmc, & & zcf1,zcf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & ! --- outputs: & fxupc,fxdnc,fxup0,fxdn0, & & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & @@ -1276,7 +1267,7 @@ subroutine rrtmg_sw_run & sfcflx(j1)%upfx0 = fsfcu0 sfcflx(j1)%dnfx0 = fsfcd0 - if (ivflip == 0) then ! output from toa to sfc + if (top_at_1) then ! output from toa to sfc ! --- ... compute heating rates @@ -1372,7 +1363,7 @@ subroutine rrtmg_sw_run & enddo endif - endif ! if_ivflip + endif ! if_top_at_1 enddo lab_do_ipt @@ -1387,9 +1378,8 @@ end subroutine rrtmg_sw_run !!\param me print control for parallel process !>\section rswinit_gen rswinit General Algorithm !----------------------------------- - subroutine rswinit & - & ( me, errflg, errmsg ) ! --- inputs: -! --- outputs: (none) + subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & + isubcsw, iovr, iswmode, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1401,17 +1391,8 @@ subroutine rswinit & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control for parallel process ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in physparam) ! -! iswrate - heating rate unit selections ! -! =1: output in k/day ! -! =2: output in k/second ! -! iswrgas - control flag for rare gases (ch4,n2o,o2, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! +! me - print control for parallel process ! +! rad_hr_units - ! ! iswcliq - liquid cloud optical properties contrl flag ! ! =0: input cloud opt depth from diagnostic scheme ! ! >0: input cwp,rew, and other cloud content parameters ! @@ -1419,9 +1400,6 @@ subroutine rswinit & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! icldflg - cloud scheme control flag ! -! =0: diagnostic scheme gives cloud tau, omiga, and g. ! -! =1: prognostic scheme gives cloud liq/ice path, etc. ! ! iovr - clouds vertical overlapping control flag ! ! =0: random overlapping clouds ! ! =1: maximum/random overlapping clouds ! @@ -1434,6 +1412,9 @@ subroutine rswinit & ! =2: pifm (zdunkowski et al., 1980) ! ! =3: discrete ordinates (liou, 1973) ! ! ! +! outputs: ! +! errflg - error flag ! +! errmsg - error message ! ! ******************************************************************* ! ! ! ! definitions: ! @@ -1446,8 +1427,9 @@ subroutine rswinit & ! ====================== end of description block ================= ! ! --- inputs: - integer, intent(in) :: me - + integer, intent(in) :: me, rad_hr_units, iswcliq, isubcsw, iovr, & + iswmode + logical, intent(in) :: inc_minor_gas ! --- outputs: character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -1466,14 +1448,6 @@ subroutine rswinit & errflg = 0 errmsg = '' - if ( iovr<0 .or. iovr>5 ) then - print *,' *** Error in specification of cloud overlap flag', & - & ' IOVR=',iovr,' in RSWINIT !!' - errflg = 1 - errmsg = 'ERROR(rswinit): cloud-overlap (iovr) scheme selected not valid.' - return - endif - if (me == 0) then print *,' - Using AER Shortwave Radiation, Version: ',VTAGSW @@ -1485,7 +1459,7 @@ subroutine rswinit & print *,' --- Discrete ordinates 2-stream transfer scheme' endif - if (iswrgas <= 0) then + if (.not. inc_minor_gas) then print *,' --- Rare gases absorption is NOT included in SW' else print *,' --- Include rare gases N2O, CH4, O2, absorptions',& @@ -1501,42 +1475,13 @@ subroutine rswinit & elseif ( isubcsw == 2 ) then print *,' --- Using MCICA sub-colum clouds approximation ', & & 'with provided input array of permutation seeds' - else - print *,' *** Error in specification of sub-column cloud ', & - & ' control flag isubcsw =',isubcsw,' !!' - errflg = 1 - errmsg = 'ERROR(rswinit): sub-column scheme (isubcsw) selected not valid.' - return endif endif -!> - Check cloud flags for consistency. - - if ((icldflg == 0 .and. iswcliq /= 0) .or. & - & (icldflg == 1 .and. iswcliq == 0)) then - print *,' *** Model cloud scheme inconsistent with SW', & - & ' radiation cloud radiative property setup !!' - errflg = 1 - errmsg = 'ERROR(rswinit): Model cloud scheme inconsistent with SW'//& - & ' radiation cloud radiative property setup' - return - endif - - if ( isubcsw==0 .and. iovr>2 ) then - if (me == 0) then - print *,' *** IOVR=',iovr,' is not available for', & - & ' ISUBCSW=0 setting!!' - print *,' The program will use maximum/random overlap', & - & ' instead.' - endif - - iovr = 1 - endif - !> - Setup constant factors for heating rate !! the 1.0e-2 is to convert pressure from mb to \f$N/m^2\f$ . - if (iswrate == 1) then + if (rad_hr_units == 1) then ! heatfac = 8.4391 ! heatfac = con_g * 86400. * 1.0e-2 / con_cp ! (in k/day) heatfac = con_g * 864.0 / con_cp ! (in k/day) @@ -1573,7 +1518,7 @@ end subroutine rswinit !> This subroutine computes the cloud optical properties for each !! cloudy layer and g-point interval. !!\param cfrac layer cloud fraction -!!\n for physparam::iswcliq > 0 (prognostic cloud scheme) - - - +!!\n for GFS_typedefs::iswcliq > 0 (prognostic cloud scheme) - - - !!\param cliqp layer in-cloud liq water path (\f$g/m^2\f$) !!\param reliq mean eff radius for liq cloud (micron) !!\param cicep layer in-cloud ice water path (\f$g/m^2\f$) @@ -1582,7 +1527,7 @@ end subroutine rswinit !!\param cdat2 effective radius for rain drop (micron) !!\param cdat3 layer snow flake water path(\f$g/m^2\f$) !!\param cdat4 mean eff radius for snow flake(micron) -!!\n for physparam::iswcliq = 0 (diagnostic cloud scheme) - - - +!!\n for GFS_typedefs::iswcliq = 0 (diagnostic cloud scheme) - - - !!\param cliqp not used !!\param cicep not used !!\param reliq not used @@ -1609,8 +1554,8 @@ end subroutine rswinit !----------------------------------- subroutine cldprop & & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & ! --- inputs - & cf1, nlay, ipseed, dz, delgth, alpha, & - & taucw, ssacw, asycw, cldfrc, cldfmc & ! --- output + & cf1, nlay, ipseed, dz, delgth, alpha, iswcliq, iswcice, & + & isubcsw, iovr, taucw, ssacw, asycw, cldfrc, cldfmc & ! --- output & ) ! =================== program usage description =================== ! @@ -1661,7 +1606,7 @@ subroutine cldprop & ! ! ! ! ! explanation of the method for each value of iswcliq, and iswcice. ! -! set up in module "physparam" ! +! provided by host-model ! ! ! ! iswcliq=0 : input cloud optical property (tau, ssa, asy). ! ! (used for diagnostic cloud method) ! @@ -1696,7 +1641,8 @@ subroutine cldprop & use module_radsw_cldprtb ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iswcliq, iswcice, isubcsw, & + iovr real (kind=kind_phys), intent(in) :: cf1, delgth real (kind=kind_phys), dimension(nlay), intent(in) :: cliqp, & @@ -1954,7 +1900,7 @@ subroutine cldprop & call mcica_subcol & ! --- inputs: - & ( cldf, nlay, ipseed, dz, delgth, alpha, & + & ( cldf, nlay, ipseed, dz, delgth, alpha, iovr, & ! --- outputs: & lcloudy & & ) @@ -1993,7 +1939,7 @@ end subroutine cldprop !!\section mcica_sw_gen mcica_subcol General Algorithm ! ---------------------------------- subroutine mcica_subcol & - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & ! --- inputs + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- inputs & lcloudy & ! --- outputs & ) @@ -2006,15 +1952,10 @@ subroutine mcica_subcol & ! ** note : if the cloud generator is called multiple times, need ! ! to permute the seed between each call; if between calls ! ! for lw and sw, use values differ by the number of g-pts. ! -! dz - real, layer thickness (km) nlay ! -! de_lgth-real, layer cloud decorrelation length (km) 1 ! -! alpha - real, EXP/ER decorrelation parameter nlay ! -! ! -! output variables: ! -! lcloudy - logical, sub-colum cloud profile flag array nlay*ngptsw! -! ! -! other control flags from module variables: ! -! iovr : control flag for cloud overlapping method ! +! dz - real, layer thickness (km) nlay ! +! de_lgth - real, layer cloud decorrelation length (km) 1 ! +! alpha - real, EXP/ER decorrelation parameter nlay ! +! iovr - control flag for cloud overlapping method 1 ! ! =0: random ! ! =1: maximum/random overlapping clouds ! ! =2: maximum overlap cloud ! @@ -2022,12 +1963,15 @@ subroutine mcica_subcol & ! =4: exponential cloud overlap method (AER) ! ! =5: exponential-random cloud overlap method (AER) ! ! ! +! output variables: ! +! lcloudy - logical, sub-colum cloud profile flag array nlay*ngptsw! +! ! ! ===================== end of definitions ==================== ! implicit none ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iovr real (kind=kind_phys), dimension(nlay), intent(in) :: cldf, dz real (kind=kind_phys), intent(in) :: de_lgth @@ -2477,7 +2421,7 @@ end subroutine setcoef subroutine spcvrtc & & ( ssolar,cosz,sntz,albbm,albdf,sfluxzen,cldfrc, & ! --- inputs & cf1,cf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & & fxupc,fxdnc,fxup0,fxdn0, & ! --- outputs & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & & sfbmc,sfdfc,sfbm0,sfdf0,suvbfc,suvbf0 & @@ -2539,7 +2483,7 @@ subroutine spcvrtc & ! zldbt - real, layer beam transmittance for clear/cloudy nlp1 ! ! ztdbt - real, lev total beam transmittance for clr/cld nlp1 ! ! ! -! control parameters in module "physparam" ! +! control parameters in module "GFS_typedefs" ! ! iswmode - control flag for 2-stream transfer schemes ! ! = 1 delta-eddington (joseph et al., 1976) ! ! = 2 pifm (zdunkowski et al., 1980) ! @@ -2580,7 +2524,7 @@ subroutine spcvrtc & real (kind=kind_phys), parameter :: eps1 = 1.0e-8 ! --- inputs: - integer, intent(in) :: nlay, nlp1 + integer, intent(in) :: nlay, nlp1, iswmode real (kind=kind_phys), dimension(nlay,ngptsw), intent(in) :: & & taug, taur @@ -2685,7 +2629,7 @@ subroutine spcvrtc & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff). ! - Delta scaling for clear-sky condition. -! - General two-stream expressions for physparam::iswmode . +! - General two-stream expressions. ! - Compute homogeneous reflectance and transmittance for both ! conservative and non-conservative scattering. ! - Pre-delta-scaling clear and cloudy direct beam transmittance. @@ -2717,7 +2661,7 @@ subroutine spcvrtc & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -2911,7 +2855,7 @@ subroutine spcvrtc & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for total-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for ! conservative scattering and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance @@ -2946,7 +2890,7 @@ subroutine spcvrtc & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -3273,7 +3217,7 @@ end subroutine spcvrtc subroutine spcvrtm & & ( ssolar,cosz,sntz,albbm,albdf,sfluxzen,cldfmc, & ! --- inputs & cf1,cf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & & fxupc,fxdnc,fxup0,fxdn0, & ! --- outputs & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & & sfbmc,sfdfc,sfbm0,sfdf0,suvbfc,suvbf0 & @@ -3309,6 +3253,10 @@ subroutine spcvrtm & ! ssacw - real, weighted cloud single scat albedo nlay*nbdsw ! ! asycw - real, weighted cloud asymmetry factor nlay*nbdsw ! ! nlay,nlp1 - integer, number of layers/levels 1 ! +! iswmode - control flag for 2-stream transfer schemes ! +! = 1 delta-eddington (joseph et al., 1976) ! +! = 2 pifm (zdunkowski et al., 1980) ! +! = 3 discrete ordinates (liou, 1973) ! ! ! ! output variables: ! ! fxupc - real, tot sky upward flux nlp1*nbdsw ! @@ -3337,12 +3285,6 @@ subroutine spcvrtm & ! zldbt - real, layer beam transmittance for clear/cloudy nlp1 ! ! ztdbt - real, lev total beam transmittance for clr/cld nlp1 ! ! ! -! control parameters in module "physparam" ! -! iswmode - control flag for 2-stream transfer schemes ! -! = 1 delta-eddington (joseph et al., 1976) ! -! = 2 pifm (zdunkowski et al., 1980) ! -! = 3 discrete ordinates (liou, 1973) ! -! ! ! ******************************************************************* ! ! original code description ! ! ! @@ -3378,7 +3320,7 @@ subroutine spcvrtm & real (kind=kind_phys), parameter :: eps1 = 1.0e-8 ! --- inputs: - integer, intent(in) :: nlay, nlp1 + integer, intent(in) :: nlay, nlp1, iswmode real (kind=kind_phys), dimension(nlay,ngptsw), intent(in) :: & & taug, taur, cldfmc @@ -3482,7 +3424,7 @@ subroutine spcvrtm & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for clear-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for both ! conservative and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance @@ -3513,7 +3455,7 @@ subroutine spcvrtm & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -3706,7 +3648,7 @@ subroutine spcvrtm & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for total-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for ! conservative scattering and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance diff --git a/physics/radsw_main.meta b/physics/radsw_main.meta index 506e2edf0..222f3ce9e 100644 --- a/physics/radsw_main.meta +++ b/physics/radsw_main.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrtmg_sw type = scheme - dependencies = machine.F,mersenne_twister.f,physcons.F90,physparam.f,radsw_datatb.f,radsw_param.f + dependencies = machine.F,mersenne_twister.f,physcons.F90,radsw_datatb.f,radsw_param.f ######################################################################## [ccpp-arg-table] @@ -280,6 +280,55 @@ dimensions = () type = logical intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[iswcice] + standard_name = flag_for_rrtmg_sw_ice_cloud_optics + long_name = flag for rrtmg shortwave ice cloud optics + units = flag + dimensions = () + type = integer + intent = in +[iswcliq] + standard_name = flag_for_rrtmg_sw_cloud_optics + long_name = flag for rrtmg shortwave cloud optics + units = flag + dimensions = () + type = integer + intent = in +[isubcsw] + standard_name = flag_for_sw_clouds_grid_approximation + long_name = flag for sw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iswmode] + standard_name = flag_for_sw_scattering_choice + long_name = flag for rrtmg shortwave scattering choice + units = flag + dimensions = () + type = integer + intent = in [cld_cf] standard_name = total_cloud_fraction long_name = total cloud fraction diff --git a/physics/radsw_param.f b/physics/radsw_param.f index 69c8c2446..2086f5df8 100644 --- a/physics/radsw_param.f +++ b/physics/radsw_param.f @@ -66,7 +66,7 @@ module module_radsw_parameters ! !! \htmlinclude module_radsw_parameters.html !! - use physparam, only : kind_phys + use machine, only : kind_phys implicit none ! From 98cf6d2e6b68e4717f6e56889c6e7b0fd41ad7dd Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 18 Aug 2022 16:29:01 -0600 Subject: [PATCH 14/58] Adios physparam.f --- physics/GFS_cloud_diagnostics.F90 | 21 +- physics/GFS_cloud_diagnostics.meta | 22 ++ physics/GFS_rad_time_vary.fv3.F90 | 8 +- physics/GFS_rad_time_vary.fv3.meta | 16 +- physics/GFS_rad_time_vary.scm.F90 | 8 +- physics/GFS_rad_time_vary.scm.meta | 16 +- physics/GFS_rrtmg_pre.F90 | 38 +-- physics/GFS_rrtmg_pre.meta | 59 ++++ physics/GFS_rrtmg_setup.F90 | 341 +++------------------- physics/GFS_rrtmg_setup.meta | 15 +- physics/GFS_rrtmgp_cloud_overlap.F90 | 1 - physics/GFS_rrtmgp_setup.F90 | 20 +- physics/GFS_rrtmgp_setup.meta | 2 +- physics/physparam.f | 214 -------------- physics/radiation_clouds.f | 415 +++++++++++---------------- physics/radiation_gases.f | 2 +- physics/radlw_main.meta | 2 +- 17 files changed, 368 insertions(+), 832 deletions(-) delete mode 100644 physics/physparam.f diff --git a/physics/GFS_cloud_diagnostics.F90 b/physics/GFS_cloud_diagnostics.F90 index 01ecd7452..49cb992de 100644 --- a/physics/GFS_cloud_diagnostics.F90 +++ b/physics/GFS_cloud_diagnostics.F90 @@ -18,10 +18,6 @@ module GFS_cloud_diagnostics ! Version tag and last revision date character(40), parameter :: VTAGCLD='UFS-cloud-diagnostics vX.x May 2020 ' - - ! Module variables - integer :: & - llyr = 2 ! Upper limit of boundary layer clouds public GFS_cloud_diagnostics_run @@ -35,10 +31,10 @@ module GFS_cloud_diagnostics !> \section arg_table_GFS_cloud_diagnostics_run !! \htmlinclude GFS_cloud_diagnostics_run.html !! - subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, & - iovr_dcorr, iovr_exp, iovr_exprand, lsswr, lslwr, lat, de_lgth, p_lay, & + subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr, iovr_rand, iovr_maxrand, & + iovr_max, iovr_dcorr, iovr_exp, iovr_exprand, lsswr, lslwr, lat, de_lgth, p_lay, & cld_frac, p_lev, deltaZ, cloud_overlap_param, precip_overlap_param, con_pi, & - mtopa, mbota, cldsa, errmsg, errflg) + top_at_1, si, mtopa, mbota, cldsa, errmsg, errflg) implicit none ! Inputs @@ -46,6 +42,7 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_m nCol, & ! Number of horizontal grid-points nLev ! Number of vertical-layers integer, intent(in) :: & + iovr, & ! iovr_rand, & ! Flag for random cloud overlap method iovr_maxrand, & ! Flag for maximum-random cloud overlap method iovr_max, & ! Flag for maximum cloud overlap method @@ -54,12 +51,14 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_m iovr_exprand ! Flag for exponential-random cloud overlap method logical, intent(in) :: & lsswr, & ! Call SW radiation? - lslwr ! Call LW radiation + lslwr, & ! Call LW radiation + top_at_1 real(kind_phys), intent(in) :: & con_pi ! Physical constant: pi real(kind_phys), dimension(:), intent(in) :: & lat, & ! Latitude - de_lgth ! Decorrelation length + de_lgth, & ! Decorrelation length + si real(kind_phys), dimension(:,:), intent(in) :: & p_lay, & ! Pressure at model-layer cld_frac ! Total cloud fraction @@ -110,8 +109,8 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_m ! defined by ptopc. The cloud overlapping method is defined by control flag 'iovr', which may ! be different for lw and sw radiation programs. call gethml(p_lay*0.01, ptop1, cld_frac, cldcnv, deltaZ, de_lgth, cloud_overlap_param,& - nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & - iovr_exprand, cldsa, mtopa, mbota) + nCol, nLev, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + iovr_exprand, top_at_1, si, cldsa, mtopa, mbota) end subroutine GFS_cloud_diagnostics_run !> @} diff --git a/physics/GFS_cloud_diagnostics.meta b/physics/GFS_cloud_diagnostics.meta index ded38a1e7..2408397d6 100644 --- a/physics/GFS_cloud_diagnostics.meta +++ b/physics/GFS_cloud_diagnostics.meta @@ -21,6 +21,13 @@ dimensions = () type = integer intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in [iovr_rand] standard_name = flag_for_random_cloud_overlap_method long_name = choice of random cloud overlap method @@ -149,6 +156,21 @@ type = real kind = kind_phys intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[si] + standard_name = sigma_pressure_hybrid_vertical_coordinate + long_name = vertical sigma coordinate for radiation initialization + units = none + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [mtopa] standard_name = model_layer_number_at_cloud_top long_name = vertical indices for low, middle and high cloud tops diff --git a/physics/GFS_rad_time_vary.fv3.F90 b/physics/GFS_rad_time_vary.fv3.F90 index 61685e74f..c2f3540a6 100644 --- a/physics/GFS_rad_time_vary.fv3.F90 +++ b/physics/GFS_rad_time_vary.fv3.F90 @@ -18,10 +18,10 @@ module GFS_rad_time_vary !! subroutine GFS_rad_time_vary_timestep_init ( & lslwr, lsswr, isubc_lw, isubc_sw, icsdsw, icsdlw, cnx, cny, isc, jsc, & - imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & - ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) + imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim,& + ps_2delt, ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, & + errmsg, errflg) - use physparam, only: ipsd0, ipsdlim use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 @@ -30,7 +30,7 @@ subroutine GFS_rad_time_vary_timestep_init ( ! Interface variables integer, intent(in) :: isubc_lw, isubc_sw, cnx, cny, isc, jsc, kdt - integer, intent(in) :: imp_physics, imp_physics_zhao_carr + integer, intent(in) :: imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim logical, intent(in) :: lslwr, lsswr integer, intent(inout) :: icsdsw(:), icsdlw(:) integer, intent(in) :: imap(:), jmap(:) diff --git a/physics/GFS_rad_time_vary.fv3.meta b/physics/GFS_rad_time_vary.fv3.meta index 0e7c7c024..561b2ade0 100644 --- a/physics/GFS_rad_time_vary.fv3.meta +++ b/physics/GFS_rad_time_vary.fv3.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rad_time_vary type = scheme - dependencies = machine.F,mersenne_twister.f,physparam.f,radcons.f90 + dependencies = machine.F,mersenne_twister.f,radcons.f90 ######################################################################## [ccpp-arg-table] @@ -120,6 +120,20 @@ dimensions = () type = integer intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = in +[ipsdlim] + standard_name = limit_for_initial_seed_for_mcica + long_name = limit for initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = in [ps_2delt] standard_name = surface_air_pressure_two_timesteps_back long_name = surface air pressure two timesteps back diff --git a/physics/GFS_rad_time_vary.scm.F90 b/physics/GFS_rad_time_vary.scm.F90 index db1e7e290..c8e782ebb 100644 --- a/physics/GFS_rad_time_vary.scm.F90 +++ b/physics/GFS_rad_time_vary.scm.F90 @@ -17,10 +17,10 @@ module GFS_rad_time_vary !! subroutine GFS_rad_time_vary_timestep_init ( & lslwr, lsswr, isubc_lw, isubc_sw, icsdsw, icsdlw, cnx, cny, isc, jsc, & - imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & - ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) + imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim,& + ps_2delt, ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, & + errmsg, errflg) - use physparam, only: ipsd0, ipsdlim use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 @@ -29,7 +29,7 @@ subroutine GFS_rad_time_vary_timestep_init ( ! Interface variables integer, intent(in) :: isubc_lw, isubc_sw, cnx, cny, isc, jsc, kdt - integer, intent(in) :: imp_physics, imp_physics_zhao_carr + integer, intent(in) :: imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim logical, intent(in) :: lslwr, lsswr integer, intent(inout) :: icsdsw(:), icsdlw(:) integer, intent(in) :: imap(:), jmap(:) diff --git a/physics/GFS_rad_time_vary.scm.meta b/physics/GFS_rad_time_vary.scm.meta index 0e7c7c024..561b2ade0 100644 --- a/physics/GFS_rad_time_vary.scm.meta +++ b/physics/GFS_rad_time_vary.scm.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rad_time_vary type = scheme - dependencies = machine.F,mersenne_twister.f,physparam.f,radcons.f90 + dependencies = machine.F,mersenne_twister.f,radcons.f90 ######################################################################## [ccpp-arg-table] @@ -120,6 +120,20 @@ dimensions = () type = integer intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = in +[ipsdlim] + standard_name = limit_for_initial_seed_for_mcica + long_name = limit for initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = in [ps_2delt] standard_name = surface_air_pressure_two_timesteps_back long_name = surface air pressure two timesteps back diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 57e0b4347..9de3cb16c 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -27,15 +27,15 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & imp_physics,imp_physics_nssl, nssl_ccn_on, nssl_invertccn, & imp_physics_thompson, imp_physics_gfdl, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, imp_physics_wsm6, & - imp_physics_fer_hires, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & - iovr_exp, iovr_exprand, idcor_con, idcor_hogan, idcor_oreopoulos, & - julian, yearlen, lndp_var_list, lsswr, lslwr, & - ltaerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf, lmfshal, & - lmfdeep2, fhswr, fhlwr, solhr, sup, con_eps, epsm1, fvirt, & - rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, slmsk, & - prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, pert_clds, & + imp_physics_fer_hires, iovr, iovr_rand, iovr_maxrand, iovr_max, & + iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, idcor_hogan, & + idcor_oreopoulos, dcorr_con, julian, yearlen, lndp_var_list, lsswr, & + lslwr, ltaerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf, lmfshal, & + lcnorm, lmfdeep2, lcrick, fhswr, fhlwr, solhr, sup, con_eps, epsm1, & + fvirt, rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, & + slmsk, prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, pert_clds, & sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, icloud, & - iaermdl, iaerflg, con_pi, con_g, & !inputs from here and above + iaermdl, iaerflg, con_pi, con_g, con_ttp, con_thgni, si, & !inputs from here and above coszen, coszdg, effrl_inout, effri_inout, effrs_inout, & clouds1, clouds2, clouds3, clouds4, clouds5, qci_conv, & !in/out from here and above kd, kt, kb, mtopa, mbota, raddt, tsfg, tsfa, de_lgth, alb1d, delp, dz, & !output from here and below @@ -102,6 +102,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & yearlen, icloud, iaermdl, iaerflg integer, intent(in) :: & + iovr, & ! choice of cloud-overlap method iovr_rand, & ! Flag for random cloud overlap method iovr_maxrand, & ! Flag for maximum-random cloud overlap method iovr_max, & ! Flag for maximum cloud overlap method @@ -109,6 +110,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & iovr_exp, & ! Flag for exponential cloud overlap method iovr_exprand, & ! Flag for exponential-random cloud overlap method idcor_con, & + idcor, & idcor_hogan, & idcor_oreopoulos, & rrfs_smoke_band, & ! Band number for rrfs-smoke dust and smoke @@ -121,7 +123,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & logical, intent(in) :: lsswr, lslwr, ltaerosol, lgfdlmprad, & uni_cld, effr_in, do_mynnedmf, & - lmfshal, lmfdeep2, pert_clds + lmfshal, lmfdeep2, pert_clds, lcrick,& + lcnorm logical, intent(in) :: aero_dir_fdb real(kind=kind_phys), dimension(:,:), intent(in) :: smoke_ext, dust_ext @@ -129,12 +132,12 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & integer, intent(in) :: spp_rad real(kind_phys), intent(in) :: spp_wts_rad(:,:) - real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp - real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g + real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con + real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g, con_ttp, con_thgni real(kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlat, xlon, & coslat, sinlat, tsfc, & - slmsk, dx + slmsk, dx, si real(kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, prslk, & tgrs, sfc_wts, & @@ -951,20 +954,21 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: & ccnd, ncndl, cnvw, cnvc, tracer1, & & xlat, xlon, slmsk, dz, delp, IM, LM, LMK, LMP, & - & deltaq, sup, me, icloud, kdt, & + & deltaq, sup, dcorr_con, me, icloud, kdt, & & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & - & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & - & idcor_hogan, idcor_oreopoulos, & + & imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, & + & idcor_hogan, idcor_oreopoulos, lcrick, lcnorm, & & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & & effrl, effri, effrr, effrs, effr_in, & & effrl_inout, effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzb, xlat_d, julian, yearlen, gridkm, & + & dzb, xlat_d, julian, yearlen, gridkm, top_at_1, si, & + & con_ttp, con_pi, con_g, con_rd, con_thgni, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: & cld_rwp, cld_rerain, cld_swp, cld_resnow, & ! --- outputs: & cldsa, mtopa, mbota, de_lgth, alpha & ! --- outputs: diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 8fa020ec5..cb158346a 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -450,6 +450,13 @@ dimensions = () type = integer intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in [iovr_rand] standard_name = flag_for_random_cloud_overlap_method long_name = choice of random cloud overlap method @@ -492,6 +499,20 @@ dimensions = () type = integer intent = in +[dcorr_con] + standard_name = decorrelation_length_used_by_overlap_method + long_name = decorrelation length (default) used by cloud overlap method (iovr) + units = km + dimensions = () + type = real + intent = in +[idcor] + standard_name = flag_for_decorrelation_length_method + long_name = flag for decorrelation length method used in cloud overlap method (iovr) + units = flag + dimensions = () + type = integer + intent = in [idcor_con] standard_name = flag_for_constant_decorrelation_length_method long_name = choice of decorrelation length computation (costant) @@ -599,6 +620,20 @@ dimensions = () type = logical intent = in +[lcrick] + standard_name = flag_for_CRICK_proof_cloud_water + long_name = flag for CRICK-Proof cloud water + units = flag + dimensions = () + type = logical + intent = in +[lcnorm] + standard_name = flag_for_in_cloud_condensate + long_name = flag for cloud condensate normalized by cloud cover + units = flag + dimensions = () + type = logical + intent = in [fhswr] standard_name = period_of_shortwave_radiation_calls long_name = frequency for shortwave radiation @@ -663,6 +698,22 @@ type = real kind = kind_phys intent = in +[con_ttp] + standard_name = triple_point_temperature_of_water + long_name = triple point temperature of water + units = K + dimensions = () + type = real + kind = kind_phys + intent = in +[con_thgni] + standard_name = temperature_ice_nucleation_starts + long_name = temperature the H.G.Nuc. ice starts + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [epsm1] standard_name = ratio_of_dry_air_to_water_vapor_gas_constants_minus_one long_name = (rd/rv) - 1 @@ -1343,6 +1394,14 @@ dimensions = () type = logical intent = out +[si] + standard_name = sigma_pressure_hybrid_vertical_coordinate + long_name = vertical sigma coordinate for radiation initialization + units = none + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [ico2] standard_name = control_for_co2 long_name = prescribed global mean value (old opernl) diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 6891b0f24..543776e80 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -6,9 +6,6 @@ !> @{ module GFS_rrtmg_setup - use physparam, only : lcrick , lcnorm , lnoprec, & - & ivflip , ipsd0, & - & iswcliq,iovrRad=>iovr use machine, only: kind_phys use radcons, only: ltp, lextop @@ -26,7 +23,7 @@ module GFS_rrtmg_setup ! & VTAGRAD='NCEP-Radiation_driver v5.1 Nov 2012 ' ! & VTAGRAD='NCEP-Radiation_driver v5.0 Aug 2012 ' - !> new data input control variables (set/reset in subroutines radinit/radupdate): + !> new data input control variables (set/reset in subroutine radupdate): integer :: month0 = 0 integer :: iyear0 = 0 integer :: monthd = 0 @@ -41,17 +38,13 @@ module GFS_rrtmg_setup !> \section arg_table_GFS_rrtmg_setup_init Argument Table !! \htmlinclude GFS_rrtmg_setup_init.html !! - subroutine GFS_rrtmg_setup_init ( & - si, levr, ictm, isol, solar_file, ico2, iaer, ntcw, & - num_p3d, npdf3d, ntoz, iovr, & - icliq_sw, crick_proof, ccnorm, & - imp_physics, & - norad_precip, idate, iflip, & - do_RRTMGP, me, lalw1bd, iaermdl, iaerflg, & - aeros_file, con_pi, con_t0c, con_c, con_boltz, & - con_plnk, con_solr_2008, con_solr_2002, co2usr_file,& - co2cyc_file, rad_hr_units, inc_minor_gas, ilwcliq, & - iswcliq, isubcsw, isubclw, iswmode, errmsg, errflg) + subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & + iaer, ntcw, num_p3d, npdf3d, ntoz, iovr, icliq_sw, lcrick, lcnorm, & + imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, iaermdl, & + iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & + con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, rad_hr_units,& + inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, iswmode, ipsd0, & + errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -133,9 +126,9 @@ subroutine GFS_rrtmg_setup_init ( & ! =0: with out sub-column cloud approximation ! ! =1: mcica sub-col approx. prescribed random seed ! ! =2: mcica sub-col approx. provided random seed ! -! crick_proof : control flag for eliminating CRICK ! -! ccnorm : control flag for in-cloud condensate mixing ratio! -! norad_precip : control flag for not using precip in radiation ! +! lcrick : control flag for eliminating CRICK ! +! lcnorm : control flag for in-cloud condensate mixing ratio! +! lnoprec : control flag for not using precip in radiation ! ! idate(4) : ncep absolute date and time of initial condition ! ! (hour, month, day, year) ! ! iflip : control flag for direction of vertical index ! @@ -147,34 +140,27 @@ subroutine GFS_rrtmg_setup_init ( & ! ! ! =================================================================== ! ! + use module_radiation_astronomy, only : sol_init + use module_radiation_aerosols, only : aer_init + use module_radiation_gases, only : gas_init + use module_radiation_clouds, only : cld_init + use rrtmg_lw, only : rlwinit + use rrtmg_sw, only : rswinit implicit none ! interface variables real (kind=kind_phys), intent(in) :: si(:) - integer, intent(in) :: levr - integer, intent(in) :: ictm - integer, intent(in) :: isol - integer, intent(in) :: ico2 - integer, intent(in) :: iaer - integer, intent(in) :: ntcw - integer, intent(in) :: num_p3d - integer, intent(in) :: npdf3d - integer, intent(in) :: ntoz - integer, intent(in) :: iovr - integer, intent(in) :: icliq_sw - logical, intent(in) :: crick_proof - logical, intent(in) :: ccnorm - integer, intent(in) :: imp_physics - logical, intent(in) :: norad_precip + integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & + npdf3d, ntoz, iovr, icliq_sw, imp_physics, iflip, me, & + rad_hr_units, ilwcliq, iswcliq, isubcsw, isubclw, iswmode integer, intent(in) :: idate(:) - integer, intent(in) :: iflip - logical, intent(in) :: do_RRTMGP, lalw1bd, inc_minor_gas - integer, intent(in) :: me, rad_hr_units, ilwcliq, iswcliq, isubcsw, & - isubclw, iswmode + logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & + inc_minor_gas character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file,& co2cyc_file real(kind_phys), intent(in) :: con_pi, con_t0c, con_c, con_boltz, & con_plnk, con_solr_2008, con_solr_2002 + integer, intent(inout) :: ipsd0 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg integer, intent(out) :: iaermdl, iaerflg @@ -204,12 +190,6 @@ subroutine GFS_rrtmg_setup_init ( & return endif - iovrRAD = iovr - lcrick = crick_proof ! control flag for eliminating CRICK - lcnorm = ccnorm ! control flag for in-cld condensate - lnoprec = norad_precip ! precip effect on radiation flag (ferrier microphysics) - ivflip = iflip ! vertical index direction control flag - ! --- assign initial permutation seed for mcica cloud-radiation if ( isubcsw>0 .or. isubclw>0 ) then ! ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) + ipsd0 @@ -225,18 +205,19 @@ subroutine GFS_rrtmg_setup_init ( & & ' iovr=',iovr,' isubcsw=',isubcsw, & & ' isubclw=',isubclw,' icliq_sw=',icliq_sw, & & ' iflip=',iflip,' me=',me - print *,' crick_proof=',crick_proof, & - & ' ccnorm=',ccnorm,' norad_precip=',norad_precip + print *,' lcrick=',lcrick, & + & ' lcnorm=',lcnorm,' lnoprec=',lnoprec endif - call radinit & - & ( si, levr, imp_physics, me, iaermdl, iaerflg, lalw1bd, & - & aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & - & isol, solar_file, con_solr_2008, con_solr_2002, & - & co2usr_file, co2cyc_file, ico2, ictm, ntoz, rad_hr_units, & - & inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, iovr, & - & iswmode, errmsg, errflg ) - + call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002,& + con_pi ) ! astronomy initialization routine + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & + con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, & + errflg, errmsg) ! co2 and other gases initialization routine + call cld_init ( si, levr, imp_physics, me, errflg, errmsg) ! cloud initialization routine + call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, iovr, errflg, errmsg ) ! lw RRTMG initialization routine + call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, iovr, iswmode, errflg, errmsg ) ! sw RRTMG initialization routine if ( me == 0 ) then print *,' Radiation sub-cloud initial seed =',ipsd0, & @@ -314,235 +295,6 @@ subroutine GFS_rrtmg_setup_finalize (errmsg, errflg) end subroutine GFS_rrtmg_setup_finalize - -! Private functions - - - subroutine radinit( si, NLAY, imp_physics, me, iaermdl, iaerflg, lalw1bd, & - aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, isol, & - solar_file, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & - ico2, ictm, rad_hr_units, ntoz, inc_minor_gas, ilwcliq, iswcliq, & - isubcsw, isubclw, iovr, iswmode, errmsg, errflg) -!................................... - -! --- inputs: -! & ( si, NLAY, imp_physics, me, iaermdl, iaerflg) -! --- outputs: -! ( errmsg, errflg ) - -! ================= subprogram documentation block ================ ! -! ! -! subprogram: radinit initialization of radiation calculations ! -! ! -! usage: call radinit ! -! ! -! attributes: ! -! language: fortran 90 ! -! machine: wcoss ! -! ! -! ==================== definition of variables ==================== ! -! ! -! input parameters: ! -! si : model vertical sigma interface ! -! NLAY : number of model vertical layers ! -! imp_physics : MP identifier ! -! me : print control flag ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in module physparam) ! -! isolar : solar constant cntrol flag ! -! = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! -! = 1: use noaa ann-mean tsi tbl abs-scale with cycle apprx! -! = 2: use noaa ann-mean tsi tbl tim-scale with cycle apprx! -! = 3: use cmip5 ann-mean tsi tbl tim-scale with cycl apprx! -! = 4: use cmip5 mon-mean tsi tbl tim-scale with cycl apprx! -! iaerflg : 3-digit aerosol flag (abc for volc, lw, sw) ! -! a:=0 use background stratospheric aerosol ! -! =1 include stratospheric vocanic aeros ! -! b:=0 no topospheric aerosol in lw radiation ! -! =1 compute tropspheric aero in 1 broad band for lw ! -! =2 compute tropspheric aero in multi bands for lw ! -! c:=0 no topospheric aerosol in sw radiation ! -! =1 include tropspheric aerosols for sw ! -! ico2 : co2 data source control flag ! -! =0: use prescribed global mean co2 (old oper) ! -! =1: use observed co2 annual mean value only ! -! =2: use obs co2 monthly data with 2-d variation ! -! ictm : =yyyy#, external data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the ! -! forecast time, no extrapolation. ! -! = 0: use data at initial cond time, if not ! -! available, use latest, no extrapolation. ! -! = 1: use data at the forecast time, if not ! -! available, use latest and extrapolation. ! -! =yyyy0: use yyyy data for the forecast time, ! -! no further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg : ozone data source control flag ! -! =0: use climatological ozone profile ! -! =1: use interactive ozone profile ! -! imp_physics : cloud microphysics scheme control flag ! -! =99 zhao/carr/sundqvist microphysics scheme ! -! =98 zhao/carr/sundqvist microphysics+pdf cloud&cnvc,cnvw ! -! =11 GFDL cloud microphysics ! -! =8 Thompson microphysics scheme ! -! =6 WSM6 microphysics scheme ! -! =10 MG microphysics scheme ! -! iovr : control flag for cloud overlap in radiation ! -! =0: random overlapping clouds ! -! =1: max/ran overlapping clouds ! -! isubcsw : sub-column cloud approx control flag in sw radiation ! -! isubclw : sub-column cloud approx control flag in lw radiation ! -! =0: with out sub-column cloud approximation ! -! =1: mcica sub-col approx. prescribed random seed ! -! =2: mcica sub-col approx. provided random seed ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! lnoprec : precip effect in radiation flag (ferrier microphysics) ! -! =t: snow/rain has no impact on radiation ! -! =f: snow/rain has impact on radiation ! -! ivflip : vertical index direction control flag ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! -! subroutines called: sol_init, aer_init, gas_init, cld_init, ! -! rlwinit, rswinit ! -! ! -! usage: call radinit ! -! ! -! =================================================================== ! -! - - use module_radiation_astronomy, only : sol_init - use module_radiation_aerosols, only : aer_init - use module_radiation_gases, only : gas_init - use module_radiation_clouds, only : cld_init - use rrtmg_lw, only : rlwinit - use rrtmg_sw, only : rswinit - - implicit none - -! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics, iaermdl, iaerflg, & - isol, ico2, ictm, ntoz, rad_hr_units, ilwcliq, iswcliq, isubcsw,& - isubclw, iovr, iswmode - logical, intent(in) :: lalw1bd, inc_minor_gas - real (kind=kind_phys), intent(in) :: si(:), con_pi,con_t0c, con_c, & - con_boltz, con_plnk, con_solr_2008, con_solr_2002 - character(len=26), intent(in) :: aeros_file, solar_file,co2usr_file, co2cyc_file - -! --- outputs: (ccpp error handling) - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg -! --- locals: - -! -!===> ... begin here -! -!> -# Set up control variables and external module variables in -!! module physparam - loz1st = (ntoz == 0) ! first-time clim ozone data read flag - month0 = 0 - iyear0 = 0 - monthd = 0 - - if (me == 0) then -! print *,' NEW RADIATION PROGRAM STRUCTURES -- SEP 01 2004' - print *,' NEW RADIATION PROGRAM STRUCTURES BECAME OPER. ', & - & ' May 01 2007' - print *, VTAGRAD !print out version tag - print *,' - Selected Control Flag settings: ICTMflg=',ictm, & - & ' ISOLar =',isol, ' ICO2flg=',ico2,' IAERflg=',iaerflg, & - & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ntoz - print *,' IVFLIP=',ivflip,' IOVR=',iovr, & - & ' ISUBCSW=',isubcsw,' ISUBCLW=',isubclw - print *,' LCRICK=',lcrick,' LCNORM=',lcnorm,' LNOPREC=',lnoprec - print *,' LTP =',ltp,', add extra top layer =',lextop - - if ( ictm==0 .or. ictm==-2 ) then - print *,' Data usage is limited by initial condition!' - print *,' No volcanic aerosols' - endif - - if ( isubclw == 0 ) then - print *,' - ISUBCLW=',isubclw,' No McICA, use grid ', & - & 'averaged cloud in LW radiation' - elseif ( isubclw == 1 ) then - print *,' - ISUBCLW=',isubclw,' Use McICA with fixed ', & - & 'permutation seeds for LW random number generator' - elseif ( isubclw == 2 ) then - print *,' - ISUBCLW=',isubclw,' Use McICA with random ', & - & 'permutation seeds for LW random number generator' - else - print *,' - ERROR!!! ISUBCLW=',isubclw,' is not a ', & - & 'valid option ' - errflg = 1 - errmsg = 'ERROR(GFS_rrtmg_setup): ISUBCLW flag is invalid' - return - endif - - if ( isubcsw == 0 ) then - print *,' - ISUBCSW=',isubcsw,' No McICA, use grid ', & - & 'averaged cloud in SW radiation' - elseif ( isubcsw == 1 ) then - print *,' - ISUBCSW=',isubcsw,' Use McICA with fixed ', & - & 'permutation seeds for SW random number generator' - elseif ( isubcsw == 2 ) then - print *,' - ISUBCSW=',isubcsw,' Use McICA with random ', & - & 'permutation seeds for SW random number generator' - else - print *,' - ERROR!!! ISUBCSW=',isubcsw,' is not a ', & - & 'valid option ' - errflg = 1 - errmsg = 'ERROR(GFS_rrtmg_setup): ISUBCSW flag is invalid' - return - endif - - if ( isubcsw /= isubclw ) then - print *,' - *** Notice *** ISUBCSW /= ISUBCLW !!!', & - & isubcsw, isubclw - endif - endif - -!> -# Initialization -!! - astronomy initialization routine: -!! call module_radiation_astronomy::sol_init() -!! - aerosols initialization routine: -!! call module_radiation_aerosols::aer_init() -!! - CO2 and other gases intialization routine: -!! call module_radiation_gases::gas_init() -!! - cloud initialization routine: -!! call module_radiation_clouds::cld_init() -!! - LW radiation initialization routine: -!! call module_radlw_main::rlwinit() -!! - SW radiation initialization routine: -!! call module_radsw_main::rswinit() -! Initialization - - call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002,& - con_pi ) ! astronomy initialization routine - call aer_init ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, & - errflg, errmsg) ! co2 and other gases initialization routine - call cld_init ( si, NLAY, imp_physics, me, errflg, errmsg) ! cloud initialization routine - call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, iovr, errflg, errmsg ) ! lw RRTMG initialization routine - call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, iovr, iswmode, errflg, errmsg ) ! sw RRTMG initialization routine -! - return -! - end subroutine radinit - !----------------------------------- - !> This subroutine checks and updates time sensitive data used by !! radiation computations. This subroutine needs to be placed inside !! the time advancement loop but outside of the horizontal grid loop. @@ -597,31 +349,6 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! sdec, cdec : sin and cos of the solar declination angle ! ! solcon : sun-earth distance adjusted solar constant (w/m2) ! ! ! -! external module variables: ! -! iso : solar constant cntrl (in module physparam) ! -! = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! -! = 1: use noaa ann-mean tsi tbl abs-scale with cycle apprx! -! = 2: use noaa ann-mean tsi tbl tim-scale with cycle apprx! -! = 3: use cmip5 ann-mean tsi tbl tim-scale with cycl apprx! -! = 4: use cmip5 mon-mean tsi tbl tim-scale with cycl apprx! -! ictm : =yyyy#, external data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the ! -! forecast time, no extrapolation. ! -! = 0: use data at initial cond time, if not ! -! available, use latest, no extrapolation. ! -! = 1: use data at the forecast time, if not ! -! available, use latest and extrapolation. ! -! =yyyy0: use yyyy data for the forecast time, ! -! no further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ! -! module variables: ! -! loz1st : first-time clim ozone data read flag ! -! ! ! subroutines called: sol_update, aer_update, gas_update ! ! ! ! =================================================================== ! diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 2355b91c2..b6d3520bf 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rrtmg_setup type = scheme - dependencies = iounitdef.f,module_bfmicrophysics.f,physparam.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f + dependencies = iounitdef.f,module_bfmicrophysics.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f,machine.F ######################################################################## @@ -138,14 +138,14 @@ dimensions = () type = integer intent = in -[crick_proof] +[lcrick] standard_name = flag_for_CRICK_proof_cloud_water long_name = flag for CRICK-Proof cloud water units = flag dimensions = () type = logical intent = in -[ccnorm] +[lcnorm] standard_name = flag_for_in_cloud_condensate long_name = flag for cloud condensate normalized by cloud cover units = flag @@ -159,7 +159,7 @@ dimensions = () type = integer intent = in -[norad_precip] +[lnoprec] standard_name = flag_for_turning_off_precipitation_radiative_effect long_name = radiation precip flag for Ferrier/Moorthi units = flag @@ -293,6 +293,13 @@ dimensions = () type = logical intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = inout [iaermdl] standard_name = flag_for_aerosol_radiation_scheme long_name = flag for aerosol scheme to use in radiation diff --git a/physics/GFS_rrtmgp_cloud_overlap.F90 b/physics/GFS_rrtmgp_cloud_overlap.F90 index b294b4a99..28c925600 100644 --- a/physics/GFS_rrtmgp_cloud_overlap.F90 +++ b/physics/GFS_rrtmgp_cloud_overlap.F90 @@ -127,7 +127,6 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, if (iovr_convcld == iovr_dcorr .or. iovr_convcld == iovr_exp .or. iovr_convcld == iovr_exprand) then call get_alpha_exper(nCol, nLev, iovr_convcld, iovr_exprand, deltaZc*0.001, de_lgth, cld_cnv_frac, cnv_cloud_overlap_param) else - de_lgth(:) = 0. cnv_cloud_overlap_param(:,:) = 0. endif endif diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 935500739..842d8e983 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -6,10 +6,6 @@ module GFS_rrtmgp_setup use module_radiation_astronomy, only : sol_init, sol_update use module_radiation_aerosols, only : aer_init, aer_update use module_radiation_gases, only : gas_init, gas_update - ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize - ! *NOTE* These parameters below are required radiation_****** modules. They are not - ! directly used by the RRTMGP routines. - use physparam, only : ivflip implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize @@ -87,8 +83,6 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, end if ! Set radiation parameters - ivflip = iflip ! vertical index direction control flag - if ( ictm==0 .or. ictm==-2 ) then iaerflg = mod(iaer, 100) ! no volcanic aerosols for clim hindcast else @@ -125,23 +119,11 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, iyear0 = 0 monthd = 0 -!> -# Initialization -!! - astronomy initialization routine: -!! call module_radiation_astronomy::sol_init() -!! - aerosols initialization routine: -!! call module_radiation_aerosols::aer_init() -!! - CO2 and other gases intialization routine: -!! call module_radiation_gases::gas_init() - ! Call initialization routines.. call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, co2usr_file, co2cyc_file, ictm, ntoz, ico2, con_pi, errflg, errmsg ) - !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & - ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & - ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& - ! errflg) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ntoz, ictm, con_pi, errflg, errmsg ) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 4f8fe1db4..8a9fd4ef6 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rrtmgp_setup type = scheme - dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,physparam.f,radiation_aerosols.f,radiation_astronomy.f + dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,radiation_aerosols.f,radiation_astronomy.f dependencies = module_mp_thompson.F90,radiation_clouds.f,radiation_gases.f ######################################################################## diff --git a/physics/physparam.f b/physics/physparam.f deleted file mode 100644 index 0dd53a304..000000000 --- a/physics/physparam.f +++ /dev/null @@ -1,214 +0,0 @@ -!> \file physparam.f -!! This file contains module physparam. - -! ========================================================== !!!!! -! module physparam description !!!!! -! ========================================================== !!!!! -! ! -! This module defines commonly used control variables/parameters ! -! in physics related programs. ! -! ! -! Section 1 contains control variables defined in the form of ! -! parameter. They are pre-determined choices and not adjustable ! -! during model's run-time. ! -! ! -! Section 2 contains control variables defined as module variables.! -! They are more flexible to be changed during run-time by either ! -! through input namelist, or through model environment condition. ! -! They are preassigned here as the default values. ! -! ! -!!!!! ========================================================== !!!!! - -!> \defgroup phy_sparam GFS Physics Parameter Module -!! Those variables are grouped together in accordance with functionaity -!! and are given brief descriptions and value specifications. There are -!! two types of attributes (parameters vs. save) designated for the -!! control variables. Those with a "parameter" attribute are prescribed -!! with a preferred option value, while the ones with a "save" attribute -!! are given a default value but could be changed at the model's -!! execution-time (usually through an input of name-list file or through -!! run scripts). - -!> This module defines commonly used control variables and parameters -!! in physics related programs. - module physparam -! -! implicit none - -! --- ... define kind parameters here - -! ** if already exist, use the module containing kind definitions - use machine - -! ** otherwise, define kind parameter here -! implicit none -! integer, public, parameter :: kind_io4 = 4 -! integer, public, parameter :: kind_io8 = 8 -! integer, public, parameter :: kind_phys= selected_real_kind(13,60) ! the '60' maps to 64-bit real -! ..... - -! implicit none -! - public - -!================================================================================== -! Section - 1 - -! control flags are pre-set as run-time non-adjuztable parameters. -!================================================================================== - -! ............................................. ! -!> \name 1.1 Control flags for SW radiation -! ............................................. ! - -!> SW heating rate unit control flag: =1:k/day; =2:k/second. - integer,parameter :: iswrate = 2 - -!> SW minor gases effect control flag (CH4 and O2): =0:no; =1:yes. -!!\n =0: minor gases' effects are not included in calculations -!!\n =1: minor gases' effects are included in calculations - integer,parameter :: iswrgas = 1 - -!> SW optical property for liquid clouds -!!\n =0:input cld opt depth, ignoring iswcice setting -!!\n =1:cloud optical property scheme based on Hu and Stamnes(1993) \cite hu_and_stamnes_1993 method -!!\n =2:cloud optical property scheme based on Hu and Stamnes(1993) -updated - integer,save :: iswcliq = 1 - -!> SW optical property for ice clouds (only iswcliq>0) -!!\n =1:optical property scheme based on Ebert and Curry (1992) -!! \cite ebert_and_curry_1992 method -!!\n =2:optical property scheme based on Streamer v3.0 -!! \cite key_2002 method -!!\n =3:optical property scheme based on Fu's method (1996) -!! \cite fu_1996 method - integer,save :: iswcice = 3 - -!> SW control flag for scattering process approximation -!!\n =1:two-stream delta-eddington (Joseph et al. 1976 -!! \cite joseph_et_al_1976) -!!\n =2:two-stream PIFM (Zdunkowski et al. 1980 -!! \cite zdunkowski_et_al_1980) -!!\n =3:discrete ordinates (Liou, 1973 -!! \cite liou_1973) - integer,parameter :: iswmode = 2 - -! ............................................. ! -!> \name 1.2 Control flags for LW radiation -! ............................................. ! - -!> LW heating rate unit: =1:k/day; =2:k/second. - integer,parameter :: ilwrate = 2 - -!> LW minor gases effect control flag (CH4,N2O,O2,and some CFCs): -!!\n =0: minor gases' effects are not included in calculations -!!\n =1: minor gases' effects are included in calculations - integer,parameter :: ilwrgas = 1 - -!> LW optical property scheme for liquid clouds -!!\n =0:input cloud optical properties directly, not computed within -!!\n =1:input cwp,rew, use Hu and Stamnes(1993) -!! \cite hu_and_stamnes_1993 method - integer,save :: ilwcliq = 1 - -!> LW optical property scheme for ice clouds (only ilwcliq>0) -!!\n =1:optical property scheme based on Ebert and Curry (1992) -!! \cite ebert_and_curry_1992 method -!!\n =2:optical property scheme based on Streamer v3 -!! \cite key_2002 method -!!\n =3:optical property scheme use Fu's method (1998) -!! \cite fu_et_al_1998 method - integer,save :: ilwcice = 3 - -!================================================================================== -! Section - 2 - -! values of control flags might be re-set in initialization subroutines -! (may be adjusted at run time based on namelist input or run condition) -!================================================================================== - -! ............................................. ! -!> \name 2.3 For module radiation_gases -! ............................................. ! - -!> co2 data source control flag -!!\n =0:prescribed value(380 ppmv) -!!\n =1:yearly global averaged annual mean from observations -!!\n =2:monthly 15 degree horizontal resolution from observations -!!\n Opr GFS/CFS=2; see ICO2 in run scripts - integer, save :: ico2flg = 0 - -!> controls external data at initial time and data usage during -!! forecast time -!!\n =-2:as in 0,but superimpose with seasonal climatology cycle -!!\n =-1:use user data,no extrapolation in overtime -!!\n =0:use IC time to select data,no extrapolation in overtime -!!\n =1:use forecast time to select data,extrapolate when necessary -!!\n =yyyy0:use yyyy year of data, no extrapolation -!!\n =yyyy1:use yyyy year of data, extrapolate when necessary -!!\n Opr GFS/CFS=1; see ICTM in run scripts - integer, save :: ictmflg = 0 - -!> ozone data source control flag -!!\n =0:use seasonal climatology ozone data -!!\n >0:use prognostic ozone scheme (also depend on other model control -!! variable at initial time) - integer, save :: ioznflg = 1 - -! ............................................. ! -!>\name 2.4 For module radiation_clouds -! ............................................. ! - -!> cloud optical property scheme control flag -!!\n =0:use diagnostic cloud scheme for cloud cover and mean optical properties -!!\n =1:use prognostic cloud scheme for cloud cover and cloud properties - integer, save :: icldflg = 1 - -!> cloud overlapping control flag for Radiation -!!\n =0:use random cloud overlapping method -!!\n =1:use maximum-random cloud overlapping method -!!\n =2:use maximum cloud overlapping method -!!\n =3:use decorrelation length overlapping method -!!\n =4:use exponential overlapping method -!!\n =5:use exponential-random overlapping method -!!\n Opr GFS/CFS=1; see IOVR in run scripts - integer, save :: iovr = 1 -!!\n Decorrelation length type for iovr = 4 or 5 -!!\n =0:use constant decorrelation length defined by decorr_con (in module physcons) -!!\n =1:use day-of-year and latitude-varying decorrelation length - integer, save :: idcor = 1 - -!> sub-column cloud approx flag in SW radiation -!!\n =0:no McICA approximation in SW radiation -!!\n =1:use McICA with precribed permutation seeds (test mode) -!!\n =2:use McICA with randomly generated permutation seeds -!!\n Opr GFS/CFS=2; see ISUBC_SW in run scripts - integer, save :: isubcsw = 0 -!> sub-column cloud approx flag in LW radiation -!!\n =0:no McICA approximation in LW radiation -!!\n =1:use McICA with prescribed permutation seeds (test mode) -!!\n =2:use McICA with randomly generatedo -!!\n Opr GFS/CFS=2; see ISUBC_LW in run scripts - integer, save :: isubclw = 0 - -!> eliminating CRICK control flag - logical, save :: lcrick =.false. -!> in-cld condensate control flag - logical, save :: lcnorm =.false. -!> precip effect on radiation flag (Ferrier microphysics) - logical, save :: lnoprec =.false. -!> shallow convetion flag - logical, save :: lsashal =.false. - -! ............................................. ! -!> \name 2.6 general purpose -! ............................................. ! - -!> vertical profile indexing flag - integer, save :: ivflip = 1 - -!> initial permutaion seed for mcica radiation - integer, save :: ipsd0 = 0 - integer, save :: ipsdlim = 1e8 -! -!...................................! - end module physparam ! -!===================================! diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index ee7922c99..2266dca09 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -29,8 +29,8 @@ ! imp_physics, imp_physics_nssl, imp_physics_fer_hires, ! ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, ! ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, ! -! imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, ! -! iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, ! +! imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, ! +! iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, ! ! idcor_hogan, idcor_oreopoulos, ! ! imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, ! ! uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, ! @@ -68,12 +68,8 @@ ! ** fu's scheme need to be normalized by snow density (g/m**3/1.0e6)! ! ! ! external modules referenced: ! -! ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! ! 'module module_microphysics' in 'module_bfmicrophysics.f' ! ! ! -! ! ! program history log: ! ! nov 1992, y.h., k.a.c, a.k. - cloud parameterization ! ! 'cldjms' patterned after slingo and slingo's work (jgr, ! @@ -173,13 +169,6 @@ !> This module computes cloud related quantities for radiation computations. module module_radiation_clouds ! - use physparam, only : iovr, idcor, & - & lcrick, lcnorm, lnoprec, & - & ivflip - use physcons, only : con_fvirt, con_ttp, con_rocp, & - & con_t0c, con_pi, con_g, con_rd, & - & con_thgni, decorr_con - use module_microphysics, only : rsipath2 use module_iounitdef, only : NICLTUN use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, & & get_alpha_exper @@ -195,9 +184,7 @@ module module_radiation_clouds ! & VTAGCLD='NCEP-Radiation_clouds v5.0 Aug 2012 ' ! --- set constant parameters - real (kind=kind_phys), parameter :: gfac=1.0e5/con_g & - &, gord=con_g/con_rd - + real (kind=kind_phys) :: gfac,gord integer, parameter, public :: NF_CLDS = 9 !< number of fields in cloud array integer, parameter, public :: NK_CLDS = 3 !< number of cloud vertical domains @@ -281,29 +268,12 @@ subroutine cld_init & ! NLAY : vertical layer number ! ! imp_physics : MP identifier ! ! me : print control flag ! +! imp_physics : cloud microphysics scheme control flag ! ! ! ! outputs: ! ! errflg : CCPP error flag ! ! errmsg : CCPP error message ! ! ! -! external module variables: (in physparam) ! -! imp_physics : cloud microphysics scheme control flag ! -! =99: zhao/carr/sundqvist microphysics cloud ! -! =98: zhao/carr/sundqvist microphysics cloud+pdfcld! -! =11: GFDL microphysics cloud ! -! =8: Thompson microphysics ! -! =6: WSM6 microphysics ! -! =10: MG microphysics ! -! iovr : control flag for cloud overlapping scheme ! -! =0: random overlapping clouds ! -! =1: max/ran overlapping clouds ! -! =2: maximum overlap clouds (mcica only) ! -! =3: decorrelation-length overlap (mcica only) ! -! =4: exponential cloud overlap (AER; mcica only) ! -! =5: exponential-random overlap (AER; mcica only) ! -! ivflip : control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! ! usage: call cld_init ! ! ! ! subroutines called: rhtable ! @@ -321,9 +291,6 @@ subroutine cld_init & integer, intent(out) :: errflg character(len=*), intent(out) :: errmsg -! --- locals: - integer :: k, kl, ier - ! !===> ... begin here ! @@ -359,27 +326,6 @@ subroutine cld_init & return endif endif - -!> - Compute the top of BL cld (llyr), which is the topmost non -!! cld(low) layer for stratiform (at or above lowest 0.1 of the -!! atmosphere). - - if ( ivflip == 0 ) then ! data from toa to sfc - lab_do_k0 : do k = NLAY, 2, -1 - kl = k - if (si(k) < 0.9e0) exit lab_do_k0 - enddo lab_do_k0 - - llyr = kl - else ! data from sfc to top - lab_do_k1 : do k = 2, NLAY - kl = k - if (si(k) < 0.9e0) exit lab_do_k1 - enddo lab_do_k1 - - llyr = kl - 1 - endif ! end_if_ivflip - ! return !................................... @@ -393,20 +339,21 @@ subroutine radiation_clouds_prop & & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: & ccnd, ncndl, cnvw, cnvc, tracer1, & & xlat, xlon, slmsk, dz, delp, IX, LM, NLAY, NLP1, & - & deltaq, sup, me, icloud, kdt, & + & deltaq, sup, dcorr_con, me, icloud, kdt, & & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & - & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & - & idcor_hogan, idcor_oreopoulos, & + & imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, & + & idcor_hogan, idcor_oreopoulos, lcrick, lcnorm, & & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & & effrl, effri, effrr, effrs, effr_in, & & effrl_inout, effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, latdeg, julian, yearlen, gridkm, & + & dzlay, latdeg, julian, yearlen, gridkm, top_at_1, si, & + & con_ttp, con_pi, con_g, con_rd, con_thgni, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: & cld_rwp, cld_rerain, cld_swp, cld_resnow, & & clds, mtop, mbot, de_lgth, alpha & @@ -489,15 +436,17 @@ subroutine radiation_clouds_prop & ! imp_physics_zhao_carr : Zhao-Carr microphysics scheme ! ! imp_physics_zhao_carr_pdf : Zhao-Carr microphysics scheme with PDF clouds ! imp_physics_mg : Morrison-Gettelman microphysics scheme ! -! iovr_rand : choice of cloud-overlap: random (=0) -! iovr_maxrand : choice of cloud-overlap: maximum random (=1) -! iovr_max : choice of cloud-overlap: maximum (=2) -! iovr_dcorr : choice of cloud-overlap: decorrelation length (=3) -! iovr_exp : choice of cloud-overlap: exponential (=4) -! iovr_exprand : choice of cloud-overlap: exponential random (=5) -! idcor_con : choice for decorrelation-length: Use constant value (=0) -! idcor_hogan : choice for decorrelation-length: (=1) -! idcor_oreopoulos: choice for decorrelation-length: (=2) +! iovr : choice of cloud-overlap ! +! iovr_rand : flag of cloud-overlap: random (=0) ! +! iovr_maxrand : flag of cloud-overlap: maximum random (=1) ! +! iovr_max : flag of cloud-overlap: maximum (=2) ! +! iovr_dcorr : flag of cloud-overlap: decorrelation length(=3) ! +! iovr_exp : flag of cloud-overlap: exponential (=4) ! +! iovr_exprand : flag of cloud-overlap: exponential random (=5) ! +! idcor : choice for decorrelation-length ! +! idcor_con : flag for decorrelation-length: Use constant value (=0) +! idcor_hogan : flag for decorrelation-length: (=1) ! +! idcor_oreopoulos: flag for decorrelation-length: (=2) ! ! imfdeepcnv : flag for mass-flux deep convection scheme ! ! imfdeepcnv_gf : flag for scale- & aerosol-aware Grell-Freitas scheme (GSD) ! do_mynnedmf : flag for MYNN-EDMF ! @@ -505,6 +454,7 @@ subroutine radiation_clouds_prop & ! uni_cld : logical - true for cloud fraction from shoc ! ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! +! top_at_1 : logical - true if ordered from toa-2-sfc ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! clouds1 : layer total cloud fraction ! effrl, : effective radius for liquid water @@ -523,7 +473,15 @@ subroutine radiation_clouds_prop & ! latdeg(ix) : latitude (in degrees 90 -> -90) ! ! julian : day of the year (fractional julian day) ! ! yearlen : current length of the year (365/366 days) ! -! gridkm : grid length in km +! gridkm : grid length in km ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -541,20 +499,7 @@ subroutine radiation_clouds_prop & ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! +! alpha(ix,nlay) : alpha decorrelation parameter ! ! ! ! ==================== end of description ===================== ! implicit none @@ -576,19 +521,21 @@ subroutine radiation_clouds_prop & & imp_physics_mg ! Flag for MG scheme integer, intent(in) :: & + & iovr, ! & iovr_rand, ! Flag for random cloud overlap method & iovr_maxrand, ! Flag for maximum-random cloud overlap method & iovr_max, ! Flag for maximum cloud overlap method & iovr_dcorr, ! Flag for decorrelation-length cloud overlap method & iovr_exp, ! Flag for exponential cloud overlap method & iovr_exprand, ! Flag for exponential-random cloud overlap method + & idcor, & idcor_con, & idcor_hogan, & idcor_oreopoulos - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in - logical, intent(in) :: do_mynnedmf, lgfdlmprad + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in, & + & do_mynnedmf, lgfdlmprad, top_at_1, lcrick, lcnorm real (kind=kind_phys), dimension(:,:,:), intent(in) :: ccnd, & & tracer1 @@ -596,9 +543,10 @@ subroutine radiation_clouds_prop & & tlyr, tvly, qlyr, qstl, rhly, cnvw, cnvc, cldcov, & & delp, dz, effrl, effri, effrr, effrs, dzlay, clouds1 - real (kind=kind_phys), intent(in) :: sup + real (kind=kind_phys), intent(in) :: sup, dcorr_con, con_ttp, & + & con_pi, con_g, con_rd, con_thgni real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & - & slmsk + & slmsk, si real(kind=kind_phys), dimension(:), intent(in) :: latdeg, gridkm real(kind=kind_phys), intent(in) :: julian @@ -644,6 +592,10 @@ subroutine radiation_clouds_prop & print*, 'in radiation_clouds_prop=', imp_physics, uni_cld, & & ncndl, lgfdlmprad, do_mynnedmf, imfdeepcnv, kdt end if + + ! + gfac = 1.0e5/con_g + gord = con_g/con_rd do k = 1, NLAY do i = 1, IX @@ -676,7 +628,7 @@ subroutine radiation_clouds_prop & & IX, NLAY, NLP1, cldcov, & & effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -687,7 +639,7 @@ subroutine radiation_clouds_prop & & lmfshal, lmfdeep2, & & cldcov, effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -699,8 +651,8 @@ subroutine radiation_clouds_prop & & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & & xlat, xlon, slmsk, dz, delp, IX, NLAY, NLP1, & & deltaq, sup, kdt, me, dzlay, & - & cldtot, cldcnv, & ! inout - & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cldtot, cldcnv, lcrick, lcnorm, con_thgni, & ! inout + & con_ttp, cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -711,7 +663,7 @@ subroutine radiation_clouds_prop & & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & & xlat, xlon, slmsk, cldcov, dz, delp, & & IX, NLAY, NLP1, dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -721,7 +673,7 @@ subroutine radiation_clouds_prop & & xlon, slmsk, dz,delp, IX, NLAY, NLP1, cldcov, & & effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -743,7 +695,7 @@ subroutine radiation_clouds_prop & & cldcov(:,1:NLAY),effrl_inout(:,:), & & effri_inout(:,:), effrs_inout(:,:), & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -766,7 +718,7 @@ subroutine radiation_clouds_prop & & cld_frac, & & effrl, effri, effrr, effrs, effr_in , & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -781,7 +733,7 @@ subroutine radiation_clouds_prop & & effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -799,7 +751,7 @@ subroutine radiation_clouds_prop & & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:LM), effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, & + & dzlay, gridkm, top_at_1, & & cldtot, cldcnv, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & @@ -821,7 +773,7 @@ subroutine radiation_clouds_prop & & cld_frac, & & effrl, effri, effrr, effrs, effr_in , & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -838,7 +790,7 @@ subroutine radiation_clouds_prop & & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:LM), effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, & + & dzlay, gridkm, top_at_1, & & cldtot, cldcnv, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & @@ -853,7 +805,7 @@ subroutine radiation_clouds_prop & & cldcov(:,1:NLAY), cnvw, effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -888,7 +840,7 @@ subroutine radiation_clouds_prop & call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) endif if (idcor == idcor_con) then - de_lgth(:) = decorr_con + de_lgth(:) = dcorr_con endif ! Call subroutine get_alpha_exper to define alpha parameter for exponential cloud overlap options @@ -913,8 +865,8 @@ subroutine radiation_clouds_prop & call gethml & ! --- inputs: & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, & + & IX, NLAY, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, top_at_1, si, & ! --- outputs: & clds, mtop, mbot & & ) @@ -931,7 +883,7 @@ subroutine progcld_zhao_carr & & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, & & uni_cld, lmfshal, lmfdeep2, cldcov, & & effrl,effri,effrr,effrs,effr_in, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -948,9 +900,7 @@ subroutine progcld_zhao_carr & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_zhao_carr ! -! ! -! subprograms called: gethml ! +! usage: call progcld_zhao_carr ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -986,6 +936,14 @@ subroutine progcld_zhao_carr & ! effrs : effective radius for snow water ! effr_in : logical, if .true. use input effective radii ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -999,19 +957,6 @@ subroutine progcld_zhao_carr & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -1019,7 +964,8 @@ subroutine progcld_zhao_carr & ! --- inputs integer, intent(in) :: IX, NLAY, NLP1 - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in, & + & lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, cldcov, delp, dz, & @@ -1027,6 +973,7 @@ subroutine progcld_zhao_carr & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk + real (kind=kind_phys), intent(in) :: con_ttp ! --- inputs/outputs @@ -1235,7 +1182,7 @@ subroutine progcld_zhao_carr_pdf & & xlat,xlon,slmsk, dz, delp, & & ix, nlay, nlp1, & & deltaq,sup,kdt,me, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcrick, lcnorm, con_thgni, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1252,9 +1199,7 @@ subroutine progcld_zhao_carr_pdf & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_zhao_carr_pdf ! -! ! -! subprograms called: gethml ! +! usage: call progcld_zhao_carr_pdf ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1285,6 +1230,12 @@ subroutine progcld_zhao_carr_pdf & ! deltaq(ix,nlay) : half total water distribution width ! ! sup : supersaturation ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lcrick : control flag for eliminating crick ! +! =t: apply layer smoothing to eliminate crick ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1298,28 +1249,18 @@ subroutine progcld_zhao_carr_pdf & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lcrick : control flag for eliminating crick ! -! =t: apply layer smoothing to eliminate crick ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs integer, intent(in) :: ix, nlay, nlp1,kdt - + logical, intent(in) :: lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, dz, delp, dzlay ! & tlyr, tvly, qlyr, qstl, rhly, clw, cnvw, cnvc ! real (kind=kind_phys), dimension(:,:), intent(in) :: deltaq + real (kind=kind_phys), intent(in) :: con_thgni, con_ttp real (kind=kind_phys), dimension(:,:) :: deltaq, cnvw, cnvc real (kind=kind_phys) qtmp,qsc,rhs real (kind=kind_phys), intent(in) :: sup @@ -1415,7 +1356,7 @@ subroutine progcld_zhao_carr_pdf & do k = 1, nlay do i = 1, ix tem1 = tlyr(i,k) - 273.16 - if(tem1 < con_thgni) then ! for pure ice, has to be consistent with gscond + if(tem1 < (con_thgni - 273.16)) then ! for pure ice, has to be consistent with gscond qsc = sup * qstl(i,k) rhs = sup else @@ -1535,7 +1476,7 @@ subroutine progcld_gfdl_lin & & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, & ! --- inputs: & xlat,xlon,slmsk,cldtot, dz, delp, & & IX, NLAY, NLP1, & - & dzlay, cldtot1, cldcnv, & + & dzlay, cldtot1, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1552,9 +1493,7 @@ subroutine progcld_gfdl_lin & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_gfdl_lin ! -! ! -! subprograms called: gethml ! +! usage: call progcld_gfdl_lin ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1583,6 +1522,12 @@ subroutine progcld_gfdl_lin & ! IX : horizontal dimention ! ! NLAY,NLP1 : vertical layer/level dimensions ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1596,28 +1541,17 @@ subroutine progcld_gfdl_lin & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lsashal : control flag for shallow convection ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs integer, intent(in) :: IX, NLAY, NLP1 - + logical, intent(in) :: lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, cldtot, cnvw, cnvc, & & delp, dz, dzlay + real (kind=kind_phys) :: con_ttp real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk @@ -1785,7 +1719,7 @@ subroutine progcld_fer_hires & & IX, NLAY, NLP1, icloud, & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcnorm, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1802,9 +1736,7 @@ subroutine progcld_fer_hires & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_fer_hires ! -! ! -! subprograms called: gethml ! +! usage: call progcld_fer_hires ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1836,6 +1768,14 @@ subroutine progcld_fer_hires & ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1849,19 +1789,6 @@ subroutine progcld_fer_hires & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -1870,7 +1797,7 @@ subroutine progcld_fer_hires & integer, intent(in) :: IX, NLAY, NLP1, ICLOUD integer, intent(in) :: ntrac, ntcw, ntiw, ntrw - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, cldcov, delp, dz, dzlay @@ -2040,7 +1967,7 @@ subroutine progcld_thompson_wsm6 & & uni_cld, lmfshal, lmfdeep2, cldcov, cnvw, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcnorm, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2058,9 +1985,7 @@ subroutine progcld_thompson_wsm6 & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_thompson_wsm6 ! -! ! -! subprograms called: gethml ! +! usage: call progcld_thompson_wsm6 ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -2091,6 +2016,14 @@ subroutine progcld_thompson_wsm6 & ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2109,19 +2042,6 @@ subroutine progcld_thompson_wsm6 & ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -2130,7 +2050,7 @@ subroutine progcld_thompson_wsm6 & integer, intent(in) :: IX, NLAY, NLP1 integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, qlyr, qstl, rhly, cldcov, delp, dz, dzlay, & @@ -2335,7 +2255,7 @@ subroutine progcld_thompson & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, cldtot, cldcnv, & + & dzlay, gridkm, top_at_1, cldtot, cldcnv, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2354,8 +2274,6 @@ subroutine progcld_thompson & ! ! ! usage: call progcld_thompson ! ! ! -! subprograms called: gethml ! -! ! ! attributes: ! ! language: fortran 90 ! ! machine: ibm-sp, sgi ! @@ -2385,7 +2303,16 @@ subroutine progcld_thompson & ! uni_cld : logical - true for cloud fraction from shoc ! ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! +! top_at_1 : logical - true if vertical ordereing is toa-2-sfc ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2399,19 +2326,6 @@ subroutine progcld_thompson & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -2420,7 +2334,7 @@ subroutine progcld_thompson & integer, intent(in) :: IX, NLAY, NLP1 integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, qlyr, qstl, rhly, cldcov, delp, dz, dzlay, & @@ -2524,7 +2438,7 @@ subroutine progcld_thompson & cldfra1d(:) = 0.0 - if (ivflip .eq. 1) then + if (.not. top_at_1) then do k = 1, NLAY qv1d(k) = qlyr(i,k) qc1d(k) = max(0.0, clw(i,k,ntcw)) @@ -2618,7 +2532,7 @@ subroutine progclduni & & ( plyr,plvl,tlyr,tvly,ccnd,ncnd, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, cldtot, & & effrl,effri,effrr,effrs,effr_in, & - & dzlay, cldtot1, cldcnv, & + & dzlay, cldtot1, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2640,8 +2554,6 @@ subroutine progclduni & ! ! ! usage: call progclduni ! ! ! -! subprograms called: gethml ! -! ! ! attributes: ! ! language: fortran 90 ! ! machine: ibm-sp, sgi ! @@ -2672,6 +2584,14 @@ subroutine progclduni & ! dz (ix,nlay) : layer thickness (km) ! ! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2689,20 +2609,7 @@ subroutine progclduni & ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! +! alpha(ix,nlay) : alpha decorrelation parameter ! ! ! ! ==================== end of description ===================== ! ! @@ -2710,8 +2617,9 @@ subroutine progclduni & ! --- inputs integer, intent(in) :: IX, NLAY, NLP1, ncnd - logical, intent(in) :: effr_in + logical, intent(in) :: effr_in, lcrick, lcnorm + real (kind=kind_phys), intent(in) :: con_ttp real (kind=kind_phys), dimension(:,:,:), intent(in) :: ccnd real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr,& & tlyr, tvly, cldtot, effrl, effri, effrr, effrs, dz, delp, & @@ -2923,8 +2831,8 @@ end subroutine progclduni !>\section detail Detailed Algorithm subroutine gethml & & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & ! --- inputs: - & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, & + & IX, NLAY, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, top_at_1, si, & & clds, mtop, mbot & ! --- outputs: & ) @@ -2962,13 +2870,7 @@ subroutine gethml & ! output variables: ! ! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! ! -! external module variables: (in physparam) ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! +! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! ! internal module variables: ! ! iovr : control flag for cloud overlap ! ! =0 random overlapping clouds ! @@ -2983,8 +2885,10 @@ subroutine gethml & implicit none! ! --- inputs: + logical, intent(in) :: top_at_1 integer, intent(in) :: IX, NLAY integer, intent(in) :: & + & iovr, ! & iovr_rand, ! Flag for random cloud overlap method & iovr_maxrand, ! Flag for maximum-random cloud overlap method & iovr_max, ! Flag for maximum cloud overlap method @@ -2994,7 +2898,7 @@ subroutine gethml & real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, ptop1, & & cldtot, cldcnv, dz - real (kind=kind_phys), dimension(:), intent(in) :: de_lgth + real (kind=kind_phys), dimension(:), intent(in) :: de_lgth, si real (kind=kind_phys), dimension(:,:), intent(in) :: alpha ! --- outputs @@ -3007,11 +2911,30 @@ subroutine gethml & real (kind=kind_phys) :: pcur, pnxt, ccur, cnxt, alfa integer, dimension(IX):: idom, kbt1, kth1, kbt2, kth2 - integer :: i, k, id, id1, kstr, kend, kinc + integer :: i, k, id, id1, kstr, kend, kinc,kl ! !===> ... begin here ! +!> - Compute the top of BL cld (llyr), which is the topmost non +!! cld(low) layer for stratiform (at or above lowest 0.1 of the +!! atmosphere). + + if (top_at_1) then ! data from toa to sfc + lab_do_k0 : do k = NLAY, 2, -1 + kl = k + if (si(k) < 0.9e0) exit lab_do_k0 + enddo lab_do_k0 + llyr = kl + else ! data from sfc to top + lab_do_k1 : do k = 2, NLAY + kl = k + if (si(k) < 0.9e0) exit lab_do_k1 + enddo lab_do_k1 + + llyr = kl - 1 + endif ! end_if_top_at_1 + clds(:,:) = 0.0 do i = 1, IX @@ -3025,7 +2948,7 @@ subroutine gethml & !> - Calculate total and BL cloud fractions (maximum-random cloud !! overlapping is operational). - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc kstr = NLAY kend = 1 kinc = -1 @@ -3033,7 +2956,7 @@ subroutine gethml & kstr = 1 kend = NLAY kinc = 1 - endif ! end_if_ivflip + endif ! end_if_top_at_1 if ( iovr == iovr_rand ) then ! random overlap @@ -3167,7 +3090,7 @@ subroutine gethml & !> - Calculte high, mid, low cloud fractions and vertical indices of !! cloud tops/bases. - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc do i = 1, IX cl1 (i) = 0.0 @@ -3331,7 +3254,7 @@ subroutine gethml & enddo ! end_do_i_loop enddo ! end_do_k_loop - endif ! end_if_ivflip + endif ! end_if_top_at_1 ! return diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index b5eb8ffb9..85204e5ab 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -80,7 +80,7 @@ ! nov 2008 - y-t hou fix bugs in superimposing climatology ! ! seasonal cycle calculations ! ! aug 2011 - y-t hou fix a bug in subr getgases doing vertical ! -! co2 mapping. (for iflip=0 case, not affact opr). ! +! co2 mapping. (for top_at_1 case, not affact opr). ! ! aug 2012 - y-t hou modified subr getozn. moved the if-first ! ! block to subr gas_init to ensure threading safe in ! ! climatology ozone applications. (not affect gfs) ! diff --git a/physics/radlw_main.meta b/physics/radlw_main.meta index 8dc1db046..e336e6011 100644 --- a/physics/radlw_main.meta +++ b/physics/radlw_main.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrtmg_lw type = scheme - dependencies = machine.F,mersenne_twister.f,physcons.F90,physparam.f,radlw_datatb.f,radlw_param.f + dependencies = machine.F,mersenne_twister.f,physcons.F90,radlw_datatb.f,radlw_param.f ######################################################################## [ccpp-arg-table] From 1d8998d80035d36e3250810c546e6a01fb696939 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 31 Aug 2022 16:19:42 +0000 Subject: [PATCH 15/58] Revert change to CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 242275411..d14778b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,7 +195,7 @@ set_target_properties(ccpp_physics PROPERTIES VERSION ${PROJECT_VERSION} target_include_directories(ccpp_physics PUBLIC $) -target_link_libraries(ccpp_physics PUBLIC w3nco::w3nco_d NetCDF::NetCDF_Fortran) +target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d NetCDF::NetCDF_Fortran) # Define where to install the library install(TARGETS ccpp_physics From 82bcd677c7c54efab29bbbb32099519ee687a6b3 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Tue, 6 Sep 2022 20:25:14 +0000 Subject: [PATCH 16/58] Omission from previous commit --- physics/physcons.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/physics/physcons.F90 b/physics/physcons.F90 index 41d37491a..7b7a71c98 100644 --- a/physics/physcons.F90 +++ b/physics/physcons.F90 @@ -53,8 +53,8 @@ module physcons real(kind=kind_phys),parameter:: con_omega =7.2921e-5_kind_phys !< ang vel of earth (\f$s^{-1}\f$) real(kind=kind_phys),parameter:: con_p0 =1.01325e5_kind_phys !< standard atmospheric pressure (\f$Pa\f$) ! real(kind=kind_phys),parameter:: con_solr =1.36822e+3_kind_phys ! solar constant (W/m2)-aer(2001) - real(kind=kind_phys),parameter:: con_solr_old =1.3660e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-Liu(2002) - real(kind=kind_phys),parameter:: con_solr =1.3608e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-nasa-sorce Tim(2008) + real(kind=kind_phys),parameter:: con_solr_2002 =1.3660e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-Liu(2002) + real(kind=kind_phys),parameter:: con_solr_2008 =1.3608e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-nasa-sorce Tim(2008) ! real(kind=kind_phys),parameter:: con_solr =1.36742732e+3_kind_phys ! solar constant (W/m2)-gfdl(1989) - OPR as of Jan 2006 ! Selected geophysics/astronomy constants with kind=kind_dyn real(kind=kind_dyn), parameter:: con_g_dyn =9.80665e+0_kind_dyn !< gravity (\f$m/s^{2}\f$) From 2f9e6041743ae32e8a3c446c1dfd5a5b6cc76d50 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 7 Sep 2022 14:15:50 -0600 Subject: [PATCH 17/58] Adress reviewers comments --- physics/GFS_cloud_diagnostics.F90 | 68 +++++------ physics/GFS_cloud_diagnostics.meta | 6 +- physics/GFS_rrtmg_pre.meta | 4 +- physics/GFS_rrtmg_setup.F90 | 65 +++++----- physics/GFS_rrtmg_setup.meta | 42 +++++++ physics/GFS_rrtmgp_cloud_overlap.meta | 4 +- physics/GFS_rrtmgp_pre.meta | 4 +- physics/radiation_gases.f | 165 +++++++++++++++++++++++--- physics/radlw_main.F90 | 63 +++++++--- physics/radlw_main.meta | 46 ++++++- physics/radsw_main.F90 | 70 +++++++---- physics/radsw_main.meta | 46 ++++++- physics/rrtmgp_aerosol_optics.meta | 4 +- physics/rrtmgp_lw_rte.meta | 4 +- physics/rrtmgp_sw_rte.meta | 4 +- 15 files changed, 457 insertions(+), 138 deletions(-) diff --git a/physics/GFS_cloud_diagnostics.F90 b/physics/GFS_cloud_diagnostics.F90 index 49cb992de..86dc2b518 100644 --- a/physics/GFS_cloud_diagnostics.F90 +++ b/physics/GFS_cloud_diagnostics.F90 @@ -38,47 +38,47 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr, iovr_rand, iovr_maxrand, implicit none ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid-points - nLev ! Number of vertical-layers - integer, intent(in) :: & - iovr, & ! - iovr_rand, & ! Flag for random cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_max, & ! Flag for maximum cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand ! Flag for exponential-random cloud overlap method - logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr, & ! Call LW radiation - top_at_1 - real(kind_phys), intent(in) :: & - con_pi ! Physical constant: pi + integer, intent(in) :: & + nCol, & ! Number of horizontal grid-points + nLev ! Number of vertical-layers + integer, intent(in) :: & + iovr, & ! Choice of cloud-overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_max, & ! Flag for maximum cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand ! Flag for exponential-random cloud overlap method + logical, intent(in) :: & + lsswr, & ! Call SW radiation? + lslwr, & ! Call LW radiation? + top_at_1 ! Vertical ordering flag + real(kind_phys), intent(in) :: & + con_pi ! Physical constant: pi real(kind_phys), dimension(:), intent(in) :: & - lat, & ! Latitude - de_lgth, & ! Decorrelation length - si + lat, & ! Latitude + de_lgth, & ! Decorrelation length + si ! Vertical sigma coordinate real(kind_phys), dimension(:,:), intent(in) :: & - p_lay, & ! Pressure at model-layer - cld_frac ! Total cloud fraction + p_lay, & ! Pressure at model-layer + cld_frac ! Total cloud fraction real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model interfaces + p_lev ! Pressure at model interfaces real(kind_phys), dimension(:,:), intent(in) :: & - deltaZ, & ! Layer thickness (m) - cloud_overlap_param, & ! Cloud-overlap parameter - precip_overlap_param ! Precipitation overlap parameter + deltaZ, & ! Layer thickness (m) + cloud_overlap_param, & ! Cloud-overlap parameter + precip_overlap_param ! Precipitation overlap parameter ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - integer,dimension(:,:),intent(out) :: & - mbota, & ! Vertical indices for cloud tops - mtopa ! Vertical indices for cloud bases + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error flag + integer,dimension(:,:),intent(out) :: & + mbota, & ! Vertical indices for cloud tops + mtopa ! Vertical indices for cloud bases real(kind_phys),dimension(:,:), intent(out) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL + cldsa ! Fraction of clouds for low, middle, high, total and BL ! Local variables integer i,id,iCol,iLay,icld diff --git a/physics/GFS_cloud_diagnostics.meta b/physics/GFS_cloud_diagnostics.meta index 2408397d6..53d1552e6 100644 --- a/physics/GFS_cloud_diagnostics.meta +++ b/physics/GFS_cloud_diagnostics.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_cloud_diagnostics type = scheme - dependencies = machine.F + dependencies = machine.F,radiation_clouds.f ######################################################################## [ccpp-arg-table] @@ -157,8 +157,8 @@ kind = kind_phys intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index cb158346a..228b73f20 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1388,8 +1388,8 @@ kind = kind_phys intent = out [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 543776e80..5ad446985 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -39,12 +39,14 @@ module GFS_rrtmg_setup !! \htmlinclude GFS_rrtmg_setup_init.html !! subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & - iaer, ntcw, num_p3d, npdf3d, ntoz, iovr, icliq_sw, lcrick, lcnorm, & - imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, iaermdl, & - iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, con_plnk, & - con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, rad_hr_units,& - inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, iswmode, ipsd0, & - errmsg, errflg) + iaer, ntcw, num_p3d, npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, & + iovr_max, iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, lcrick, & + lcnorm, imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, & + iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & + con_plnk, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & + rad_hr_units, inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, & + iswmode, ipsd0, errmsg, errflg) + ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -151,8 +153,10 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & ! interface variables real (kind=kind_phys), intent(in) :: si(:) integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & - npdf3d, ntoz, iovr, icliq_sw, imp_physics, iflip, me, & - rad_hr_units, ilwcliq, iswcliq, isubcsw, isubclw, iswmode + npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, iovr_max, & + iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, imp_physics, & + iflip, me, rad_hr_units, ilwcliq, iswcliq, isubcsw, isubclw, & + iswmode integer, intent(in) :: idate(:) logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & inc_minor_gas @@ -197,32 +201,37 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & endif if ( me == 0 ) then - print *,' In rad_initialize (GFS_rrtmg_setup_init), before calling radinit' - print *,' si =',si - print *,' levr=',levr,' ictm=',ictm,' isol=',isol,' ico2=',ico2,& - & ' iaermdl=',iaermdl,' iaerflg=',iaerflg - print *,' np3d=',num_p3d,' ntoz=',ntoz, & - & ' iovr=',iovr,' isubcsw=',isubcsw, & - & ' isubclw=',isubclw,' icliq_sw=',icliq_sw, & - & ' iflip=',iflip,' me=',me - print *,' lcrick=',lcrick, & - & ' lcnorm=',lcnorm,' lnoprec=',lnoprec + print *,' In rad_initialize (GFS_rrtmg_setup_init), before calling RRTMG initialization' + print *,' si =',si + print *,' levr=',levr,' ictm=',ictm,' isol=',isol,' ico2=',ico2,& + ' iaermdl=',iaermdl,' iaerflg=',iaerflg + print *,' np3d=',num_p3d,' ntoz=',ntoz, & + ' iovr=',iovr,' isubcsw=',isubcsw, & + ' isubclw=',isubclw,' icliq_sw=',icliq_sw, & + ' iflip=',iflip,' me=',me + print *,' lcrick=',lcrick, & + ' lcnorm=',lcnorm,' lnoprec=',lnoprec endif - call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002,& - con_pi ) ! astronomy initialization routine - call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! aerosols initialization routine - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, & - errflg, errmsg) ! co2 and other gases initialization routine - call cld_init ( si, levr, imp_physics, me, errflg, errmsg) ! cloud initialization routine - call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, iovr, errflg, errmsg ) ! lw RRTMG initialization routine - call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, iovr, iswmode, errflg, errmsg ) ! sw RRTMG initialization routine + ! Call initialization routines + call sol_init ( me, isol, solar_file, con_solr_2008,con_solr_2002,& + con_pi ) + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, & + con_pi, con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & + con_pi, errflg, errmsg) + call cld_init ( si, levr, imp_physics, me, errflg, errmsg) + call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, & + iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand, errflg, errmsg ) + call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, & + iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand,iswmode, errflg, errmsg ) if ( me == 0 ) then print *,' Radiation sub-cloud initial seed =',ipsd0, & & ' IC-idate =',idate - print *,' return from rad_initialize (GFS_rrtmg_setup_init) - after calling radinit' + print *,' return from rad_initialize (GFS_rrtmg_setup_init) - after calling RRTMG initialization' endif ! is_initialized = .true. diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index b6d3520bf..40da39a1c 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -110,6 +110,48 @@ dimensions = () type = integer intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [isubcsw] standard_name = flag_for_sw_clouds_grid_approximation long_name = flag for sw clouds sub-grid approximation diff --git a/physics/GFS_rrtmgp_cloud_overlap.meta b/physics/GFS_rrtmgp_cloud_overlap.meta index f7d12bed5..cf6a05217 100644 --- a/physics/GFS_rrtmgp_cloud_overlap.meta +++ b/physics/GFS_rrtmgp_cloud_overlap.meta @@ -210,8 +210,8 @@ kind = kind_phys intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 86645cb1a..ff6e262cc 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -364,8 +364,8 @@ kind = kind_phys intent = inout [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index 85204e5ab..797028d97 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -221,7 +221,15 @@ module module_radiation_gases !> This subroutine sets up ozone, co2, etc. parameters. If climatology !! ozone then read in monthly ozone data. -!!\param me print message control flag +!!\param me print message control flag +!!\param co2usr_file co2 user defined data table +!!\param co2cyc_file co2 climotology monthly cycle data table +!!\param ictmflg data ic time/date control flag +!!\param ico2flg co2 data source control flag +!!\param ioznflg ozone data control flag +!!\param con_pi physical constant Pi +!!\param errflg error flag +!!\param errmsg error message !>\section gas_init_gen gas_init General Algorithm !----------------------------------- subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & @@ -233,12 +241,34 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & ! then read in monthly ozone data. ! ! ! ! inputs: ! -! me - print message control flag ! -! co2usr_file - external co2 user defined data table ! -! co2cyc_file - external co2 climotology monthly cycle data table ! +! me - print message control flag ! +! ico2flg - co2 data source control flag ! +! =0: use prescribed co2 global mean value ! +! =1: use input global mean co2 value (co2_glb) ! +! =2: use input 2-d monthly co2 value (co2vmr_sav) ! +! ictmflg - =yyyy#, data ic time/date control flag ! +! =-2: same as 0, but superimpose seasonal cycle ! +! from climatology data set. ! +! =-1: use user provided external data for the fcst ! +! time, no extrapolation. ! +! =0: use data at initial cond time, if not existed ! +! then use latest, without extrapolation. ! +! =1: use data at the forecast time, if not existed ! +! then use latest and extrapolate to fcst time. ! +! =yyyy0: use yyyy data for the forecast time, no ! +! further data extrapolation. ! +! =yyyy1: use yyyy data for the fcst. if needed, do ! +! extrapolation to match the fcst time. ! +! ioznflg - ozone data control flag ! +! =0: use climatological ozone profile ! +! >0: use interactive ozone profile ! +! co2usr_file - external co2 user defined data table ! +! co2cyc_file - external co2 climotology monthly cycle data table ! +! con_pi - physical constant Pi ! ! ! ! outputs: (CCPP error handling) ! -! (errflg, errmsg) ! +! errflg - error flag ! +! errmsg - error message ! ! ! ! internal module variables: ! ! pkstr, o3r - arrays for climatology ozone data ! @@ -508,13 +538,20 @@ end subroutine gas_init !> This subroutine reads in 2-d monthly co2 data set for a specified !! year. Data are in a 15 degree lat/lon horizontal resolution. -!!\param iyear year of the requested data for fcst -!!\param imon month of the year -!!\param iday day of the month -!!\param ihour hour of the day -!!\param loz1st clim ozone 1st time update control flag -!!\param ldoco2 co2 update control flag -!!\param me print message control flag +!!\param iyear year of the requested data for fcst +!!\param imon month of the year +!!\param iday day of the month +!!\param ihour hour of the day +!!\param loz1st clim ozone 1st time update control flag +!!\param ldoco2 co2 update control flag +!!\param me print message control flag +!!\param co2dat_file co2 2d monthly obsv data table +!!\param co2gbl_file co2 global annual mean data table +!!\param ictmflg data ic time/date control flag +!!\param ico2flg co2 data source control flag +!!\param ioznflg ozone data control flag +!!\param errflg error flag +!!\param errmsg error message !>\section gen_gas_update gas_update General Algorithm !----------------------------------- subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & @@ -526,6 +563,50 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! gas_update reads in 2-d monthly co2 data set for a specified year. ! ! data are in a 15 degree lat/lon horizontal resolution. ! ! ! +! inputs: dimemsion ! +! iyear - year of the requested data for fcst 1 ! +! imon - month of the year 1 ! +! iday - day of the month 1 ! +! ihour - hour of the day 1 ! +! loz1st - clim ozone 1st time update control flag 1 ! +! ldoco2 - co2 update control flag 1 ! +! me - print message control flag 1 ! +! ico2flg - co2 data source control flag ! +! =0: use prescribed co2 global mean value ! +! =1: use input global mean co2 value (co2_glb) ! +! =2: use input 2-d monthly co2 value (co2vmr_sav) ! +! ictmflg - =yyyy#, data ic time/date control flag ! +! =-2: same as 0, but superimpose seasonal cycle ! +! from climatology data set. ! +! =-1: use user provided external data for the fcst ! +! time, no extrapolation. ! +! =0: use data at initial cond time, if not existed ! +! then use latest, without extrapolation. ! +! =1: use data at the forecast time, if not existed ! +! then use latest and extrapolate to fcst time. ! +! =yyyy0: use yyyy data for the forecast time, no ! +! further data extrapolation. ! +! =yyyy1: use yyyy data for the fcst. if needed, do ! +! extrapolation to match the fcst time. ! +! ioznflg - ozone data control flag ! +! =0: use climatological ozone profile ! +! >0: use interactive ozone profile ! +! ivflip - vertical profile indexing flag ! +! co2dat_file - external co2 2d monthly obsv data table ! +! co2gbl_file - external co2 global annual mean data table ! +! ! +! outputs: (CCPP error handling) ! +! errflg - error flag ! +! errmsg - error message ! +! ! +! internal module variables: ! +! co2vmr_sav - monthly co2 volume mixing ratio IMXCO2*JMXCO2*12 ! +! co2cyc_sav - monthly cycle co2 vol mixing ratio IMXCO2*JMXCO2*12 ! +! co2_glb - global annual mean co2 mixing ratio ! +! gco2cyc - global monthly mean co2 variation 12 ! +! k1oz,k2oz,facoz ! +! - climatology ozone parameters 1 ! +! ! ! usage: call gas_update ! ! ! ! subprograms called: none ! @@ -691,7 +772,6 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! --- ... set up input data file name - print*,"co2dat_file: ",co2dat_file cfile1 = co2dat_file write(cfile1(19:22),34) idyr 34 format(i4.4) @@ -867,6 +947,9 @@ end subroutine gas_update !!\param xlat (IMAX), grid latitude in radians, default range to !! pi/2 -> -pi/2, otherwise see in-line comment !!\param IMAX, LMAX horizontal/vertical dimensions for output data +!!\param ico2flg (1), co2 data source control flag +!!\param top_at_1 (1), vertical ordering flag +!!\param con_pi (1), physical constant Pi !!\param gasdat (IMAX,LMAX,NF_VGAS) - gases volume mixing ratioes !!\n (:,:,1) - co2 !!\n (:,:,2) - n2o @@ -878,6 +961,12 @@ end subroutine gas_update !!\n (:,:,8) - cfc22 !!\n (:,:,9) - ccl4 !!\n (:,:,10) - cfc113 +!!\n +!> - Internal module variables : +!!\n co2vmr_sav - saved monthly co2 concentration from sub gas_update +!!\n co2_glb - saved global annual mean co2 value from gas_update +!!\n gco2cyc - saved global seasonal variation of co2 climatology +!! in 12-month form !>\section gen_getgases getgases General Algorithm !----------------------------------- subroutine getgases( plvl, xlon, xlat, IMAX, LMAX, ico2flg, & @@ -889,6 +978,39 @@ subroutine getgases( plvl, xlon, xlat, IMAX, LMAX, ico2flg, & ! observed values, all other gases are asigned to the climatological ! ! values. ! ! ! +! inputs: ! +! plvl(IMAX,LMAX+1)- pressure at model layer interfaces (mb) ! +! xlon(IMAX) - grid longitude in radians, ok both 0->2pi or ! +! -pi -> +pi arrangements ! +! xlat(IMAX) - grid latitude in radians, default range to ! +! pi/2 -> -pi/2, otherwise see in-line comment ! +! IMAX, LMAX - horiz, vert dimensions for output data ! +! ico2flg - co2 data source control flag ! +! =0: use prescribed co2 global mean value ! +! =1: use input global mean co2 value (co2_glb) ! +! =2: use input 2-d monthly co2 value (co2vmr_sav)! +! top_at_1 - vertical profile indexing flag ! +! con_pi - physical constant Pi ! +! ! +! outputs: ! +! gasdat(IMAX,LMAX,NF_VGAS) - gases volume mixing ratioes ! +! (:,:,1) - co2 ! +! (:,:,2) - n2o ! +! (:,:,3) - ch4 ! +! (:,:,4) - o2 ! +! (:,:,5) - co ! +! (:,:,6) - cfc11 ! +! (:,:,7) - cfc12 ! +! (:,:,8) - cfc22 ! +! (:,:,9) - ccl4 ! +! (:,:,10) - cfc113 ! +! ! +! note: for lower atmos co2vmr_sav may have clim monthly deviations ! +! superimposed on init-cond co2 value, while co2_glb only ! +! contains the global mean value, thus needs to add the ! +! monthly dglobal mean deviation gco2cyc at upper atmos. for ! +! ictmflg/=-2, this value will be zero. ! +! ! ! usage: call getgases ! ! ! ! subprograms called: none ! @@ -986,7 +1108,8 @@ end subroutine getgases !!\param prslk (IMAX,LM), exner function = \f$(p/p0)^{rocp}\f$ !!\param xlat (IMAX), latitude in radians, default to pi/2 -> !! -pi/2 range, otherwise see in-line comment -!!\param IMAX, LM horizontal and vertical dimensions +!!\param IMAX, LM (1), horizontal and vertical dimensions +!!\param top_at_1 (1), vertical profile indexing flag !!\param o3mmr (IMAX,LM), output ozone profile in mass mixing !! ratio (g/g) !>\section getozn_gen getozn General Algorithm @@ -999,6 +1122,20 @@ subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, o3mmr) ! ! ! this code is originally written By Shrinivas Moorthi ! ! ! +! inputs: ! +! prslk (IMAX,LM) - exner function = (p/p0)**rocp ! +! xlat (IMAX) - latitude in radians, default to pi/2 -> -pi/2 ! +! range, otherwise see in-line comment ! +! IMAX, LM - horizontal and vertical dimensions ! +! top_at_1 - vertical profile indexing flag ! +! ! +! outputs: ! +! o3mmr (IMAX,LM) - output ozone profile in mass mixing ratio (g/g)! +! ! +! module variables: ! +! k1oz, k2oz - ozone data interpolation indices ! +! facoz - ozone data interpolation factor ! +! ! ! usage: call getozn ! ! ! ! =================================================================== ! diff --git a/physics/radlw_main.F90 b/physics/radlw_main.F90 index 341ca47ed..34db600e5 100644 --- a/physics/radlw_main.F90 +++ b/physics/radlw_main.F90 @@ -423,6 +423,8 @@ subroutine rrtmg_lw_run & & icseed,aeraod,aerssa,sfemis,sfgtmp, & & dzlyr,delpin,de_lgth,alpha, & & npts, nlay, nlp1, lprnt, cld_cf, lslwr, top_at_1, iovr, & + & iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + & iovr_exprand, & & inc_minor_gas, ilwcliq, ilwcice, isubclw, & & hlwc,topflx,sfcflx,cldtau, & ! --- outputs & HLW0,HLWB,FLXPRF, & ! --- optional @@ -495,13 +497,19 @@ subroutine rrtmg_lw_run & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud (used for isubclw>0 only) ! -! =3: decorrelation-length overlap (for isubclw>0 only) ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! ! ! output variables: ! ! hlwc (npts,nlay): total sky heating rate (k/day or k/sec) ! @@ -599,7 +607,8 @@ subroutine rrtmg_lw_run & ! --- inputs: integer, intent(in) :: npts, nlay, nlp1, ilwcliq, ilwcice, & - isubclw, iovr + isubclw, iovr, iovr_dcorr, iovr_exp, iovr_exprand, iovr_rand,& + iovr_maxrand, iovr_max integer, intent(in) :: icseed(npts) logical, intent(in) :: lprnt, inc_minor_gas @@ -784,7 +793,7 @@ subroutine rrtmg_lw_run & endif stemp = sfgtmp(iplon) ! surface ground temp - if (iovr == 3) delgth= de_lgth(iplon) ! clouds decorr-length + if (iovr == iovr_dcorr) delgth= de_lgth(iplon) ! clouds decorr-length !> -# Prepare atmospheric profile for use in rrtm. ! the vertical index of internal array is from surface to top @@ -808,7 +817,7 @@ subroutine rrtmg_lw_run & tavel(k)= tlyr(iplon,k1) tz(k) = tlvl(iplon,k1) dz(k) = dzlyr(iplon,k1) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(iplon,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(iplon,k) ! alpha decorrelation !> -# Set absorber amount for h2o, co2, and o3. @@ -921,7 +930,7 @@ subroutine rrtmg_lw_run & tavel(k)= tlyr(iplon,k) tz(k) = tlvl(iplon,k+1) dz(k) = dzlyr(iplon,k) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(iplon,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(iplon,k) ! alpha decorrelation ! --- ... set absorber amount !test use @@ -1311,7 +1320,8 @@ end subroutine rrtmg_lw_run !!\param me print control for parallel process !!\section rlwinit_gen rlwinit General Algorithm subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & - isubclw, iovr, errflg, errmsg ) + isubclw, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr,& + iovr_exp, iovr_exprand, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1334,12 +1344,18 @@ subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! ! iovr - clouds vertical overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud (isubcol>0 only) ! -! =3: decorrelation-length overlap (for isubclw>0 only) ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! ! ! outputs: ! ! errflg - error flag ! @@ -1373,7 +1389,9 @@ subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & ! ====================== end of description block ================= ! ! --- inputs: - integer, intent(in) :: me, rad_hr_units, ilwcliq, isubclw, iovr + integer, intent(in) :: me, rad_hr_units, ilwcliq, isubclw, iovr, & + iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + iovr_exprand logical, intent(in) :: inc_minor_gas ! --- outputs: @@ -1394,6 +1412,13 @@ subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & errflg = 0 errmsg = '' + if ((iovr .ne. iovr_rand) .and. (iovr .ne. iovr_maxrand) .and. & + (iovr .ne. iovr_max) .and. (iovr .ne. iovr_dcorr) .and. & + (iovr .ne. iovr_exp) .and. (iovr .ne. iovr_exprand)) then + errflg = 1 + errmsg = 'ERROR(rlwinit): Error in specification of cloud overlap flag' + endif + if (me == 0) then print *,' - Using AER Longwave Radiation, Version: ', VTAGLW diff --git a/physics/radlw_main.meta b/physics/radlw_main.meta index e336e6011..406f773e3 100644 --- a/physics/radlw_main.meta +++ b/physics/radlw_main.meta @@ -242,8 +242,8 @@ type = logical intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical @@ -255,6 +255,48 @@ dimensions = () type = integer intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [inc_minor_gas] standard_name = flag_to_include_minor_gases_in_rrtmg long_name = flag to include minor trace gases in rrtmg diff --git a/physics/radsw_main.F90 b/physics/radsw_main.F90 index cf6c37346..602fa3ae3 100644 --- a/physics/radsw_main.F90 +++ b/physics/radsw_main.F90 @@ -500,8 +500,8 @@ subroutine rrtmg_sw_run & & dzlyr,delpin,de_lgth,alpha, & & cosz,solcon,NDAY,idxday, & & npts, nlay, nlp1, lprnt, inc_minor_gas, iswcliq, iswcice, & - & isubcsw, iovr, top_at_1, iswmode, & - & cld_cf, lsswr, & + & isubcsw, iovr, top_at_1, iswmode, cld_cf, lsswr, iovr_rand,& + & iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, iovr_exprand,& & hswc,topflx,sfcflx,cldtau, & ! --- outputs & HSW0,HSWB,FLXPRF,FDNCMP, & ! --- optional & cld_lwp, cld_ref_liq, cld_iwp, cld_ref_ice, & @@ -584,13 +584,19 @@ subroutine rrtmg_sw_run & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud ! -! =3: decorrelation-length overlap clouds ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! ! ! output variables: ! ! hswc (npts,nlay): total sky heating rates (k/sec or k/day) ! @@ -680,7 +686,8 @@ subroutine rrtmg_sw_run & ! --- inputs: integer, intent(in) :: npts, nlay, nlp1, NDAY, iswcliq, iswcice, & - isubcsw, iovr, iswmode + isubcsw, iovr, iswmode, iovr_dcorr, iovr_exp, iovr_exprand, & + iovr_rand, iovr_maxrand, iovr_max integer, dimension(:), intent(in) :: idxday, icseed @@ -889,7 +896,7 @@ subroutine rrtmg_sw_run & cosz1 = cosz(j1) sntz1 = f_one / cosz(j1) ssolar = s0fac * cosz(j1) - if (iovr == 3) delgth = de_lgth(j1) ! clouds decorr-length + if (iovr == iovr_dcorr) delgth = de_lgth(j1) ! clouds decorr-length !> - Prepare surface albedo: bm,df - dir,dif; 1,2 - nir,uvv. albbm(1) = sfcalb_nir_dir(j1) @@ -911,7 +918,7 @@ subroutine rrtmg_sw_run & tavel(k) = tlyr(j1,kk) delp (k) = delpin(j1,kk) dz (k) = dzlyr (j1,kk) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(j1,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(j1,k) ! alpha decorrelation !> - Set absorber and gas column amount, convert from volume mixing !! ratio to molec/cm2 based on coldry (scaled to 1.0e-20) @@ -1002,7 +1009,7 @@ subroutine rrtmg_sw_run & tavel(k) = tlyr(j1,k) delp (k) = delpin(j1,k) dz (k) = dzlyr (j1,k) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(j1,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(j1,k) ! alpha decorrelation ! --- ... set absorber amount !test use @@ -1093,11 +1100,11 @@ subroutine rrtmg_sw_run & zcf0 = f_one zcf1 = f_one - if (iovr == 0) then ! random overlapping + if (iovr == iovr_rand) then ! random overlapping do k = 1, nlay zcf0 = zcf0 * (f_one - cfrac(k)) enddo - else if (iovr == 1) then ! max/ran/exp overlapping + else if (iovr == iovr_maxrand) then ! max/ran/exp overlapping do k = 1, nlay if (cfrac(k) > ftiny) then ! cloudy layer zcf1 = min ( zcf1, f_one-cfrac(k) ) @@ -1379,7 +1386,8 @@ end subroutine rrtmg_sw_run !>\section rswinit_gen rswinit General Algorithm !----------------------------------- subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & - isubcsw, iovr, iswmode, errflg, errmsg ) + isubcsw, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr,& + iovr_exp, iovr_exprand, iswmode, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1400,13 +1408,19 @@ subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - clouds vertical overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud ! -! =3: decorrelation-length overlap clouds ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! iswmode - control flag for 2-stream transfer scheme ! ! =1; delta-eddington (joseph et al., 1976) ! ! =2: pifm (zdunkowski et al., 1980) ! @@ -1428,7 +1442,8 @@ subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & ! --- inputs: integer, intent(in) :: me, rad_hr_units, iswcliq, isubcsw, iovr, & - iswmode + iswmode, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand logical, intent(in) :: inc_minor_gas ! --- outputs: character(len=*), intent(out) :: errmsg @@ -1448,6 +1463,13 @@ subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & errflg = 0 errmsg = '' + if ((iovr .ne. iovr_rand) .and. (iovr .ne. iovr_maxrand) .and. & + (iovr .ne. iovr_max) .and. (iovr .ne. iovr_dcorr) .and. & + (iovr .ne. iovr_exp) .and. (iovr .ne. iovr_exprand)) then + errflg = 1 + errmsg = 'ERROR(rswinit): Error in specification of cloud overlap flag' + endif + if (me == 0) then print *,' - Using AER Shortwave Radiation, Version: ',VTAGSW diff --git a/physics/radsw_main.meta b/physics/radsw_main.meta index 222f3ce9e..85e446498 100644 --- a/physics/radsw_main.meta +++ b/physics/radsw_main.meta @@ -288,8 +288,8 @@ type = logical intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical @@ -322,6 +322,48 @@ dimensions = () type = integer intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in [iswmode] standard_name = flag_for_sw_scattering_choice long_name = flag for rrtmg shortwave scattering choice diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index f2fc09be6..5f5946afa 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -22,8 +22,8 @@ type = logical intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/rrtmgp_lw_rte.meta b/physics/rrtmgp_lw_rte.meta index 0ad0754b5..15dbc1062 100644 --- a/physics/rrtmgp_lw_rte.meta +++ b/physics/rrtmgp_lw_rte.meta @@ -72,8 +72,8 @@ type = integer intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/rrtmgp_sw_rte.meta b/physics/rrtmgp_sw_rte.meta index 9ab24c8b3..3f5bf2b3c 100644 --- a/physics/rrtmgp_sw_rte.meta +++ b/physics/rrtmgp_sw_rte.meta @@ -67,8 +67,8 @@ kind = kind_phys intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical From 0650bae3ed02503c904a0e94d05b98c21eb3d725 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Mon, 12 Sep 2022 15:45:26 -0600 Subject: [PATCH 18/58] Fix bug in metadata. --- physics/GFS_rrtmg_setup.F90 | 11 +++++------ physics/GFS_rrtmg_setup.meta | 15 ++++----------- physics/radlw_main.meta | 12 ++++++------ physics/radsw_main.meta | 12 ++++++------ 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 5ad446985..c61ce358e 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -44,8 +44,8 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & lcnorm, imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, & iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & con_plnk, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & - rad_hr_units, inc_minor_gas, ilwcliq, iswcliq, isubcsw, isubclw, & - iswmode, ipsd0, errmsg, errflg) + rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw, iswmode, & + ipsd0, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! @@ -155,8 +155,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, iovr_max, & iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, imp_physics, & - iflip, me, rad_hr_units, ilwcliq, iswcliq, isubcsw, isubclw, & - iswmode + iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode integer, intent(in) :: idate(:) logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & inc_minor_gas @@ -221,10 +220,10 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & con_pi, errflg, errmsg) call cld_init ( si, levr, imp_physics, me, errflg, errmsg) - call rlwinit ( me, rad_hr_units, inc_minor_gas, ilwcliq, isubcsw, & + call rlwinit ( me, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, & iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & iovr_exp, iovr_exprand, errflg, errmsg ) - call rswinit ( me, rad_hr_units, inc_minor_gas, iswcliq, isubclw, & + call rswinit ( me, rad_hr_units, inc_minor_gas, icliq_sw, isubclw, & iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & iovr_exp, iovr_exprand,iswmode, errflg, errmsg ) diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 40da39a1c..bf323676d 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -274,18 +274,11 @@ dimensions = () type = logical intent = in -[ilwcliq] - standard_name = flag_for_rrtmg_lw_cloud_optics - long_name = flag for rrtmg longwave cloud optics +[icliq_lw] + standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation + long_name = lw optical property for liquid clouds units = flag - dimensions = () - type = integer - intent = in -[iswcliq] - standard_name = flag_for_rrtmg_sw_cloud_optics - long_name = flag for rrtmg shortwave cloud optics - units = flag - dimensions = () + dimensions = () type = integer intent = in [con_pi] diff --git a/physics/radlw_main.meta b/physics/radlw_main.meta index 406f773e3..3dccc97b3 100644 --- a/physics/radlw_main.meta +++ b/physics/radlw_main.meta @@ -305,17 +305,17 @@ type = logical intent = in [ilwcliq] - standard_name = flag_for_rrtmg_lw_cloud_optics - long_name = flag for rrtmg longwave cloud optics + standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation + long_name = lw optical property for liquid clouds units = flag - dimensions = () + dimensions = () type = integer intent = in [ilwcice] - standard_name = flag_for_rrtmg_lw_ice_cloud_optics - long_name = flag for rrtmg longwave ice cloud optics + standard_name = flag_for_optical_property_for_ice_clouds_for_longwave_radiation + long_name = lw optical property for ice clouds units = flag - dimensions = () + dimensions = () type = integer intent = in [isubclw] diff --git a/physics/radsw_main.meta b/physics/radsw_main.meta index 85e446498..eff5cdca3 100644 --- a/physics/radsw_main.meta +++ b/physics/radsw_main.meta @@ -295,17 +295,17 @@ type = logical intent = in [iswcice] - standard_name = flag_for_rrtmg_sw_ice_cloud_optics - long_name = flag for rrtmg shortwave ice cloud optics + standard_name = flag_for_optical_property_for_ice_clouds_for_shortwave_radiation + long_name = sw optical property for ice clouds units = flag - dimensions = () + dimensions = () type = integer intent = in [iswcliq] - standard_name = flag_for_rrtmg_sw_cloud_optics - long_name = flag for rrtmg shortwave cloud optics + standard_name = control_for_shortwave_radiation_liquid_clouds + long_name = sw optical property for liquid clouds units = flag - dimensions = () + dimensions = () type = integer intent = in [isubcsw] From 2fe654eddc9e559b91c555f14b1645385cb9128d Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 21 Sep 2022 11:08:26 -0600 Subject: [PATCH 19/58] Address reviewers comments. Bug found in seeding for cloud-sampling in RRTMGP. --- physics/GFS_rrtmg_pre.F90 | 10 ++---- physics/GFS_rrtmg_pre.meta | 2 +- physics/GFS_rrtmgp_cloud_overlap.F90 | 2 +- physics/GFS_rrtmgp_pre.F90 | 50 ++++++++++----------------- physics/GFS_rrtmgp_pre.meta | 8 ++--- physics/GFS_rrtmgp_setup.F90 | 42 +++++++++++++---------- physics/GFS_rrtmgp_setup.meta | 51 +++++----------------------- physics/myjsfc_wrapper.F90 | 2 +- 8 files changed, 59 insertions(+), 108 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 9de3cb16c..d5540a043 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -19,7 +19,7 @@ module GFS_rrtmg_pre !>\section rrtmg_pre_gen General Algorithm subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & imfdeepcnv, imfdeepcnv_gf, me, ncnd, ntrac, num_p3d, npdf3d, ncnvcld3d,& - ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, & + ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, top_at_1, & ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & ntclamt, nleffr, nieffr, nseffr, lndp_type, kdt, & ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, & @@ -45,7 +45,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & aero_dir_fdb, smoke_ext, dust_ext, & - spp_wts_rad, spp_rad, rrfs_smoke_band, top_at_1, ico2, errmsg, errflg) + spp_wts_rad, spp_rad, rrfs_smoke_band, ico2, errmsg, errflg) use machine, only: kind_phys @@ -124,7 +124,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & logical, intent(in) :: lsswr, lslwr, ltaerosol, lgfdlmprad, & uni_cld, effr_in, do_mynnedmf, & lmfshal, lmfdeep2, pert_clds, lcrick,& - lcnorm + lcnorm, top_at_1 logical, intent(in) :: aero_dir_fdb real(kind=kind_phys), dimension(:,:), intent(in) :: smoke_ext, dust_ext @@ -203,7 +203,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & faerlw2,& faerlw3 real(kind=kind_phys), dimension(:,:), intent(out) :: alpha - logical, intent(out) :: top_at_1 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -260,9 +259,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, & errmsg = '' errflg = 0 - ! Vertical ordering - top_at_1 = (prsi(1,1) .lt. prsi(1, LMP)) - if (.not. (lsswr .or. lslwr)) return !--- set commonly used integers diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 228b73f20..752a6e1ed 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1393,7 +1393,7 @@ units = flag dimensions = () type = logical - intent = out + intent = in [si] standard_name = sigma_pressure_hybrid_vertical_coordinate long_name = vertical sigma coordinate for radiation initialization diff --git a/physics/GFS_rrtmgp_cloud_overlap.F90 b/physics/GFS_rrtmgp_cloud_overlap.F90 index 28c925600..0094f8165 100644 --- a/physics/GFS_rrtmgp_cloud_overlap.F90 +++ b/physics/GFS_rrtmgp_cloud_overlap.F90 @@ -100,6 +100,7 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, ! ! Cloud decorrelation length ! + de_lgth(:) = 0. if (idcor == idcor_hogan) then call cmp_dcorr_lgth(nCol, lat, con_pi, de_lgth) endif @@ -116,7 +117,6 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, if (iovr == iovr_dcorr .or. iovr == iovr_exp .or. iovr == iovr_exprand) then call get_alpha_exper(nCol, nLev, iovr, iovr_exprand, deltaZc*0.001, de_lgth, cld_frac, cloud_overlap_param) else - de_lgth(:) = 0. cloud_overlap_param(:,:) = 0. endif diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 9822aaf74..f68cdf000 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -5,19 +5,14 @@ !! \brief This module contains code to prepare model fields for use by the RRTMGP !! radiation scheme. module GFS_rrtmgp_pre - use machine, only: & - kind_phys !< Working type - use funcphys, only: & - fpvs !< Function ot compute sat. vapor pressure over liq. - use module_radiation_astronomy, only: & - coszmn - use module_radiation_gases, only: & - NF_VGAS, & !< Number of active gas species - getgases, & !< Routine to setup trace gases - getozn !< Routine to setup ozone - ! RRTMGP types - use mo_gas_concentrations, only: ty_gas_concs - use radiation_tools, only: check_error_msg,cmp_tlev + use machine, only: kind_phys + use funcphys, only: fpvs + use module_radiation_astronomy, only: coszmn + use module_radiation_gases, only: NF_VGAS, getgases, getozn + use mo_gas_concentrations, only: ty_gas_concs + use radiation_tools, only: check_error_msg,cmp_tlev + + implicit none real(kind_phys), parameter :: & amd = 28.9644_kind_phys, & !< Molecular weight of dry-air (g/mol) @@ -120,12 +115,16 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Inputs integer, intent(in) :: & + me, & ! Current MPI rank nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers nTracers, & ! Number of tracers from model. i_o3, & ! Index into tracer array for ozone - ico2 ! Flag for co2 radiation scheme + ico2, & ! Flag for co2 radiation scheme + iSFC, & ! Vertical index for surface + iTOA ! Vertical index for TOA logical, intent(in) :: & + top_at_1, & ! Vertical ordering flag lsswr, & ! Call SW radiation? lslwr ! Call LW radiation real(kind_phys), intent(in) :: & @@ -164,11 +163,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw character(len=*), intent(out) :: & errmsg ! Error message integer, intent(out) :: & - errflg, & ! Error flag - iSFC, & ! Vertical index for surface - iTOA ! Vertical index for TOA - logical, intent(out) :: & - top_at_1 ! Vertical ordering flag + errflg ! Error flag real(kind_phys), intent(inout) :: & raddt ! Radiation time-step real(kind_phys), dimension(:), intent(inout) :: & @@ -209,20 +204,6 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw errflg = 0 if (.not. (lsswr .or. lslwr)) return - - ! ####################################################################################### - ! What is vertical ordering? - ! ####################################################################################### - top_at_1 = (prsi(1,1) .lt. prsi(1, nLev)) - if (top_at_1) then - iSFC = nLev - iTOA = 1 - iSFC_ilev = iSFC + 1 - else - iSFC = 1 - iTOA = nLev - iSFC_ilev = 1 - endif ! ####################################################################################### ! Compute some fields needed by RRTMGP @@ -384,6 +365,9 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Setup surface ground temperature and ground/air skin temperature if required. ! ####################################################################################### + iSFC_ilev = 1 + if (top_at_1) iSFC_ilev = iSFC + 1 + tsfg(1:NCOL) = t_lev(1:NCOL,iSFC_ilev) tsfa(1:NCOL) = t_lay(1:NCOL,iSFC) diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index ff6e262cc..1c269af0f 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmgp_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,physcons.F90,radcons.f90,radiation_aerosols.f - dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90 + dependencies = radiation_astronomy.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90 ######################################################################## [ccpp-arg-table] @@ -369,21 +369,21 @@ units = flag dimensions = () type = logical - intent = out + intent = in [iSFC] standard_name = vertical_index_for_surface_in_RRTMGP long_name = index for surface layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = in [iTOA] standard_name = vertical_index_for_TOA_in_RRTMGP long_name = index for TOA layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = in [tsfc_radtime] standard_name = surface_skin_temperature_on_radiation_timestep long_name = surface skin temperature on radiation timestep diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 842d8e983..ad1d05cf8 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -9,7 +9,9 @@ module GFS_rrtmgp_setup implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize - + + private + ! Version tag and last revision date character(40), parameter :: & VTAGRAD='NCEP-RRTMGP_driver v1.0 Sep 2019 ' @@ -35,10 +37,9 @@ module GFS_rrtmgp_setup subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & - ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & - norad_precip, lalw1bd, idate, iflip, me, aeros_file, iaermdl, iaerflg, con_pi, & - con_t0c, con_c, con_boltz, con_plnk, solar_file, con_solr_2008, con_solr_2002, & - co2usr_file, co2cyc_file, errmsg, errflg) + ntcw, ntoz, iovr, isubc_sw, isubc_lw, lalw1bd, idate, me, aeros_file, & + iaermdl, iaerflg, con_pi, con_t0c, con_c, con_boltz, con_plnk, solar_file, & + con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, ipsd0, errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -56,18 +57,19 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, real(kind_phys), dimension(:), intent(in) :: & si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & - ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, & - icliq_sw, iflip, me + ntcw, ntoz, iovr, isubc_sw, isubc_lw, & + me logical, intent(in) :: & - crick_proof, ccnorm, norad_precip, lalw1bd + lalw1bd integer, intent(in), dimension(:) :: & idate character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file, co2cyc_file ! Outputs - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - integer, intent(out) :: iaermdl, iaerflg + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + integer, intent(inout) :: ipsd0 + integer, intent(out) :: iaermdl, iaerflg ! Initialize the CCPP error handling variables errmsg = '' @@ -94,6 +96,11 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, errflg = 1 return endif + + ! Assign initial permutation seed for mcica cloud-radiation + if ( isubc_sw>0 .or. isubc_lw>0 ) then + ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) + endif if ( me == 0 ) then print *,' In rad_initialize (GFS_rrtmgp_setup_init), before calling radinit' @@ -102,18 +109,17 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ' ictm = ',ictm, & ' isol = ',isol, & ' ico2 = ',ico2, & - ' iaer = ',iaer, & - ' ntcw = ',ntcw - print *,' np3d = ',num_p3d, & + ' iaermdl = ',iaermdl, & + ' iaerflg = ',iaerflg, & + ' ntcw = ',ntcw, & ' ntoz = ',ntoz, & ' iovr = ',iovr, & ' isubc_sw = ',isubc_sw, & ' isubc_lw = ',isubc_lw, & - ' icliq_sw = ',icliq_sw, & - ' iflip = ',iflip, & + ' ipsd0 = ',ipsd0, & ' me = ',me endif - + loz1st = (ntoz == 0) ! first-time clim ozone data read flag month0 = 0 iyear0 = 0 @@ -123,7 +129,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ntoz, ictm, con_pi, errflg, errmsg ) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, errflg, errmsg ) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 8a9fd4ef6..d47aadb93 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -2,7 +2,7 @@ name = GFS_rrtmgp_setup type = scheme dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,radiation_aerosols.f,radiation_astronomy.f - dependencies = module_mp_thompson.F90,radiation_clouds.f,radiation_gases.f + dependencies = module_mp_thompson.F90,radiation_gases.f ######################################################################## [ccpp-arg-table] @@ -146,13 +146,6 @@ dimensions = () type = integer intent = in -[num_p3d] - standard_name = number_of_microphysics_variables_in_xyz_dimensioned_restart_array - long_name = number of 3D arrays needed for microphysics - units = count - dimensions = () - type = integer - intent = in [ntoz] standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array long_name = tracer index for ozone mixing ratio @@ -181,34 +174,6 @@ dimensions = () type = integer intent = in -[icliq_sw] - standard_name = control_for_shortwave_radiation_liquid_clouds - long_name = sw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[crick_proof] - standard_name = flag_for_CRICK_proof_cloud_water - long_name = flag for CRICK-Proof cloud water - units = flag - dimensions = () - type = logical - intent = in -[ccnorm] - standard_name = flag_for_in_cloud_condensate - long_name = flag for cloud condensate normalized by cloud cover - units = flag - dimensions = () - type = logical - intent = in -[norad_precip] - standard_name = flag_for_turning_off_precipitation_radiative_effect - long_name = radiation precip flag for Ferrier/Moorthi - units = flag - dimensions = () - type = logical - intent = in [lalw1bd] standard_name = flag_for_longwave_aerosol_band_properties long_name = flag for band or multiband longwave aerosol properties @@ -223,13 +188,6 @@ dimensions = (4) type = integer intent = in -[iflip] - standard_name = control_for_vertical_index_direction - long_name = flag for vertical index direction control - units = flag - dimensions = () - type = integer - intent = in [me] standard_name = mpi_rank long_name = current MPI-rank @@ -301,6 +259,13 @@ type = character kind = len=26 intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = none + dimensions = () + type = integer + intent = inout [iaermdl] standard_name = flag_for_aerosol_radiation_scheme long_name = flag for aerosol scheme to use in radiation diff --git a/physics/myjsfc_wrapper.F90 b/physics/myjsfc_wrapper.F90 index 81cb36765..cebd2a9f1 100644 --- a/physics/myjsfc_wrapper.F90 +++ b/physics/myjsfc_wrapper.F90 @@ -334,7 +334,7 @@ SUBROUTINE myjsfc_wrapper_run( & & ,phy_f2d_myj(1:im,13) & & ,1,im,1,1,1,levs & & ,1,im,1,1,1,levs & - & ,1,im,1,1,1,levs) + & ,1,im,1,1,1,levs, errmsg, errflg) do i = 1, im if(flag_iter(i))then From 51b9243107a4c886e35b270768cd501f602d4534 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 22 Sep 2022 10:52:18 -0600 Subject: [PATCH 20/58] Update CODEOWNERS file --- CODEOWNERS | 170 ++++++++++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index cf7a886aa..a8cbf59ca 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,127 +4,127 @@ # Default codeowners for files that don't have specific owners: -* @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +* @grantfirl @ChunxiZhang-NOAA @dustinswales @mzhangw # The following lines are from the CCPP Primary Schemes Points of Contact # https://docs.google.com/spreadsheets/d/14y0Th_sSpCqlssEMNfSZ_Ni9wrpPqfpPY0kRG7jCZB8/edit#gid=0 # (Internal NOAA document.) -smoke/* @haiqinli @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +smoke/* @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/cs_conv_aw_adj.* @AnningCheng-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cs_conv.* @AnningCheng-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cu_gf* @hannahcbarnes @haiqinli @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sascnvn.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cu_ntiedtke* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich -physics/rascnv.* @SMoorthi-emc @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/cs_conv_aw_adj.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cs_conv.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cu_gf* @hannahcbarnes @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sascnvn.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cu_ntiedtke* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rascnv.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/samfdeepcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/samfshalcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/samfaerosols.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/samfdeepcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfshalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfaerosols.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/shalcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/unified_ugwp* @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/ugwp_driver_v0.F @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/drag_suite.* @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/shalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/unified_ugwp* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwp_driver_v0.F @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/drag_suite.* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gwdc.* @Songyou184 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gwdps.* @Songyou184 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/gwdc.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gwdps.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gfdl_fv_sat_adj.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gfdl_cloud_microphys.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/gfdl_fv_sat_adj.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_gfdl_cloud_microphys.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/multi_gases.F90 @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/module_gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/multi_gases.F90 @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/mp_fer_hires.* @ericaligo-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MP_FER_HIRES.* @ericaligo-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/mp_fer_hires.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_MP_FER_HIRES.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mp_thompson* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/precpd.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gscond.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/precpd.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gscond.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/m_micro* @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/m_micro* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/ozphys* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/ozphys* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/satmedmfvdif.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/satmedmfvdifq.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfpbl.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfscu.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfpbltq.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfscuq.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/satmedmfvdif.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/satmedmfvdifq.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpbl.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfscu.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpbltq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfscuq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/shinhongvdif.* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich -physics/ysuvdif.* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich +physics/shinhongvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ysuvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @JongilHan66 @WeiguoWang-NOAA @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich +physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @JongilHan66 @WeiguoWang-NOAA @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/moninedmf.* @JongilHan66 @WeiguoWang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/moninedmf.* @JongilHan66 @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_BL_MYJPBL.* @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MYJPBL_wrapper.* @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/module_BL_MYJPBL.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_MYJPBL_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_bl_mynn.* @joeolson42 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MYNNPBL_wrapper.* @joeolson42 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/module_bl_mynn.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_MYNNPBL_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gcm_shoc.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/moninshoc.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/gcm_shoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/moninshoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/rte-rrtmgp @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radiation_tools.* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/rrtmgp_lw_rte.met* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/rrtmgp_sw_rte.met* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/rte-rrtmgp @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_tools.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_lw_rte.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_sw_rte.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radlw_main.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/HWRF_mcica_random_numbers.F90 @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/HWRF_mersenne_twister.F90 @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radlw_datatb.f @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radsw_datatb.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radsw_main.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/radlw_main.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/HWRF_mcica_random_numbers.F90 @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/HWRF_mersenne_twister.F90 @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radlw_datatb.f @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radsw_datatb.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radsw_main.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radsw_param.f @dustinswales @Qingfu-Liu @mjiacono @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/radsw_param.f @dustinswales @Qingfu-Liu @mjiacono @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/rayleigh_damp.* @yangfanglin @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/flake* @YihuaWu-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/rayleigh_damp.* @yangfanglin @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/flake* @YihuaWu-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sfc_drv.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sflx.f @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/surface_perturbation.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/sfc_drv.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sflx.f @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/surface_perturbation.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/*noahmp* @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/*noahmp* @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/namelist_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/namelist_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/namelist_soilveg_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/set_soilveg_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_sf_ruclsm.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_soil_pre.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_drv_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/namelist_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/set_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_ruclsm.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_soil_pre.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_drv_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/date_def.f @XuLi-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/*nst* @XuLi-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/date_def.f @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/*nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sfc_ocean.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_diff.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/sfc_ocean.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diff.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/h2ophys.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/h2ophys.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sfc_sice.* @wd20xw @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_cice.* @wd20xw @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +physics/sfc_sice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_cice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales ######################################################################## From f5ca603e55d705b0fdcddfafb096da0d643f8a44 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 22 Sep 2022 14:34:52 -0600 Subject: [PATCH 21/58] Update CODEOWNERS --- CODEOWNERS | 262 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 167 insertions(+), 95 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index a8cbf59ca..55373ae36 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -12,119 +12,191 @@ # (Internal NOAA document.) smoke/* @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales - +physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aerinterp.F90 @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/bl_mynn_common.f90 @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/calpreciptype.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_orowam2017.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_tauamf_data.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cnvc90.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cs_conv_aw_adj.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cs_conv.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cu_gf* @hannahcbarnes @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sascnvn.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cu_ntiedtke* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/rascnv.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/samfdeepcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/samfshalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/samfaerosols.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/shalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/unified_ugwp* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/ugwp_driver_v0.F @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/date_def.f @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/dcyc2t3.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales physics/drag_suite.* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - +physics/flake* @YihuaWu-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/funcphys.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/fv_sat_adj.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gcycle.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/get_phi_fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/get_prs_fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFDL_parse_tracers.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_sfc_layer.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_cloud_diagnostics.* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_DCNV_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_DCNV_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_debug.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_GWD_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_GWD_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_MP_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_MP_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_common.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_phys_time_vary.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_phys_time_vary.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfs_phy_tracer_config.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_radiation_surface.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rad_time_vary.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rad_time_vary.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_cloud_mp.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_cloud_overlap.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_lw_post.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_pre.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_setup.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_sw_post.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_sw_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_setup.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_SCNV_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_SCNV_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_1.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_2.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_4.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_5.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_phys_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_rad_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_stateout_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_stateout_update.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_inter.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_loop_control_part1.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_loop_control_part2.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_time_vary_pre.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_time_vary_pre.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gocart_tracer_config_stub.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/gwdc.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/gwdps.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/gfdl_fv_sat_adj.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/module_gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/multi_gases.F90 @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/mp_fer_hires.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_MP_FER_HIRES.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/precpd.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gscond.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/m_micro* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/ozphys* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/satmedmfvdif.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/satmedmfvdifq.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2o_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2ointerp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2ophys.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/hedmf.* @JongilHan66 @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iccn_def.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iccninterp.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iounitdef.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/lsm_noah.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/lsm_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/machine.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/maximum_hourly_diagnostics.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mersenne_twister.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfpbl.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/mfscu.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpblt.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfpbltq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfscu.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfscuq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/shinhongvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/ysuvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @JongilHan66 @WeiguoWang-NOAA @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/moninedmf.* @JongilHan66 @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - +physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/m_micro* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_bfmicrophysics.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_BL_MYJPBL.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_MYJPBL_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales - physics/module_bl_mynn.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_MYNNPBL_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/gcm_shoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_MP_FER_HIRES.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_nssl_2mom.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_exchcoef.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_SF_JSFC.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_mynn.F90 @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_ruclsm.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_soil_pre.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales physics/moninshoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/rte-rrtmgp @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radiation_tools.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/rrtmgp_lw_rte.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/rrtmgp_sw_rte.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/radlw_main.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/HWRF_mcica_random_numbers.F90 @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/HWRF_mersenne_twister.F90 @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radlw_datatb.f @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radsw_datatb.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radsw_main.* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/radsw_param.f @dustinswales @Qingfu-Liu @mjiacono @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/rayleigh_damp.* @yangfanglin @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/flake* @YihuaWu-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/sfc_drv.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sflx.f @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/surface_perturbation.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/*noahmp* @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_fer_hires.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_nssl.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/multi_gases.F90 @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/myjpbl_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/myjsfc_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mynnedmf_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mynnsfc_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/namelist_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales - physics/namelist_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/*noahmp* @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozinterp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozne_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozphys* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/physcons.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/physparam.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/phys_tend.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/progsigma_calc.f90 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radcons.f90 @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_aerosols.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_astronomy.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_cloud_overlap.F90 @dustinswales @mjiacono @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_clouds.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_gases.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_surface.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_tools.F90 @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radlw_* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radsw_* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rad_sw_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rascnv.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rayleigh_damp.* @yangfanglin @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_cloud_optics.F90 @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_pre.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_aerosol_optics.* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_lw_* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_sw_* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_sw_cloud_optics.F90 @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_sw_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rte-rrtmgp @RobertPincus @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfdeepcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfshalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfaerosols.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sascnvn.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/satmedmfvdif.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/satmedmfvdifq.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/scm_sfc_flux_spec.* @grantfirl @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales physics/set_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_sf_ruclsm.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_soil_pre.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sfc_drv_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/date_def.f @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/*nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/sfc_ocean.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_cice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diag.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diag_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/sfc_diff.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales - -physics/h2ophys.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales - +physics/sfc_nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_ocean.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/sfc_sice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/sfc_cice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales +#physics/sfcsub.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sflx.f @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sgscloud_radpost.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sgscloud_radpre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shinhongvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/surface_perturbation.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @WeiguoWang-NOAA @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwp_driver_v0.F @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwpv1_gsldrag.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwpv1_gsldrag_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/unified_ugwp* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ysuvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/zhaocarr_gscond.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/zhaocarr_precpd.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales ######################################################################## From d0d7d509c5e1c013093f09b2c44b05ab5eb9488b Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Mon, 17 Oct 2022 21:47:45 +0000 Subject: [PATCH 22/58] Update CODEOWNERS --- CODEOWNERS | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 55373ae36..3cf17b8bb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -19,7 +19,7 @@ physics/bl_mynn_common.f90 @joeolson42 physics/calpreciptype.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cires_orowam2017.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cires_tauamf_data.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_ugwp* @ValeryYudin-NOAA @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales physics/cnvc90.* @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -38,7 +38,7 @@ physics/get_phi_fv3.* physics/get_prs_fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales physics/GFDL_parse_tracers.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/gfdl_sfc_layer.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_sfc_layer.* @ZhanZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/GFS_cloud_diagnostics.* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales physics/GFS_DCNV_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/GFS_DCNV_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -92,7 +92,7 @@ physics/gwdc.* @Songyou184 physics/gwdps.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/h2o_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/h2ointerp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/h2ophys.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2ophys.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales physics/hedmf.* @JongilHan66 @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/iccn_def.F @grantfirl @ChunxiZhang-NOAA @dustinswales physics/iccninterp.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -103,7 +103,7 @@ physics/machine.* physics/maximum_hourly_diagnostics.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mersenne_twister.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfpbl.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/mfpblt.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpblt.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfpbltq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfscu.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mfscuq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -119,11 +119,11 @@ physics/module_mp_radar.* @gthompsnWRF @RuiyuSun physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_sf_exchcoef.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/module_SF_JSFC.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_SF_JSFC.F90 @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_sf_mynn.F90 @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_sf_ruclsm.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales physics/module_soil_pre.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/moninshoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/moninshoc.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mp_fer_hires.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mp_nssl.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -137,13 +137,12 @@ physics/namelist_soilveg_ruc.* @tanyasmirnova physics/*noahmp* @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales physics/ozinterp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/ozne_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/ozphys* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozphys* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales physics/physcons.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/physparam.f @grantfirl @ChunxiZhang-NOAA @dustinswales physics/phys_tend.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/progsigma_calc.f90 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales physics/radcons.f90 @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/radiation_aerosols.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_aerosols.f @Qingfu-Liu @dustinswales @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/radiation_astronomy.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales physics/radiation_cloud_overlap.F90 @dustinswales @mjiacono @grantfirl @ChunxiZhang-NOAA @dustinswales physics/radiation_clouds.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales @@ -186,11 +185,11 @@ physics/sgscloud_radpost.* physics/sgscloud_radpre.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/shalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/shinhongvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/shoc.* @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shoc.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales physics/surface_perturbation.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @WeiguoWang-NOAA @AlexBelochitski-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/ugwp_driver_v0.F @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/ugwpv1_gsldrag.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwpv1_gsldrag.* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/ugwpv1_gsldrag_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales physics/unified_ugwp* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales From 469ef08b05e7dd74fd4d1adc557d9d18241a63ad Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 27 Oct 2022 13:10:24 -0600 Subject: [PATCH 23/58] Update CODEOWNERS --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 3cf17b8bb..15821a791 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -163,8 +163,8 @@ physics/rrtmgp_sw_* @dustinswales physics/rrtmg_sw_cloud_optics.F90 @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales physics/rrtmg_sw_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales physics/rte-rrtmgp @RobertPincus @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/samfdeepcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales -physics/samfshalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfdeepcnv.* @JongilHan66 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfshalcnv.* @JongilHan66 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales physics/samfaerosols.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/sascnvn.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales physics/satmedmfvdif.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales From 6d74eafffee0b1a5e3763a1dd1fb01b17d896078 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 27 Oct 2022 14:36:24 -0600 Subject: [PATCH 24/58] Changes to metadata to accommodate standard_name rules. --- physics/GFS_phys_time_vary.fv3.meta | 6 ++--- physics/GFS_rad_time_vary.fv3.meta | 4 +-- physics/GFS_rad_time_vary.scm.meta | 4 +-- physics/GFS_rrtmg_pre.meta | 12 ++++----- physics/GFS_rrtmg_setup.meta | 38 ++++++++++++++--------------- physics/GFS_rrtmgp_setup.meta | 24 +++++++++--------- physics/radsw_main.meta | 6 ++--- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index 36ac38ab9..ce8c6c54b 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -45,9 +45,9 @@ type = logical intent = in [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = in diff --git a/physics/GFS_rad_time_vary.fv3.meta b/physics/GFS_rad_time_vary.fv3.meta index 387625796..19eb41dc2 100644 --- a/physics/GFS_rad_time_vary.fv3.meta +++ b/physics/GFS_rad_time_vary.fv3.meta @@ -137,14 +137,14 @@ [ipsd0] standard_name = initial_seed_for_mcica long_name = initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = in [ipsdlim] standard_name = limit_for_initial_seed_for_mcica long_name = limit for initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = in diff --git a/physics/GFS_rad_time_vary.scm.meta b/physics/GFS_rad_time_vary.scm.meta index 387625796..19eb41dc2 100644 --- a/physics/GFS_rad_time_vary.scm.meta +++ b/physics/GFS_rad_time_vary.scm.meta @@ -137,14 +137,14 @@ [ipsd0] standard_name = initial_seed_for_mcica long_name = initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = in [ipsdlim] standard_name = limit_for_initial_seed_for_mcica long_name = limit for initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = in diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 34aade056..53f05225b 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -220,16 +220,16 @@ type = integer intent = in [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = in [iaerflg] - standard_name = flag_for_aerosol_effects_in_radiation - long_name = flag for aerosol effects to include in radiation - units = flag + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 dimensions = () type = integer intent = in diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index d6f0b0e7a..5821de33f 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -167,9 +167,9 @@ type = integer intent = in [iswmode] - standard_name = flag_for_sw_scattering_choice - long_name = flag for rrtmg shortwave scattering choice - units = flag + standard_name = control_for_sw_scattering_choice + long_name = control of rrtmg shortwave scattering choice + units = 1 dimensions = () type = integer intent = in @@ -261,9 +261,9 @@ kind = len=26 intent = in [rad_hr_units] - standard_name = flag_for_radiation_heating_rate_units - long_name = flag to control heating rate units - units = count + standard_name = control_for_radiation_heating_rate_units + long_name = control of heating rate units + units = 1 dimensions = () type = integer intent = in @@ -322,9 +322,9 @@ kind = kind_phys intent = in [lalw1bd] - standard_name = flag_for_longwave_aerosol_band_properties - long_name = flag for band or multiband longwave aerosol properties - units = flag + standard_name = do_longwave_aerosol_band_properties + long_name = control of band or multiband longwave aerosol properties + units = 1 dimensions = () type = logical intent = in @@ -345,21 +345,21 @@ [ipsd0] standard_name = initial_seed_for_mcica long_name = initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = inout [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = out [iaerflg] - standard_name = flag_for_aerosol_effects_in_radiation - long_name = flag for aerosol effects to include in radiation - units = flag + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 dimensions = () type = integer intent = out @@ -428,9 +428,9 @@ type = integer intent = in [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = in diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index d47aadb93..ad4a8a765 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -175,9 +175,9 @@ type = integer intent = in [lalw1bd] - standard_name = flag_for_longwave_aerosol_band_properties - long_name = flag for band or multiband longwave aerosol properties - units = flag + standard_name = do_longwave_aerosol_band_properties + long_name = control of band or multiband longwave aerosol properties + units = 1 dimensions = () type = logical intent = in @@ -267,16 +267,16 @@ type = integer intent = inout [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = out [iaerflg] - standard_name = flag_for_aerosol_effects_in_radiation - long_name = flag for aerosol effects to include in radiation - units = flag + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 dimensions = () type = integer intent = out @@ -390,9 +390,9 @@ type = integer intent = in [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = in diff --git a/physics/radsw_main.meta b/physics/radsw_main.meta index eff5cdca3..1edb6fcac 100644 --- a/physics/radsw_main.meta +++ b/physics/radsw_main.meta @@ -365,9 +365,9 @@ type = integer intent = in [iswmode] - standard_name = flag_for_sw_scattering_choice - long_name = flag for rrtmg shortwave scattering choice - units = flag + standard_name = control_for_sw_scattering_choice + long_name = control of rrtmg shortwave scattering choice + units = 1 dimensions = () type = integer intent = in From 4900b309c9a15c9544c64ae42b343458f203031e Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 2 Nov 2022 10:02:34 -0600 Subject: [PATCH 25/58] Omission from previous commit. --- physics/GFS_rrtmg_setup.meta | 6 +++--- physics/rrtmgp_aerosol_optics.meta | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 5821de33f..93319fe75 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -435,9 +435,9 @@ type = integer intent = in [iaerflg] - standard_name = flag_for_aerosol_effects_in_radiation - long_name = flag for aerosol effects to include in radiation - units = flag + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 dimensions = () type = integer intent = in diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index 5f5946afa..74c0f4f70 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -175,16 +175,16 @@ kind = kind_phys intent = in [iaermdl] - standard_name = flag_for_aerosol_radiation_scheme - long_name = flag for aerosol scheme to use in radiation - units = flag + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 dimensions = () type = integer intent = in [iaerflg] - standard_name = flag_for_aerosol_effects_in_radiation - long_name = flag for aerosol effects to include in radiation - units = flag + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 dimensions = () type = integer intent = in From 786cd2083f7e77fa3c5597ad1fabd63cd833ba56 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Tue, 22 Nov 2022 11:11:09 -0700 Subject: [PATCH 26/58] Omission from previous commit --- physics/GFS_rrtmgp_setup.meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index ad4a8a765..2bba14506 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -262,7 +262,7 @@ [ipsd0] standard_name = initial_seed_for_mcica long_name = initial permutaion seed for mcica radiation - units = none + units = 1 dimensions = () type = integer intent = inout From fb6fdb9914cb3e9c2cbed4b91c32d7de3e868ba8 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Tue, 22 Nov 2022 15:43:49 -0700 Subject: [PATCH 27/58] Move declaration to init. --- physics/GFS_rrtmg_setup.F90 | 10 +++++----- physics/GFS_rrtmg_setup.meta | 16 ++++++++++++++++ physics/radiation_clouds.f | 12 ++++++------ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index addd847a2..384d5252d 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -42,9 +42,9 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & iovr_max, iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, lcrick, & lcnorm, imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, & iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & - con_plnk, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, & - rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw, iswmode, & - ipsd0, ltp, lextop, errmsg, errflg) + con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd, co2usr_file, & + co2cyc_file, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw,& + iswmode, ipsd0, ltp, lextop, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -162,7 +162,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file,& co2cyc_file real(kind_phys), intent(in) :: con_pi, con_t0c, con_c, con_boltz, & - con_plnk, con_solr_2008, con_solr_2002 + con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd integer, intent(inout) :: ipsd0 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -220,7 +220,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & con_pi, con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & con_pi, errflg, errmsg) - call cld_init ( si, levr, imp_physics, me, errflg, errmsg) + call cld_init ( si, levr, imp_physics, me, con_g, con_rd, errflg, errmsg) call rlwinit ( me, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, & iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & iovr_exp, iovr_exprand, errflg, errmsg ) diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 93319fe75..adf6d8750 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -321,6 +321,22 @@ type = real kind = kind_phys intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in [lalw1bd] standard_name = do_longwave_aerosol_band_properties long_name = control of band or multiband longwave aerosol properties diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 0b7fba648..bb851c607 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -252,7 +252,7 @@ module module_radiation_clouds !!\param me print control flag !>\section cld_init General Algorithm subroutine cld_init & - & ( si, NLAY, imp_physics, me, errflg, errmsg ) + & ( si, NLAY, imp_physics, me, con_g, con_rd, errflg, errmsg ) ! =================================================================== ! ! ! ! abstract: cld_init is an initialization program for cloud-radiation ! @@ -281,7 +281,7 @@ subroutine cld_init & ! --- inputs: integer, intent(in) :: NLAY, me, imp_physics - real (kind=kind_phys), intent(in) :: si(:) + real (kind=kind_phys), intent(in) :: si(:), con_g, con_rd ! --- outputs: integer, intent(out) :: errflg @@ -294,6 +294,10 @@ subroutine cld_init & errmsg = '' errflg = 0 + ! Initialze module parameters + gfac = 1.0e5/con_g + gord = con_g/con_rd + if (me == 0) then print *, VTAGCLD !print out version tag print *,' - Using Prognostic Cloud Method' @@ -588,10 +592,6 @@ subroutine radiation_clouds_prop & print*, 'in radiation_clouds_prop=', imp_physics, uni_cld, & & ncndl, lgfdlmprad, do_mynnedmf, imfdeepcnv, kdt end if - - ! - gfac = 1.0e5/con_g - gord = con_g/con_rd do k = 1, NLAY do i = 1, IX From 7a5b0818c4eb38082c32eadaa7f8baf479f24adf Mon Sep 17 00:00:00 2001 From: Grant Firl Date: Tue, 22 Nov 2022 09:40:39 -0500 Subject: [PATCH 28/58] Merge pull request #9 from dustinswales/add_cnvcldcnd_mp2rad_cplng Couple convective cloud to radiation --- physics/GFS_rrtmgp_cloud_mp.F90 | 49 +++++++++++++++++++++++--------- physics/GFS_rrtmgp_cloud_mp.meta | 15 ++++++++++ physics/radiation_clouds.f | 16 ++++++----- 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/physics/GFS_rrtmgp_cloud_mp.F90 b/physics/GFS_rrtmgp_cloud_mp.F90 index 2acf8b4da..c76f40da1 100644 --- a/physics/GFS_rrtmgp_cloud_mp.F90 +++ b/physics/GFS_rrtmgp_cloud_mp.F90 @@ -50,11 +50,12 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & deltaZ, deltaZc, deltaP, qc_mynn, qi_mynn, cld_pbl_frac, con_g, con_rd, con_eps, & - con_ttp, doGP_cldoptics_PADE, doGP_cldoptics_LUT, cld_frac, cld_lwp, cld_reliq, & + con_ttp, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_smearclds, & + cld_frac, cld_lwp, cld_reliq, & cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - errmsg, errflg) + cldfra2d, errmsg, errflg) implicit none ! Inputs @@ -92,7 +93,8 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic uni_cld, & ! Flag for unified cloud scheme lmfdeep2, & ! Flag for mass flux deep convection doGP_cldoptics_LUT, & ! Flag to do GP cloud-optics (LUTs) - doGP_cldoptics_PADE ! (PADE approximation) + doGP_cldoptics_PADE, & ! (PADE approximation) + doGP_smearclds ! If true, add sgs clouds to gridmean clouds real(kind_phys), intent(in) :: & con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air @@ -135,6 +137,8 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic iwp_ex, & ! Total ice water path from explicit microphysics lwp_fc, & ! Total liquid water path from cloud fraction scheme iwp_fc ! Total ice water path from cloud fraction scheme + real(kind_phys), dimension(:), intent(out) :: & + cldfra2d ! Instantaneous 2D (max-in-column) cloud fraction real(kind_phys), dimension(:,:),intent(inout) :: & cld_frac, & ! Cloud-fraction for stratiform clouds cld_lwp, & ! Water path for stratiform liquid cloud-particles @@ -267,8 +271,9 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic endif call cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, & - relhum, con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH = .true.) + relhum, con_ttp, con_g, con_rd, con_eps, alpha0, cnv_mixratio, lwp_ex, & + iwp_ex, lwp_fc, iwp_fc, cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, & + cond_cfrac_onRH = .true., doGP_smearclds = doGP_smearclds) endif ! Bound effective radii for RRTMGP, LUT's for cloud-optics go from @@ -293,6 +298,14 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic endif endif + ! Instantaneous 2D (max-in-column) cloud fraction + do iCol = 1, nCol + cldfra2d(iCol) = 0._kind_phys + do iLay = 1, nLev-1 + cldfra2d(iCol) = max(cldfra2d(iCol), cld_frac(iCol,iLay)) + enddo + enddo + precip_frac(1:nCol,1:nLev) = cld_frac(1:nCol,1:nLev) end subroutine GFS_rrtmgp_cloud_mp_run @@ -659,13 +672,14 @@ end subroutine cloud_mp_uni !! \section cloud_mp_thompson_gen General Algorithm subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, relhum, & - con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, cld_frac, cld_lwp,& - cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH) + con_ttp, con_g, con_rd, con_eps, alpha0, cnv_mixratio, lwp_ex, iwp_ex, lwp_fc, & + iwp_fc, cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH, doGP_smearclds) implicit none ! Inputs logical, intent(in), optional :: & - cond_cfrac_onRH + cond_cfrac_onRH, & ! If true, cloud-fracion set to unity when rh>99% + doGP_smearclds ! If true, add sgs clouds to gridmean clouds integer, intent(in) :: & nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers @@ -677,6 +691,7 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c i_cldsnow, & ! cloud snow amount. i_cldgrpl ! cloud groupel amount. real(kind_phys), intent(in) :: & + con_ttp, & ! Triple point temperature of water (K) con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air con_eps, & ! Physical constant: gas constant air / gas constant H2O @@ -687,7 +702,8 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c qs_lay, & ! Saturation vapor pressure (Pa) q_lay, & ! water-vapor mixing ratio (kg/kg) relhum, & ! Relative humidity - p_lay ! Pressure at model-layers (Pa) + p_lay, & ! Pressure at model-layers (Pa) + cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) real(kind_phys), dimension(:,:), intent(in) :: & p_lev ! Pressure at model-level interfaces (Pa) real(kind_phys), dimension(:,:,:),intent(in) :: & @@ -707,16 +723,15 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c cld_rwp ! Cloud rain water path ! Local variables - real(kind_phys) :: tem1, pfac, cld_mr, deltaP + real(kind_phys) :: tem1, pfac, cld_mr, deltaP, tem2 real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate integer :: iCol,iLay,l ! Cloud condensate cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water - cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water - cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel - tracer(1:nCol,1:nLev,i_cldgrpl) + cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain hydrometeors + cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) ! -snow hydrometeors cld_lwp(:,:) = 0.0 cld_iwp(:,:) = 0.0 @@ -726,6 +741,12 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c tem1 = 1.0e5/con_g do iLay = 1, nLev-1 do iCol = 1, nCol + ! Add convective cloud to gridmean cloud? + if (doGP_smearclds) then + tem2 = min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) + cld_condensate(iCol,iLay,1) = cld_condensate(iCol,iLay,1) + cnv_mixratio(iCol,iLay)*(1._kind_phys - tem2) + cld_condensate(iCol,iLay,2) = cld_condensate(iCol,iLay,2) + cnv_mixratio(iCol,iLay)*tem2 + endif ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1 * deltaP) @@ -738,7 +759,7 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c cld_frac(iCol,iLay) = 1._kind_phys else cld_mr = cld_condensate(iCol,iLay,1) + cld_condensate(iCol,iLay,2) + & - cld_condensate(iCol,iLay,4) + cld_condensate(iCol,iLay,3) + cld_condensate(iCol,iLay,4) cld_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & qs_lay(iCol,iLay), relhum(iCol,iLay), cld_mr, alpha0) endif diff --git a/physics/GFS_rrtmgp_cloud_mp.meta b/physics/GFS_rrtmgp_cloud_mp.meta index 4f48d53ef..1eb870da8 100644 --- a/physics/GFS_rrtmgp_cloud_mp.meta +++ b/physics/GFS_rrtmgp_cloud_mp.meta @@ -462,6 +462,13 @@ dimensions = () type = logical intent = in +[doGP_smearclds] + standard_name = flag_for_implicit_sgs_cloud_in_RRTMGP + long_name = logical flag to impicit SGS cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in [cld_frac] standard_name = total_cloud_fraction long_name = layer total cloud fraction @@ -646,6 +653,14 @@ type = real kind = kind_phys intent = inout +[cldfra2d] + standard_name = max_in_column_cloud_fraction + long_name = instantaneous 2D (max-in-column) cloud fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 47b9b79fa..bf255ce00 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -2160,7 +2160,7 @@ subroutine progcld_thompson_wsm6 & integer :: i, k, id, nf ! --- constant values - real (kind=kind_phys), parameter :: xrc3 = 200. + real (kind=kind_phys), parameter :: xrc3 = 100. ! !===> ... begin here @@ -2177,7 +2177,7 @@ subroutine progcld_thompson_wsm6 & rei (i,k) = re_ice(i,k) rer (i,k) = rrain_def ! default rain radius to 1000 micron res (i,k) = re_snow(i,K) -! tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) + tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) clwf(i,k) = 0.0 enddo enddo @@ -2208,12 +2208,14 @@ subroutine progcld_thompson_wsm6 & enddo enddo -!> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . - +!> - Compute total-cloud liquid/ice condensate path in \f$ g/m^2 \f$. +!> The total condensate includes convective condensate. do k = 1, NLAY-1 do i = 1, IX - cwp(i,k) = max(0.0, clw(i,k,ntcw) * gfac * delp(i,k)) - cip(i,k) = max(0.0, clw(i,k,ntiw) * gfac * delp(i,k)) + cwp(i,k) = max(0.0, (clw(i,k,ntcw)+cnvw(i,k)* + & (1.-tem2d(i,k))) * gfac * delp(i,k)) + cip(i,k) = max(0.0, (clw(i,k,ntiw) + cnvw(i,k)* + & tem2d(i,k)) *gfac * delp(i,k)) crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) csp(i,k) = max(0.0, clw(i,k,ntsw) * gfac * delp(i,k)) enddo @@ -3902,7 +3904,7 @@ subroutine cloud_fraction_mass_flx_2 & clwmin = 0.0 do k = 1, NLAY-1 do i = 1, IX - clwt = 1.0e-10 * (plyr(i,k)*0.001) + clwt = 1.0e-6 * (plyr(i,k)*0.001) if (clwf(i,k) > clwt) then if(rhly(i,k) > 0.99) then From d083f87f42f0adafbd37add81b79440e3e166ed7 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Mon, 19 Dec 2022 17:12:20 -0700 Subject: [PATCH 29/58] Bugfox in argument list --- physics/radiation_clouds.f | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 07ef01a1a..81a845fd2 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -723,7 +723,7 @@ subroutine radiation_clouds_prop & call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - & ntsw-1,ntgl-1, & + & ntsw-1,ntgl-1,con_ttp, & & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:NLAY), cnvw, effrl_inout, & & effri_inout, effrs_inout, & @@ -796,7 +796,7 @@ subroutine radiation_clouds_prop & call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - & ntsw-1,ntgl-1, & + & ntsw-1,ntgl-1,con_ttp, & & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:NLAY), cnvw, effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & @@ -1958,7 +1958,7 @@ end subroutine progcld_fer_hires subroutine progcld_thompson_wsm6 & & ( plyr,plvl,tlyr,qlyr,qstl,rhly,clw, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, & - & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl, & + & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl,con_ttp, & & IX, NLAY, NLP1, & & uni_cld, lmfshal, lmfdeep2, cldcov, cnvw, & & re_cloud,re_ice,re_snow, & @@ -2058,7 +2058,7 @@ subroutine progcld_thompson_wsm6 & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - + real (kind=kind_phys), intent(in) :: con_ttp ! --- inputs/outputs real (kind=kind_phys), dimension(:,:), intent(inout) :: & From 2ffa0f547335fe127be678d72509b8bbeed63e21 Mon Sep 17 00:00:00 2001 From: ChunxiZhang-NOAA <49283036+ChunxiZhang-NOAA@users.noreply.github.com> Date: Tue, 7 Feb 2023 09:49:16 -0500 Subject: [PATCH 30/58] Merge pull request #34 from dustinswales/rrtmgp_refactor RRTMGP refactoring --- .gitmodules | 2 +- CMakeLists.txt | 12 - physics/GFS_rrtmgp_cloud_mp.F90 | 48 +- physics/GFS_rrtmgp_cloud_mp.meta | 6 +- physics/GFS_rrtmgp_lw_post.F90 | 188 ----- physics/GFS_rrtmgp_lw_post.meta | 253 ------- physics/GFS_rrtmgp_post.F90 | 394 ++++++++++ ...tmgp_sw_post.meta => GFS_rrtmgp_post.meta} | 191 ++++- physics/GFS_rrtmgp_pre.F90 | 118 +-- physics/GFS_rrtmgp_pre.meta | 136 ++-- physics/GFS_rrtmgp_setup.F90 | 6 +- physics/GFS_rrtmgp_setup.meta | 2 +- physics/GFS_rrtmgp_sw_post.F90 | 286 -------- physics/GFS_rrtmgp_sw_pre.F90 | 95 --- physics/GFS_rrtmgp_sw_pre.meta | 124 ---- physics/rrtmgp_aerosol_optics.F90 | 66 +- physics/rrtmgp_aerosol_optics.meta | 80 +- physics/rrtmgp_lw_cloud_optics.F90 | 218 +----- physics/rrtmgp_lw_cloud_optics.meta | 412 ----------- physics/rrtmgp_lw_cloud_sampling.F90 | 170 ----- physics/rrtmgp_lw_cloud_sampling.meta | 226 ------ physics/rrtmgp_lw_gas_optics.F90 | 121 +--- physics/rrtmgp_lw_gas_optics.meta | 203 ------ physics/rrtmgp_lw_main.F90 | 611 ++++++++++++++++ physics/rrtmgp_lw_main.meta | 641 ++++++++++++++++ physics/rrtmgp_lw_pre.F90 | 61 -- physics/rrtmgp_lw_pre.meta | 47 -- physics/rrtmgp_lw_rte.F90 | 208 ------ physics/rrtmgp_lw_rte.meta | 208 ------ physics/rrtmgp_sw_cloud_optics.F90 | 244 +------ physics/rrtmgp_sw_cloud_optics.meta | 393 ---------- physics/rrtmgp_sw_cloud_sampling.F90 | 174 ----- physics/rrtmgp_sw_cloud_sampling.meta | 240 ------ physics/rrtmgp_sw_gas_optics.F90 | 137 +--- physics/rrtmgp_sw_gas_optics.meta | 201 ------ physics/rrtmgp_sw_main.F90 | 683 ++++++++++++++++++ physics/rrtmgp_sw_main.meta | 664 +++++++++++++++++ physics/rrtmgp_sw_rte.F90 | 219 ------ physics/rrtmgp_sw_rte.meta | 240 ------ physics/rte-rrtmgp | 2 +- 40 files changed, 3470 insertions(+), 4860 deletions(-) delete mode 100644 physics/GFS_rrtmgp_lw_post.F90 delete mode 100644 physics/GFS_rrtmgp_lw_post.meta create mode 100644 physics/GFS_rrtmgp_post.F90 rename physics/{GFS_rrtmgp_sw_post.meta => GFS_rrtmgp_post.meta} (71%) delete mode 100644 physics/GFS_rrtmgp_sw_post.F90 delete mode 100644 physics/GFS_rrtmgp_sw_pre.F90 delete mode 100644 physics/GFS_rrtmgp_sw_pre.meta delete mode 100644 physics/rrtmgp_lw_cloud_optics.meta delete mode 100644 physics/rrtmgp_lw_cloud_sampling.F90 delete mode 100644 physics/rrtmgp_lw_cloud_sampling.meta delete mode 100644 physics/rrtmgp_lw_gas_optics.meta create mode 100644 physics/rrtmgp_lw_main.F90 create mode 100644 physics/rrtmgp_lw_main.meta delete mode 100644 physics/rrtmgp_lw_pre.F90 delete mode 100644 physics/rrtmgp_lw_pre.meta delete mode 100644 physics/rrtmgp_lw_rte.F90 delete mode 100644 physics/rrtmgp_lw_rte.meta delete mode 100644 physics/rrtmgp_sw_cloud_optics.meta delete mode 100644 physics/rrtmgp_sw_cloud_sampling.F90 delete mode 100644 physics/rrtmgp_sw_cloud_sampling.meta delete mode 100644 physics/rrtmgp_sw_gas_optics.meta create mode 100644 physics/rrtmgp_sw_main.F90 create mode 100644 physics/rrtmgp_sw_main.meta delete mode 100644 physics/rrtmgp_sw_rte.F90 delete mode 100644 physics/rrtmgp_sw_rte.meta diff --git a/.gitmodules b/.gitmodules index 75e5ea836..8758980ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "physics/rte-rrtmgp"] path = physics/rte-rrtmgp url = https://github.com/earth-system-radiation/rte-rrtmgp - branch = dtc/ccpp + branch = main diff --git a/CMakeLists.txt b/CMakeLists.txt index d14778b06..482081614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,14 +81,10 @@ get_filename_component(LOCAL_CURRENT_SOURCE_DIR ${FULL_PATH_TO_CMAKELISTS} DIREC # List of files that need to be compiled without OpenMP set(SCHEMES_OPENMP_OFF ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_optics.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_constants.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_reorder.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_string.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/kernels/mo_gas_optics_kernels.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/kernels/mo_rrtmgp_util_reorder_kernels.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/tests/mo_testing_io.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/tests/clear_sky_regression.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_rrtmgp_clr_all_sky.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_fluxes_byband.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/solar_variability/mo_solar_variability.F90 @@ -97,14 +93,6 @@ set(SCHEMES_OPENMP_OFF ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_ ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_compute_bc.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_sampling.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_optics.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/mo_load_coefficients.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/rrtmgp_rfmip_sw.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/mo_rfmip_io.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/rrtmgp_rfmip_lw.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/mo_simple_netcdf.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/rrtmgp_allsky.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/mo_load_cloud_coefficients.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/mo_garand_atmos_io.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_rte_config.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_source_functions.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_rte_sw.F90 diff --git a/physics/GFS_rrtmgp_cloud_mp.F90 b/physics/GFS_rrtmgp_cloud_mp.F90 index 9ca340763..32104b7f8 100644 --- a/physics/GFS_rrtmgp_cloud_mp.F90 +++ b/physics/GFS_rrtmgp_cloud_mp.F90 @@ -27,7 +27,7 @@ module GFS_rrtmgp_cloud_mp reice_min = 10.0, & ! Minimum ice size allowed by GFDL MP scheme reice_max = 150.0 ! Maximum ice size allowed by GFDL MP scheme - public GFS_rrtmgp_cloud_mp_run + public GFS_rrtmgp_cloud_mp_init, GFS_rrtmgp_cloud_mp_run, GFS_rrtmgp_cloud_mp_finalize contains @@ -45,7 +45,7 @@ module GFS_rrtmgp_cloud_mp subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, & i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, i_cldliq_nc, i_cldice_nc, i_twa, kdt, & imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, doSWrad, doLWrad, effr_in, lmfshal, & - ltaerosol,mraerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & + ltaerosol,mraerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & lgfdlmprad, do_mynnedmf, uni_cld, lmfdeep2, p_lev, p_lay, t_lay, qs_lay, q_lay, & relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & @@ -462,6 +462,7 @@ subroutine cloud_mp_MYNN(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum enddo end subroutine cloud_mp_MYNN + !> \ingroup GFS_rrtmgp_cloud_mp !! Compute cloud radiative properties for SAMF convective cloud scheme. !! @@ -484,47 +485,48 @@ subroutine cloud_mp_SAMF(nCol, nLev, t_lay, p_lev, p_lay, qs_lay, relhum, nCol, & ! Number of horizontal grid points nLev ! Number of vertical layers real(kind_phys), intent(in) :: & - con_g, & ! Physical constant: gravitational constant - con_ttp, & ! Triple point temperature of water (K) + con_g, & ! Physical constant: gravity (m s-2) + con_ttp, & ! Triple point temperature of water (K) alpha0 ! real(kind_phys), dimension(:,:),intent(in) :: & - t_lay, & ! Temperature at layer centers (K) - p_lev, & ! Pressure at layer interfaces (Pa) - p_lay, & ! - qs_lay, & ! - relhum, & ! - cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) + t_lay, & ! Temperature at layer-centers (K) + p_lev, & ! Pressure at layer-interfaces (Pa) + p_lay, & ! Presure at layer-centers (Pa) + qs_lay, & ! Specific-humidity at layer-centers (kg/kg) + relhum, & ! Relative-humidity (1) + cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) ! Outputs real(kind_phys), dimension(:,:),intent(inout) :: & cld_cnv_lwp, & ! Convective cloud liquid water path cld_cnv_reliq, & ! Convective cloud liquid effective radius cld_cnv_iwp, & ! Convective cloud ice water path cld_cnv_reice, & ! Convective cloud ice effecive radius - cld_cnv_frac ! Convective cloud-fraction (1) + cld_cnv_frac ! Convective cloud-fraction ! Local integer :: iCol, iLay - real(kind_phys) :: tem1, deltaP, clwc + real(kind_phys) :: tem0, tem1, deltaP, clwc + tem0 = 1.0e5/con_g do iLay = 1, nLev do iCol = 1, nCol if (cnv_mixratio(iCol,iLay) > 0._kind_phys) then tem1 = min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 - clwc = max(0.0, cnv_mixratio(iCol,iLay)) * con_g * deltaP - cld_cnv_iwp(iCol,iLay) = clwc * tem1 - cld_cnv_lwp(iCol,iLay) = clwc - cld_cnv_iwp(iCol,iLay) + clwc = max(0.0, cnv_mixratio(iCol,iLay)) * tem0 * deltaP + cld_cnv_iwp(iCol,iLay) = clwc * tem1 + cld_cnv_lwp(iCol,iLay) = clwc - cld_cnv_iwp(iCol,iLay) cld_cnv_reliq(iCol,iLay) = reliq_def cld_cnv_reice(iCol,iLay) = reice_def ! Xu-Randall (1996) cloud-fraction. - cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & + cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & qs_lay(iCol,iLay), relhum(iCol,iLay), cnv_mixratio(iCol,iLay), alpha0) endif enddo enddo end subroutine cloud_mp_SAMF - + !> \ingroup GFS_rrtmgp_cloud_mp !! This routine computes the cloud radiative properties for a "unified cloud". !! - "unified cloud" implies that the cloud-fraction is PROVIDED. @@ -656,7 +658,6 @@ subroutine cloud_mp_uni(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrai enddo ! nLev end subroutine cloud_mp_uni - !> \ingroup GFS_rrtmgp_cloud_mp !! This routine computes the cloud radiative properties for the Thompson cloud micro- !! physics scheme. @@ -834,11 +835,11 @@ function cld_frac_XuRandall(p_lay, qs_lay, relhum, cld_mr, alpha) return end function -!> \ingroup GFS_rrtmgp_cloud_mp -!! This routine is a wrapper to update the Thompson effective particle sizes used by the -!! RRTMGP radiation scheme. -!! -!! \section cmp_reff_Thompson_gen General Algorithm + ! ###################################################################################### + ! This routine is a wrapper to update the Thompson effective particle sizes used by the + ! RRTMGP radiation scheme. + ! + ! ###################################################################################### subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol, & mraerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow) @@ -922,4 +923,5 @@ subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice enddo end subroutine cmp_reff_Thompson + end module GFS_rrtmgp_cloud_mp diff --git a/physics/GFS_rrtmgp_cloud_mp.meta b/physics/GFS_rrtmgp_cloud_mp.meta index 1eb870da8..b782e73b4 100644 --- a/physics/GFS_rrtmgp_cloud_mp.meta +++ b/physics/GFS_rrtmgp_cloud_mp.meta @@ -345,9 +345,9 @@ kind = kind_phys intent = inout [tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 + standard_name = tracer_concentration + long_name = model layer mean tracer concentration + units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) type = real kind = kind_phys diff --git a/physics/GFS_rrtmgp_lw_post.F90 b/physics/GFS_rrtmgp_lw_post.F90 deleted file mode 100644 index afd56dcf1..000000000 --- a/physics/GFS_rrtmgp_lw_post.F90 +++ /dev/null @@ -1,188 +0,0 @@ -!> \file GFS_rrtmgp_lw_post.F90 -!! -!> \defgroup GFS_rrtmgp_lw_post GFS_rrtmgp_lw_post.F90 -!! -!! \brief RRTMGP Longwave post-processing routine. -!! -module GFS_rrtmgp_lw_post - use machine, only: kind_phys - use module_radlw_parameters, only: topflw_type, sfcflw_type - use mo_heating_rates, only: compute_heating_rate - use radiation_tools, only: check_error_msg - implicit none - - public GFS_rrtmgp_lw_post_run - -contains - -!>\defgroup gfs_rrtmgp_lw_post_mod GFS RRTMGP-LW Post Module -!> \section arg_table_GFS_rrtmgp_lw_post_run -!! \htmlinclude GFS_rrtmgp_lw_post.html -!! -!! \ingroup GFS_rrtmgp_lw_post -!! -!! \brief The all-sky longwave radiation tendency is computed, the clear-sky tendency is computed -!! if requested. -!! -!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics -!! calls. -!! -!! (optional) Save additional diagnostics. -!! -!! \section GFS_rrtmgp_lw_post_run - ! ######################################################################################## - subroutine GFS_rrtmgp_lw_post_run (nCol, nLev, lslwr, do_lw_clrsky_hr, save_diag, fhlwr, & - p_lev, t_lay, tsfa, fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, iSFC, iTOA,& - fluxlwDOWN_clrsky, raddt, cldsa, mtopa, mbota, cld_frac, cldtaulw, fluxr, sfcdlw, & - sfculw, sfcflw, tsflw, htrlw, htrlwu, topflw, htrlwc, errmsg, errflg) - - ! Inputs - integer, intent(in) :: & - nCol, & ! Horizontal loop extent - nLev, & ! Number of vertical layers - iSFC, & ! Vertical index for surface level - iTOA ! Vertical index for TOA level - logical, intent(in) :: & - lslwr, & ! Logical flags for lw radiation calls - do_lw_clrsky_hr, & ! Output clear-sky SW heating-rate? - save_diag ! Output radiation diagnostics? - real(kind_phys), intent(in) :: & - fhlwr ! Frequency for SW radiation - real(kind_phys), dimension(nCol), intent(in) :: & - tsfa ! Lowest model layer air temperature for radiation (K) - real(kind_phys), dimension(nCol, nLev), intent(in) :: & - t_lay ! Temperature @ model layer centers (K) - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - fluxlwUP_allsky, & ! RRTMGP longwave all-sky flux (W/m2) - fluxlwDOWN_allsky, & ! RRTMGP longwave all-sky flux (W/m2) - fluxlwUP_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) - fluxlwDOWN_clrsky ! RRTMGP longwave clear-sky flux (W/m2) - real(kind_phys), intent(in) :: & - raddt ! Radiation time step - real(kind_phys), dimension(nCol,5), intent(in) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL - integer, dimension(nCol,3), intent(in) ::& - mbota, & ! vertical indices for low, middle and high cloud tops - mtopa ! vertical indices for low, middle and high cloud bases - real(kind_phys), dimension(nCol,nLev), intent(in) :: & - cld_frac, & ! Total cloud fraction in each layer - cldtaulw ! approx 10.mu band layer cloud optical depth - - real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr - - ! Outputs (mandatory) - real(kind_phys), dimension(nCol), intent(inout) :: & - sfcdlw, & ! Total sky sfc downward lw flux (W/m2) - sfculw, & ! Total sky sfc upward lw flux (W/m2) - tsflw ! surface air temp during lw calculation (K) - type(sfcflw_type), dimension(nCol), intent(inout) :: & - sfcflw ! LW radiation fluxes at sfc - real(kind_phys), dimension(nCol,nLev), intent(inout) :: & - htrlw, & ! LW all-sky heating rate - htrlwu ! Heating-rate updated in-between radiation calls. - type(topflw_type), dimension(nCol), intent(out) :: & - topflw ! lw_fluxes_top_atmosphere - character(len=*), intent(out) :: & - errmsg - integer, intent(out) :: & - errflg - - ! Outputs (optional) - real(kind_phys),dimension(nCol, nLev),intent(inout),optional :: & - htrlwc ! Longwave clear-sky heating-rate (K/sec) - - ! Local variables - integer :: i, j, k, itop, ibtc - real(kind_phys) :: tem0d, tem1, tem2 - real(kind_phys),dimension(nCol,nLev) :: hlwc - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. lslwr) return - ! ####################################################################################### - ! Compute LW heating-rates. - ! ####################################################################################### - ! Clear-sky heating-rate (optional) - if (do_lw_clrsky_hr) then - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxlwUP_clrsky, & ! IN - RRTMGP upward longwave clear-sky flux profiles (W/m2) - fluxlwDOWN_clrsky, & ! IN - RRTMGP downward longwave clear-sky flux profiles (W/m2) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - htrlwc)) ! OUT - Longwave clear-sky heating rate (K/sec) - endif - - ! All-sky heating-rate (mandatory) - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxlwUP_allsky, & ! IN - RRTMGP upward longwave all-sky flux profiles (W/m2) - fluxlwDOWN_allsky, & ! IN - RRTMGP downward longwave all-sky flux profiles (W/m2) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - htrlw)) ! OUT - Longwave all-sky heating rate (K/sec) - - ! ####################################################################################### - ! Save LW outputs. - ! (Copy fluxes from RRTMGP types into model radiation types.) - ! ####################################################################################### - ! TOA fluxes - topflw(:)%upfxc = fluxlwUP_allsky(:,iTOA) - topflw(:)%upfx0 = fluxlwUP_clrsky(:,iTOA) - - ! Surface fluxes - sfcflw(:)%upfxc = fluxlwUP_allsky(:,iSFC) - sfcflw(:)%upfx0 = fluxlwUP_clrsky(:,iSFC) - sfcflw(:)%dnfxc = fluxlwDOWN_allsky(:,iSFC) - sfcflw(:)%dnfx0 = fluxlwDOWN_clrsky(:,iSFC) - - ! Save surface air temp for diurnal adjustment at model t-steps - tsflw (:) = tsfa(:) - - ! Radiation fluxes for other physics processes - sfcdlw(:) = sfcflw(:)%dnfxc - sfculw(:) = sfcflw(:)%upfxc - - ! Heating-rate at radiation timestep, used for adjustment between radiation calls. - htrlwu = htrlw - - ! ####################################################################################### - ! Save LW diagnostics - ! - For time averaged output quantities (including total-sky and clear-sky SW and LW - ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base - ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in - ! corresponding slots of array fluxr with appropriate time weights. - ! - Collect the fluxr data for wrtsfc - ! ####################################################################################### - if (save_diag) then - do i=1,nCol - ! LW all-sky fluxes - fluxr(i,1 ) = fluxr(i,1 ) + fhlwr * fluxlwUP_allsky( i,iTOA) ! total sky top lw up - fluxr(i,19) = fluxr(i,19) + fhlwr * fluxlwDOWN_allsky(i,iSFC) ! total sky sfc lw dn - fluxr(i,20) = fluxr(i,20) + fhlwr * fluxlwUP_allsky( i,iSFC) ! total sky sfc lw up - ! LW clear-sky fluxes - fluxr(i,28) = fluxr(i,28) + fhlwr * fluxlwUP_clrsky( i,iTOA) ! clear sky top lw up - fluxr(i,30) = fluxr(i,30) + fhlwr * fluxlwDOWN_clrsky(i,iSFC) ! clear sky sfc lw dn - fluxr(i,33) = fluxr(i,33) + fhlwr * fluxlwUP_clrsky( i,iSFC) ! clear sky sfc lw up - enddo - - ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud is reversed for - ! the fluxr output. save interface pressure (pa) of top/bot - do j = 1, 3 - do i = 1, nCol - tem0d = raddt * cldsa(i,j) - itop = mtopa(i,j) - ibtc = mbota(i,j) - - ! Add optical depth and emissivity output - tem2 = 0. - do k=ibtc,itop - tem2 = tem2 + cldtaulw(i,k) ! approx 10. mu channel - enddo - fluxr(i,46-j) = fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) - enddo - enddo - endif - - end subroutine GFS_rrtmgp_lw_post_run - -end module GFS_rrtmgp_lw_post diff --git a/physics/GFS_rrtmgp_lw_post.meta b/physics/GFS_rrtmgp_lw_post.meta deleted file mode 100644 index d458b25f3..000000000 --- a/physics/GFS_rrtmgp_lw_post.meta +++ /dev/null @@ -1,253 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_lw_post - type = scheme - dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radlw_param.f,rte-rrtmgp/extensions/mo_fluxes_byband.F90,radiation_tools.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,rte-rrtmgp/extensions/mo_heating_rates.F90 - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_lw_post_run - type = scheme -[nCol] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[iSFC] - standard_name = vertical_index_for_surface_in_RRTMGP - long_name = index for surface layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[iTOA] - standard_name = vertical_index_for_TOA_in_RRTMGP - long_name = index for TOA layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[lslwr] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[do_lw_clrsky_hr] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output lw heating rate - units = flag - dimensions = () - type = logical - intent = in -[save_diag] - standard_name = flag_for_diagnostics - long_name = logical flag for storing diagnostics - units = flag - dimensions = () - type = logical - intent = in -[fhlwr] - standard_name = period_of_longwave_radiation_calls - long_name = frequency for longwave radiation - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[tsfa] - standard_name = surface_air_temperature_for_radiation - long_name = lowest model layer air temperature for radiation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature at vertical layer for radiation calculation - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwUP_allsky] - standard_name = RRTMGP_lw_flux_profile_upward_allsky - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwDOWN_allsky] - standard_name = RRTMGP_lw_flux_profile_downward_allsky - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwUP_clrsky] - standard_name = RRTMGP_lw_flux_profile_upward_clrsky - long_name = RRTMGP upward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwDOWN_clrsky] - standard_name = RRTMGP_lw_flux_profile_downward_clrsky - long_name = RRTMGP downward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[raddt] - standard_name = time_step_for_radiation - long_name = radiation time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[cldsa] - standard_name = cloud_area_fraction_for_radiation - long_name = fraction of clouds for low, middle, high, total and BL - units = frac - dimensions = (horizontal_loop_extent,5) - type = real - kind = kind_phys - intent = in -[mtopa] - standard_name = model_layer_number_at_cloud_top - long_name = vertical indices for low, middle and high cloud tops - units = index - dimensions = (horizontal_loop_extent,3) - type = integer - intent = in -[mbota] - standard_name = model_layer_number_at_cloud_base - long_name = vertical indices for low, middle and high cloud bases - units = index - dimensions = (horizontal_loop_extent,3) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cldtaulw] - standard_name = cloud_optical_depth_layers_at_10mu_band - long_name = approx 10mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[fluxr] - standard_name = cumulative_radiation_diagnostic - long_name = time-accumulated 2D radiation-related diagnostic fields - units = mixed - dimensions = (horizontal_loop_extent,number_of_diagnostics_variables_for_radiation) - type = real - kind = kind_phys - intent = inout -[sfcdlw] - standard_name = surface_downwelling_longwave_flux_on_radiation_timestep - long_name = total sky sfc downward lw flux - units = W m-2 - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[sfculw] - standard_name = surface_upwelling_longwave_flux_on_radiation_timestep - long_name = total sky sfc upward lw flux - units = W m-2 - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[sfcflw] - standard_name = surface_lw_fluxes_assuming_total_and_clear_sky_on_radiation_timestep - long_name = lw radiation fluxes at sfc - units = W m-2 - dimensions = (horizontal_loop_extent) - type = sfcflw_type - intent = inout -[tsflw] - standard_name = air_temperature_at_surface_adjacent_layer_on_radiation_timestep - long_name = surface air temp during lw calculation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[htrlw] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep - long_name = total sky lw heating rate - units = K s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[htrlwu] - standard_name = updated_tendency_of_air_temperature_due_to_longwave_heating_on_physics_timestep - long_name = total sky longwave heating rate on physics time step - units = K s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[topflw] - standard_name = lw_fluxes_top_atmosphere - long_name = lw radiation fluxes at top - units = W m-2 - dimensions = (horizontal_loop_extent) - type = topflw_type - intent = out -[htrlwc] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_timestep - long_name = longwave clear sky heating rate - units = K s-1 - dimensions = (horizontal_loop_extent,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/GFS_rrtmgp_post.F90 b/physics/GFS_rrtmgp_post.F90 new file mode 100644 index 000000000..22fe2fc21 --- /dev/null +++ b/physics/GFS_rrtmgp_post.F90 @@ -0,0 +1,394 @@ +!> \file GFS_rrtmgp_post.F90 +!! +!> \defgroup GFS_rrtmgp_post GFS_rrtmgp_post.F90 +!! +!! \brief RRTMGP post-processing routine. +!! +module GFS_rrtmgp_post + use machine, only: kind_phys + use module_radlw_parameters, only: topflw_type, sfcflw_type + use module_radsw_parameters, only: topfsw_type, sfcfsw_type, cmpfsw_type + use mo_heating_rates, only: compute_heating_rate + use radiation_tools, only: check_error_msg + implicit none + + public GFS_rrtmgp_post_run + +contains + ! ######################################################################################## +!>\defgroup gfs_rrtmgp_post_mod GFS RRTMGP Post Module +!> \section arg_table_GFS_rrtmgp_post_run +!! \htmlinclude GFS_rrtmgp_post.html +!! +!! \ingroup GFS_rrtmgp_post +!! +!! \brief The all-sky radiation tendency is computed, the clear-sky tendency is computed +!! if requested. +!! +!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics +!! calls. +!! +!! (optional) Save additional diagnostics. +!! +!! \section GFS_rrtmgp_post_run + ! ######################################################################################## + subroutine GFS_rrtmgp_post_run (nCol, nLev, nDay, iSFC, iTOA, idxday, doLWrad, doSWrad, & + do_lw_clrsky_hr, do_sw_clrsky_hr, save_diag, fhlwr, fhswr, sfc_alb_nir_dir, & + sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, p_lev, tsfa, coszen, coszdg, & + fluxlwDOWN_clrsky, fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, & + fluxswDOWN_clrsky, fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky, & + raddt, aerodp, cldsa, mtopa, mbota, cld_frac, cldtaulw, cldtausw, scmpsw, fluxr, & + sfcdlw, sfculw, sfcflw, tsflw, htrlw, htrlwu, topflw, nirbmdi, nirdfdi, visbmdi, & + visdfdi, nirbmui, nirdfui, visbmui, visdfui, sfcnsw, sfcdsw, htrsw, sfcfsw, topfsw, & + htrswc, htrlwc, errmsg, errflg) + + ! Inputs + integer, intent(in) :: & + nCol, & ! Horizontal loop extent + nLev, & ! Number of vertical layers + nDay, & ! Number of daylit columns + iSFC, & ! Vertical index for surface level + iTOA ! Vertical index for TOA level + integer, intent(in), dimension(:) :: & + idxday ! Index array for daytime points + integer, intent(in), dimension(:,:) :: & + mbota, & ! Vertical indices for low, middle and high cloud tops + mtopa ! ertical indices for low, middle and high cloud bases + logical, intent(in) :: & + doLWrad, & ! Logical flags for lw radiation calls + doSWrad, & ! Logical flags for sw radiation calls + do_lw_clrsky_hr, & ! Output clear-sky LW heating-rate? + do_sw_clrsky_hr, & ! Output clear-sky SW heating-rate? + save_diag ! Output radiation diagnostics? + real(kind_phys), intent(in) :: & + fhlwr, & ! Frequency for LW radiation calls + fhswr ! Frequency for SW radiation calls + real(kind_phys), dimension(:), intent(in) :: & + tsfa, & ! Lowest model layer air temperature for radiation (K) + coszen, & ! Cosine(SZA) + coszdg, & ! Cosine(SZA), daytime + sfc_alb_nir_dir, & ! Surface albedo (direct) + sfc_alb_nir_dif, & ! Surface albedo (diffuse) + sfc_alb_uvvis_dir, & ! Surface albedo (direct) + sfc_alb_uvvis_dif ! Surface albedo (diffuse) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev, & ! Pressure @ model layer-interfaces (Pa) + fluxlwUP_allsky, & ! RRTMGP longwave all-sky flux (W/m2) + fluxlwDOWN_allsky, & ! RRTMGP longwave all-sky flux (W/m2) + fluxlwUP_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) + fluxlwDOWN_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) + fluxswUP_allsky, & ! RRTMGP shortwave all-sky flux (W/m2) + fluxswDOWN_allsky, & ! RRTMGP shortwave all-sky flux (W/m2) + fluxswUP_clrsky, & ! RRTMGP shortwave clear-sky flux (W/m2) + fluxswDOWN_clrsky ! RRTMGP shortwave clear-sky flux (W/m2) + real(kind_phys), intent(in) :: & + raddt ! Radiation time step + real(kind_phys), dimension(:,:), intent(in) :: & + aerodp, & ! Vertical integrated optical depth for various aerosol species + cldsa, & ! Fraction of clouds for low, middle, high, total and BL + cld_frac, & ! Total cloud fraction in each layer + cldtaulw, & ! approx 10.mu band layer cloud optical depth + cldtausw ! approx .55mu band layer cloud optical depth + type(cmpfsw_type), dimension(:), intent(in) :: & + scmpsw ! 2D surface fluxes, components: + ! uvbfc - total sky downward uv-b flux at (W/m2) + ! uvbf0 - clear sky downward uv-b flux at (W/m2) + ! nirbm - downward nir direct beam flux (W/m2) + ! nirdf - downward nir diffused flux (W/m2) + ! visbm - downward uv+vis direct beam flux (W/m2) + ! visdf - downward uv+vis diffused flux (W/m2) + + + real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr + + ! Outputs (mandatory) + real(kind_phys), dimension(:), intent(inout) :: & + tsflw, & ! LW sfc air temp during calculation (K) + sfcdlw, & ! LW sfc all-sky downward flux (W/m2) + sfculw, & ! LW sfc all-sky upward flux (W/m2) + nirbmdi, & ! SW sfc nir beam downward flux (W/m2) + nirdfdi, & ! SW sfc nir diff downward flux (W/m2) + visbmdi, & ! SW sfc uv+vis beam downward flux (W/m2) + visdfdi, & ! SW sfc uv+vis diff downward flux (W/m2) + nirbmui, & ! SW sfc nir beam upward flux (W/m2) + nirdfui, & ! SW sfc nir diff upward flux (W/m2) + visbmui, & ! SW sfc uv+vis beam upward flux (W/m2) + visdfui, & ! SW sfc uv+vis diff upward flux (W/m2) + sfcnsw, & ! SW sfc all-sky net flux (W/m2) flux into ground + sfcdsw ! SW sfc all-sky downward flux (W/m2) + real(kind_phys), dimension(:,:), intent(inout) :: & + htrlw, & ! LW all-sky heating rate (K/s) + htrsw, & ! SW all-sky heating rate (K/s) + htrlwu ! LW all-sky heating-rate updated in-between radiation calls. + type(sfcflw_type), dimension(:), intent(inout) :: & + sfcflw ! LW radiation fluxes at sfc + type(sfcfsw_type), dimension(:), intent(inout) :: & + sfcfsw ! SW radiation fluxes at sfc + type(topfsw_type), dimension(:), intent(inout) :: & + topfsw ! SW fluxes at top atmosphere + type(topflw_type), dimension(:), intent(inout) :: & + topflw ! LW fluxes at top atmosphere + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Outputs (optional) + real(kind_phys),dimension(:,:),intent(inout),optional :: & + htrlwc, & ! LW clear-sky heating-rate (K/s) + htrswc ! SW clear-sky heating rate (K/s) + + ! Local variables + integer :: i, j, k, itop, ibtc + real(kind_phys) :: tem0d, tem1, tem2 + real(kind_phys), dimension(nDay, nLev) :: thetaTendClrSky, thetaTendAllSky + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. (doLWrad .or. doSWrad)) return + + if (doLWRad) then + ! ####################################################################################### + ! Compute LW heating-rates. + ! ####################################################################################### + + ! Clear-sky heating-rate (optional) + if (do_lw_clrsky_hr) then + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxlwUP_clrsky, & ! IN - RRTMGP upward longwave clear-sky flux profiles (W/m2) + fluxlwDOWN_clrsky, & ! IN - RRTMGP downward longwave clear-sky flux profiles (W/m2) + p_lev, & ! IN - Pressure @ layer-interfaces (Pa) + htrlwc)) ! OUT - Longwave clear-sky heating rate (K/sec) + endif + + ! All-sky heating-rate (mandatory) + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxlwUP_allsky, & ! IN - RRTMGP upward longwave all-sky flux profiles (W/m2) + fluxlwDOWN_allsky, & ! IN - RRTMGP downward longwave all-sky flux profiles (W/m2) + p_lev, & ! IN - Pressure @ layer-interfaces (Pa) + htrlw)) ! OUT - Longwave all-sky heating rate (K/sec) + + ! ####################################################################################### + ! Save LW outputs. + ! (Copy fluxes from RRTMGP types into model radiation types.) + ! ####################################################################################### + ! TOA fluxes + + topflw(:)%upfxc = fluxlwUP_allsky(:,iTOA) + topflw(:)%upfx0 = fluxlwUP_clrsky(:,iTOA) + + ! Surface fluxes + sfcflw(:)%upfxc = fluxlwUP_allsky(:,iSFC) + sfcflw(:)%upfx0 = fluxlwUP_clrsky(:,iSFC) + sfcflw(:)%dnfxc = fluxlwDOWN_allsky(:,iSFC) + sfcflw(:)%dnfx0 = fluxlwDOWN_clrsky(:,iSFC) + + ! Save surface air temp for diurnal adjustment at model t-steps + tsflw (:) = tsfa(:) + + ! Radiation fluxes for other physics processes + sfcdlw(:) = sfcflw(:)%dnfxc + sfculw(:) = sfcflw(:)%upfxc + + ! Heating-rate at radiation timestep, used for adjustment between radiation calls. + htrlwu = htrlw + + ! ####################################################################################### + ! Save LW diagnostics + ! - For time averaged output quantities (including total-sky and clear-sky SW and LW + ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base + ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in + ! corresponding slots of array fluxr with appropriate time weights. + ! - Collect the fluxr data for wrtsfc + ! ####################################################################################### + if (save_diag) then + do i=1,nCol + ! LW all-sky fluxes + fluxr(i,1 ) = fluxr(i,1 ) + fhlwr * fluxlwUP_allsky( i,iTOA) ! total sky top lw up + fluxr(i,19) = fluxr(i,19) + fhlwr * fluxlwDOWN_allsky(i,iSFC) ! total sky sfc lw dn + fluxr(i,20) = fluxr(i,20) + fhlwr * fluxlwUP_allsky( i,iSFC) ! total sky sfc lw up + ! LW clear-sky fluxes + fluxr(i,28) = fluxr(i,28) + fhlwr * fluxlwUP_clrsky( i,iTOA) ! clear sky top lw up + fluxr(i,30) = fluxr(i,30) + fhlwr * fluxlwDOWN_clrsky(i,iSFC) ! clear sky sfc lw dn + fluxr(i,33) = fluxr(i,33) + fhlwr * fluxlwUP_clrsky( i,iSFC) ! clear sky sfc lw up + enddo + + ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud is reversed for + ! the fluxr output. save interface pressure (pa) of top/bot + do j = 1, 3 + do i = 1, nCol + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) + ibtc = mbota(i,j) + + ! Add optical depth and emissivity output + tem2 = 0. + do k=ibtc,itop + tem2 = tem2 + cldtaulw(i,k) ! approx 10. mu channel + enddo + fluxr(i,46-j) = fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) + enddo + enddo + endif + endif + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + if (doSWRad) then + if (nDay .gt. 0) then + ! ################################################################################# + ! Compute SW heating-rates + ! ################################################################################# + + ! Clear-sky heating-rate (optional) + if (do_sw_clrsky_hr) then + htrswc(:,:) = 0._kind_phys + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxswUP_clrsky(idxday(1:nDay),:), & ! IN - Shortwave upward clear-sky flux profiles (W/m2) + fluxswDOWN_clrsky(idxday(1:nDay),:), & ! IN - Shortwave downward clear-sky flux profiles (W/m2) + p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) + thetaTendClrSky)) ! OUT - Clear-sky heating-rate (K/sec) + htrswc(idxday(1:nDay),:)=thetaTendClrSky !**NOTE** GP doesn't use radiation levels, it uses the model fields. Not sure if this is necessary + endif + + ! All-sky heating-rate (mandatory) + htrsw(:,:) = 0._kind_phys + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxswUP_allsky(idxday(1:nDay),:), & ! IN - Shortwave upward all-sky flux profiles (W/m2) + fluxswDOWN_allsky(idxday(1:nDay),:), & ! IN - Shortwave downward all-sky flux profiles (W/m2) + p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) + thetaTendAllSky)) ! OUT - All-sky heating-rate (K/sec) + htrsw(idxday(1:nDay),:) = thetaTendAllSky + + ! ################################################################################# + ! Save SW outputs + ! (Copy fluxes from RRTMGP types into model radiation types.) + ! ################################################################################# + + ! TOA fluxes + topfsw(:)%upfxc = fluxswUP_allsky(:,iTOA) + topfsw(:)%upfx0 = fluxswUP_clrsky(:,iTOA) + topfsw(:)%dnfxc = fluxswDOWN_allsky(:,iTOA) + + ! Surface fluxes + sfcfsw(:)%upfxc = fluxswUP_allsky(:,iSFC) + sfcfsw(:)%upfx0 = fluxswUP_clrsky(:,iSFC) + sfcfsw(:)%dnfxc = fluxswDOWN_allsky(:,iSFC) + sfcfsw(:)%dnfx0 = fluxswDOWN_clrsky(:,iSFC) + + ! Surface down and up spectral component fluxes + ! - Save two spectral bands' surface downward and upward fluxes for output. + do i=1,nCol + nirbmdi(i) = scmpsw(i)%nirbm + nirdfdi(i) = scmpsw(i)%nirdf + visbmdi(i) = scmpsw(i)%visbm + visdfdi(i) = scmpsw(i)%visdf + nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(i) + nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(i) + visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(i) + visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(i) + enddo + else ! if_nday_block + ! ################################################################################# + ! Dark everywhere + ! ################################################################################# + htrsw(:,:) = 0.0 + sfcfsw = sfcfsw_type( 0.0, 0.0, 0.0, 0.0 ) + topfsw = topfsw_type( 0.0, 0.0, 0.0 ) + do i=1,nCol + nirbmdi(i) = 0.0 + nirdfdi(i) = 0.0 + visbmdi(i) = 0.0 + visdfdi(i) = 0.0 + nirbmui(i) = 0.0 + nirdfui(i) = 0.0 + visbmui(i) = 0.0 + visdfui(i) = 0.0 + enddo + + if (do_sw_clrsky_hr) then + htrswc(:,:) = 0 + endif + endif ! end_if_nday + + ! Radiation fluxes for other physics processes + do i=1,nCol + sfcnsw(i) = sfcfsw(i)%dnfxc - sfcfsw(i)%upfxc + sfcdsw(i) = sfcfsw(i)%dnfxc + enddo + + ! ################################################################################# + ! Save SW diagnostics + ! - For time averaged output quantities (including total-sky and clear-sky SW and LW + ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base + ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in + ! corresponding slots of array fluxr with appropriate time weights. + ! - Collect the fluxr data for wrtsfc + ! ################################################################################# + if (save_diag) then + do i=1,nCol + fluxr(i,34) = aerodp(i,1) ! total aod at 550nm + fluxr(i,35) = aerodp(i,2) ! DU aod at 550nm + fluxr(i,36) = aerodp(i,3) ! BC aod at 550nm + fluxr(i,37) = aerodp(i,4) ! OC aod at 550nm + fluxr(i,38) = aerodp(i,5) ! SU aod at 550nm + fluxr(i,39) = aerodp(i,6) ! SS aod at 550nm + if (coszen(i) > 0.) then + ! SW all-sky fluxes + tem0d = fhswr * coszdg(i) / coszen(i) + fluxr(i,2 ) = fluxr(i,2) + topfsw(i)%upfxc * tem0d ! total sky top sw up + fluxr(i,3 ) = fluxr(i,3) + sfcfsw(i)%upfxc * tem0d + fluxr(i,4 ) = fluxr(i,4) + sfcfsw(i)%dnfxc * tem0d ! total sky sfc sw dn + ! SW uv-b fluxes + fluxr(i,21) = fluxr(i,21) + scmpsw(i)%uvbfc * tem0d ! total sky uv-b sw dn + fluxr(i,22) = fluxr(i,22) + scmpsw(i)%uvbf0 * tem0d ! clear sky uv-b sw dn + ! SW TOA incoming fluxes + fluxr(i,23) = fluxr(i,23) + topfsw(i)%dnfxc * tem0d ! top sw dn + ! SW SFC flux components + fluxr(i,24) = fluxr(i,24) + visbmdi(i) * tem0d ! uv/vis beam sw dn + fluxr(i,25) = fluxr(i,25) + visdfdi(i) * tem0d ! uv/vis diff sw dn + fluxr(i,26) = fluxr(i,26) + nirbmdi(i) * tem0d ! nir beam sw dn + fluxr(i,27) = fluxr(i,27) + nirdfdi(i) * tem0d ! nir diff sw dn + ! SW clear-sky fluxes + fluxr(i,29) = fluxr(i,29) + topfsw(i)%upfx0 * tem0d + fluxr(i,31) = fluxr(i,31) + sfcfsw(i)%upfx0 * tem0d + fluxr(i,32) = fluxr(i,32) + sfcfsw(i)%dnfx0 * tem0d + endif + enddo + + ! Save total and boundary-layer clouds + do i=1,nCol + fluxr(i,17) = fluxr(i,17) + raddt * cldsa(i,4) + fluxr(i,18) = fluxr(i,18) + raddt * cldsa(i,5) + enddo + + ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud + ! is reversed for the fluxr output. save interface pressure (pa) of top/bot + do j = 1, 3 + do i = 1, nCol + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) + ibtc = mbota(i,j) + fluxr(i, 8-j) = fluxr(i, 8-j) + tem0d + fluxr(i,11-j) = fluxr(i,11-j) + tem0d * p_lev(i,itop) + fluxr(i,14-j) = fluxr(i,14-j) + tem0d * p_lev(i,ibtc) + fluxr(i,17-j) = fluxr(i,17-j) + tem0d * p_lev(i,itop) + + ! Add optical depth and emissivity output + tem1 = 0. + do k=ibtc,itop + tem1 = tem1 + cldtausw(i,k) ! approx .55 mu channel + enddo + fluxr(i,43-j) = fluxr(i,43-j) + tem0d * tem1 + enddo + enddo + endif + endif + + end subroutine GFS_rrtmgp_post_run +end module GFS_rrtmgp_post diff --git a/physics/GFS_rrtmgp_sw_post.meta b/physics/GFS_rrtmgp_post.meta similarity index 71% rename from physics/GFS_rrtmgp_sw_post.meta rename to physics/GFS_rrtmgp_post.meta index 7da3b10b0..e4bc3e5dc 100644 --- a/physics/GFS_rrtmgp_sw_post.meta +++ b/physics/GFS_rrtmgp_post.meta @@ -1,14 +1,13 @@ [ccpp-table-properties] - name = GFS_rrtmgp_sw_post + name = GFS_rrtmgp_post type = scheme - dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radsw_param.f,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - dependencies = rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,rte-rrtmgp/extensions/mo_heating_rates.F90,radiation_tools.F90 + dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radlw_param.f,radiation_tools.F90,rte-rrtmgp/extensions/mo_heating_rates.F90 ######################################################################## [ccpp-arg-table] - name = GFS_rrtmgp_sw_post_run + name = GFS_rrtmgp_post_run type = scheme -[ncol] +[nCol] standard_name = horizontal_loop_extent long_name = horizontal loop extent units = count @@ -50,7 +49,7 @@ dimensions = (horizontal_loop_extent) type = integer intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag @@ -64,6 +63,20 @@ dimensions = () type = logical intent = in +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[do_lw_clrsky_hr] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output lw heating rate + units = flag + dimensions = () + type = logical + intent = in [save_diag] standard_name = flag_for_diagnostics long_name = logical flag for storing diagnostics @@ -71,6 +84,14 @@ dimensions = () type = logical intent = in +[fhlwr] + standard_name = period_of_longwave_radiation_calls + long_name = frequency for longwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [fhswr] standard_name = period_of_shortwave_radiation_calls long_name = frequency for shortwave radiation @@ -95,22 +116,6 @@ type = real kind = kind_phys intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature at vertical layer for radiation calculation - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in [sfc_alb_nir_dir] standard_name = surface_albedo_due_to_near_IR_direct long_name = surface albedo due to near IR direct beam @@ -143,6 +148,54 @@ type = real kind = kind_phys intent = in +[tsfa] + standard_name = surface_air_temperature_for_radiation + long_name = lowest model layer air temperature for radiation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure level + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwUP_allsky] + standard_name = RRTMGP_lw_flux_profile_upward_allsky + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwDOWN_allsky] + standard_name = RRTMGP_lw_flux_profile_downward_allsky + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwUP_clrsky] + standard_name = RRTMGP_lw_flux_profile_upward_clrsky + long_name = RRTMGP upward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwDOWN_clrsky] + standard_name = RRTMGP_lw_flux_profile_downward_clrsky + long_name = RRTMGP downward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [fluxswUP_allsky] standard_name = RRTMGP_sw_flux_profile_upward_allsky long_name = RRTMGP upward shortwave all-sky flux profile @@ -199,16 +252,16 @@ type = real kind = kind_phys intent = in -[mbota] - standard_name = model_layer_number_at_cloud_base - long_name = vertical indices for low, middle and high cloud bases +[mtopa] + standard_name = model_layer_number_at_cloud_top + long_name = vertical indices for low, middle and high cloud tops units = index dimensions = (horizontal_loop_extent,3) type = integer intent = in -[mtopa] - standard_name = model_layer_number_at_cloud_top - long_name = vertical indices for low, middle and high cloud tops +[mbota] + standard_name = model_layer_number_at_cloud_base + long_name = vertical indices for low, middle and high cloud bases units = index dimensions = (horizontal_loop_extent,3) type = integer @@ -221,6 +274,14 @@ type = real kind = kind_phys intent = in +[cldtaulw] + standard_name = cloud_optical_depth_layers_at_10mu_band + long_name = approx 10mu band layer cloud optical depth + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [cldtausw] standard_name = cloud_optical_depth_layers_at_0p55mu_band long_name = approx .55mu band layer cloud optical depth @@ -229,6 +290,13 @@ type = real kind = kind_phys intent = in +[scmpsw] + standard_name = components_of_surface_downward_shortwave_fluxes + long_name = derived type for special components of surface downward shortwave fluxes + units = W m-2 + dimensions = (horizontal_loop_extent) + type = cmpfsw_type + intent = in [fluxr] standard_name = cumulative_radiation_diagnostic long_name = time-accumulated 2D radiation-related diagnostic fields @@ -237,6 +305,60 @@ type = real kind = kind_phys intent = inout +[sfcdlw] + standard_name = surface_downwelling_longwave_flux_on_radiation_timestep + long_name = total sky sfc downward lw flux + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[sfculw] + standard_name = surface_upwelling_longwave_flux_on_radiation_timestep + long_name = total sky sfc upward lw flux + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[sfcflw] + standard_name = surface_lw_fluxes_assuming_total_and_clear_sky_on_radiation_timestep + long_name = lw radiation fluxes at sfc + units = W m-2 + dimensions = (horizontal_loop_extent) + type = sfcflw_type + intent = inout +[tsflw] + standard_name = air_temperature_at_surface_adjacent_layer_on_radiation_timestep + long_name = surface air temp during lw calculation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[htrlw] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep + long_name = total sky lw heating rate + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[htrlwu] + standard_name = updated_tendency_of_air_temperature_due_to_longwave_heating_on_physics_timestep + long_name = total sky longwave heating rate on physics time step + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[topflw] + standard_name = lw_fluxes_top_atmosphere + long_name = lw radiation fluxes at top + units = W m-2 + dimensions = (horizontal_loop_extent) + type = topflw_type + intent = inout [nirbmdi] standard_name = surface_downwelling_direct_nir_shortwave_flux_on_radiation_timestep long_name = sfc nir beam sw downward flux @@ -347,12 +469,13 @@ type = real kind = kind_phys intent = inout -[scmpsw] - standard_name = components_of_surface_downward_shortwave_fluxes - long_name = derived type for special components of surface downward shortwave fluxes - units = W m-2 - dimensions = (horizontal_loop_extent) - type = cmpfsw_type +[htrlwc] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_timestep + long_name = longwave clear sky heating rate + units = K s-1 + dimensions = (horizontal_loop_extent,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys intent = inout [errmsg] standard_name = ccpp_error_message diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 755b977b3..8e115b774 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -15,9 +15,9 @@ module GFS_rrtmgp_pre NF_VGAS, & !< Number of active gas species getgases, & !< Routine to setup trace gases getozn !< Routine to setup ozone - ! RRTMGP types - use mo_gas_concentrations, only: ty_gas_concs use radiation_tools, only: check_error_msg,cmp_tlev + use rrtmgp_lw_gas_optics, only: lw_gas_props + implicit none real(kind_phys), parameter :: & amd = 28.9644_kind_phys, & !< Molecular weight of dry-air (g/mol) @@ -25,6 +25,9 @@ module GFS_rrtmgp_pre amo3 = 47.9982_kind_phys, & !< Modelular weight of ozone (g/mol) amdw = amd/amw, & !< Molecular weight of dry air / water vapor amdo3 = amd/amo3 !< Molecular weight of dry air / ozone + real(kind_phys), parameter :: eps = 1.0e-6_kind_phys + real(kind_phys), parameter :: oneminus = 1.0_kind_phys - eps + real(kind_phys), parameter :: ftiny = 1.0e-12_kind_phys ! Save trace gas indices. integer :: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, iStr_o2, iStr_ccl4, & @@ -111,27 +114,25 @@ end subroutine GFS_rrtmgp_pre_init !! !! \section GFS_rrtmgp_pre_run ! ######################################################################################### - subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhswr, fhlwr, & + subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhlwr, & xlat, xlon, prsl, tgrs, prslk, prsi, qgrs, tsfc, coslat, sinlat, con_g, con_rd, & - con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, minGPpres, maxGPpres, minGPtemp, & - maxGPtemp, raddt, p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, qs_lay, q_lay, tv_lay, & - relhum, tracer, deltaZ, deltaZc, deltaP, active_gases_array, gas_concentrations, & - tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, errmsg, errflg) + con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, raddt, p_lay, t_lay, p_lev, t_lev, & + vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, & + vmr_n2o, vmr_co2, tsfg, tsfa, qs_lay, q_lay, tv_lay, & + relhum, deltaZ, deltaZc, deltaP, active_gases_array, & + tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, nDay, idxday, semis, & + sfc_emiss_byband, errmsg, errflg) ! Inputs integer, intent(in) :: & + me, & ! MPI rank nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers - nTracers, & ! Number of tracers from model. i_o3 ! Index into tracer array for ozone logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr ! Call LW radiation + doSWrad, & ! Call SW radiation? + doLWrad ! Call LW radiation real(kind_phys), intent(in) :: & - minGPtemp, & ! Minimum temperature allowed in RRTMGP. - maxGPtemp, & ! Maximum ... - minGPpres, & ! Minimum pressure allowed in RRTMGP. - maxGPpres, & ! Maximum pressure allowed in RRTMGP. fhswr, & ! Frequency of SW radiation call. fhlwr ! Frequency of LW radiation call. real(kind_phys), intent(in) :: & @@ -147,7 +148,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw xlat, & ! Latitude tsfc, & ! Surface skin temperature (K) coslat, & ! Cosine(latitude) - sinlat ! Sine(latitude) + sinlat, & ! Sine(latitude) + semis real(kind_phys), dimension(:,:), intent(in) :: & prsl, & ! Pressure at model-layer centers (Pa) tgrs, & ! Temperature at model-layer centers (K) @@ -163,9 +165,11 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw errmsg ! Error message integer, intent(out) :: & errflg, & ! Error flag + nDay + integer, intent(inout) :: & iSFC, & ! Vertical index for surface iTOA ! Vertical index for TOA - logical, intent(out) :: & + logical, intent(inout) :: & top_at_1 ! Vertical ordering flag real(kind_phys), intent(inout) :: & raddt ! Radiation time-step @@ -175,6 +179,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw tsfc_radtime, & ! Surface temperature at radiation timestep coszen, & ! Cosine of SZA coszdg ! Cosine of SZA, daytime + integer, dimension(:), intent(inout) :: & + idxday ! Indices for daylit points real(kind_phys), dimension(:,:), intent(inout) :: & p_lay, & ! Pressure at model-layer t_lay, & ! Temperature at model layer @@ -186,15 +192,12 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw deltaZc, & ! Layer thickness (m) (between layer centers) deltaP, & ! Layer thickness (Pa) p_lev, & ! Pressure at model-interface - t_lev ! Temperature at model-interface - real(kind_phys), dimension(:,:,:),intent(inout) :: & - tracer ! Array containing trace gases - type(ty_gas_concs), intent(inout) :: & - gas_concentrations ! RRTMGP DDT: gas volumne mixing ratios + sfc_emiss_byband, & ! + t_lev, & ! Temperature at model-interface + vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2 ! Local variables integer :: i, j, iCol, iBand, iLay, iLev, iSFC_ilev - real(kind_phys),dimension(nCol,nLev) :: vmr_o3, vmr_h2o real(kind_phys) :: es, tem1, tem2, pfac real(kind_phys), dimension(nLev+1) :: hgtb real(kind_phys), dimension(nLev) :: hgtc @@ -206,7 +209,9 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw errmsg = '' errflg = 0 - if (.not. (lsswr .or. lslwr)) return + nday = 0 + idxday = 0 + if (.not. (doSWrad .or. doLWrad)) return ! ####################################################################################### ! What is vertical ordering? @@ -242,27 +247,29 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Bound temperature/pressure at layer centers. do iLay=1,nLev do iCol=1,NCOL - if (t_lay(iCol,iLay) .le. minGPtemp) then - t_lay(iCol,iLay) = minGPtemp + epsilon(minGPtemp) + if (t_lay(iCol,iLay) .le. lw_gas_props%get_temp_min()) then + t_lay(iCol,iLay) = lw_gas_props%get_temp_min() + epsilon(lw_gas_props%get_temp_min()) endif - if (p_lay(iCol,iLay) .le. minGPpres) then - p_lay(iCol,iLay) = minGPpres + epsilon(minGPpres) + if (p_lay(iCol,iLay) .le. lw_gas_props%get_press_min()) then + p_lay(iCol,iLay) = lw_gas_props%get_press_min() + epsilon(lw_gas_props%get_press_min()) endif - if (t_lay(iCol,iLay) .ge. maxGPtemp) then - t_lay(iCol,iLay) = maxGPtemp - epsilon(maxGPtemp) + if (t_lay(iCol,iLay) .ge. lw_gas_props%get_temp_max()) then + t_lay(iCol,iLay) = lw_gas_props%get_temp_max() - epsilon(lw_gas_props%get_temp_max()) endif - if (p_lay(iCol,iLay) .ge. maxGPpres) then - p_lay(iCol,iLay) = maxGPpres - epsilon(maxGPpres) + if (p_lay(iCol,iLay) .ge. lw_gas_props%get_press_max()) then + p_lay(iCol,iLay) = lw_gas_props%get_press_max() - epsilon(lw_gas_props%get_press_max()) endif enddo enddo ! Temperature at layer-interfaces - call cmp_tlev(nCol,nLev,minGPpres,p_lay,t_lay,p_lev,tsfc,t_lev) + call cmp_tlev(nCol,nLev,lw_gas_props%get_press_min(),p_lay,t_lay,p_lev,tsfc,t_lev) do iLev=1,nLev+1 do iCol=1,nCol - if (t_lev(iCol,iLev) .le. minGPtemp) t_lev(iCol,iLev) = minGPtemp + epsilon(minGPtemp) - if (t_lev(iCol,iLev) .ge. maxGPtemp) t_lev(iCol,iLev) = maxGPtemp - epsilon(maxGPtemp) + if (t_lev(iCol,iLev) .le. lw_gas_props%get_temp_min()) t_lev(iCol,iLev) = & + lw_gas_props%get_temp_min() + epsilon(lw_gas_props%get_temp_min()) + if (t_lev(iCol,iLev) .ge. lw_gas_props%get_temp_max()) t_lev(iCol,iLev) = & + lw_gas_props%get_temp_max() - epsilon(lw_gas_props%get_temp_max()) enddo enddo @@ -336,16 +343,11 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Get layer ozone mass mixing ratio ! ####################################################################################### - ! First recast remaining all tracers (except sphum) forcing them all to be positive - do j = 2, nTracers - tracer(1:NCOL,:,j) = qgrs(1:NCOL,:,j) - where(tracer(:,:,j) .lt. 0.0) tracer(:,:,j) = 0._kind_phys - enddo if (i_o3 > 0) then do iLay=1,nlev do iCol=1,NCOL - o3_lay(iCol,iLay) = max( con_epsqs, tracer(iCol,iLay,i_o3) ) + o3_lay(iCol,iLay) = max( con_epsqs, qgrs(iCol,iLay,i_o3) ) enddo enddo ! OR Use climatological ozone data @@ -358,21 +360,14 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Call getgases(), to set up non-prognostic gas volume mixing ratios (gas_vmr). call getgases (p_lev/100., xlon, xlat, nCol, nLev, gas_vmr) + vmr_o2 = gas_vmr(:,:,4) + vmr_ch4 = gas_vmr(:,:,3) + vmr_n2o = gas_vmr(:,:,2) + vmr_co2 = gas_vmr(:,:,1) ! Compute volume mixing-ratios for ozone (mmr) and specific-humidity. vmr_h2o = merge((q_lay/(1-q_lay))*amdw, 0., q_lay .ne. 1.) vmr_o3 = merge(o3_lay*amdo3, 0., o3_lay .gt. 0.) - - ! Populate RRTMGP DDT w/ gas-concentrations - gas_concentrations%ncol = nCol - gas_concentrations%nlay = nLev - gas_concentrations%gas_name(:) = active_gases_array(:) - gas_concentrations%concs(istr_o2)%conc(:,:) = gas_vmr(:,:,4) - gas_concentrations%concs(istr_co2)%conc(:,:) = gas_vmr(:,:,1) - gas_concentrations%concs(istr_ch4)%conc(:,:) = gas_vmr(:,:,3) - gas_concentrations%concs(istr_n2o)%conc(:,:) = gas_vmr(:,:,2) - gas_concentrations%concs(istr_h2o)%conc(:,:) = vmr_h2o(:,:) - gas_concentrations%concs(istr_o3)%conc(:,:) = vmr_o3(:,:) ! ####################################################################################### ! Radiation time step (output) (Is this really needed?) (Used by some diagnostics) @@ -388,10 +383,29 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Compute cosine of zenith angle (only when SW is called) ! ####################################################################################### - if (lsswr) then + if (doSWrad) then call coszmn (xlon, sinlat, coslat, solhr, nCol, me, coszen, coszdg) + ! For SW gather daylit points + nday = 0 + idxday = 0 + do iCol = 1, nCol + if (coszen(iCol) >= 0.0001) then + nday = nday + 1 + idxday(nday) = iCol + endif + enddo + else + nday = 0 + idxday = 0 endif + ! ####################################################################################### + ! Surface emissivity + ! ####################################################################################### + do iBand=1,lw_gas_props%get_nband() + sfc_emiss_byband(iBand,:) = semis + enddo + end subroutine GFS_rrtmgp_pre_run end module GFS_rrtmgp_pre diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 88face855..455010e58 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -72,21 +72,14 @@ dimensions = () type = integer intent = in -[nTracers] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag dimensions = () type = logical intent = in -[lslwr] +[doLWrad] standard_name = flag_for_calling_longwave_radiation long_name = logical flags for lw radiation calls units = flag @@ -252,38 +245,6 @@ type = real kind = kind_phys intent = in -[minGPpres] - standard_name = minimum_pressure_in_RRTMGP - long_name = minimum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = in -[maxGPpres] - standard_name = maximum_pressure_in_RRTMGP - long_name = maximum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = in -[minGPtemp] - standard_name = minimum_temperature_in_RRTMGP - long_name = minimum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = in -[maxGPtemp] - standard_name = maximum_temperature_in_RRTMGP - long_name = maximum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = in [raddt] standard_name = time_step_for_radiation long_name = radiation time step @@ -354,21 +315,21 @@ units = flag dimensions = () type = logical - intent = out + intent = inout [iSFC] standard_name = vertical_index_for_surface_in_RRTMGP long_name = index for surface layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = inout [iTOA] standard_name = vertical_index_for_TOA_in_RRTMGP long_name = index for TOA layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = inout [tsfc_radtime] standard_name = surface_skin_temperature_on_radiation_timestep long_name = surface skin temperature on radiation timestep @@ -425,11 +386,51 @@ type = real kind = kind_phys intent = inout -[tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = inout @@ -441,13 +442,6 @@ type = character kind = len=* intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = inout [coszdg] standard_name = cosine_of_solar_zenith_angle_on_radiation_timestep long_name = daytime mean cosz over rad call period @@ -464,6 +458,36 @@ type = real kind = kind_phys intent = inout +[semis] + standard_name = surface_longwave_emissivity + long_name = surface lw emissivity in fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_emiss_byband] + standard_name = surface_emissivity_in_each_RRTMGP_LW_band + long_name = surface emissivity in each RRTMGP LW band + units = none + dimensions = (number_of_longwave_bands,horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[nday] + standard_name = daytime_points_dimension + long_name = daytime points dimension + units = count + dimensions = () + type = integer + intent = inout +[idxday] + standard_name = daytime_points + long_name = daytime points + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 3cd8af019..f028acca2 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -156,7 +156,7 @@ end subroutine GFS_rrtmgp_setup_init !> \section arg_table_GFS_rrtmgp_setup_timestep_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! - subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, & + subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad, me, & slag, sdec, cdec, solcon, errmsg, errflg) ! Inputs @@ -164,7 +164,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, integer, intent(in) :: jdate(:) real(kind_phys), intent(in) :: deltsw real(kind_phys), intent(in) :: deltim - logical, intent(in) :: lsswr + logical, intent(in) :: doSWrad integer, intent(in) :: me ! Outputs @@ -222,7 +222,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, endif ! Update solar forcing... - if (lsswr) then + if (doSWrad) then if ( isolar == 0 .or. isolar == 10 ) then lsol_chg = .false. elseif ( iyear0 /= iyear ) then diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 41bf63ac8..160430765 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -256,7 +256,7 @@ type = real kind = kind_phys intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag diff --git a/physics/GFS_rrtmgp_sw_post.F90 b/physics/GFS_rrtmgp_sw_post.F90 deleted file mode 100644 index 87ddc719b..000000000 --- a/physics/GFS_rrtmgp_sw_post.F90 +++ /dev/null @@ -1,286 +0,0 @@ -!> \file GFS_rrtmgp_sw_post.F90 -!! -!> \defgroup GFS_rrtmgp_sw_post GFS_rrtmgp_sw_post.F90 -!! -!! \brief RRTMGP Shortwave post-processing routine. -!! -module GFS_rrtmgp_sw_post - use machine, only: kind_phys - use module_radiation_aerosols, only: NSPC1 - use module_radsw_parameters, only: topfsw_type, sfcfsw_type, cmpfsw_type - use mo_heating_rates, only: compute_heating_rate - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - implicit none - - public GFS_rrtmgp_sw_post_run - -contains - -!>\defgroup gfs_rrtmgp_sw_post_mod GFS RRTMGP-SW Post Module -!> \section arg_table_GFS_rrtmgp_sw_post_run -!! \htmlinclude GFS_rrtmgp_sw_post_run.html -!! -!> \ingroup GFS_rrtmgp_sw_post -!! RRTMGP Shortwave post-processing routine. -!! -!! \brief The all-sky shortwave radiation tendency is computed, the clear-sky tendency is -!! computed if requested. -!! -!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics -!! calls. -!! -!! (optional) Save additional diagnostics. -!! -!! \section GFS_rrtmgp_sw_post_run - ! ######################################################################################### - subroutine GFS_rrtmgp_sw_post_run (nCol, nLev, nDay, idxday, lsswr, do_sw_clrsky_hr, & - save_diag, fhswr, coszen, coszdg, t_lay, p_lev, sfc_alb_nir_dir, sfc_alb_nir_dif, & - sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, fluxswUP_allsky, & - fluxswDOWN_allsky, fluxswUP_clrsky, fluxswDOWN_clrsky, raddt, aerodp, cldsa, mbota, & - mtopa, cld_frac, cldtausw, fluxr, iSFC, iTOA, & - nirbmdi, nirdfdi, visbmdi, visdfdi, nirbmui, nirdfui, visbmui, visdfui, sfcnsw, & - sfcdsw, htrsw, sfcfsw, topfsw, htrswc, scmpsw, errmsg, errflg) - - ! Inputs - integer, intent(in) :: & - nCol, & ! Horizontal loop extent - nLev, & ! Number of vertical layers - nDay, & ! Number of daylit columns - iSFC, & ! Vertical index for surface level - iTOA ! Vertical index for TOA level - integer, intent(in), dimension(nday) :: & - idxday ! Index array for daytime points - logical, intent(in) :: & - lsswr, & ! Call SW radiation? - do_sw_clrsky_hr, & ! Output clear-sky SW heating-rate? - save_diag ! Output radiation diagnostics? - real(kind_phys), intent(in) :: & - fhswr ! Frequency for SW radiation - real(kind_phys), dimension(nCol), intent(in) :: & - t_lay, & ! Temperature at model layer centers (K) - coszen, & ! Cosine(SZA) - coszdg ! Cosine(SZA), daytime - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - p_lev ! Pressure @ model layer-interfaces (Pa) - real(kind_phys), dimension(ncol), intent(in) :: & - sfc_alb_nir_dir, & ! Surface albedo (direct) - sfc_alb_nir_dif, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir, & ! Surface albedo (direct) - sfc_alb_uvvis_dif ! Surface albedo (diffuse) - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - fluxswUP_allsky, & ! SW All-sky flux (W/m2) - fluxswDOWN_allsky, & ! SW All-sky flux (W/m2) - fluxswUP_clrsky, & ! SW Clear-sky flux (W/m2) - fluxswDOWN_clrsky ! SW All-sky flux (W/m2) - real(kind_phys), intent(in) :: & - raddt ! Radiation time step - real(kind_phys), dimension(nCol,NSPC1), intent(in) :: & - aerodp ! Vertical integrated optical depth for various aerosol species - real(kind_phys), dimension(nCol,5), intent(in) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL - integer, dimension(nCol,3), intent(in) ::& - mbota, & ! vertical indices for low, middle and high cloud tops - mtopa ! vertical indices for low, middle and high cloud bases - real(kind_phys), dimension(nCol,nLev), intent(in) :: & - cld_frac, & ! Total cloud fraction in each layer - cldtausw ! approx .55mu band layer cloud optical depth - type(cmpfsw_type), dimension(nCol), intent(in) :: & - scmpsw ! 2D surface fluxes, components: - ! uvbfc - total sky downward uv-b flux at (W/m2) - ! uvbf0 - clear sky downward uv-b flux at (W/m2) - ! nirbm - downward nir direct beam flux (W/m2) - ! nirdf - downward nir diffused flux (W/m2) - ! visbm - downward uv+vis direct beam flux (W/m2) - ! visdf - downward uv+vis diffused flux (W/m2) - - real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr - - ! Outputs (mandatory) - real(kind_phys), dimension(nCol), intent(inout) :: & - nirbmdi, & ! sfc nir beam sw downward flux (W/m2) - nirdfdi, & ! sfc nir diff sw downward flux (W/m2) - visbmdi, & ! sfc uv+vis beam sw downward flux (W/m2) - visdfdi, & ! sfc uv+vis diff sw downward flux (W/m2) - nirbmui, & ! sfc nir beam sw upward flux (W/m2) - nirdfui, & ! sfc nir diff sw upward flux (W/m2) - visbmui, & ! sfc uv+vis beam sw upward flux (W/m2) - visdfui, & ! sfc uv+vis diff sw upward flux (W/m2) - sfcnsw, & ! total sky sfc netsw flx into ground - sfcdsw ! - real(kind_phys), dimension(nCol,nLev), intent(inout) :: & - htrsw ! SW all-sky heating rate - type(sfcfsw_type), dimension(nCol), intent(inout) :: & - sfcfsw ! sw radiation fluxes at sfc - type(topfsw_type), dimension(nCol), intent(inout) :: & - topfsw ! sw_fluxes_top_atmosphere - character(len=*), intent(out) :: & - errmsg - integer, intent(out) :: & - errflg - - ! Outputs (optional) - real(kind_phys),dimension(nCol, nLev),intent(inout),optional :: & - htrswc ! Clear-sky heating rate (K/s) - - ! Local variables - integer :: i, j, k, itop, ibtc - real(kind_phys) :: tem0d, tem1, tem2 - real(kind_phys), dimension(nDay, nLev) :: thetaTendClrSky, thetaTendAllSky - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. lsswr) return - if (nDay .gt. 0) then - - ! ####################################################################################### - ! Compute SW heating-rates - ! ####################################################################################### - ! Clear-sky heating-rate (optional) - if (do_sw_clrsky_hr) then - htrswc(:,:) = 0._kind_phys - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxswUP_clrsky(idxday(1:nDay),:), & ! IN - Shortwave upward clear-sky flux profiles (W/m2) - fluxswDOWN_clrsky(idxday(1:nDay),:), & ! IN - Shortwave downward clear-sky flux profiles (W/m2) - p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) - thetaTendClrSky)) ! OUT - Clear-sky heating-rate (K/sec) - htrswc(idxday(1:nDay),:)=thetaTendClrSky !**NOTE** GP doesn't use radiation levels, it uses the model fields. Not sure if this is necessary - endif - - ! All-sky heating-rate (mandatory) - htrsw(:,:) = 0._kind_phys - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxswUP_allsky(idxday(1:nDay),:), & ! IN - Shortwave upward all-sky flux profiles (W/m2) - fluxswDOWN_allsky(idxday(1:nDay),:), & ! IN - Shortwave downward all-sky flux profiles (W/m2) - p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) - thetaTendAllSky)) ! OUT - All-sky heating-rate (K/sec) - htrsw(idxday(1:nDay),:) = thetaTendAllSky - - ! ####################################################################################### - ! Save SW outputs - ! (Copy fluxes from RRTMGP types into model radiation types.) - ! ####################################################################################### - - ! TOA fluxes - topfsw(:)%upfxc = fluxswUP_allsky(:,iTOA) - topfsw(:)%upfx0 = fluxswUP_clrsky(:,iTOA) - topfsw(:)%dnfxc = fluxswDOWN_allsky(:,iTOA) - - ! Surface fluxes - sfcfsw(:)%upfxc = fluxswUP_allsky(:,iSFC) - sfcfsw(:)%upfx0 = fluxswUP_clrsky(:,iSFC) - sfcfsw(:)%dnfxc = fluxswDOWN_allsky(:,iSFC) - sfcfsw(:)%dnfx0 = fluxswDOWN_clrsky(:,iSFC) - - ! Surface down and up spectral component fluxes - ! - Save two spectral bands' surface downward and upward fluxes for output. - do i=1,nCol - nirbmdi(i) = scmpsw(i)%nirbm - nirdfdi(i) = scmpsw(i)%nirdf - visbmdi(i) = scmpsw(i)%visbm - visdfdi(i) = scmpsw(i)%visdf - nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(i) - nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(i) - visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(i) - visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(i) - enddo - else ! if_nday_block - ! ####################################################################################### - ! Dark everywhere - ! ####################################################################################### - htrsw(:,:) = 0.0 - sfcfsw = sfcfsw_type( 0.0, 0.0, 0.0, 0.0 ) - topfsw = topfsw_type( 0.0, 0.0, 0.0 ) - do i=1,nCol - nirbmdi(i) = 0.0 - nirdfdi(i) = 0.0 - visbmdi(i) = 0.0 - visdfdi(i) = 0.0 - nirbmui(i) = 0.0 - nirdfui(i) = 0.0 - visbmui(i) = 0.0 - visdfui(i) = 0.0 - enddo - - if (do_sw_clrsky_hr) then - htrswc(:,:) = 0 - endif - endif ! end_if_nday - - ! Radiation fluxes for other physics processes - do i=1,nCol - sfcnsw(i) = sfcfsw(i)%dnfxc - sfcfsw(i)%upfxc - sfcdsw(i) = sfcfsw(i)%dnfxc - enddo - - ! ####################################################################################### - ! Save SW diagnostics - ! - For time averaged output quantities (including total-sky and clear-sky SW and LW - ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base - ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in - ! corresponding slots of array fluxr with appropriate time weights. - ! - Collect the fluxr data for wrtsfc - ! ####################################################################################### - if (save_diag) then - do i=1,nCol - fluxr(i,34) = aerodp(i,1) ! total aod at 550nm - fluxr(i,35) = aerodp(i,2) ! DU aod at 550nm - fluxr(i,36) = aerodp(i,3) ! BC aod at 550nm - fluxr(i,37) = aerodp(i,4) ! OC aod at 550nm - fluxr(i,38) = aerodp(i,5) ! SU aod at 550nm - fluxr(i,39) = aerodp(i,6) ! SS aod at 550nm - if (coszen(i) > 0.) then - ! SW all-sky fluxes - tem0d = fhswr * coszdg(i) / coszen(i) - fluxr(i,2 ) = fluxr(i,2) + topfsw(i)%upfxc * tem0d ! total sky top sw up - fluxr(i,3 ) = fluxr(i,3) + sfcfsw(i)%upfxc * tem0d - fluxr(i,4 ) = fluxr(i,4) + sfcfsw(i)%dnfxc * tem0d ! total sky sfc sw dn - ! SW uv-b fluxes - fluxr(i,21) = fluxr(i,21) + scmpsw(i)%uvbfc * tem0d ! total sky uv-b sw dn - fluxr(i,22) = fluxr(i,22) + scmpsw(i)%uvbf0 * tem0d ! clear sky uv-b sw dn - ! SW TOA incoming fluxes - fluxr(i,23) = fluxr(i,23) + topfsw(i)%dnfxc * tem0d ! top sw dn - ! SW SFC flux components - fluxr(i,24) = fluxr(i,24) + visbmdi(i) * tem0d ! uv/vis beam sw dn - fluxr(i,25) = fluxr(i,25) + visdfdi(i) * tem0d ! uv/vis diff sw dn - fluxr(i,26) = fluxr(i,26) + nirbmdi(i) * tem0d ! nir beam sw dn - fluxr(i,27) = fluxr(i,27) + nirdfdi(i) * tem0d ! nir diff sw dn - ! SW clear-sky fluxes - fluxr(i,29) = fluxr(i,29) + topfsw(i)%upfx0 * tem0d - fluxr(i,31) = fluxr(i,31) + sfcfsw(i)%upfx0 * tem0d - fluxr(i,32) = fluxr(i,32) + sfcfsw(i)%dnfx0 * tem0d - endif - enddo - - ! Save total and boundary-layer clouds - do i=1,nCol - fluxr(i,17) = fluxr(i,17) + raddt * cldsa(i,4) - fluxr(i,18) = fluxr(i,18) + raddt * cldsa(i,5) - enddo - - ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud - ! is reversed for the fluxr output. save interface pressure (pa) of top/bot - do j = 1, 3 - do i = 1, nCol - tem0d = raddt * cldsa(i,j) - itop = mtopa(i,j) - ibtc = mbota(i,j) - fluxr(i, 8-j) = fluxr(i, 8-j) + tem0d - fluxr(i,11-j) = fluxr(i,11-j) + tem0d * p_lev(i,itop) - fluxr(i,14-j) = fluxr(i,14-j) + tem0d * p_lev(i,ibtc) - fluxr(i,17-j) = fluxr(i,17-j) + tem0d * p_lev(i,itop) - - ! Add optical depth and emissivity output - tem1 = 0. - do k=ibtc,itop - tem1 = tem1 + cldtausw(i,k) ! approx .55 mu channel - enddo - fluxr(i,43-j) = fluxr(i,43-j) + tem0d * tem1 - enddo - enddo - endif - end subroutine GFS_rrtmgp_sw_post_run - -end module GFS_rrtmgp_sw_post diff --git a/physics/GFS_rrtmgp_sw_pre.F90 b/physics/GFS_rrtmgp_sw_pre.F90 deleted file mode 100644 index 87d0f9ad1..000000000 --- a/physics/GFS_rrtmgp_sw_pre.F90 +++ /dev/null @@ -1,95 +0,0 @@ -!> \file GFS_rrtmgp_sw_pre.F90 -!! This file contains code to gather the sunlit points for the RRTMGP shortwave scheme. -!! -!> \defgroup GFS_rrtmgp_sw_pre RRTMGP Shortwave pre -!! -!! \brief *TODO* Combine with rrtmg_sw_pre.F90, maybe call sw_rad_pre.F90, use by both. -!! -module GFS_rrtmgp_sw_pre - use machine, only: kind_phys - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use rrtmgp_sw_gas_optics, only: sw_gas_props - public GFS_rrtmgp_sw_pre_run -contains - -!> \section arg_table_GFS_rrtmgp_sw_pre_run -!! \htmlinclude GFS_rrtmgp_sw_pre.html -!! -!! \section GFS_rrtmgp_sw_pre RRTMGP shortwave pre routine -!! @{ -!! -!! Gather the sunlit points for shortwave radiation. -!! - ! ######################################################################################### - subroutine GFS_rrtmgp_sw_pre_run(nCol, doSWrad, coszen, nday, idxday, sfc_alb_nir_dir, & - sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, sfc_alb_nir_dir_byband, & - sfc_alb_nir_dif_byband, sfc_alb_uvvis_dir_byband, sfc_alb_uvvis_dif_byband, errmsg, & - errflg) - - ! Input - integer, intent(in) :: & - nCol ! Number of horizontal grid points - logical,intent(in) :: & - doSWrad ! Call RRTMGP SW radiation? - real(kind_phys), dimension(:), intent(in) :: & - coszen - real(kind_phys), dimension(:), intent(in) :: & - sfc_alb_nir_dir, & ! - sfc_alb_nir_dif, & ! - sfc_alb_uvvis_dir, & ! - sfc_alb_uvvis_dif ! - - ! Outputs - integer, intent(out) :: & - nday ! Number of daylit points - integer, dimension(:), intent(out) :: & - idxday ! Indices for daylit points - real(kind_phys), dimension(:,:), intent(out) :: & - sfc_alb_nir_dir_byband, & ! Surface albedo (direct) - sfc_alb_nir_dif_byband, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir_byband, & ! Surface albedo (direct) - sfc_alb_uvvis_dif_byband ! Surface albedo (diffuse) - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - integer :: i, iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (doSWrad) then - ! #################################################################################### - ! For SW gather daylit points - ! #################################################################################### - nday = 0 - idxday = 0 - do i = 1, nCol - if (coszen(i) >= 0.0001) then - nday = nday + 1 - idxday(nday) = i - endif - enddo - - ! Spread across all SW bands - do iBand=1,sw_gas_props%get_nband() - sfc_alb_nir_dir_byband(iBand,1:nCol) = sfc_alb_nir_dir(1:nCol) - sfc_alb_nir_dif_byband(iBand,1:nCol) = sfc_alb_nir_dif(1:nCol) - sfc_alb_uvvis_dir_byband(iBand,1:nCol) = sfc_alb_uvvis_dir(1:nCol) - sfc_alb_uvvis_dif_byband(iBand,1:nCol) = sfc_alb_uvvis_dif(1:nCol) - enddo - else - nday = 0 - idxday = 0 - sfc_alb_nir_dir_byband(:,1:nCol) = 0. - sfc_alb_nir_dif_byband(:,1:nCol) = 0. - sfc_alb_uvvis_dir_byband(:,1:nCol) = 0. - sfc_alb_uvvis_dif_byband(:,1:nCol) = 0. - endif - - end subroutine GFS_rrtmgp_sw_pre_run -!> @} -end module GFS_rrtmgp_sw_pre diff --git a/physics/GFS_rrtmgp_sw_pre.meta b/physics/GFS_rrtmgp_sw_pre.meta deleted file mode 100644 index 462ab5f18..000000000 --- a/physics/GFS_rrtmgp_sw_pre.meta +++ /dev/null @@ -1,124 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_sw_pre - type = scheme - dependencies = machine.F,radiation_astronomy.f,rrtmgp_sw_gas_optics.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90, - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_sw_pre_run - type = scheme -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = out -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = out -[coszen] - standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep - long_name = mean cos of zenith angle over rad call period - units = none - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dir] - standard_name = surface_albedo_due_to_near_IR_direct - long_name = surface albedo due to near IR direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dif] - standard_name = surface_albedo_due_to_near_IR_diffused - long_name = surface albedo due to near IR diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dir] - standard_name = surface_albedo_due_to_UV_and_VIS_direct - long_name = surface albedo due to UV+VIS direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dif] - standard_name = surface_albedo_due_to_UV_and_VIS_diffused - long_name = surface albedo due to UV+VIS diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dir_byband] - standard_name = surface_albedo_nearIR_direct - long_name = near-IR (direct) surface albedo (sfc_alb_nir_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_nir_dif_byband] - standard_name = surface_albedo_nearIR_diffuse - long_name = near-IR (diffuse) surface albedo (sfc_alb_nir_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_uvvis_dir_byband] - standard_name = surface_albedo_uvvis_direct - long_name = UVVIS (direct) surface albedo (sfc_alb_uvvis_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_uvvis_dif_byband] - standard_name = surface_albedo_uvvis_diffuse - long_name = UVVIS (diffuse) surface albedo (sfc_alb_uvvis_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index e2cc95994..cf3f7deea 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -3,16 +3,10 @@ module rrtmgp_aerosol_optics use machine, only: kind_phys - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str, ty_optical_props_1scl use radiation_tools, only: check_error_msg use rrtmgp_sw_gas_optics, only: sw_gas_props use rrtmgp_lw_gas_optics, only: lw_gas_props - use module_radiation_aerosols, only: & - NF_AESW, & ! Number of optical-fields in SW output (3=tau+g+omega) - NF_AELW, & ! Number of optical-fields in LW output (3=tau+g+omega) - setaer, & ! Routine to compute aerosol radiative properties (tau,g,omega) - NSPC1 ! Number of species for vertically integrated aerosol optical-depth + use module_radiation_aerosols, only: setaer use netcdf implicit none @@ -30,9 +24,9 @@ module rrtmgp_aerosol_optics !! \section arg_table_rrtmgp_aerosol_optics_run !! \htmlinclude rrtmgp_aerosol_optics_run.html !! - subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTracerAer, & - nDay, idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - aerodp, sw_optical_props_aerosol, lw_optical_props_aerosol, errmsg, errflg ) + subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, p_lev, & + p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & + aerodp, aerlw_tau, aerlw_ssa, aerlw_g, aersw_tau, aersw_ssa, aersw_g, errmsg, errflg ) ! Inputs logical, intent(in) :: & @@ -41,10 +35,8 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra integer, intent(in) :: & nCol, & ! Number of horizontal grid points nDay, & ! Number of daylit points - nLev, & ! Number of vertical layers - nTracer, & ! Number of tracers - nTracerAer ! Number of aerosol tracers - integer,intent(in),dimension(:) :: & + nLev ! Number of vertical layers + integer,dimension(:), intent(in) :: & idxday ! Indices for daylit points. real(kind_phys), dimension(:), intent(in) :: & lon, & ! Longitude @@ -65,19 +57,22 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra ! Outputs real(kind_phys), dimension(:,:), intent(out) :: & aerodp ! Vertical integrated optical depth for various aerosol species - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) + real(kind_phys), dimension(:,:,:), intent(out) :: & + aerlw_tau, & ! Longwave aerosol optical depth + aerlw_ssa, & ! Longwave aerosol single scattering albedo + aerlw_g, & ! Longwave aerosol asymmetry parameter + aersw_tau, & ! Shortwave aerosol optical depth + aersw_ssa, & ! Shortwave aerosol single scattering albedo + aersw_g ! Shortwave aerosol asymmetry parameter integer, intent(out) :: & errflg ! CCPP error flag character(len=*), intent(out) :: & errmsg ! CCPP error message ! Local variables - real(kind_phys), dimension(nCol, nLev, lw_gas_props%get_nband(), NF_AELW) :: & + real(kind_phys), dimension(nCol, nLev, lw_gas_props%get_nband(), 3) :: & aerosolslw ! - real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), NF_AESW) :: & + real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), 3) :: & aerosolssw, aerosolssw2 integer :: iBand @@ -85,14 +80,14 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra errmsg = '' errflg = 0 - if (.not. doSWrad) return + if (.not. (doSWrad .or. doLWrad)) return ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile call setaer(p_lev*0.01, p_lay*0.01, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & nLev+1, .true., .true., aerosolssw2, aerosolslw, aerodp) ! Shortwave - if (nDay .gt. 0) then + if (doSWrad .and. (nDay .gt. 0)) then ! Store aerosol optical properties ! SW. ! For RRTMGP SW the bands are now ordered from [IR(band) -> nIR -> UV], in RRTMG the @@ -103,26 +98,19 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),1) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,1) aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),2) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,2) aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),3) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,3) - - ! Allocate RRTMGP DDT: Aerosol optics [nCol,nlev,nBands] - call check_error_msg('rrtmgp_aerosol_optics_run',sw_optical_props_aerosol%alloc_2str( & - nDay, nlev, sw_gas_props%get_band_lims_wavenumber())) - - ! Copy aerosol optical information to RRTMGP DDT - sw_optical_props_aerosol%tau = aerosolssw(idxday(1:nday),:,:,1) - sw_optical_props_aerosol%ssa = aerosolssw(idxday(1:nday),:,:,2) - sw_optical_props_aerosol%g = aerosolssw(idxday(1:nday),:,:,3) + + ! Copy aerosol optical information/ + aersw_tau = aerosolssw(:,:,:,1) + aersw_ssa = aerosolssw(:,:,:,2) + aersw_g = aerosolssw(:,:,:,3) endif ! Longwave - if (.not. doLWrad) return - lw_optical_props_aerosol%tau = aerosolslw(:,:,:,1) * (1. - aerosolslw(:,:,:,2)) - - lw_optical_props_aerosol%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_aerosol%band2gpt(1:2,iBand) = iBand - lw_optical_props_aerosol%gpt2band(iBand) = iBand - end do + if (doLWrad) then + aerlw_tau = aerosolslw(:,:,:,1) + aerlw_ssa = aerosolslw(:,:,:,2) + aerlw_g = aerosolslw(:,:,:,3) + endif end subroutine rrtmgp_aerosol_optics_run !> @} diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index f0c37edc0..6dbf9c73c 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -35,20 +35,6 @@ dimensions = () type = integer intent = in -[nTracer] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[nTracerAer] - standard_name = number_of_aerosol_tracers_MG - long_name = number of aerosol tracers for Morrison Gettelman MP - units = count - dimensions = () - type = integer - intent = in [nday] standard_name = daytime_points_dimension long_name = daytime points dimension @@ -112,9 +98,9 @@ kind = kind_phys intent = in [tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 + standard_name = tracer_concentration + long_name = model layer mean tracer concentration + units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) type = real kind = kind_phys @@ -151,20 +137,54 @@ type = real kind = kind_phys intent = out -[sw_optical_props_aerosol] - standard_name = shortwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str +[aersw_tau] + standard_name = aerosol_optical_depth_for_shortwave_bands_01_16 + long_name = aerosol optical depth for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aersw_ssa] + standard_name = aerosol_single_scattering_albedo_for_shortwave_bands_01_16 + long_name = aerosol single scattering albedo for shortwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aersw_g] + standard_name = aerosol_asymmetry_parameter_for_shortwave_bands_01_16 + long_name = aerosol asymmetry parameter for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_tau] + standard_name = aerosol_optical_depth_for_longwave_bands_01_16 + long_name = aerosol optical depth for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_ssa] + standard_name = aerosol_single_scattering_albedo_for_longwave_bands_01_16 + long_name = aerosol single scattering albedo for longwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_g] + standard_name = aerosol_asymmetry_parameter_for_longwave_bands_01_16 + long_name = aerosol asymmetry parameter for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys intent = out -[lw_optical_props_aerosol] - standard_name = longwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/rrtmgp_lw_cloud_optics.F90 b/physics/rrtmgp_lw_cloud_optics.F90 index 8bdd71696..9915c0040 100644 --- a/physics/rrtmgp_lw_cloud_optics.F90 +++ b/physics/rrtmgp_lw_cloud_optics.F90 @@ -12,8 +12,6 @@ module rrtmgp_lw_cloud_optics use machine, only: kind_phys use mo_rte_kind, only: wl use mo_cloud_optics, only: ty_cloud_optics - use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str - use mo_rrtmg_lw_cloud_optics, only: rrtmg_lw_cloud_optics use rrtmgp_lw_gas_optics, only: lw_gas_props use radiation_tools, only: check_error_msg use netcdf @@ -74,55 +72,42 @@ module rrtmgp_lw_cloud_optics contains -!>\defgroup rrtmgp_lw_cloud_optics_mod GFS RRTMGP-LW Cloud Optics Module -!> \section arg_table_rrtmgp_lw_cloud_optics_init -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_lw_cloud_optics -!! -!! RRTMGP relies heavily on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP longwave scheme. The data needed -!! to compute the shortwave cloud optical properties are initialized here and loaded into -!! the RRTMGP DDT, ty_cloud_optics. -!! -!! \section rrtmgp_sw_cloud_optics_init - subroutine rrtmgp_lw_cloud_optics_init(nrghice, mpicomm, mpirank, mpiroot, & - doG_cldoptics, doGP_cldoptics_PADE, doGP_cldoptics_LUT, rrtmgp_root_dir, & - rrtmgp_lw_file_clouds, errmsg, errflg) + ! ###################################################################################### + ! SUBROUTINE rrtmgp_lw_cloud_optics_init() + ! ###################################################################################### + subroutine rrtmgp_lw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_lw_file_clouds ! RRTMGP file containing clouds optics data + logical, intent(in) :: & - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? + doGP_cldoptics_PADE,& ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? integer, intent(inout) :: & - nrghice ! Number of ice-roughness categories + nrghice ! Number of ice-roughness categories integer, intent(in) :: & - mpicomm, & ! MPI communicator - mpirank, & ! Current MPI rank - mpiroot ! Master MPI rank - character(len=128),intent(in) :: & - rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_lw_file_clouds ! RRTMGP file containing coefficients used to compute clouds optical properties + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank ! Outputs character(len=*), intent(out) :: & - errmsg ! Error message + errmsg ! Error message integer, intent(out) :: & - errflg ! Error code + errflg ! Error code ! Local variables integer :: dimID,varID,status,ncid,mpierr character(len=264) :: lw_cloud_props_file - integer,parameter :: max_strlen=256, nrghice_default=2 ! Initialize errmsg = '' errflg = 0 - ! If not using RRTMGP cloud optics, return. - if (doG_cldoptics) return - ! Filenames are set in the physics_nml lw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_lw_file_clouds) @@ -391,171 +376,4 @@ subroutine rrtmgp_lw_cloud_optics_init(nrghice, mpicomm, mpirank, mpiroot, call check_error_msg('lw_cloud_optics_init',lw_cloud_props%set_ice_roughness(nrghice)) end subroutine rrtmgp_lw_cloud_optics_init - ! ###################################################################################### -!> \section arg_table_rrtmgp_lw_cloud_optics_run -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_lw_cloud_optics -!! -!! Compute longwave optical prperties (optical-depth) for ALL cloud types visible to RRTMGP. -!! -!! \section rrtmgp_lw_gas_optics_run - subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_lwscat, do_mynnedmf, imfdeepcnv, & - imfdeepcnv_gf, imfdeepcnv_samf, nCol, nLev, nbndsGPlw , p_lay, cld_frac, cld_lwp, & - cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, & - precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & - cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lon, lat, cldtaulw, & - lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & - lw_optical_props_MYNNcloudsByBand, lw_optical_props_precipByBand, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad, & ! Logical flag for longwave radiation call - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? - doGP_lwscat, & ! Include scattering in LW cloud-optics? - do_mynnedmf ! - integer, intent(in) :: & - nbndsGPlw, & ! - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - icliq_lw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_lw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf ! - real(kind_phys), dimension(:), intent(in) :: & - lon, & ! Longitude - lat ! Latitude - real(kind_phys), dimension(:,:),intent(in) :: & - p_lay, & ! Layer pressure (Pa) - cld_frac, & ! Total cloud fraction by layer - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effective radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac, & ! Precipitation fraction by layer. - cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) - cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) - cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) - cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) - cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles - cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles - cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles - cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) - lw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (MYNN-PBL cloud) - lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) - real(kind_phys), dimension(:,:), intent(inout) :: & - cldtaulw ! Approx 10.mu band layer cloud optical depth - - ! Local variables - real(kind_phys) :: tau_rain, tau_snow - real(kind_phys), dimension(ncol,nLev,nbndsGPlw) :: & - tau_cld, tau_precip - integer :: iCol, iLay, iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Initialize locals - tau_cld = 0._kind_phys - tau_precip = 0._kind_phys - - if (.not. doLWrad) return - - ! Compute cloud-optics for RTE. - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - - ! i) Cloud-optics. - lw_optical_props_cloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_cloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_cloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_cloud_optics_run - clouds',lw_cloud_props%cloud_optics(& - cld_lwp, & ! IN - Cloud liquid water path (g/m2) - cld_iwp, & ! IN - Cloud ice water path (g/m2) - cld_reliq, & ! IN - Cloud liquid effective radius (microns) - cld_reice, & ! IN - Cloud ice effective radius (microns) - lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties - ! in each band - ! ii) Convective cloud-optics - if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then - lw_optical_props_cnvcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_cnvcloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_cnvcloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_cnvcloud_optics_run - convective cloud',lw_cloud_props%cloud_optics(& - cld_cnv_lwp, & ! IN - Convective cloud liquid water path (g/m2) - cld_cnv_iwp, & ! IN - Convective cloud ice water path (g/m2) - cld_cnv_reliq, & ! IN - Convective cloud liquid effective radius (microns) - cld_cnv_reice, & ! IN - Convective cloud ice effective radius (microns) - lw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties - ! in each band - endif - - ! iii) MYNN cloud-optics - if (do_mynnedmf) then - lw_optical_props_MYNNcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_MYNNcloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_MYNNcloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_MYNNcloud_optics_run - MYNN-EDMF cloud',lw_cloud_props%cloud_optics(& - cld_pbl_lwp, & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) - cld_pbl_iwp, & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) - cld_pbl_reliq, & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) - cld_pbl_reice, & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) - lw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties - ! in each band - endif - - ! iv) Cloud precipitation optics: rain and snow(+groupel) - lw_optical_props_precipByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_precipByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_precipByBand%gpt2band(iBand) = iBand - end do - do iCol=1,nCol - do iLay=1,nLev - if (cld_frac(iCol,iLay) .gt. 0.) then - ! Rain optical-depth (No band dependence) - tau_rain = absrain*cld_rwp(iCol,iLay) - - ! Snow (+groupel) optical-depth (No band dependence) - if (cld_swp(iCol,iLay) .gt. 0. .and. cld_resnow(iCol,iLay) .gt. 10._kind_phys) then - tau_snow = abssnow0*1.05756*cld_swp(iCol,iLay)/cld_resnow(iCol,iLay) - else - tau_snow = 0.0 - endif - do iBand=1,nbndsGPlw - lw_optical_props_precipByBand%tau(iCol,iLay,iBand) = tau_rain + tau_snow - enddo - endif - enddo - enddo - endif - - ! All-sky LW optical depth ~10microns (DJS asks: Same as SW, move to cloud-diagnostics?) - cldtaulw = lw_optical_props_cloudsByBand%tau(:,:,7) - - end subroutine rrtmgp_lw_cloud_optics_run - end module rrtmgp_lw_cloud_optics diff --git a/physics/rrtmgp_lw_cloud_optics.meta b/physics/rrtmgp_lw_cloud_optics.meta deleted file mode 100644 index c58496dc5..000000000 --- a/physics/rrtmgp_lw_cloud_optics.meta +++ /dev/null @@ -1,412 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_cloud_optics - type = scheme - dependencies = machine.F,rrtmg_lw_cloud_optics.F90,radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_cloud_optics_init - type = scheme -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[nrghice] - standard_name = number_of_ice_roughness_categories - long_name = number of ice-roughness categories in RRTMGP calculation - units = count - dimensions = () - type = integer - intent = inout -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_lw_file_clouds] - standard_name = filename_of_rrtmgp_longwave_cloud_optics_coefficients - long_name = file containing coefficients for RRTMGP LW cloud optics - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_cloud_optics_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[icliq_lw] - standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation - long_name = lw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[icice_lw] - standard_name = flag_for_optical_property_for_ice_clouds_for_longwave_radiation - long_name = lw optical property for ice clouds - units = flag - dimensions = () - type = integer - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_lwscat] - standard_name = flag_to_include_longwave_scattering_in_cloud_optics - long_name = logical flag to control the addition of LW scattering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_swp] - standard_name = cloud_snow_water_path - long_name = cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow flake - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain drop - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_lwp] - standard_name = convective_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_iwp] - standard_name = convective_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reliq] - standard_name = mean_effective_radius_for_liquid_convective_cloud - long_name = mean effective radius for liquid convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reice] - standard_name = mean_effective_radius_for_ice_convective_cloud - long_name = mean effective radius for ice convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_lwp] - standard_name = MYNN_SGS_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_iwp] - standard_name = MYNN_SGS_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reliq] - standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud - long_name = mean effective radius for liquid MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reice] - standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud - long_name = mean effective radius for ice MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[nbndsGPlw] - standard_name = number_of_longwave_bands - long_name = number of lw bands used in RRTMGP - units = count - dimensions = () - type = integer - intent = in -[lon] - standard_name = longitude - long_name = longitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lat] - standard_name = latitude - long_name = latitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[cldtaulw] - standard_name = cloud_optical_depth_layers_at_10mu_band - long_name = approx 10mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[lw_optical_props_cloudsByBand] - standard_name = longwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_MYNNcloudsByBand] - standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - diff --git a/physics/rrtmgp_lw_cloud_sampling.F90 b/physics/rrtmgp_lw_cloud_sampling.F90 deleted file mode 100644 index 80fd3444a..000000000 --- a/physics/rrtmgp_lw_cloud_sampling.F90 +++ /dev/null @@ -1,170 +0,0 @@ -!> \file rrtmgp_lw_cloud_sampling.F90 -!! -!> \defgroup rrtmgp_lw_cloud_sampling rrtmgp_lw_cloud_sampling.F90 -!! -!! \brief -!! -module rrtmgp_lw_cloud_sampling - use machine, only: kind_phys, kind_dbl_prec - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str - use rrtmgp_sampling, only: sampled_mask, draw_samples - use mersenne_twister, only: random_setseed, random_number, random_stat - use radiation_tools, only: check_error_msg - use rrtmgp_lw_gas_optics, only: lw_gas_props - use netcdf - - implicit none - -contains - -!>\defgroup rrtmgp_lw_cloud_sampling_mod GFS RRTMGP-LW Cloud Sampling Module -!> \section arg_table_rrtmgp_lw_cloud_sampling_run -!! \htmlinclude rrtmgp_lw_cloud_sampling_run.html -!! -!> \ingroup rrtmgp_lw_cloud_sampling -!! -!! \brief This routine performs the McICA cloud-sampling and maps the shortwave cloud- -!! optical properties, defined for each spectral band, to each spectral point (g-point). -!! -!! \section rrtmgp_lw_cloud_sampling_run - subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr,iovr_convcld,& - iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, & - cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param, cld_cnv_frac, & - cnv_cloud_overlap_param, imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, & - lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & - lw_optical_props_precipByBand, lw_optical_props_clouds, lw_optical_props_cnvclouds, & - lw_optical_props_precip, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad ! Logical flag for shortwave radiation call - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical layers - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf, & ! - iovr, & ! Choice of cloud-overlap method - iovr_convcld, & ! Choice of convective cloud-overlap - iovr_max, & ! Flag for maximum cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_rand, & ! Flag for random cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand, & ! Flag for exponential-random cloud overlap method - isubc_lw - integer,intent(in),dimension(:) :: & - icseed_lw ! auxiliary special cloud related array when module - ! variable isubc_lw=2, it provides permutation seed - ! for each column profile that are used for generating - ! random numbers. when isubc_lw /=2, it will not be used. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_cnv_frac, & ! Convective cloud fraction by layer - precip_frac, & ! Precipitation fraction by layer - cloud_overlap_param, & ! Cloud overlap parameter - cnv_cloud_overlap_param, & ! Convective cloud overlap parameter - precip_overlap_param ! Precipitation overlap parameter - type(ty_optical_props_2str),intent(in) :: & - lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) - lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (clouds) - lw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (convective cloud) - lw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties by spectral point (precipitation) - - ! Local variables - integer :: iCol, iLay, iBand - integer,dimension(ncol) :: ipseed_lw - type(random_stat) :: rng_stat - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt(),nLev,ncol) :: rng3D,rng3D2 - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()*nLev) :: rng2D - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()) :: rng1D - logical, dimension(ncol,nLev,lw_gas_props%get_ngpt()) :: maskMCICA - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! #################################################################################### - ! First sample the clouds... - ! #################################################################################### - lw_optical_props_clouds%band2gpt = lw_gas_props%get_band_lims_gpoint() - lw_optical_props_clouds%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_clouds%gpt2band(lw_optical_props_clouds%band2gpt(1,iBand):lw_optical_props_clouds%band2gpt(2,iBand)) = iBand - end do - - ! Change random number seed value for each radiation invocation (isubc_lw =1 or 2). - if(isubc_lw == 1) then ! advance prescribed permutation seed - do iCol = 1, ncol - ipseed_lw(iCol) = lw_gas_props%get_ngpt() + iCol - enddo - elseif (isubc_lw == 2) then ! use input array of permutaion seeds - do iCol = 1, ncol - ipseed_lw(iCol) = icseed_lw(iCol) - enddo - endif - - ! Call RNG. Mersennse Twister accepts 1D array, so loop over columns and collapse along G-points - ! and layers. ([nGpts,nLev,nColumn]-> [nGpts*nLev]*nColumn) - do iCol=1,ncol - call random_setseed(ipseed_lw(icol),rng_stat) - ! Use same rng for each layer - if (iovr == iovr_max) then - call random_number(rng1D,rng_stat) - do iLay=1,nLev - rng3D(:,iLay,iCol) = rng1D - enddo - else - do iLay=1,nLev - call random_number(rng1D,rng_stat) - rng3D(:,iLay,iCol) = rng1D - enddo - endif - enddo - - ! Cloud-overlap. - ! Maximum-random, random or maximum. - if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA) - endif - ! Exponential decorrelation length overlap - if (iovr == iovr_dcorr) then - ! Generate second RNG - do iCol=1,ncol - call random_setseed(ipseed_lw(icol),rng_stat) - call random_number(rng2D,rng_stat) - rng3D2(:,:,iCol) = reshape(source = rng2D,shape=[lw_gas_props%get_ngpt(),nLev]) - enddo - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA, & - overlap_param = cloud_overlap_param(:,1:nLev-1), & - randoms2 = real(rng3D2, kind=kind_phys)) - endif - ! Exponential or Exponential-random - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA, & - overlap_param = cloud_overlap_param(:,1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_lw_cloud_sampling_run_draw_samples',& - draw_samples(maskMCICA, .true., & - lw_optical_props_cloudsByBand, & - lw_optical_props_clouds)) - - end subroutine rrtmgp_lw_cloud_sampling_run - -end module rrtmgp_lw_cloud_sampling diff --git a/physics/rrtmgp_lw_cloud_sampling.meta b/physics/rrtmgp_lw_cloud_sampling.meta deleted file mode 100644 index c1ae9d139..000000000 --- a/physics/rrtmgp_lw_cloud_sampling.meta +++ /dev/null @@ -1,226 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_cloud_sampling - type = scheme - dependencies = machine.F,mersenne_twister.f,rrtmgp_sampling.F90,radiation_tools.F90 - -###################################################### -[ccpp-arg-table] - name = rrtmgp_lw_cloud_sampling_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[iovr_convcld] - standard_name = flag_for_convective_cloud_overlap_method_for_radiation - long_name = flag for convective cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[isubc_lw] - standard_name = flag_for_lw_clouds_sub_grid_approximation - long_name = flag for lw clouds sub-grid approximation - units = flag - dimensions = () - type = integer - intent = in -[iovr] - standard_name = flag_for_cloud_overlap_method_for_radiation - long_name = max-random overlap clouds - units = flag - dimensions = () - type = integer - intent = in -[iovr_maxrand] - standard_name = flag_for_maximum_random_cloud_overlap_method - long_name = choice of maximum-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_dcorr] - standard_name = flag_for_decorrelation_length_cloud_overlap_method - long_name = choice of decorrelation-length cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exp] - standard_name = flag_for_exponential_cloud_overlap_method - long_name = choice of exponential cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exprand] - standard_name = flag_for_exponential_random_cloud_overlap_method - long_name = choice of exponential-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_rand] - standard_name = flag_for_random_cloud_overlap_method - long_name = choice of random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_max] - standard_name = flag_for_maximum_cloud_overlap_method - long_name = choice of maximum cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[icseed_lw] - standard_name = random_number_seed_for_mcica_longwave - long_name = seed for random number generation for longwave radiation - units = none - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_frac] - standard_name = convective_cloud_fraction_for_RRTMGP - long_name = layer convective cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cloud_overlap_param] - standard_name = cloud_overlap_param - long_name = cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cnv_cloud_overlap_param] - standard_name = convective_cloud_overlap_param - long_name = convective cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_overlap_param] - standard_name = precip_overlap_param - long_name = precipitation overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[lw_optical_props_cloudsByBand] - standard_name = longwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_clouds] - standard_name = longwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precip] - standard_name = longwave_optical_properties_for_precipitation - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvclouds] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_gas_optics.F90 b/physics/rrtmgp_lw_gas_optics.F90 index fad01a336..8cd38f210 100644 --- a/physics/rrtmgp_lw_gas_optics.F90 +++ b/physics/rrtmgp_lw_gas_optics.F90 @@ -12,8 +12,6 @@ module rrtmgp_lw_gas_optics use mo_rte_kind, only: wl use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_gas_concentrations, only: ty_gas_concs - use mo_source_functions, only: ty_source_func_lw - use mo_optical_props, only: ty_optical_props_1scl use radiation_tools, only: check_error_msg use netcdf #ifdef MPI @@ -77,28 +75,18 @@ module rrtmgp_lw_gas_optics contains -!>\defgroup rrtmgp_lw_gas_optics_mod GFS RRTMGP-LW Gas Optics Module -!! \section arg_table_rrtmgp_lw_gas_optics_init -!! \htmlinclude rrtmgp_lw_gas_optics.html -!! -!> \ingroup rrtmgp_lw_gas_optics -!! -!! RRTMGP relies heavility on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP longwave scheme. The data needed -!! for the correlated k-distribution is also contained within this type. Within this module, -!! the full k-distribution data is read in, reduced by the "active gases" provided, and -!! loaded into the RRTMGP DDT, ty_gas_optics_rrtmgp. -!! -!! \section rrtmgp_lw_gas_optics_init - ! ###################################################################################### - subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicomm, & - mpirank, mpiroot, minGPpres, maxGPpres, minGPtemp, maxGPtemp, active_gases_array, & - errmsg, errflg) + ! ######################################################################################### + ! SUBROUTINE rrtmgp_lw_gas_optics_init + ! ######################################################################################### + subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, & + active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) ! Inputs character(len=128),intent(in) :: & rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_lw_file_gas ! RRTMGP file containing coefficients used to compute gaseous optical properties + rrtmgp_lw_file_gas ! RRTMGP file containing K-distribution data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array integer,intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank @@ -109,20 +97,12 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom errmsg ! CCPP error message integer, intent(out) :: & errflg ! CCPP error code - real(kind_phys), intent(out) :: & - minGPtemp, & ! Minimum temperature allowed by RRTMGP. - maxGPtemp, & ! Maximum ... - minGPpres, & ! Minimum pressure allowed by RRTMGP. - maxGPpres ! Maximum pressure allowed by RRTMGP. - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array ! Local variables - integer :: ncid, dimID, varID, status, iGas, ierr, ii, mpierr, iChar - integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4, & - temp_log_array1, temp_log_array2, temp_log_array3, temp_log_array4 + integer :: ncid, dimID, varID, status, ii, mpierr, iChar + integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4 character(len=264) :: lw_gas_props_file - type(ty_gas_concs) :: gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) + type(ty_gas_concs) :: gas_concs ! RRTMGP DDT: trace gas concentrations (vmr) ! Initialize errmsg = '' @@ -455,9 +435,8 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom ! Initialize RRTMGP DDT's... ! ! ####################################################################################### - allocate(gas_concentrations%gas_name(1:size(active_gases_array))) - gas_concentrations%gas_name(:) = active_gases_array(:) - call check_error_msg('rrtmgp_lw_gas_optics_init',lw_gas_props%load(gas_concentrations, & + call check_error_msg('rrtmgp_lw_gas_optics_init_gas_concs',gas_concs%init(active_gases_array)) + call check_error_msg('rrtmgp_lw_gas_optics_init_load',lw_gas_props%load(gas_concs, & gas_namesLW, key_speciesLW, band2gptLW, band_limsLW, press_refLW, press_ref_tropLW,& temp_refLW, temp_ref_pLW, temp_ref_tLW, vmr_refLW, kmajorLW, kminor_lowerLW, & kminor_upperLW, gas_minorLW, identifier_minorLW, minor_gases_lowerLW, & @@ -467,80 +446,6 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom scale_by_complement_upperLW, kminor_start_lowerLW, kminor_start_upperLW, totplnkLW,& planck_fracLW, rayl_lowerLW, rayl_upperLW, optimal_angle_fitLW)) - ! The minimum pressure allowed in GP RTE calculations. Used to bound uppermost layer - ! temperature (GFS_rrtmgp_pre.F90) - minGPpres = lw_gas_props%get_press_min() - maxGPpres = lw_gas_props%get_press_max() - minGPtemp = lw_gas_props%get_temp_min() - maxGPtemp = lw_gas_props%get_temp_max() - end subroutine rrtmgp_lw_gas_optics_init -!> \section arg_table_rrtmgp_lw_gas_optics_run -!! \htmlinclude rrtmgp_lw_gas_optics_run.html -!! -!! Compute longwave optical prperties (optical-depth) for clear-sky conditions. -!! \section rrtmgp_lw_gas_optics_run - subroutine rrtmgp_lw_gas_optics_run(doLWrad, nCol, nLev, p_lay, p_lev, t_lay, t_lev, tsfg, & - gas_concentrations, lw_optical_props_clrsky, sources, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad ! Flag to calculate LW irradiances - integer,intent(in) :: & - ncol, & ! Number of horizontal points - nLev ! Number of vertical levels - real(kind_phys), dimension(ncol,nLev), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay ! Temperature (K) - real(kind_phys), dimension(ncol,nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - t_lev ! Temperature @ model levels - real(kind_phys), dimension(ncol), intent(in) :: & - tsfg ! Surface ground temperature (K) - type(ty_gas_concs),intent(in) :: & - gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) - - ! Output - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky radiative properties - type(ty_source_func_lw),intent(inout) :: & - sources ! RRTMGP DDT: longwave source functions - - ! Local - integer :: ii - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Copy spectral information into GP DDTs. - lw_optical_props_clrsky%band2gpt = lw_gas_props%get_band_lims_gpoint() - sources%band2gpt = lw_gas_props%get_band_lims_gpoint() - sources%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - lw_optical_props_clrsky%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do ii=1,nbndsLW - lw_optical_props_clrsky%gpt2band(band2gptLW(1,ii):band2gptLW(2,ii)) = ii - sources%gpt2band(band2gptLW(1,ii):band2gptLW(2,ii)) = ii - end do - - ! Gas-optics - call check_error_msg('rrtmgp_lw_gas_optics_run',lw_gas_props%gas_optics(& - p_lay, & ! IN - Pressure @ layer-centers (Pa) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - t_lay, & ! IN - Temperature @ layer-centers (K) - tsfg, & ! IN - Skin-temperature (K) - gas_concentrations, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios - lw_optical_props_clrsky, & ! OUT - RRTMGP DDT: longwave optical properties - sources, & ! OUT - RRTMGP DDT: source functions - tlev=t_lev)) ! IN - Temperature @ layer-interfaces (K) (optional) - - end subroutine rrtmgp_lw_gas_optics_run - end module rrtmgp_lw_gas_optics diff --git a/physics/rrtmgp_lw_gas_optics.meta b/physics/rrtmgp_lw_gas_optics.meta deleted file mode 100644 index 0b484b6ac..000000000 --- a/physics/rrtmgp_lw_gas_optics.meta +++ /dev/null @@ -1,203 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_gas_optics - type = scheme - dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90,rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90,rte-rrtmgp/rte/mo_source_functions.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_gas_optics_init - type = scheme -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_lw_file_gas] - standard_name = filename_of_rrtmgp_longwave_k_distribution - long_name = file containing RRTMGP LW k-distribution - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[minGPpres] - standard_name = minimum_pressure_in_RRTMGP - long_name = minimum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = out -[maxGPpres] - standard_name = maximum_pressure_in_RRTMGP - long_name = maximum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = out -[minGPtemp] - standard_name = minimum_temperature_in_RRTMGP - long_name = minimum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = out -[maxGPtemp] - standard_name = maximum_temperature_in_RRTMGP - long_name = maximum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = out -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_gas_optics_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = flag to calculate LW irradiances - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[t_lev] - standard_name = air_temperature_at_interface_for_RRTMGP - long_name = air temperature level - units = K - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[tsfg] - standard_name = surface_ground_temperature_for_radiation - long_name = surface ground temperature for radiation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = in -[lw_optical_props_clrsky] - standard_name = longwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[sources] - standard_name = longwave_source_function - long_name = Fortran DDT containing RRTMGP source functions - units = DDT - dimensions = () - type = ty_source_func_lw - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_main.F90 b/physics/rrtmgp_lw_main.F90 new file mode 100644 index 000000000..c0bc99d35 --- /dev/null +++ b/physics/rrtmgp_lw_main.F90 @@ -0,0 +1,611 @@ +! ########################################################################################### +!> \file rrtmgp_lw_main.F90 +!! +!> \defgroup rrtmgp_lw_main rrtmgp_lw_main.F90 +!! +!! \brief This module contains the longwave RRTMGP radiation scheme. +!! +! ########################################################################################### +module rrtmgp_lw_main + use machine, only: kind_phys, kind_dbl_prec + use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str + use mo_cloud_optics, only: ty_cloud_optics + use mo_rte_lw, only: rte_lw + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_gas_concentrations, only: ty_gas_concs + use mo_fluxes_byband, only: ty_fluxes_byband + use mo_source_functions, only: ty_source_func_lw + use radiation_tools, only: check_error_msg + use rrtmgp_lw_gas_optics, only: lw_gas_props,rrtmgp_lw_gas_optics_init + use rrtmgp_lw_cloud_optics, only: lw_cloud_props, rrtmgp_lw_cloud_optics_init, abssnow0, & + abssnow1, absrain + use module_radiation_gases, only: NF_VGAS, getgases, getozn + use GFS_rrtmgp_pre, only: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, & + iStr_o2, iStr_ccl4, iStr_cfc11, iStr_cfc12, iStr_cfc22, & + eps, oneminus, ftiny + use mersenne_twister, only: random_setseed, random_number, random_stat + use rrtmgp_sampling, only: sampled_mask, draw_samples + implicit none + + type(ty_gas_concs) :: gas_concs + type(ty_optical_props_1scl) :: lw_optical_props_clrsky, lw_optical_props_aerosol_local + type(ty_optical_props_2str) :: lw_optical_props_clouds, lw_optical_props_cloudsByBand, & + lw_optical_props_cnvcloudsByBand, lw_optical_props_pblcloudsByBand, & + lw_optical_props_precipByBand + type(ty_source_func_lw) :: sources + + public rrtmgp_lw_main_init, rrtmgp_lw_main_run +contains + ! ######################################################################################### +!! \section arg_table_rrtmgp_lw_main_init +!! \htmlinclude rrtmgp_lw_main_int.html +!! +!> \ingroup rrtmgp_lw_main +!! +!! \brief +!! +!! \section rrtmgp_lw_main_init +!> @{ + ! ######################################################################################### + subroutine rrtmgp_lw_main_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, rrtmgp_lw_file_clouds,& + active_gases_array, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_sgs_pbl, & + doGP_sgs_cnv, nrghice, mpicomm, mpirank, mpiroot, nLay, rrtmgp_phys_blksz, & + errmsg, errflg) + + ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_lw_file_clouds, & ! RRTMGP file containing coefficients used to compute + ! clouds optical properties + rrtmgp_lw_file_gas ! RRTMGP file containing coefficients used to compute + ! gaseous optical properties + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array) + logical, intent(in) :: & + doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer, intent(inout) :: & + nrghice ! Number of ice-roughness categories + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot, & ! Master MPI rank + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nLay + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! RRTMGP longwave gas-optics (k-distribution) initialization + call rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, & + active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) + + ! RRTMGP longwave cloud-optics initialization + call rrtmgp_lw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) + + ! DDTs + + ! ty_gas_concs + call check_error_msg('rrtmgp_lw_main_gas_concs_init',gas_concs%init(active_gases_array)) + + ! ty_optical_props + call check_error_msg('rrtmgp_lw_main_gas_optics_init',& + lw_optical_props_clrsky%alloc_1scl(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_sources_init',& + sources%alloc(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_cloud_optics_init',& + lw_optical_props_cloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_lw_main_precip_optics_init',& + lw_optical_props_precipByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_lw_mian_cloud_sampling_init', & + lw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_aerosol_optics_init',& + lw_optical_props_aerosol_local%alloc_1scl(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics_init',& + lw_optical_props_cnvcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + endif + if (doGP_sgs_pbl) then + call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics_init',& + lw_optical_props_pblcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + endif + + end subroutine rrtmgp_lw_main_init +!> @} + ! ###################################################################################### +!! \section arg_table_rrtmgp_lw_main_run +!! \htmlinclude rrtmgp_lw_main_run.html +!! +!> \ingroup rrtmgp_lw_main +!! +!! \brief +!! +!! \section rrtmgp_lw_main_run +!> @{ + ! ###################################################################################### + subroutine rrtmgp_lw_main_run(doLWrad, doLWclrsky, top_at_1, doGP_lwscat, & + use_LW_jacobian, doGP_sgs_cnv, doGP_sgs_pbl, nCol, nLay, nGases,rrtmgp_phys_blksz,& + nGauss_angles, icseed_lw, iovr, iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, & + iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, semis, tsfg, p_lay, p_lev, t_lay, & + t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, & + cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, & + cld_rwp, cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, & + cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, & + cloud_overlap_param, active_gases_array, aerlw_tau, aerlw_ssa, aerlw_g, & + fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, fluxlwDOWN_clrsky, & + fluxlwUP_jac, fluxlwUP_radtime, fluxlwDOWN_radtime, errmsg, errflg) + + ! Inputs + logical, intent(in) :: & + doLWrad, & ! Flag to perform longwave calculation + doLWclrsky, & ! Flag to compute clear-sky fluxes + top_at_1, & ! Flag for vertical ordering convention + use_LW_jacobian, & ! Flag to compute Jacobian of longwave surface flux + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv, & ! Flag to include sgs convective clouds + doGP_lwscat ! Flag to include scattering in clouds + integer,intent(in) :: & + nCol, & ! Number of horizontal points + nLay, & ! Number of vertical grid points. + nGases, & ! Number of active gases + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nGauss_angles, & ! Number of gaussian quadrature angles used + iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap + iovr_max, & ! Flag for maximum cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + isubc_lw ! Flag for cloud-seeding (rng) for cloud-sampling + integer,intent(in),dimension(:) :: & + icseed_lw ! Seed for random number generation for longwave radiation + real(kind_phys), dimension(:), intent(in) :: & + semis, & ! Surface-emissivity (1) + tsfg ! Skin temperature (K) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lay, & ! Pressure @ model layer-centers (Pa) + t_lay, & ! Temperature (K) + p_lev, & ! Pressure @ model layer-interfaces (Pa) + t_lev, & ! Temperature @ model levels (K) + vmr_o2, & ! Molar-mixing ratio oxygen + vmr_h2o, & ! Molar-mixing ratio water vapor + vmr_o3, & ! Molar-mixing ratio ozone + vmr_ch4, & ! Molar-mixing ratio methane + vmr_n2o, & ! Molar-mixing ratio nitrous oxide + vmr_co2, & ! Molar-mixing ratio carbon dioxide + cld_frac, & ! Cloud-fraction for stratiform clouds + cld_lwp, & ! Water path for stratiform liquid cloud-particles + cld_reliq, & ! Effective radius for stratiform liquid cloud-particles + cld_iwp, & ! Water path for stratiform ice cloud-particles + cld_reice, & ! Effective radius for stratiform ice cloud-particles + cld_swp, & ! Water path for snow hydrometeors + cld_resnow, & ! Effective radius for snow hydrometeors + cld_rwp, & ! Water path for rain hydrometeors + cld_rerain, & ! Effective radius for rain hydrometeors + precip_frac, & ! Precipitation fraction (not active, currently precipitation optics uses cloud-fraction) + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles + cld_cnv_iwp, & ! Water path for convective ice cloud-particles + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles + cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for PBL ice cloud-particles + cld_pbl_reice, & ! Effective radius for PBL ice cloud-particles + cloud_overlap_param ! Cloud overlap parameter + real(kind_phys), dimension(:,:,:), intent(in) :: & + aerlw_tau, & ! Aerosol optical depth + aerlw_ssa, & ! Aerosol single scattering albedo + aerlw_g ! Aerosol asymmetry paramter + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array + + ! Outputs + real(kind_phys), dimension(:,:), intent(inout) :: & + fluxlwUP_jac, & ! Jacobian of upwelling LW surface radiation (W/m2/K) + fluxlwUP_allsky, & ! All-sky flux (W/m2) + fluxlwDOWN_allsky, & ! All-sky flux (W/m2) + fluxlwUP_clrsky, & ! Clear-sky flux (W/m2) + fluxlwDOWN_clrsky, & ! All-sky flux (W/m2) + fluxlwUP_radtime, & ! Copy of fluxes (Used for coupling) + fluxlwDOWN_radtime ! + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local variables + type(ty_fluxes_byband) :: flux_allsky, flux_clrsky + integer :: iCol, iLay, iGas, iBand, iCol2, ix, iblck + integer, dimension(rrtmgp_phys_blksz) :: ipseed_lw + type(random_stat) :: rng_stat + real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1 + logical, dimension(rrtmgp_phys_blksz,nLay,lw_gas_props%get_ngpt()) :: maskMCICA + real(kind_phys), dimension(rrtmgp_phys_blksz) :: tau_rain, tau_snow + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()) :: rng1D + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3D,rng3D2 + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()*nLay) :: rng2D + real(kind_phys), dimension(rrtmgp_phys_blksz,nLay+1,lw_gas_props%get_nband()),target :: & + fluxLW_up_allsky, fluxLW_up_clrsky, fluxLW_dn_allsky, fluxLW_dn_clrsky + real(kind_phys), dimension(rrtmgp_phys_blksz,lw_gas_props%get_ngpt()) :: lw_Ds + real(kind_phys), dimension(lw_gas_props%get_nband(),rrtmgp_phys_blksz) :: sfc_emiss_byband + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. doLWrad) return + + ! ###################################################################################### + ! + ! Loop over all columns... + ! + ! ###################################################################################### + do iCol=1,nCol,rrtmgp_phys_blksz + iCol2 = iCol + rrtmgp_phys_blksz - 1 + + ! Initialize/reset + + ! ty_optical_props + lw_optical_props_clrsky%tau = 0._kind_phys + lw_optical_props_precipByBand%tau = 0._kind_phys + lw_optical_props_precipByBand%ssa = 0._kind_phys + lw_optical_props_precipByBand%g = 0._kind_phys + lw_optical_props_cloudsByBand%tau = 0._kind_phys + lw_optical_props_cloudsByBand%ssa = 0._kind_phys + lw_optical_props_cloudsByBand%g = 0._kind_phys + lw_optical_props_clouds%tau = 0._kind_phys + lw_optical_props_clouds%ssa = 0._kind_phys + lw_optical_props_clouds%g = 0._kind_phys + sources%sfc_source = 0._kind_phys + sources%lay_source = 0._kind_phys + sources%lev_source_inc = 0._kind_phys + sources%lev_source_dec = 0._kind_phys + sources%sfc_source_Jac = 0._kind_phys + fluxLW_up_allsky = 0._kind_phys + fluxLW_dn_allsky = 0._kind_phys + fluxLW_up_clrsky = 0._kind_phys + fluxLW_dn_clrsky = 0._kind_phys + if (doGP_sgs_cnv) lw_optical_props_cnvcloudsByBand%tau = 0._kind_phys + if (doGP_sgs_pbl) lw_optical_props_pblcloudsByBand%tau = 0._kind_phys + + ! ty_fluxes_byband + fluxLW_up_allsky = 0._kind_phys + fluxLW_dn_allsky = 0._kind_phys + fluxLW_up_clrsky = 0._kind_phys + fluxLW_dn_clrsky = 0._kind_phys + flux_allsky%bnd_flux_up => fluxLW_up_allsky + flux_allsky%bnd_flux_dn => fluxLW_dn_allsky + flux_clrsky%bnd_flux_up => fluxLW_up_clrsky + flux_clrsky%bnd_flux_dn => fluxLW_dn_clrsky + + ! ################################################################################### + ! + ! Set gas-concentrations + ! + ! ################################################################################### + call check_error_msg('rrtmgp_lw_main_set_vmr_o2', & + gas_concs%set_vmr(trim(active_gases_array(istr_o2)), vmr_o2(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_co2', & + gas_concs%set_vmr(trim(active_gases_array(istr_co2)),vmr_co2(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_ch4', & + gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),vmr_ch4(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_n2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),vmr_n2o(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_h2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),vmr_h2o(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_o3', & + gas_concs%set_vmr(trim(active_gases_array(istr_o3)), vmr_o3(iCol:iCol2,:))) + + ! ################################################################################### + ! + ! Surface emissity in each band + ! + ! ################################################################################### + ! Assign same emissivity to all band + do iblck=1,rrtmgp_phys_blksz + if (semis(iCol+iblck-1) > eps .and. semis(iCol+iblck-1) <= 1._kind_phys) then + do iBand=1,lw_gas_props%get_nband() + sfc_emiss_byband(iBand,iblck) = semis(iCol+iblck-1) + enddo + else + sfc_emiss_byband(1:lw_gas_props%get_nband(),iblck) = 1.0 + endif + enddo + + ! ################################################################################### + ! + ! Compute gas-optics... + ! + ! ################################################################################### + call check_error_msg('rrtmgp_lw_main_gas_optics',lw_gas_props%gas_optics(& + p_lay(iCol:iCol2,:), & ! IN - Pressure @ layer-centers (Pa) + p_lev(iCol:iCol2,:), & ! IN - Pressure @ layer-interfaces (Pa) + t_lay(iCol:iCol2,:), & ! IN - Temperature @ layer-centers (K) + tsfg(iCol:iCol2), & ! IN - Skin-temperature (K) + gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios + lw_optical_props_clrsky, & ! OUT - RRTMGP DDT: longwave optical properties + sources, & ! OUT - RRTMGP DDT: source functions + tlev=t_lev(iCol:iCol2,:))) ! IN - Temperature @ layer-interfaces (K) (optional) + + ! ################################################################################### + ! + ! Compute cloud-optics... + ! + ! ################################################################################### + ! Create clear/cloudy indicator + zcf0(:) = 1._kind_phys + zcf1(:) = 1._kind_phys + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(iCol+iblck-1,iLay)) + enddo + if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys + if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys + zcf1(iblck) = 1._kind_phys - zcf0(iblck) + enddo + + if (any(zcf1 .gt. eps)) then + ! Microphysical (gridmean) cloud optics + call check_error_msg('rrtmgp_lw_main_cloud_optics',lw_cloud_props%cloud_optics(& + cld_lwp(iCol:iCol2,:), & ! IN - Cloud liquid water path (g/m2) + cld_iwp(iCol:iCol2,:), & ! IN - Cloud ice water path (g/m2) + cld_reliq(iCol:iCol2,:), & ! IN - Cloud liquid effective radius (microns) + cld_reice(iCol:iCol2,:), & ! IN - Cloud ice effective radius (microns) + lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties + ! in each band + ! Include convective (subgrid scale) clouds? + if (doGP_sgs_cnv) then + ! Compute + call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics',lw_cloud_props%cloud_optics(& + cld_cnv_lwp(iCol:iCol2,:), & ! IN - Convective cloud liquid water path (g/m2) + cld_cnv_iwp(iCol:iCol2,:), & ! IN - Convective cloud ice water path (g/m2) + cld_cnv_reliq(iCol:iCol2,:), & ! IN - Convective cloud liquid effective radius (microns) + cld_cnv_reice(iCol:iCol2,:), & ! IN - Convective cloud ice effective radius (microns) + lw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_cnvclouds_to_clouds',& + lw_optical_props_cnvcloudsByBand%increment(lw_optical_props_cloudsByBand)) + endif + + ! Include PBL (subgrid scale) clouds? + if (doGP_sgs_pbl) then + ! Compute + call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics',lw_cloud_props%cloud_optics(& + cld_pbl_lwp(iCol:iCol2,:), & ! IN - PBL cloud liquid water path (g/m2) + cld_pbl_iwp(iCol:iCol2,:), & ! IN - PBL cloud ice water path (g/m2) + cld_pbl_reliq(iCol:iCol2,:), & ! IN - PBL cloud liquid effective radius (microns) + cld_pbl_reice(iCol:iCol2,:), & ! IN - PBL cloud ice effective radius (microns) + lw_optical_props_pblcloudsByBand)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_pblclouds_to_clouds',& + lw_optical_props_pblcloudsByBand%increment(lw_optical_props_cloudsByBand)) + endif + endif + + ! ################################################################################### + ! + ! Cloud precipitation optics: rain and snow(+groupel) + ! + ! ################################################################################### + tau_rain(:) = 0._kind_phys + tau_snow(:) = 0._kind_phys + do ix=1,rrtmgp_phys_blksz + do iLay=1,nLay + if (cld_frac(iCol+ix-1,iLay) .gt. eps) then + ! Rain optical-depth (No band dependence) + tau_rain(ix) = absrain*cld_rwp(iCol+ix-1,iLay) + + ! Snow (+groupel) optical-depth (No band dependence) + if (cld_swp(iCol+ix-1,iLay) .gt. 0. .and. cld_resnow(iCol+ix-1,iLay) .gt. 10._kind_phys) then + tau_snow(ix) = abssnow0*1.05756*cld_swp(iCol+ix-1,iLay)/cld_resnow(iCol+ix-1,iLay) + else + tau_snow(ix) = 0.0 + endif + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_precipByBand%tau(ix,iLay,iBand) = tau_rain(ix) + tau_snow(ix) + enddo + endif + enddo + enddo + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_precip_to_clouds',& + lw_optical_props_precipByBand%increment(lw_optical_props_cloudsByBand)) + + ! ################################################################################### + ! + ! Cloud-sampling + ! *Note* All of the included cloud-types are sampled together, not independently. + ! + ! ################################################################################### + if (any(zcf1 .gt. eps)) then + ! Change random number seed value for each radiation invocation (isubc_lw =1 or 2). + if(isubc_lw == 1) then ! advance prescribed permutation seed + do ix=1,rrtmgp_phys_blksz + ipseed_lw(ix) = lw_gas_props%get_ngpt() + iCol + ix - 1 + enddo + elseif (isubc_lw == 2) then ! use input array of permutaion seeds + do ix=1,rrtmgp_phys_blksz + ipseed_lw(ix) = icseed_lw(iCol+ix-1) + enddo + endif + + ! Call RNG + do ix=1,rrtmgp_phys_blksz + call random_setseed(ipseed_lw(ix),rng_stat) + ! Use same rng for each layer + if (iovr == iovr_max) then + call random_number(rng1D,rng_stat) + do iLay=1,nLay + rng3D(:,iLay,ix) = rng1D + enddo + else + do iLay=1,nLay + call random_number(rng1D,rng_stat) + rng3D(:,iLay,ix) = rng1D + enddo + endif + enddo + + ! Cloud-overlap. + ! Maximum-random, random or maximum. + if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA) + endif + ! Exponential decorrelation length overlap + if (iovr == iovr_dcorr) then + do ix=1,rrtmgp_phys_blksz + ! Generate second RNG + call random_setseed(ipseed_lw(ix),rng_stat) + call random_number(rng2D,rng_stat) + rng3D2(:,:,ix) = reshape(source = rng2D,shape=[lw_gas_props%get_ngpt(),nLay]) + enddo + ! + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCol:iCol2,1:nLay-1), randoms2 = real(rng3D2, kind=kind_phys)) + endif + ! Exponential or Exponential-random + if (iovr == iovr_exp .or. iovr == iovr_exprand) then + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCol:iCol2,1:nLay-1)) + endif + ! Sampling. Map band optical depth to each g-point using McICA + call check_error_msg('rrtmgp_lw_main_cloud_sampling',& + draw_samples(maskMCICA, .true., & + lw_optical_props_cloudsByBand, lw_optical_props_clouds)) + endif + + ! ################################################################################### + ! + ! Compute clear-sky fluxes (gaseous+aerosol) (optional) + ! + ! ################################################################################### + ! Increment + lw_optical_props_aerosol_local%tau = aerlw_tau(iCol:iCol2,:,:) + call check_error_msg('rrtmgp_lw_main_increment_aerosol_to_clrsky',& + lw_optical_props_aerosol_local%increment(lw_optical_props_clrsky)) + + ! Call RTE solver + if (doLWclrsky) then + call check_error_msg('rrtmgp_lw_main_opt_angle',& + lw_gas_props%compute_optimal_angles(lw_optical_props_clrsky,lw_Ds)) + if (nGauss_angles .gt. 1) then + call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_clrsky, & ! OUT - Fluxes + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + else + call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_clrsky, & ! OUT - Fluxes + lw_Ds = lw_Ds)) + endif + + ! Store fluxes + fluxlwUP_clrsky(iCol:iCol2,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxlwDOWN_clrsky(iCol:iCol2,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + else + fluxlwUP_clrsky(iCol:iCol2,:) = 0.0 + fluxlwDOWN_clrsky(iCol:iCol2,:) = 0.0 + endif + + ! ################################################################################### + ! + ! All-sky fluxes (clear-sky + clouds + precipitation) + ! *Note* CCPP does not allow for polymorphic types, they are ambiguous to the CCPP + ! framework. rte-rrtmgp uses polymorphic types extensively, for example, querying the + ! type to determine physics configuration/pathway/etc... + ! + ! The logic in the code below is to satisfy the polymorphishm in the rte-rrtmgp code. + ! The rte-rrtmgp "increment" procedures are utilized to provide the correct type to the + ! rte solver (rte_lw). Rte_lw quieries the type determine if scattering is to be + ! included in the calculation. The increment procedures are called so that the correct + ! optical properties are inherited. ugh... + ! + ! ################################################################################### + + ! Include LW cloud-scattering? + if (doGP_lwscat) then + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_clrsky_to_clouds',& + lw_optical_props_clrsky%increment(lw_optical_props_clouds)) + + if (use_LW_jacobian) then + ! Compute LW Jacobians + call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( & + lw_optical_props_clouds, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature + flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) + else + call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( & + lw_optical_props_clouds, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + end if + ! No scattering in LW clouds. + else + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_clouds_to_clrsky', & + lw_optical_props_clouds%increment(lw_optical_props_clrsky)) + + if (use_LW_jacobian) then + ! Compute LW Jacobians + call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature + flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) + else + call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + end if + endif + + ! Store fluxes + fluxlwUP_allsky(iCol:iCol2,:) = sum(flux_allsky%bnd_flux_up, dim=3) + fluxlwDOWN_allsky(iCol:iCol2,:) = sum(flux_allsky%bnd_flux_dn, dim=3) + + ! Save fluxes for coupling + fluxlwUP_radtime(iCol:iCol2,:) = fluxlwUP_allsky(iCol:iCol2,:) + fluxlwDOWN_radtime(iCol:iCol2,:) = fluxlwDOWN_allsky(iCol:iCol2,:) + + enddo + + end subroutine rrtmgp_lw_main_run +!> @} +end module rrtmgp_lw_main diff --git a/physics/rrtmgp_lw_main.meta b/physics/rrtmgp_lw_main.meta new file mode 100644 index 000000000..a1a384b25 --- /dev/null +++ b/physics/rrtmgp_lw_main.meta @@ -0,0 +1,641 @@ +[ccpp-table-properties] + name = rrtmgp_lw_main + type = scheme + dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 + dependencies = rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 + dependencies = rte-rrtmgp/rte/mo_source_functions.F90,rte-rrtmgp/rte/mo_rte_lw.F90,rte-rrtmgp/rte/mo_fluxes.F90 + dependencies = rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90, rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90 + dependencies = mersenne_twister.f,rrtmgp_sampling.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 + dependencies = rrtmgp_lw_gas_optics.F90, rrtmgp_lw_cloud_optics.F90 + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_lw_main_init + type = scheme +[rrtmgp_root_dir] + standard_name = directory_for_rte_rrtmgp_source_code + long_name = directory for rte+rrtmgp source code + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_lw_file_gas] + standard_name = filename_of_rrtmgp_longwave_k_distribution + long_name = file containing RRTMGP LW k-distribution + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_lw_file_clouds] + standard_name = filename_of_rrtmgp_longwave_cloud_optics_coefficients + long_name = file containing coefficients for RRTMGP LW cloud optics + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[doGP_cldoptics_PADE] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_cldoptics_LUT] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[nrghice] + standard_name = number_of_ice_roughness_categories + long_name = number of ice-roughness categories in RRTMGP calculation + units = count + dimensions = () + type = integer + intent = inout +[mpirank] + standard_name = mpi_rank + long_name = current MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpiroot] + standard_name = mpi_root + long_name = master MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpicomm] + standard_name = mpi_communicator + long_name = MPI communicator + units = index + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_LW_block + long_name = number of columns to process at a time by RRTMGP LW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_lw_main_run + type = scheme +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[doLWclrsky] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output lw heating rate (Radtend%lwhc) + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[use_LW_jacobian] + standard_name = flag_to_calc_RRTMGP_LW_jacobian + long_name = logical flag to control RRTMGP LW calculation + units = flag + dimensions = () + type = logical + intent = in +[doGP_lwscat] + standard_name = flag_to_include_longwave_scattering_in_cloud_optics + long_name = logical flag to control the addition of LW scattering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[ncol] + standard_name = horizontal_loop_extent + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_LW_block + long_name = number of columns to process at a time by RRTMGP LW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[nGauss_angles] + standard_name = number_of_gaussian_quadrature_angles_for_radiation + long_name = Number of angles used in Gaussian quadrature + units = count + dimensions = () + type = integer + intent = in +[nGases] + standard_name = number_of_active_gases_used_by_RRTMGP + long_name = number of gases available used by RRTMGP (Model%nGases) + units = count + dimensions = () + type = integer + intent = in +[isubc_lw] + standard_name = flag_for_lw_clouds_sub_grid_approximation + long_name = flag for lw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[icseed_lw] + standard_name = random_number_seed_for_mcica_longwave + long_name = seed for random number generation for longwave radiation + units = none + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[semis] + standard_name = surface_longwave_emissivity + long_name = surface lw emissivity in fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[tsfg] + standard_name = surface_ground_temperature_for_radiation + long_name = surface ground temperature for radiation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[p_lay] + standard_name = air_pressure_at_layer_for_RRTMGP + long_name = air pressure at vertical layer for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure at vertical interface for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[t_lay] + standard_name = air_temperature_at_layer_for_RRTMGP + long_name = air temperature at vertical layer for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[t_lev] + standard_name = air_temperature_at_interface_for_RRTMGP + long_name = air temperature at vertical interface for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_frac] + standard_name = total_cloud_fraction + long_name = layer total cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_lwp] + standard_name = cloud_liquid_water_path + long_name = layer cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reliq] + standard_name = mean_effective_radius_for_liquid_cloud + long_name = mean effective radius for liquid cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_iwp] + standard_name = cloud_ice_water_path + long_name = layer cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reice] + standard_name = mean_effective_radius_for_ice_cloud + long_name = mean effective radius for ice cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_swp] + standard_name = cloud_snow_water_path + long_name = layer cloud snow water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_resnow] + standard_name = mean_effective_radius_for_snow_flake + long_name = mean effective radius for snow cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rwp] + standard_name = cloud_rain_water_path + long_name = layer cloud rain water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rerain] + standard_name = mean_effective_radius_for_rain_drop + long_name = mean effective radius for rain cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[precip_frac] + standard_name = precipitation_fraction_by_layer + long_name = precipitation fraction in each layer + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cloud_overlap_param] + standard_name = cloud_overlap_param + long_name = cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[aerlw_tau] + standard_name = aerosol_optical_depth_for_longwave_bands_01_16 + long_name = aerosol optical depth for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[aerlw_ssa] + standard_name = aerosol_single_scattering_albedo_for_longwave_bands_01_16 + long_name = aerosol single scattering albedo for longwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[aerlw_g] + standard_name = aerosol_asymmetry_parameter_for_longwave_bands_01_16 + long_name = aerosol asymmetry parameter for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[fluxlwUP_radtime] + standard_name = RRTMGP_lw_flux_profile_upward_allsky_on_radiation_timestep + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_radtime] + standard_name = RRTMGP_lw_flux_profile_downward_allsky_on_radiation_timestep + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_allsky] + standard_name = RRTMGP_lw_flux_profile_upward_allsky + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_allsky] + standard_name = RRTMGP_lw_flux_profile_downward_allsky + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_clrsky] + standard_name = RRTMGP_lw_flux_profile_upward_clrsky + long_name = RRTMGP upward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_clrsky] + standard_name = RRTMGP_lw_flux_profile_downward_clrsky + long_name = RRTMGP downward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_jac] + standard_name = RRTMGP_jacobian_of_lw_flux_upward + long_name = RRTMGP Jacobian upward longwave flux profile + units = W m-2 K-1 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out \ No newline at end of file diff --git a/physics/rrtmgp_lw_pre.F90 b/physics/rrtmgp_lw_pre.F90 deleted file mode 100644 index 1501ca319..000000000 --- a/physics/rrtmgp_lw_pre.F90 +++ /dev/null @@ -1,61 +0,0 @@ -!> \file rrtmgp_lw_pre.F90 -!! -!> \defgroup rrtmgp_lw_pre rrtmgp_lw_pre.F90 -!! -!! \brief RRTMGP Longwave pre-processing routine. -!! -module rrtmgp_lw_pre - use machine, only: & - kind_phys ! Working type - use mo_gas_optics_rrtmgp, only: & - ty_gas_optics_rrtmgp - use rrtmgp_lw_gas_optics, only: lw_gas_props - - implicit none - - public rrtmgp_lw_pre_run - -contains - -!>\defgroup rrtmgp_lw_pre_mode GFS RRTMGP-LW Pre Module -!> \section arg_table_rrtmgp_lw_pre_run -!! \htmlinclude rrtmgp_lw_pre_run.html -!! -!> \ingroup rrtmgp_lw_pre -!! -!! \brief -!! -!! \section rrtmgp_lw_pre_run - subroutine rrtmgp_lw_pre_run (doLWrad, semis, sfc_emiss_byband, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad - real(kind_phys), dimension(:), intent(in) :: & - semis - - ! Outputs - real(kind_phys), dimension(:,:), intent(inout) :: & - sfc_emiss_byband ! Surface emissivity in each band - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - integer :: iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Assign same emissivity to all bands - do iBand=1,lw_gas_props%get_nband() - sfc_emiss_byband(iBand,:) = semis - enddo - - end subroutine rrtmgp_lw_pre_run - -end module rrtmgp_lw_pre diff --git a/physics/rrtmgp_lw_pre.meta b/physics/rrtmgp_lw_pre.meta deleted file mode 100644 index aa2a06a0f..000000000 --- a/physics/rrtmgp_lw_pre.meta +++ /dev/null @@ -1,47 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_pre - type = scheme - dependencies = iounitdef.f,machine.F - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_pre_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[semis] - standard_name = surface_longwave_emissivity - long_name = surface lw emissivity in fraction - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_emiss_byband] - standard_name = surface_emissivity_in_each_RRTMGP_LW_band - long_name = surface emissivity in each RRTMGP LW band - units = none - dimensions = (number_of_longwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_rte.F90 b/physics/rrtmgp_lw_rte.F90 deleted file mode 100644 index 9109a5780..000000000 --- a/physics/rrtmgp_lw_rte.F90 +++ /dev/null @@ -1,208 +0,0 @@ -!> \file rrtmgp_lw_rte.F90 -!! -!> \defgroup rrtmgp_lw_rte rrtmgp_lw_rte.F90 -!! -!! \brief This module contains the main rte longwave driver. -!! -module rrtmgp_lw_rte - use machine, only: kind_phys - use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str - use mo_rte_lw, only: rte_lw - use mo_fluxes_byband, only: ty_fluxes_byband - use mo_source_functions, only: ty_source_func_lw - use radiation_tools, only: check_error_msg - use rrtmgp_lw_gas_optics, only: lw_gas_props - implicit none - - public rrtmgp_lw_rte_run -contains - -!>\defgroup rrtmgp_lw_rte_mod GFS RRTMGP-LW RTE Module -!> \section arg_table_rrtmgp_lw_rte_run -!! \htmlinclude rrtmgp_lw_rte_run.html -!! -!> \ingroup rrtmgp_lw_rte -!! -!! \brief This routine takes all of the longwave optical properties ,ty_optical_props_1scl, -!! and computes the longwave radiative fluxes for cloudy and clear-sky conditions. -!! -!! \section rrtmgp_lw_rte_run - subroutine rrtmgp_lw_rte_run(doLWrad, doLWclrsky, use_LW_jacobian, doGP_lwscat, nCol, & - nLev, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, sfc_emiss_byband, sources, & - lw_optical_props_clrsky, lw_optical_props_clouds, lw_optical_props_precipByBand, & - lw_optical_props_cnvcloudsByBand, lw_optical_props_MYNNcloudsByBand, & - lw_optical_props_aerosol, nGauss_angles, fluxlwUP_allsky, fluxlwDOWN_allsky, & - fluxlwUP_clrsky, fluxlwDOWN_clrsky, fluxlwUP_jac, fluxlwUP_radtime, & - fluxlwDOWN_radtime, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doLWrad, & ! Logical flag for longwave radiation call - doLWclrsky, & ! Compute clear-sky fluxes for clear-sky heating-rate? - use_LW_jacobian, & ! Compute Jacobian of LW to update radiative fluxes between radiation calls? - doGP_sgs_mynn, & ! Flag for sgs MYNN-EDMF PBL cloud scheme - doGP_sgs_cnv, & ! Flagg for sgs convective cloud scheme - doGP_lwscat ! Include scattering in LW cloud-optics? - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - nGauss_angles ! Number of angles used in Gaussian quadrature - real(kind_phys), dimension(:,:), intent(in) :: & - sfc_emiss_byband ! Surface emissivity in each band - type(ty_source_func_lw),intent(in) :: & - sources ! RRTMGP DDT: longwave source functions - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol, &! RRTMGP DDT: longwave aerosol optical properties - lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky optical properties - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_clouds, & ! RRTMGP DDT: longwave cloud optical properties - lw_optical_props_precipByBand, & ! RRTMGP DDT: longwave precipitation optical properties - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: longwave convective cloud optical properties - lw_optical_props_MYNNcloudsByBand ! RRTMGP DDT: longwave MYNN-EDMF PBL cloud optical properties - ! Outputs - real(kind_phys), dimension(:,:), intent(inout) :: & - fluxlwUP_jac, & ! Jacobian of upwelling LW surface radiation (W/m2/K) - fluxlwUP_allsky, & ! All-sky flux (W/m2) - fluxlwDOWN_allsky, & ! All-sky flux (W/m2) - fluxlwUP_clrsky, & ! Clear-sky flux (W/m2) - fluxlwDOWN_clrsky, & ! All-sky flux (W/m2) - fluxlwUP_radtime, & ! Copy of fluxes (Used for coupling) - fluxlwDOWN_radtime - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local variables - type(ty_fluxes_byband) :: & - flux_allsky, flux_clrsky - real(kind_phys), dimension(ncol,nLev+1,lw_gas_props%get_nband()),target :: & - fluxLW_up_allsky, fluxLW_up_clrsky, fluxLW_dn_allsky, fluxLW_dn_clrsky - real(kind_phys), dimension(nCol,lw_gas_props%get_ngpt()) :: lw_Ds - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Initialize RRTMGP DDT containing 2D(3D) fluxes - flux_allsky%bnd_flux_up => fluxLW_up_allsky - flux_allsky%bnd_flux_dn => fluxLW_dn_allsky - flux_clrsky%bnd_flux_up => fluxLW_up_clrsky - flux_clrsky%bnd_flux_dn => fluxLW_dn_clrsky - - ! - ! Compute clear-sky fluxes (if requested) - ! - ! Add aerosol optics to gas optics - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_aerosol%increment(lw_optical_props_clrsky)) - - ! Call RTE solver - if (doLWclrsky) then - call check_error_msg('rrtmgp_lw_rte_run_opt_angle',lw_gas_props%compute_optimal_angles(lw_optical_props_clrsky,lw_Ds)) - if (nGauss_angles .gt. 1) then - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_clrsky, & ! OUT - Fluxes - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_clrsky, & ! OUT - Fluxes - lw_Ds = lw_Ds)) - endif - - ! Store fluxes - fluxlwUP_clrsky = sum(flux_clrsky%bnd_flux_up,dim=3) - fluxlwDOWN_clrsky = sum(flux_clrsky%bnd_flux_dn,dim=3) - else - fluxlwUP_clrsky = 0.0 - fluxlwDOWN_clrsky = 0.0 - endif - - ! - ! All-sky fluxes (clear-sky + clouds + precipitation) - ! - - ! Include convective cloud? - if (doGP_sgs_cnv) then - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_cnvcloudsByBand%increment(lw_optical_props_clrsky)) - endif - - ! Include MYNN-EDMF PBL clouds? - if (doGP_sgs_mynn) then - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_MYNNcloudsByBand%increment(lw_optical_props_clrsky)) - endif - - ! Add in precipitation - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_precipByBand%increment(lw_optical_props_clouds)) - - ! Include LW cloud-scattering? - if (doGP_lwscat) then - ! Add clear-sky optics to cloud-optics (2-stream) - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_clrsky%increment(lw_optical_props_clouds)) - - if (use_LW_jacobian) then - ! Compute LW Jacobians - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clouds, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature - flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clouds, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - end if - ! No scattering in LW clouds. - else - ! Add cloud optics to clear-sky optics (scalar) - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_clouds%increment(lw_optical_props_clrsky)) - - if (use_LW_jacobian) then - ! Compute LW Jacobians - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature - flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - end if - endif - - ! Store fluxes - fluxlwUP_allsky = sum(flux_allsky%bnd_flux_up,dim=3) - fluxlwDOWN_allsky = sum(flux_allsky%bnd_flux_dn,dim=3) - - ! Save fluxes for coupling - fluxlwUP_radtime = fluxlwUP_allsky - fluxlwDOWN_radtime = fluxlwDOWN_allsky - - end subroutine rrtmgp_lw_rte_run - -end module rrtmgp_lw_rte diff --git a/physics/rrtmgp_lw_rte.meta b/physics/rrtmgp_lw_rte.meta deleted file mode 100644 index 0ad0754b5..000000000 --- a/physics/rrtmgp_lw_rte.meta +++ /dev/null @@ -1,208 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_rte - type = scheme - dependencies = machine.F,rte-rrtmgp/rte/mo_rte_lw.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,radiation_tools.F90 - dependencies = rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_rte_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[doLWclrsky] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output lw heating rate (Radtend%lwhc) - units = flag - dimensions = () - type = logical - intent = in -[use_LW_jacobian] - standard_name = flag_to_calc_RRTMGP_LW_jacobian - long_name = logical flag to control RRTMGP LW calculation - units = flag - dimensions = () - type = logical - intent = in -[doGP_lwscat] - standard_name = flag_to_include_longwave_scattering_in_cloud_optics - long_name = logical flag to control the addition of LW scattering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_cnv] - standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP - long_name = logical flag to control sgs convective cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_mynn] - standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP - long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nGauss_angles] - standard_name = number_of_gaussian_quadrature_angles_for_radiation - long_name = Number of angles used in Gaussian quadrature - units = count - dimensions = () - type = integer - intent = in -[top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[sfc_emiss_byband] - standard_name = surface_emissivity_in_each_RRTMGP_LW_band - long_name = surface emissivity in each RRTMGP LW band - units = none - dimensions = (number_of_longwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lw_optical_props_clrsky] - standard_name = longwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[lw_optical_props_clouds] - standard_name = longwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_MYNNcloudsByBand] - standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_aerosol] - standard_name = longwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[sources] - standard_name = longwave_source_function - long_name = Fortran DDT containing RRTMGP source functions - units = DDT - dimensions = () - type = ty_source_func_lw - intent = in -[fluxlwUP_radtime] - standard_name = RRTMGP_lw_flux_profile_upward_allsky_on_radiation_timestep - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_radtime] - standard_name = RRTMGP_lw_flux_profile_downward_allsky_on_radiation_timestep - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_allsky] - standard_name = RRTMGP_lw_flux_profile_upward_allsky - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_allsky] - standard_name = RRTMGP_lw_flux_profile_downward_allsky - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_clrsky] - standard_name = RRTMGP_lw_flux_profile_upward_clrsky - long_name = RRTMGP upward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_clrsky] - standard_name = RRTMGP_lw_flux_profile_downward_clrsky - long_name = RRTMGP downward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_jac] - standard_name = RRTMGP_jacobian_of_lw_flux_upward - long_name = RRTMGP Jacobian upward longwave flux profile - units = W m-2 K-1 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_cloud_optics.F90 b/physics/rrtmgp_sw_cloud_optics.F90 index 3aab115cd..4293a7be6 100644 --- a/physics/rrtmgp_sw_cloud_optics.F90 +++ b/physics/rrtmgp_sw_cloud_optics.F90 @@ -1,18 +1,7 @@ -!> \file rrtmgp_sw_cloud_optics.F90 -!! -!> \defgroup rrtmgp_sw_cloud_optics rrtmgp_sw_cloud_optics.F90 -!! -!! \brief This module contains two routines: The first initializes data and functions -!! needed to compute the shortwave cloud radiative properteis in RRTMGP. The second routine -!! is a ccpp scheme within the "radiation loop", where the shortwave optical prperties -!! (optical-depth, single-scattering albedo, asymmetry parameter) are computed for ALL -!! cloud types visible to RRTMGP. module rrtmgp_sw_cloud_optics use machine, only: kind_phys use mo_rte_kind, only: wl use mo_cloud_optics, only: ty_cloud_optics - use mo_optical_props, only: ty_optical_props_2str - use mo_rrtmg_sw_cloud_optics, only: rrtmg_sw_cloud_optics use rrtmgp_sw_gas_optics, only: sw_gas_props use radiation_tools, only: check_error_msg use netcdf @@ -59,52 +48,41 @@ module rrtmgp_sw_cloud_optics pade_exticeSW, & ! PADE coefficients for shortwave ice extinction pade_ssaiceSW, & ! PADE coefficients for shortwave ice single scattering albedo pade_asyiceSW ! PADE coefficients for shortwave ice asymmetry parameter + real(kind_phys) :: & + radliq_lwrSW, & ! Liquid particle size lower bound for LUT interpolation + radliq_uprSW, & ! Liquid particle size upper bound for LUT interpolation + radice_lwrSW, & ! Ice particle size upper bound for LUT interpolation + radice_uprSW ! Ice particle size lower bound for LUT interpolation - ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics + ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics. *NOTE* Same as in RRTMG + ! Need to document these magic numbers below. real(kind_phys),parameter :: & - a0r = 3.07e-3, & ! - a0s = 0.0, & ! - a1s = 1.5 ! + a0r = 3.07e-3, & ! + a0s = 0.0, & ! + a1s = 1.5 ! real(kind_phys),dimension(:),allocatable :: b0r,b0s,b1s,c0r,c0s - real(kind_phys) :: & - radliq_lwrSW, & ! Liquid particle size lower bound for LUT interpolation - radliq_uprSW, & ! Liquid particle size upper bound for LUT interpolation - radice_lwrSW, & ! Ice particle size upper bound for LUT interpolation - radice_uprSW ! Ice particle size lower bound for LUT interpolation contains - -!>\defgroup rrtmgp_sw_cloud_optics_mod GFS RRTMGP-SW Cloud Optics Module -!> \section arg_table_rrtmgp_sw_cloud_optics_init -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_sw_cloud_optics -!! -!! RRTMGP relies heavily on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP shortwave scheme. The data needed -!! to compute the shortwave cloud optical properties are initialized here and loaded into -!! the RRTMGP DDT, ty_cloud_optics. -!! -!! \section rrtmgp_sw_cloud_optics_init ! ###################################################################################### - subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, & - doGP_cldoptics_LUT, nrghice, rrtmgp_root_dir, rrtmgp_sw_file_clouds, mpicomm, & - mpirank, mpiroot, errmsg, errflg) + ! SUBROUTINE sw_cloud_optics_init + ! ###################################################################################### + subroutine rrtmgp_sw_cloud_optics_init( rrtmgp_root_dir, rrtmgp_sw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_sw_file_clouds ! RRTMGP file containing cloud-optic data logical, intent(in) :: & - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? + doGP_cldoptics_PADE,& ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? integer, intent(inout) :: & nrghice ! Number of ice-roughness categories integer, intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank mpiroot ! Master MPI rank - character(len=128),intent(in) :: & - rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_sw_file_clouds ! RRTMGP file containing coefficients used to compute clouds optical properties ! Outputs character(len=*), intent(out) :: & @@ -120,8 +98,6 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, errmsg = '' errflg = 0 - if (doG_cldoptics) return - ! Filenames are set in the physics_nml sw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_sw_file_clouds) @@ -180,7 +156,7 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, call mpi_bcast(nPairsSW, 1, MPI_INTEGER, mpiroot, mpicomm, mpierr) #endif - ! Has the number of ice-roughnesses provided from the namelist? + ! Has the number of ice-roughnes categories been provided from the namelist? ! If so, override nrghice from cloud-optics file if (nrghice .ne. 0) nrghice_fromfileSW = nrghice #ifdef MPI @@ -404,182 +380,4 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, 0.970, 0.970, 0.970, 0.700, 0.700, 0.700, 0.700/) end subroutine rrtmgp_sw_cloud_optics_init - -!> \section arg_table_rrtmgp_sw_cloud_optics_run -!! \htmlinclude rrtmgp_sw_cloud_optics.html -!! -!> \ingroup rrtmgp_sw_cloud_optics -!! -!! Compute shortwave optical prperties (optical-depth, single-scattering albedo, -!! asymmetry parameter) for ALL cloud types visible to RRTMGP. -!! -!! \section rrtmgp_sw_gas_optics_run - ! ###################################################################################### - subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, do_mynnedmf, imfdeepcnv, imfdeepcnv_gf, & - imfdeepcnv_samf, nCol, nLev, nDay, nbndsGPsw, idxday, cld_frac, cld_lwp, cld_reliq, & - cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & - cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, & - cld_pbl_iwp, cld_pbl_reice, sw_optical_props_cloudsByBand, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_precipByBand, & - sw_optical_props_MYNNcloudsByBand, cldtausw, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad, & ! Logical flag for shortwave radiation call - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? - do_mynnedmf ! - integer, intent(in) :: & - nbndsGPsw, & ! Number of shortwave bands - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - nday, & ! Number of daylit points. - icliq_sw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_sw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf ! - integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effective radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac, & ! Precipitation fraction by layer - cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) - cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) - cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) - cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) - cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles - cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles - cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles - cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) - sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (convective cloud) - sw_optical_props_MYNNcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (MYNN PBL cloud) - sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (cloud precipitation) - real(kind_phys), dimension(:,:), intent(out) :: & - cldtausw ! Approx 10.mu band layer cloud optical depth - - ! Local variables - integer :: iDay, iLay, iBand - real(kind_phys) :: tau_rain, tau_snow, ssa_rain, ssa_snow, asy_rain, asy_snow, & - tau_prec, asy_prec, ssa_prec, asyw, ssaw, za1, za2 - real(kind_phys), dimension(nday,nLev,nbndsGPsw) :: & - tau_cld, ssa_cld, asy_cld, tau_precip, ssa_precip, asy_precip - type(ty_optical_props_2str) :: sw_optical_props_cloudsByBand_daylit - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - ! Only process sunlit points... - if (nDay .gt. 0) then - - ! Compute cloud/precipitation optics. - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - ! i) Cloud-optics. - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cloudsByBand',& - sw_optical_props_cloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_cloud_optics_run - clouds',sw_cloud_props%cloud_optics(& - cld_lwp(idxday(1:nday),:), & ! IN - Cloud liquid water path - cld_iwp(idxday(1:nday),:), & ! IN - Cloud ice water path - cld_reliq(idxday(1:nday),:), & ! IN - Cloud liquid effective radius - cld_reice(idxday(1:nday),:), & ! IN - Cloud ice effective radius - sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, - ! in each band (tau,ssa,g) - - ! ii) Convective cloud-optics - if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cnvcloudsByBand',& - sw_optical_props_cnvcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_cloud_optics_run - convective clouds',sw_cloud_props%cloud_optics(& - cld_cnv_lwp(idxday(1:nday),:), & ! IN - Convective cloud liquid water path - cld_cnv_iwp(idxday(1:nday),:), & ! IN - Convective cloud ice water path - cld_cnv_reliq(idxday(1:nday),:), & ! IN - Convective cloud liquid effective radius - cld_cnv_reice(idxday(1:nday),:), & ! IN - Convective cloud ice effective radius - sw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, - ! in each band (tau,ssa,g) - endif - - ! iii) MYNN cloud-optics - if (do_mynnedmf) then - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_MYNNcloudsByBand',& - sw_optical_props_MYNNcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_MYNNcloud_optics_run - MYNN-EDMF cloud',sw_cloud_props%cloud_optics(& - cld_pbl_lwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) - cld_pbl_iwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) - cld_pbl_reliq(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) - cld_pbl_reice(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) - sw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties - ! in each band - endif - - ! iv) Cloud precipitation optics: rain and snow(+groupel) - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_precipByBand',& - sw_optical_props_precipByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - sw_optical_props_precipByBand%tau(:,:,:) = 0._kind_phys - sw_optical_props_precipByBand%ssa(:,:,:) = 1._kind_phys - sw_optical_props_precipByBand%g(:,:,:) = 0._kind_phys - - do iDay=1,nDay - do iLay=1,nLev - if (cld_frac(idxday(iDay),iLay) .gt. 1.e-12_kind_phys) then - ! Rain/Snow optical depth (No band dependence) - tau_rain = cld_rwp(idxday(iDay),iLay)*a0r - if (cld_swp(idxday(iDay),iLay) .gt. 0. .and. cld_resnow(idxday(iDay),iLay) .gt. 10._kind_phys) then - tau_snow = cld_swp(idxday(iDay),iLay)*1.09087*(a0s + a1s/(1.0315*cld_resnow(idxday(iDay),iLay))) ! fu's formula - else - tau_snow = 0._kind_phys - endif - - ! Rain/Snow single-scattering albedo and asymmetry (Band dependent) - do iBand=1,nbndsGPsw - ! By species - ssa_rain = tau_rain*(1.-b0r(iBand)) - asy_rain = ssa_rain*c0r(iBand) - ssa_snow = tau_snow*(1.-(b0s(iBand)+b1s(iBand)*1.0315*cld_resnow(idxday(iDay),iLay))) - asy_snow = ssa_snow*c0s(iBand) - ! Combine - tau_prec = max(1.e-12_kind_phys, tau_rain + tau_snow) - ssa_prec = max(1.e-12_kind_phys, ssa_rain + ssa_snow) - asy_prec = max(1.e-12_kind_phys, asy_rain + asy_snow) - asyw = asy_prec/max(1.e-12_kind_phys, ssa_prec) - ssaw = min(1._kind_phys-0.000001, ssa_prec/tau_prec) - za1 = asyw * asyw - za2 = ssaw * za1 - sw_optical_props_precipByBand%tau(iDay,iLay,iBand) = (1._kind_phys - za2) * tau_prec - sw_optical_props_precipByBand%ssa(iDay,iLay,iBand) = (ssaw - za2) / (1._kind_phys - za2) - sw_optical_props_precipByBand%g(iDay,iLay,iBand) = asyw/(1+asyw) - enddo - endif - enddo - enddo - endif - - ! All-sky SW optical depth ~0.55microns (DJS asks: Move to cloud diagnostics?) - cldtausw(idxday(1:nDay),:) = sw_optical_props_cloudsByBand%tau(:,:,11) - endif - - end subroutine rrtmgp_sw_cloud_optics_run - end module rrtmgp_sw_cloud_optics diff --git a/physics/rrtmgp_sw_cloud_optics.meta b/physics/rrtmgp_sw_cloud_optics.meta deleted file mode 100644 index 064b7cf80..000000000 --- a/physics/rrtmgp_sw_cloud_optics.meta +++ /dev/null @@ -1,393 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_cloud_optics - type = scheme - dependencies = machine.F,rrtmg_sw_cloud_optics.F90,radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_cloud_optics_init - type = scheme -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[nrghice] - standard_name = number_of_ice_roughness_categories - long_name = number of ice-roughness categories in RRTMGP calculation - units = count - dimensions = () - type = integer - intent = inout -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_sw_file_clouds] - standard_name = filename_of_rrtmgp_shortwave_cloud_optics_coefficients - long_name = file containing coefficients for RRTMGP SW cloud optics - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_cloud_optics_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[icliq_sw] - standard_name = control_for_shortwave_radiation_liquid_clouds - long_name = sw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[icice_sw] - standard_name = flag_for_optical_property_for_ice_clouds_for_shortwave_radiation - long_name = sw optical property for ice clouds - units = flag - dimensions = () - type = integer - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_swp] - standard_name = cloud_snow_water_path - long_name = layer cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = layer cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_lwp] - standard_name = convective_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_iwp] - standard_name = convective_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reliq] - standard_name = mean_effective_radius_for_liquid_convective_cloud - long_name = mean effective radius for liquid convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reice] - standard_name = mean_effective_radius_for_ice_convective_cloud - long_name = mean effective radius for ice convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_lwp] - standard_name = MYNN_SGS_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_iwp] - standard_name = MYNN_SGS_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reliq] - standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud - long_name = mean effective radius for liquid MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reice] - standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud - long_name = mean effective radius for ice MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[nbndsGPsw] - standard_name = number_of_shortwave_bands - long_name = number of sw bands used in RRTMGP - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[sw_optical_props_cloudsByBand] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_MYNNcloudsByBand] - standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[cldtausw] - standard_name = cloud_optical_depth_layers_at_0p55mu_band - long_name = approx .55mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_cloud_sampling.F90 b/physics/rrtmgp_sw_cloud_sampling.F90 deleted file mode 100644 index 238ed7d1c..000000000 --- a/physics/rrtmgp_sw_cloud_sampling.F90 +++ /dev/null @@ -1,174 +0,0 @@ -!> \file rrtmgp_sw_cloud_sampling.F90 -!! -!> \defgroup rrtmgp_sw_cloud_sampling rrtmgp_sw_cloud_sampling.F90 -!! -module rrtmgp_sw_cloud_sampling - use machine, only: kind_phys, kind_dbl_prec - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str - use rrtmgp_sampling, only: sampled_mask, draw_samples - use mersenne_twister, only: random_setseed, random_number, random_stat - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - use netcdf - - implicit none - -contains - -!>\defgroup rrtmgp_sw_cloud_sampling_mod GFS RRTMGP-SW Cloud Sampling Module -!> @{ -!> \section arg_table_rrtmgp_sw_cloud_sampling_run -!! \htmlinclude rrtmgp_sw_cloud_sampling.html -!! -!> \ingroup rrtmgp_sw_cloud_sampling -!! -!! \brief This routine performs the McICA cloud-sampling and maps the shortwave cloud- -!! optical properties, defined for each spectral band, to each spectral point (g-point). -!! -!! \section rrtmgp_sw_cloud_sampling_run - subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, & - iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, & - isubc_sw,icseed_sw, cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param,& - imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, cnv_cloud_overlap_param, cld_cnv_frac, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_cloudsByBand, & - sw_optical_props_precipByBand, sw_optical_props_clouds, sw_optical_props_cnvclouds, & - sw_optical_props_precip, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad ! Logical flag for shortwave radiation call - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nDay, & ! Number of daylit points. - nLev, & ! Number of vertical layers - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf, & ! - iovr, & ! Choice of cloud-overlap method - iovr_convcld, & ! Choice of convective cloud-overlap method - iovr_max, & ! Flag for maximum cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_rand, & ! Flag for random cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand, & ! Flag for exponential-random cloud overlap method - isubc_sw - integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. - integer,intent(in),dimension(:) :: & - icseed_sw ! auxiliary special cloud related array when module - ! variable isubc_sw=2, it provides permutation seed - ! for each column profile that are used for generating - ! random numbers. when isubc_sw /=2, it will not be used. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_cnv_frac, & ! Convective cloud fraction by layer - precip_frac ! Precipitation fraction by layer - real(kind_phys), dimension(:,:), intent(in) :: & - cloud_overlap_param, & ! Cloud overlap parameter - cnv_cloud_overlap_param, & ! Convective cloud overlap parameter - precip_overlap_param ! Precipitation overlap parameter - type(ty_optical_props_2str),intent(in) :: & - sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) - sw_optical_props_cnvcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (convectivecloud) - sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (precipitation) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (clouds) - sw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (convectivecloud) - sw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties at each spectral point (precipitation) - - ! Local variables - integer :: iday,iLay,iGpt - integer,dimension(nday) :: ipseed_sw - type(random_stat) :: rng_stat - real(kind_phys) :: tauloc,asyloc,ssaloc - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt(),nLev,nday) :: rng3D,rng3D2 - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()*nLev) :: rng2D - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()) :: rng1D - logical, dimension(nday,nLev,sw_gas_props%get_ngpt()) :: maskMCICA - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - if (nDay .gt. 0) then - ! ################################################################################# - ! First sample the clouds... - ! ################################################################################# - - ! Allocate space RRTMGP DDTs [nday,nLev,nGpt] - call check_error_msg('rrtmgp_sw_cloud_sampling_run', & - sw_optical_props_clouds%alloc_2str(nday, nLev, sw_gas_props)) - - ! Change random number seed value for each radiation invocation (isubc_sw =1 or 2). - if(isubc_sw == 1) then ! advance prescribed permutation seed - do iday = 1, nday - ipseed_sw(iday) = sw_gas_props%get_ngpt() + iday - enddo - elseif (isubc_sw == 2) then ! use input array of permutaion seeds - do iday = 1, nday - ipseed_sw(iday) = icseed_sw(idxday(iday)) - enddo - endif - - ! Call RNG. Mersennse Twister accepts 1D array, so loop over columns and collapse along G-points - ! and layers. ([nGpts,nLev,nDayumn]-> [nGpts*nLev]*nDayumn) - do iday=1,nday - call random_setseed(ipseed_sw(iday),rng_stat) - ! Use same rng for each layer - if (iovr == iovr_max) then - call random_number(rng1D,rng_stat) - do iLay=1,nLev - rng3D(:,iLay,iday) = rng1D - enddo - else - do iLay=1,nLev - call random_number(rng1D,rng_stat) - rng3D(:,iLay,iday) = rng1D - enddo - endif - enddo - - ! Cloud overlap. - ! Maximum-random, random, or maximum cloud overlap - if (iovr == iovr_maxrand .or. iovr == iovr_max .or. iovr == iovr_rand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA) - endif - ! Decorrelation-length overlap - if (iovr == iovr_dcorr) then - do iday=1,nday - call random_setseed(ipseed_sw(iday),rng_stat) - call random_number(rng2D,rng_stat) - rng3D2(:,:,iday) = reshape(source = rng2D,shape=[sw_gas_props%get_ngpt(),nLev]) - enddo - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA, & - overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1), & - randoms2 = real(rng3D2, kind=kind_phys)) - endif - ! Exponential or exponential-random cloud overlap - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA, & - overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_sw_cloud_sampling_run_draw_samples', & - draw_samples(maskMCICA, .true., & - sw_optical_props_cloudsByBand, & - sw_optical_props_clouds)) - endif - - end subroutine rrtmgp_sw_cloud_sampling_run - -!> @} -end module rrtmgp_sw_cloud_sampling diff --git a/physics/rrtmgp_sw_cloud_sampling.meta b/physics/rrtmgp_sw_cloud_sampling.meta deleted file mode 100644 index 1415108f8..000000000 --- a/physics/rrtmgp_sw_cloud_sampling.meta +++ /dev/null @@ -1,240 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_cloud_sampling - type = scheme - dependencies = machine.F,mersenne_twister.f,rrtmgp_sampling.F90,radiation_tools.F90 - -###################################################### -[ccpp-arg-table] - name = rrtmgp_sw_cloud_sampling_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[iovr_convcld] - standard_name = flag_for_convective_cloud_overlap_method_for_radiation - long_name = flag for convective cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[isubc_sw] - standard_name = flag_for_sw_clouds_grid_approximation - long_name = flag for sw clouds sub-grid approximation - units = flag - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[iovr] - standard_name = flag_for_cloud_overlap_method_for_radiation - long_name = max-random overlap clouds - units = flag - dimensions = () - type = integer - intent = in -[iovr_maxrand] - standard_name = flag_for_maximum_random_cloud_overlap_method - long_name = choice of maximum-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_dcorr] - standard_name = flag_for_decorrelation_length_cloud_overlap_method - long_name = choice of decorrelation-length cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exp] - standard_name = flag_for_exponential_cloud_overlap_method - long_name = choice of exponential cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exprand] - standard_name = flag_for_exponential_random_cloud_overlap_method - long_name = choice of exponential-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_rand] - standard_name = flag_for_random_cloud_overlap_method - long_name = choice of random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_max] - standard_name = flag_for_maximum_cloud_overlap_method - long_name = choice of maximum cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[icseed_sw] - standard_name = random_number_seed_for_mcica_shortwave - long_name = seed for random number generation for shortwave radiation - units = none - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_frac] - standard_name = convective_cloud_fraction_for_RRTMGP - long_name = layer convective cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cnv_cloud_overlap_param] - standard_name = convective_cloud_overlap_param - long_name = convective cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cloud_overlap_param] - standard_name = cloud_overlap_param - long_name = cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_overlap_param] - standard_name = precip_overlap_param - long_name = precipitation overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[sw_optical_props_cloudsByBand] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_clouds] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_cnvclouds] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_precip] - standard_name = shortwave_optical_properties_for_precipitation - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_gas_optics.F90 b/physics/rrtmgp_sw_gas_optics.F90 index 4bafa56a4..f62a75e4b 100644 --- a/physics/rrtmgp_sw_gas_optics.F90 +++ b/physics/rrtmgp_sw_gas_optics.F90 @@ -2,11 +2,8 @@ !! !> \defgroup rrtmgp_sw_gas_optics rrtmgp_sw_gas_optics.F90 !! -!! \brief This module contains two routines: One to initialize the k-distribution data -!! and functions needed to compute the shortwave gaseous optical properties in RRTMGP. -!! The second routine is a ccpp scheme within the "radiation loop", where the shortwave -!! optical prperties (optical-depth, single-scattering albedo, asymmetry parameter) are -!! computed for clear-sky conditions (no aerosols) +!! \brief This module contains a routine to initialize the k-distribution data used +!! by the RRTMGP shortwave radiation scheme. !! module rrtmgp_sw_gas_optics use machine, only: kind_phys @@ -14,7 +11,6 @@ module rrtmgp_sw_gas_optics use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_gas_concentrations, only: ty_gas_concs use radiation_tools, only: check_error_msg - use mo_optical_props, only: ty_optical_props_2str use netcdf #ifdef MPI use mpi @@ -83,7 +79,7 @@ module rrtmgp_sw_gas_optics scale_by_complement_upperSW ! Absorption is scaled by concentration of scaling_gas (F) or its complement (T) contains - + ! ###################################################################################### !>\defgroup rrtmgp_sw_gas_optics_mod GFS RRTMGP-SW Gas Optics Module !> @{ !! \section arg_table_rrtmgp_sw_gas_optics_init @@ -100,19 +96,19 @@ module rrtmgp_sw_gas_optics !! \section rrtmgp_sw_gas_optics_init !> @{ ! ###################################################################################### - subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, & + subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, & active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) ! Inputs character(len=128),intent(in) :: & rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_sw_file_gas ! RRTMGP file containing coefficients used to compute gaseous optical properties + rrtmgp_sw_file_gas ! RRTMGP file containing K-distribution data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array integer,intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank mpiroot ! Master MPI rank - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array ! Outputs character(len=*), intent(out) :: & @@ -121,11 +117,10 @@ subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, errflg ! CCPP error code ! Local variables - integer :: status, ncid, dimid, varID, iGas, mpierr, iChar + integer :: status, ncid, dimid, varID, mpierr, iChar integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4 character(len=264) :: sw_gas_props_file - type(ty_gas_concs) :: gas_concentrations ! RRTMGP DDT containing active trace gases - + type(ty_gas_concs) :: gas_concs ! RRTMGP DDT containing active trace gases ! Initialize errmsg = '' @@ -488,129 +483,19 @@ subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, ! Initialize RRTMGP DDT's... ! ! ####################################################################################### - allocate(gas_concentrations%gas_name(1:size(active_gases_array))) - gas_concentrations%gas_name(:) = active_gases_array(:) - call check_error_msg('sw_gas_optics_init',sw_gas_props%load(gas_concentrations, & + call check_error_msg('rrtmgp_sw_gas_optics_init_gas_concs',gas_concs%init(active_gases_array)) + call check_error_msg('rrtmgp_sw_gas_optics_init_load',sw_gas_props%load(gas_concs, & gas_namesSW, key_speciesSW, band2gptSW, band_limsSW, press_refSW, press_ref_tropSW,& temp_refSW, temp_ref_pSW, temp_ref_tSW, vmr_refSW, kmajorSW, kminor_lowerSW, & kminor_upperSW, gas_minorSW, identifier_minorSW, minor_gases_lowerSW, & minor_gases_upperSW, minor_limits_gpt_lowerSW, minor_limits_gpt_upperSW, & minor_scales_with_density_lowerSW, minor_scales_with_density_upperSW, & scaling_gas_lowerSW, scaling_gas_upperSW, scale_by_complement_lowerSW, & - - scale_by_complement_upperSW, kminor_start_lowerSW, kminor_start_upperSW, & solar_quietSW, solar_facularSW, solar_sunspotSW, tsi_defaultSW, mg_defaultSW, & sb_defaultSW, rayl_lowerSW, rayl_upperSW)) end subroutine rrtmgp_sw_gas_optics_init - -!> @} - ! ###################################################################################### -!> \section arg_table_rrtmgp_sw_gas_optics_run -!! \htmlinclude rrtmgp_sw_gas_optics.html -!! -!> \ingroup rrtmgp_sw_gas_optics -!! -!! Compute shortwave optical prperties (optical-depth, single-scattering albedo, -!! asymmetry parameter) for clear-sky conditions. -!! -!! \section rrtmgp_sw_gas_optics_run -!> @{ - ! ###################################################################################### - subroutine rrtmgp_sw_gas_optics_run(doSWrad, nCol, nLev, ngptsGPsw, nday, idxday, p_lay, & - p_lev, toa_src_sw, t_lay, t_lev, active_gases_array, gas_concentrations, solcon, & - sw_optical_props_clrsky, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad ! Flag to calculate SW irradiances - integer,intent(in) :: & - ngptsGPsw, & ! Number of spectral (g) points. - nDay, & ! Number of daylit points. - nCol, & ! Number of horizontal points - nLev ! Number of vertical levels - integer,intent(in),dimension(ncol) :: & - idxday ! Indices for daylit points. - real(kind_phys), dimension(ncol,nLev), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay ! Temperature (K) - real(kind_phys), dimension(ncol,nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - t_lev ! Temperature @ model levels - type(ty_gas_concs),intent(inout) :: & - gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) - real(kind_phys), intent(in) :: & - solcon ! Solar constant - - ! Output - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_clrsky ! RRTMGP DDT: clear-sky shortwave optical properties, spectral (tau,ssa,g) - real(kind_phys), dimension(nCol,ngptsGPsw), intent(out) :: & - toa_src_sw ! TOA incident spectral flux (W/m2) - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array - - ! Local variables - integer :: ij,iGas - real(kind_phys), dimension(ncol,nLev) :: vmrTemp - real(kind_phys), dimension(nday,ngptsGPsw) :: toa_src_sw_temp - type(ty_gas_concs) :: gas_concentrations_daylit - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - gas_concentrations%gas_name(:) = active_gases_array(:) - - toa_src_sw(:,:) = 0._kind_phys - if (nDay .gt. 0) then - ! Allocate space - call check_error_msg('rrtmgp_sw_gas_optics_run_alloc_2str',& - sw_optical_props_clrsky%alloc_2str(nday, nLev, sw_gas_props)) - - gas_concentrations_daylit%ncol = nDay - gas_concentrations_daylit%nlay = nLev - allocate(gas_concentrations_daylit%gas_name(gas_concentrations%get_num_gases())) - allocate(gas_concentrations_daylit%concs(gas_concentrations%get_num_gases())) - do iGas=1,gas_concentrations%get_num_gases() - allocate(gas_concentrations_daylit%concs(iGas)%conc(nDay, nLev)) - enddo - gas_concentrations_daylit%gas_name(:) = active_gases_array(:) - - ! Subset the gas concentrations. - do iGas=1,gas_concentrations%get_num_gases() - call check_error_msg('rrtmgp_sw_gas_optics_run_get_vmr',& - gas_concentrations%get_vmr(trim(gas_concentrations_daylit%gas_name(iGas)),vmrTemp)) - call check_error_msg('rrtmgp_sw_gas_optics_run_set_vmr',& - gas_concentrations_daylit%set_vmr(trim(gas_concentrations_daylit%gas_name(iGas)),vmrTemp(idxday(1:nday),:))) - enddo - - ! Call SW gas-optics - call check_error_msg('rrtmgp_sw_gas_optics_run',sw_gas_props%gas_optics(& - p_lay(idxday(1:nday),:), & ! IN - Pressure @ layer-centers (Pa) - p_lev(idxday(1:nday),:), & ! IN - Pressure @ layer-interfaces (Pa) - t_lay(idxday(1:nday),:), & ! IN - Temperature @ layer-centers (K) - gas_concentrations_daylit, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios - sw_optical_props_clrsky, & ! OUT - RRTMGP DDT: Shortwave optical properties, by - ! spectral point (tau,ssa,g) - toa_src_sw_temp)) ! OUT - TOA incident shortwave radiation (spectral) - toa_src_sw(idxday(1:nday),:) = toa_src_sw_temp - - ! Scale incident flux - do ij=1,nday - toa_src_sw(idxday(ij),:) = toa_src_sw(idxday(ij),:)*solcon/ & - sum(toa_src_sw(idxday(ij),:)) - enddo - endif - - end subroutine rrtmgp_sw_gas_optics_run !> @} end module rrtmgp_sw_gas_optics diff --git a/physics/rrtmgp_sw_gas_optics.meta b/physics/rrtmgp_sw_gas_optics.meta deleted file mode 100644 index 1fdbc946b..000000000 --- a/physics/rrtmgp_sw_gas_optics.meta +++ /dev/null @@ -1,201 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_gas_optics - type = scheme - dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90,rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_gas_optics_init - type = scheme -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_sw_file_gas] - standard_name = filename_of_rrtmgp_shortwave_k_distribution - long_name = file containing RRTMGP SW k-distribution - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_gas_optics_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = flag to calculate SW irradiances - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[ngptsGPsw] - standard_name = number_of_shortwave_spectral_points - long_name = number of spectral points in RRTMGP SW calculation - units = count - dimensions = () - type = integer - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[t_lev] - standard_name = air_temperature_at_interface_for_RRTMGP - long_name = air temperature level - units = K - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[toa_src_sw] - standard_name = toa_incident_sw_flux_by_spectral_point - long_name = TOA shortwave incident flux at each spectral points - units = W m-2 - dimensions = (horizontal_loop_extent,number_of_shortwave_spectral_points) - type = real - kind = kind_phys - intent = out -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = inout -[solcon] - standard_name = solar_constant - long_name = solar constant - units = W m-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out -[sw_optical_props_clrsky] - standard_name = shortwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out diff --git a/physics/rrtmgp_sw_main.F90 b/physics/rrtmgp_sw_main.F90 new file mode 100644 index 000000000..b25e093e7 --- /dev/null +++ b/physics/rrtmgp_sw_main.F90 @@ -0,0 +1,683 @@ +! ########################################################################################### +! ########################################################################################### +module rrtmgp_sw_main + use machine, only: kind_phys, kind_dbl_prec + use mo_optical_props, only: ty_optical_props_2str + use mo_cloud_optics, only: ty_cloud_optics + use module_radsw_parameters, only: cmpfsw_type + use mo_rte_sw, only: rte_sw + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_gas_concentrations, only: ty_gas_concs + use mo_fluxes_byband, only: ty_fluxes_byband + use radiation_tools, only: check_error_msg + use rrtmgp_sw_gas_optics, only: sw_gas_props,rrtmgp_sw_gas_optics_init + use rrtmgp_sw_cloud_optics, only: sw_cloud_props, rrtmgp_sw_cloud_optics_init, a0r, a0s, & + a1s, b0r, b0s, b1s, c0r, c0s + use GFS_rrtmgp_pre, only: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, & + iStr_o2, iStr_ccl4, iStr_cfc11, iStr_cfc12, iStr_cfc22, & + eps, oneminus, ftiny + use mersenne_twister, only: random_setseed, random_number, random_stat + use rrtmgp_sampling, only: sampled_mask, draw_samples + implicit none + + type(ty_gas_concs) :: gas_concs + type(ty_optical_props_2str) :: sw_optical_props_accum, sw_optical_props_aerosol_local, & + sw_optical_props_cloudsByBand, sw_optical_props_cnvcloudsByBand, & + sw_optical_props_pblcloudsByBand, sw_optical_props_precipByBand, & + sw_optical_props_clouds + + public rrtmgp_sw_main_init, rrtmgp_sw_main_run + +contains + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_sw_main_init + ! ######################################################################################### +!! \section arg_table_rrtmgp_sw_main_init +!! \htmlinclude rrtmgp_sw_main_init.html +!! + subroutine rrtmgp_sw_main_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, rrtmgp_sw_file_clouds,& + active_gases_array, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_sgs_pbl, & + doGP_sgs_cnv, nrghice, mpicomm, mpirank, mpiroot, nLay, rrtmgp_phys_blksz, & + errmsg, errflg) + + ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_sw_file_clouds, & ! RRTMGP file containing K-distribution data + rrtmgp_sw_file_gas ! RRTMGP file containing cloud-optics data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array) + logical, intent(in) :: & + doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer, intent(inout) :: & + nrghice ! Number of ice-roughness categories + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot, & ! Master MPI rank + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nLay + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! RRTMGP shortwave gas-optics (k-distribution) initialization + call rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, active_gases_array,& + mpicomm, mpirank, mpiroot, errmsg, errflg) + + ! RRTMGP shortwave cloud-optics initialization + call rrtmgp_sw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) + + ! DDTs + + ! ty_gas_concs + call check_error_msg('rrtmgp_sw_main_gas_concs_init',gas_concs%init(active_gases_array)) + + ! ty_optical_props + call check_error_msg('rrtmgp_sw_main_accumulated_optics_init',& + sw_optical_props_accum%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props)) + call check_error_msg('rrtmgp_sw_main_cloud_optics_init',& + sw_optical_props_cloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_sw_main_precip_optics_init',& + sw_optical_props_precipByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_sw_mian_cloud_sampling_init', & + sw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props)) + call check_error_msg('rrtmgp_sw_main_aerosol_optics_init',& + sw_optical_props_aerosol_local%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics_init',& + sw_optical_props_cnvcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + endif + if (doGP_sgs_pbl) then + call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics_init',& + sw_optical_props_pblcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + endif + end subroutine rrtmgp_sw_main_init + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_sw_main_run + ! ######################################################################################### +!! \section arg_table_rrtmgp_sw_main_run +!! \htmlinclude rrtmgp_sw_main_run.html +!! + subroutine rrtmgp_sw_main_run(doSWrad, doSWclrsky, top_at_1, doGP_sgs_cnv, doGP_sgs_pbl, & + nCol, nDay, nLay, nGases, rrtmgp_phys_blksz, idx, icseed_sw, iovr, iovr_convcld, & + iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_sw, & + iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, coszen,& + p_lay, p_lev, t_lay, t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, & + cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & + cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, & + cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, cloud_overlap_param, & + active_gases_array, aersw_tau, aersw_ssa, aersw_g, solcon, scmpsw, & + fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky, fluxswDOWN_clrsky, cldtausw, & + errmsg, errflg) + + ! Inputs + logical, intent(in) :: & + doSWrad, & ! Flag to perform shortwave calculation + doSWclrsky, & ! Flag to compute clear-sky fluxes + top_at_1, & ! Flag for vertical ordering convention + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer,intent(in) :: & + nCol, & ! Number of horizontal points + nDay, & ! Number of daytime points + nLay, & ! Number of vertical grid points. + nGases, & ! Number of active gases + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap + iovr_max, & ! Flag for maximum cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + isubc_sw, & ! + iSFC + integer,intent(in),dimension(:) :: & + idx, & ! Index array for daytime points + icseed_sw ! Seed for random number generation for shortwave radiation + real(kind_phys), dimension(:), intent(in) :: & + sfc_alb_nir_dir, & ! Surface albedo (direct) + sfc_alb_nir_dif, & ! Surface albedo (diffuse) + sfc_alb_uvvis_dir, & ! Surface albedo (direct) + sfc_alb_uvvis_dif, & ! Surface albedo (diffuse) + coszen ! Cosize of SZA + real(kind_phys), dimension(:,:), intent(in) :: & + p_lay, & ! Pressure @ model layer-centers (Pa) + t_lay, & ! Temperature (K) + p_lev, & ! Pressure @ model layer-interfaces (Pa) + t_lev, & ! Temperature @ model levels (K) + vmr_o2, & ! Molar-mixing ratio oxygen + vmr_h2o, & ! Molar-mixing ratio water vapor + vmr_o3, & ! Molar-mixing ratio ozone + vmr_ch4, & ! Molar-mixing ratio methane + vmr_n2o, & ! Molar-mixing ratio nitrous oxide + vmr_co2, & ! Molar-mixing ratio carbon dioxide + cld_frac, & ! Cloud-fraction for stratiform clouds + cld_lwp, & ! Water path for stratiform liquid cloud-particles + cld_reliq, & ! Effective radius for stratiform liquid cloud-particles + cld_iwp, & ! Water path for stratiform ice cloud-particles + cld_reice, & ! Effective radius for stratiform ice cloud-particles + cld_swp, & ! Water path for snow hydrometeors + cld_resnow, & ! Effective radius for snow hydrometeors + cld_rwp, & ! Water path for rain hydrometeors + cld_rerain, & ! Effective radius for rain hydrometeors + precip_frac, & ! Precipitation fraction + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles + cld_cnv_iwp, & ! Water path for convective ice cloud-particles + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles + cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for PBL ice cloud-particles + cld_pbl_reice, & ! Effective radius for PBL ice cloud-particles + cloud_overlap_param ! + real(kind_phys), dimension(:,:,:), intent(in) :: & + aersw_tau, & ! Aerosol optical depth + aersw_ssa, & ! Aerosol single scattering albedo + aersw_g ! Aerosol asymmetry paramter + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array + real(kind_phys), intent(in) :: & + solcon ! Solar constant + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + real(kind_phys), dimension(:,:), intent(inout) :: & + cldtausw ! Approx 10.mu band layer cloud optical depth + real(kind_phys), dimension(:,:), intent(inout) :: & + fluxswUP_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2) + fluxswDOWN_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2) + fluxswUP_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2) + fluxswDOWN_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2) + type(cmpfsw_type), dimension(:), intent(inout) :: & + scmpsw ! 2D surface fluxes, components: + ! uvbfc - total sky downward uv-b flux (W/m2) + ! uvbf0 - clear sky downward uv-b flux (W/m2) + ! nirbm - downward nir direct beam flux (W/m2) + ! nirdf - downward nir diffused flux (W/m2) + ! visbm - downward uv+vis direct beam flux (W/m2) + ! visdf - downward uv+vis diffused flux (W/m2) + + ! Local variables + type(cmpfsw_type), dimension(rrtmgp_phys_blksz) :: scmpsw_clrsky, scmpsw_allsky + type(ty_fluxes_byband) :: flux_allsky, flux_clrsky + real(kind_phys) :: tau_rain, tau_snow, ssa_rain, ssa_snow, asy_rain, asy_snow, & + tau_prec, asy_prec, ssa_prec, asyw, ssaw, za1, za2, flux_dir, flux_dif + real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1 + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()) :: rng1D + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3D,rng3D2 + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()*nLay) :: rng2D + logical, dimension(rrtmgp_phys_blksz,nLay,sw_gas_props%get_ngpt()) :: maskMCICA + logical :: cloudy_column, clear_column + real(kind_phys), dimension(sw_gas_props%get_nband(),rrtmgp_phys_blksz) :: & + sfc_alb_dir, sfc_alb_dif + real(kind_phys), dimension(rrtmgp_phys_blksz,nLay+1,sw_gas_props%get_nband()),target :: & + fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_dir_clrsky, fluxSW_dn_allsky, & + fluxSW_dn_clrsky, fluxSW_dn_dir_allsky + integer :: iBand, ibd, ibd_uv, iCol, iGas, iLay, ix, ix2, iblck + integer, dimension(rrtmgp_phys_blksz) :: ipseed_sw, iCols + type(random_stat) :: rng_stat + real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits + real(kind_phys), dimension(2), parameter :: & + nIR_uvvis_bnd = (/12850,16000/), & + uvb_bnd = (/29000,38000/) + real(kind_phys), dimension(rrtmgp_phys_blksz,sw_gas_props%get_ngpt()) :: toa_src_sw + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. doSWrad) return + + if (nDay .gt. 0) then + + bandlimits = sw_gas_props%get_band_lims_wavenumber() + ! ###################################################################################### + ! + ! Loop over all (daylit) columns... + ! + ! ###################################################################################### + do iCol=1,nDay,rrtmgp_phys_blksz + !ix = idx(iCol) + !ix2 = idx(iCol + rrtmgp_phys_blksz - 1) + iCols = idx(iCol:iCol + rrtmgp_phys_blksz - 1) + + ! Create clear/cloudy indicator + zcf0(:) = 1._kind_phys + zcf1(:) = 1._kind_phys + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(iCols(iblck),iLay)) + enddo + if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys + if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys + zcf1(iblck) = 1._kind_phys - zcf0(iblck) + enddo + cloudy_column = any(zcf1 .gt. eps) + clear_column = .true. + if (cloudy_column) clear_column = .false. + + ! ################################################################################### + ! + ! Initialize/reset + ! + ! ################################################################################### + sw_optical_props_clouds%tau = 0._kind_phys + sw_optical_props_clouds%ssa = 0._kind_phys + sw_optical_props_clouds%g = 0._kind_phys + sw_optical_props_accum%tau = 0._kind_phys + sw_optical_props_accum%ssa = 0._kind_phys + sw_optical_props_accum%g = 0._kind_phys + sw_optical_props_cloudsByBand%tau = 0._kind_phys + sw_optical_props_cloudsByBand%ssa = 0._kind_phys + sw_optical_props_cloudsByBand%g = 0._kind_phys + sw_optical_props_precipByBand%tau = 0._kind_phys + sw_optical_props_precipByBand%ssa = 0._kind_phys + sw_optical_props_precipByBand%g = 0._kind_phys + if (doGP_sgs_cnv) then + sw_optical_props_cnvcloudsByBand%tau = 0._kind_phys + sw_optical_props_cnvcloudsByBand%ssa = 0._kind_phys + sw_optical_props_cnvcloudsByBand%g = 0._kind_phys + endif + if (doGP_sgs_pbl) then + sw_optical_props_pblcloudsByBand%tau = 0._kind_phys + sw_optical_props_pblcloudsByBand%ssa = 0._kind_phys + sw_optical_props_pblcloudsByBand%g = 0._kind_phys + endif + scmpsw_clrsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + scmpsw_allsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + cldtausw = 0._kind_phys + + ! ty_fluxes_byband + fluxSW_up_allsky = 0._kind_phys + fluxSW_dn_allsky = 0._kind_phys + fluxSW_dn_dir_allsky = 0._kind_phys + fluxSW_up_clrsky = 0._kind_phys + fluxSW_dn_clrsky = 0._kind_phys + flux_allsky%bnd_flux_up => fluxSW_up_allsky + flux_allsky%bnd_flux_dn => fluxSW_dn_allsky + flux_allsky%bnd_flux_dn_dir => fluxSW_dn_dir_allsky + flux_clrsky%bnd_flux_up => fluxSW_up_clrsky + flux_clrsky%bnd_flux_dn => fluxSW_dn_clrsky + + ! ################################################################################### + ! + ! Set gas-concentrations + ! + ! ################################################################################### + call check_error_msg('rrtmgp_sw_main_set_vmr_o2', & + gas_concs%set_vmr(trim(active_gases_array(istr_o2)), vmr_o2(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_co2', & + gas_concs%set_vmr(trim(active_gases_array(istr_co2)),vmr_co2(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_ch4', & + gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),vmr_ch4(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_n2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),vmr_n2o(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_h2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),vmr_h2o(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_o3', & + gas_concs%set_vmr(trim(active_gases_array(istr_o3)), vmr_o3(iCols,:))) + + ! ################################################################################### + ! + ! Compute gas-optics + ! + ! ################################################################################### + + call check_error_msg('rrtmgp_sw_main_gas_optics',sw_gas_props%gas_optics(& + p_lay(iCols,:), & ! IN - Pressure @ layer-centers (Pa) + p_lev(iCols,:), & ! IN - Pressure @ layer-interfaces (Pa) + t_lay(iCols,:), & ! IN - Temperature @ layer-centers (K) + gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios + sw_optical_props_accum, & ! OUT - RRTMGP DDT: Shortwave optical properties, by + ! spectral point (tau,ssa,g) + toa_src_sw)) ! OUT - TOA incident shortwave radiation (spectral) + ! Scale incident flux + do iblck = 1, rrtmgp_phys_blksz + toa_src_sw(iblck,:) = toa_src_sw(iblck,:)*solcon / sum(toa_src_sw(iblck,:)) + enddo + + ! ################################################################################### + ! + ! Set surface albedo + ! + ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1 + ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1 + ! For overlapping band, average near-IR and us-vis albedos. + ! + ! ################################################################################### + do iblck = 1, rrtmgp_phys_blksz + do iBand=1,sw_gas_props%get_nband() + if (bandlimits(1,iBand) .lt. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,iblck) = sfc_alb_nir_dir(iCols(iblck)) + sfc_alb_dif(iBand,iblck) = sfc_alb_nir_dif(iCols(iblck)) + endif + if (bandlimits(1,iBand) .eq. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,iblck) = 0.5_kind_phys*(sfc_alb_nir_dir(iCols(iblck)) + & + sfc_alb_uvvis_dir(iCols(iblck))) + sfc_alb_dif(iBand,iblck) = 0.5_kind_phys*(sfc_alb_nir_dif(iCols(iblck)) + & + sfc_alb_uvvis_dif(iCols(iblck))) + ibd = iBand + endif + if (bandlimits(1,iBand) .ge. nIR_uvvis_bnd(2)) then + sfc_alb_dir(iBand,iblck) = sfc_alb_uvvis_dir(iCols(iblck)) + sfc_alb_dif(iBand,iblck) = sfc_alb_uvvis_dif(iCols(iblck)) + endif + if (bandlimits(1,iBand) .eq. uvb_bnd(1)) ibd_uv = iBand + enddo + enddo + + ! ################################################################################### + ! + ! Compute optics for cloud(s) and precipitation, sample clouds... + ! + ! ################################################################################### + if (cloudy_column) then + ! Gridmean/mp-clouds + call check_error_msg('rrtmgp_sw_main_cloud_optics',sw_cloud_props%cloud_optics(& + cld_lwp(iCols,:), & ! IN - Cloud liquid water path + cld_iwp(iCols,:), & ! IN - Cloud ice water path + cld_reliq(iCols,:), & ! IN - Cloud liquid effective radius + cld_reice(iCols,:), & ! IN - Cloud ice effective radius + sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, + ! in each band (tau,ssa,g) + cldtausw(iCols,:) = sw_optical_props_cloudsByBand%tau(:,:,11) + + ! Include convective clouds? + if (doGP_sgs_cnv) then + ! Compute + call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics',sw_cloud_props%cloud_optics(& + cld_cnv_lwp(iCols,:), & ! IN - Convective cloud liquid water path (g/m2) + cld_cnv_iwp(iCols,:), & ! IN - Convective cloud ice water path (g/m2) + cld_cnv_reliq(iCols,:), & ! IN - Convective cloud liquid effective radius (microns) + cld_cnv_reice(iCols,:), & ! IN - Convective cloud ice effective radius (microns) + sw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_cnvclouds_to_clouds',& + sw_optical_props_cnvcloudsByBand%increment(sw_optical_props_cloudsByBand)) + endif + + ! Include PBL clouds? + if (doGP_sgs_pbl) then + ! Compute + call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics',sw_cloud_props%cloud_optics(& + cld_pbl_lwp(iCols,:), & ! IN - PBL cloud liquid water path (g/m2) + cld_pbl_iwp(iCols,:), & ! IN - PBL cloud ice water path (g/m2) + cld_pbl_reliq(iCols,:), & ! IN - PBL cloud liquid effective radius (microns) + cld_pbl_reice(iCols,:), & ! IN - PBL cloud ice effective radius (microns) + sw_optical_props_pblcloudsByBand)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_pblclouds_to_clouds',& + sw_optical_props_pblcloudsByBand%increment(sw_optical_props_cloudsByBand)) + endif + + ! Cloud precipitation optics: rain and snow(+groupel) + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + if (cld_frac(iCols(iblck),iLay) .gt. ftiny) then + ! Rain/Snow optical depth (No band dependence) + tau_rain = cld_rwp(iCols(iblck),iLay)*a0r + if (cld_swp(iCols(iblck),iLay) .gt. 0. .and. cld_resnow(iCols(iblck),iLay) .gt. 10._kind_phys) then + tau_snow = cld_swp(iCols(iblck),iLay)*1.09087*(a0s + a1s/(1.0315*cld_resnow(iCols(iblck),iLay))) ! fu's formula + else + tau_snow = 0._kind_phys + endif + + ! Rain/Snow single-scattering albedo and asymmetry (Band dependent) + do iBand=1,sw_gas_props%get_nband() + ! By species + ssa_rain = tau_rain*(1.-b0r(iBand)) + asy_rain = ssa_rain*c0r(iBand) + ssa_snow = tau_snow*(1.-(b0s(iBand)+b1s(iBand)*1.0315*cld_resnow(iCols(iblck),iLay))) + asy_snow = ssa_snow*c0s(iBand) + ! Combine + tau_prec = max(1.e-12_kind_phys, tau_rain + tau_snow) + ssa_prec = max(1.e-12_kind_phys, ssa_rain + ssa_snow) + asy_prec = max(1.e-12_kind_phys, asy_rain + asy_snow) + asyw = asy_prec/max(1.e-12_kind_phys, ssa_prec) + ssaw = min(1._kind_phys-0.000001, ssa_prec/tau_prec) + za1 = asyw * asyw + za2 = ssaw * za1 + sw_optical_props_precipByBand%tau(iblck,iLay,iBand) = (1._kind_phys - za2) * tau_prec + sw_optical_props_precipByBand%ssa(iblck,iLay,iBand) = (ssaw - za2) / (1._kind_phys - za2) + sw_optical_props_precipByBand%g(iblck,iLay,iBand) = asyw/(1+asyw) + enddo + endif + enddo + enddo + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_precip_to_clouds',& + sw_optical_props_precipByBand%increment(sw_optical_props_cloudsByBand)) + + ! ################################################################################### + ! + ! Cloud-sampling + ! + ! ################################################################################### + ! Change random number seed value for each radiation invocation (isubc_sw =1 or 2). + if(isubc_sw == 1) then ! advance prescribed permutation seed + do iblck = 1, rrtmgp_phys_blksz + ipseed_sw(iblck) = sw_gas_props%get_ngpt() + iCols(iblck) + enddo + elseif (isubc_sw == 2) then ! use input array of permutaion seeds + do iblck = 1, rrtmgp_phys_blksz + ipseed_sw(iblck) = icseed_sw(iCols(iblck)) + enddo + endif + + ! Call RNG + do iblck = 1, rrtmgp_phys_blksz + call random_setseed(ipseed_sw(iblck),rng_stat) + ! Use same rng for each layer + if (iovr == iovr_max) then + call random_number(rng1D,rng_stat) + do iLay=1,nLay + rng3D(:,iLay,iblck) = rng1D + enddo + else + do iLay=1,nLay + call random_number(rng1D,rng_stat) + rng3D(:,iLay,iblck) = rng1D + enddo + endif + enddo + + ! Cloud-overlap. + ! Maximum-random, random or maximum. + if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA) + endif + ! Exponential decorrelation length overlap + if (iovr == iovr_dcorr) then + do iblck = 1, rrtmgp_phys_blksz + ! Generate second RNG + call random_setseed(ipseed_sw(iblck),rng_stat) + call random_number(rng2D,rng_stat) + rng3D2(:,:,iblck) = reshape(source = rng2D,shape=[sw_gas_props%get_ngpt(),nLay]) + enddo + ! + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCols,1:nLay-1), randoms2 = real(rng3D2, kind=kind_phys)) + endif + ! Exponential or Exponential-random + if (iovr == iovr_exp .or. iovr == iovr_exprand) then + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCols,1:nLay-1)) + endif + ! Sampling. Map band optical depth to each g-point using McICA + call check_error_msg('rrtmgp_sw_main_cloud_sampling',& + draw_samples(maskMCICA, .true., & + sw_optical_props_cloudsByBand, sw_optical_props_clouds)) + endif ! cloudy_column + + ! ################################################################################### + ! + ! Compute clear-sky fluxes (gaseous+aerosol) + ! + ! ################################################################################### + ! Increment optics (always) + sw_optical_props_aerosol_local%tau = aersw_tau(iCols,:,:) + sw_optical_props_aerosol_local%ssa = aersw_ssa(iCols,:,:) + sw_optical_props_aerosol_local%g = aersw_g(iCols,:,:) + call check_error_msg('rrtmgp_sw_main_increment_aerosol_to_clrsky', & + sw_optical_props_aerosol_local%increment(sw_optical_props_accum)) + + ! Compute clear-sky fluxes (Yes for no-clouds. Optional for cloudy scenes) + if (clear_column .or. doSWclrsky) then + call check_error_msg('rrtmgp_sw_main_rte_sw_clrsky',rte_sw( & + sw_optical_props_accum, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + coszen(iCols), & ! IN - Cosine of solar zenith angle + toa_src_sw, & ! IN - incident solar flux at TOA + sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) + sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) + flux_clrsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand) + + ! Store fluxes + fluxswUP_clrsky(iCols,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxswDOWN_clrsky(iCols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + + ! Compute surface downward beam/diffused flux components + do iblck = 1, rrtmgp_phys_blksz + do iBand=1,sw_gas_props%get_nband() + flux_dir = flux_clrsky%bnd_flux_dn(iblck,iSFC,iBand) + flux_dif = 0._kind_phys + ! Near-IR bands + if (iBand < ibd) then + scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir + scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif + endif + ! Transition band + if (iBand == ibd) then + scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir*0.5_kind_phys + scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif*0.5_kind_phys + scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir*0.5_kind_phys + scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif*0.5_kind_phys + endif + ! UV-VIS bands + if (iBand > ibd) then + scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir + scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif + endif + ! uv-b surface downward flux + scmpsw_clrsky(iblck)%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + enddo + else + fluxswUP_clrsky(iCols,:) = 0._kind_phys + fluxswDOWN_clrsky(iCols,:) = 0._kind_phys + scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + endif + + ! ################################################################################### + ! + ! All-sky fluxes (clear-sky + clouds + precipitation) + ! + ! ################################################################################### + if (cloudy_column) then + ! Delta scale + !call check_error_msg('rrtmgp_sw_main_delta_scale',sw_optical_props_clouds%delta_scale()) + + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_clouds_to_clrsky', & + sw_optical_props_clouds%increment(sw_optical_props_accum)) + + ! Compute fluxes + call check_error_msg('rrtmgp_sw_main_rte_sw_allsky',rte_sw( & + sw_optical_props_accum, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + coszen(iCols), & ! IN - Cosine of solar zenith angle + toa_src_sw, & ! IN - incident solar flux at TOA + sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) + sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) + flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand) + + ! Store fluxes + fluxswUP_allsky(iCols,:) = sum(flux_allsky%bnd_flux_up, dim=3) + fluxswDOWN_allsky(iCols,:) = sum(flux_allsky%bnd_flux_dn, dim=3) + + ! Compute and store downward beam/diffused flux components + do iblck = 1, rrtmgp_phys_blksz + ! Loop over bands, sum fluxes... + do iBand=1,sw_gas_props%get_nband() + flux_dir = flux_allsky%bnd_flux_dn_dir(iblck,iSFC,iBand) + flux_dif = flux_allsky%bnd_flux_dn(iblck,iSFC,iBand) - flux_allsky%bnd_flux_dn_dir(iblck,iSFC,iBand) + ! Near-IR bands + if (iBand < ibd) then + scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir + scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif + endif + ! Transition band + if (iBand == ibd) then + scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir*0.5_kind_phys + scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif*0.5_kind_phys + scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir*0.5_kind_phys + scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif*0.5_kind_phys + endif + ! UV-VIS bands + if (iBand > ibd) then + scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir + scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif + endif + ! uv-b surface downward flux + scmpsw_allsky(iblck)%uvbfc = flux_allsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + ! Store surface downward beam/diffused flux components + if (zcf1(iblck) .gt. eps) then + scmpsw(iCols(iblck))%nirbm = scmpsw_allsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_allsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_allsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_allsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_allsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + else + scmpsw(iCols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + endif + scmpsw(iCols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + else ! No clouds + fluxswUP_allsky(iCols,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxswDOWN_allsky(iCols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + do iblck = 1, rrtmgp_phys_blksz + scmpsw(iCols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + scmpsw(iCols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + endif + ! + enddo ! nday + else + fluxswUP_allsky(:,:) = 0._kind_phys + fluxswDOWN_allsky(:,:) = 0._kind_phys + fluxswUP_clrsky(:,:) = 0._kind_phys + fluxswDOWN_clrsky(:,:) = 0._kind_phys + scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + endif + end subroutine rrtmgp_sw_main_run +end module rrtmgp_sw_main diff --git a/physics/rrtmgp_sw_main.meta b/physics/rrtmgp_sw_main.meta new file mode 100644 index 000000000..4ca6cc716 --- /dev/null +++ b/physics/rrtmgp_sw_main.meta @@ -0,0 +1,664 @@ +[ccpp-table-properties] + name = rrtmgp_sw_main + type = scheme + dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 + dependencies = rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 + dependencies = rte-rrtmgp/rte/mo_rte_sw.F90,rte-rrtmgp/rte/mo_fluxes.F90 + dependencies = rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90, rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90 + dependencies = mersenne_twister.f,rrtmgp_sampling.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 + dependencies = rrtmgp_sw_gas_optics.F90, rrtmgp_sw_cloud_optics.F90 + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_sw_main_init + type = scheme +[rrtmgp_root_dir] + standard_name = directory_for_rte_rrtmgp_source_code + long_name = directory for rte+rrtmgp source code + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_sw_file_gas] + standard_name = filename_of_rrtmgp_shortwave_k_distribution + long_name = file containing RRTMGP SW k-distribution + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_sw_file_clouds] + standard_name = filename_of_rrtmgp_shortwave_cloud_optics_coefficients + long_name = file containing coefficients for RRTMGP SW cloud optics + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[doGP_cldoptics_PADE] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_cldoptics_LUT] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[nrghice] + standard_name = number_of_ice_roughness_categories + long_name = number of ice-roughness categories in RRTMGP calculation + units = count + dimensions = () + type = integer + intent = inout +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_SW_block + long_name = number of columns to process at a time by RRTMGP SW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[mpirank] + standard_name = mpi_rank + long_name = current MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpiroot] + standard_name = mpi_root + long_name = master MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpicomm] + standard_name = mpi_communicator + long_name = MPI communicator + units = index + dimensions = () + type = integer + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_sw_main_run + type = scheme +[doSWrad] + standard_name = flag_for_calling_shortwave_radiation + long_name = logical flags for sw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[doSWclrsky] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output sw heating rate (Radtend%swhc) + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_RRTMGP + long_name = flag for vertical ordering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[iSFC] + standard_name = vertical_index_for_surface_in_RRTMGP + long_name = index for surface layer in RRTMGP + units = flag + dimensions = () + type = integer + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[ncol] + standard_name = horizontal_loop_extent + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_SW_block + long_name = number of columns to process at a time by RRTMGP SW scheme + units = count + dimensions = () + type = integer + intent = in +[nGases] + standard_name = number_of_active_gases_used_by_RRTMGP + long_name = number of gases available used by RRTMGP (Model%nGases) + units = count + dimensions = () + type = integer + intent = in +[nday] + standard_name = daytime_points_dimension + long_name = daytime points dimension + units = count + dimensions = () + type = integer + intent = in +[idx] + standard_name = daytime_points + long_name = daytime points + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[coszen] + standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep + long_name = mean cos of zenith angle over rad call period + units = none + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[isubc_sw] + standard_name = flag_for_sw_clouds_grid_approximation + long_name = flag for sw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[icseed_sw] + standard_name = random_number_seed_for_mcica_shortwave + long_name = seed for random number generation for shortwave radiation + units = none + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[p_lay] + standard_name = air_pressure_at_layer_for_RRTMGP + long_name = air pressure at vertical layer for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure at vertical interface for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[t_lay] + standard_name = air_temperature_at_layer_for_RRTMGP + long_name = air temperature at vertical layer for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[t_lev] + standard_name = air_temperature_at_interface_for_RRTMGP + long_name = air temperature at vertical interface for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_frac] + standard_name = total_cloud_fraction + long_name = layer total cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_lwp] + standard_name = cloud_liquid_water_path + long_name = layer cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reliq] + standard_name = mean_effective_radius_for_liquid_cloud + long_name = mean effective radius for liquid cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_iwp] + standard_name = cloud_ice_water_path + long_name = layer cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reice] + standard_name = mean_effective_radius_for_ice_cloud + long_name = mean effective radius for ice cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_swp] + standard_name = cloud_snow_water_path + long_name = layer cloud snow water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_resnow] + standard_name = mean_effective_radius_for_snow_flake + long_name = mean effective radius for snow cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rwp] + standard_name = cloud_rain_water_path + long_name = layer cloud rain water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rerain] + standard_name = mean_effective_radius_for_rain_drop + long_name = mean effective radius for rain cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[precip_frac] + standard_name = precipitation_fraction_by_layer + long_name = precipitation fraction in each layer + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cloud_overlap_param] + standard_name = cloud_overlap_param + long_name = cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[sfc_alb_nir_dir] + standard_name = surface_albedo_due_to_near_IR_direct + long_name = surface albedo due to near IR direct beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_nir_dif] + standard_name = surface_albedo_due_to_near_IR_diffused + long_name = surface albedo due to near IR diffused beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_uvvis_dir] + standard_name = surface_albedo_due_to_UV_and_VIS_direct + long_name = surface albedo due to UV+VIS direct beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_uvvis_dif] + standard_name = surface_albedo_due_to_UV_and_VIS_diffused + long_name = surface albedo due to UV+VIS diffused beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[aersw_tau] + standard_name = aerosol_optical_depth_for_shortwave_bands_01_16 + long_name = aerosol optical depth for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[aersw_ssa] + standard_name = aerosol_single_scattering_albedo_for_shortwave_bands_01_16 + long_name = aerosol single scattering albedo for shortwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[aersw_g] + standard_name = aerosol_asymmetry_parameter_for_shortwave_bands_01_16 + long_name = aerosol asymmetry parameter for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[solcon] + standard_name = solar_constant + long_name = solar constant + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[scmpsw] + standard_name = components_of_surface_downward_shortwave_fluxes + long_name = derived type for special components of surface downward shortwave fluxes + units = W m-2 + dimensions = (horizontal_loop_extent) + type = cmpfsw_type + intent = inout +[fluxswUP_allsky] + standard_name = RRTMGP_sw_flux_profile_upward_allsky + long_name = RRTMGP upward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswDOWN_allsky] + standard_name = RRTMGP_sw_flux_profile_downward_allsky + long_name = RRTMGP downward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswUP_clrsky] + standard_name = RRTMGP_sw_flux_profile_upward_clrsky + long_name = RRTMGP upward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswDOWN_clrsky] + standard_name = RRTMGP_sw_flux_profile_downward_clrsky + long_name = RRTMGP downward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[cldtausw] + standard_name = cloud_optical_depth_layers_at_0p55mu_band + long_name = approx .55mu band layer cloud optical depth + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out diff --git a/physics/rrtmgp_sw_rte.F90 b/physics/rrtmgp_sw_rte.F90 deleted file mode 100644 index 521aae2c1..000000000 --- a/physics/rrtmgp_sw_rte.F90 +++ /dev/null @@ -1,219 +0,0 @@ -!> \file rrtmgp_sw_rte.F90 -!! -!> \defgroup rrtmgp_sw_rte rrtmgp_sw_rte.F90 -!! -!! \brief This module contains the main rte shortwave driver. -module rrtmgp_sw_rte - use machine, only: kind_phys - use mo_optical_props, only: ty_optical_props_2str - use mo_rte_sw, only: rte_sw - use mo_fluxes_byband, only: ty_fluxes_byband - use module_radsw_parameters, only: cmpfsw_type - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - implicit none - - public rrtmgp_sw_rte_run - -contains -!>\defgroup rrtmgp_sw_rte_mod GFS RRTMGP-SW RTE Module -!> \section arg_table_rrtmgp_sw_rte_run -!! \htmlinclude rrtmgp_sw_rte.html -!! -!> \ingroup rrtmgp_sw_rte -!! -!! \brief This routine takes all of the shortwave optical properties ,ty_optical_props_2str, -!! and computes the shortwave radiative fluxes for cloudy and clear-sky conditions. -!! -!! \section rrtmgp_sw_rte_run Main Driver -!> @{ - ! ###################################################################################### - subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, coszen, p_lay,& - t_lay, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif,& - sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, toa_src_sw, sw_optical_props_clrsky, & - sw_optical_props_clouds, sw_optical_props_precipByBand, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_MYNNcloudsByBand, & - sw_optical_props_aerosol, scmpsw, fluxswUP_allsky, fluxswDOWN_allsky, & - fluxswUP_clrsky, fluxswDOWN_clrsky, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doGP_sgs_mynn, & ! Flag for MYNN-EDMF PBL cloud scheme - doGP_sgs_cnv, & ! Flag for sgs convective clouds scheme - doSWrad, & ! Flag to calculate SW irradiances - doSWclrsky ! Compute clear-sky fluxes? - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nday, & ! Number of daytime points - nLev, & ! Number of vertical levels - iSFC ! Vertical index for surface-level - integer, intent(in), dimension(:) :: & - idxday ! Index array for daytime points - real(kind_phys),intent(in), dimension(:) :: & - sfc_alb_nir_dir, & ! Surface albedo (direct) - sfc_alb_nir_dif, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir, & ! Surface albedo (direct) - sfc_alb_uvvis_dif, & ! Surface albedo (diffuse) - coszen ! Cosize of SZA - real(kind_phys), dimension(:,:), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay, & ! Temperature (K) - toa_src_sw ! TOA incident spectral flux (W/m2) - type(ty_optical_props_2str),intent(inout) :: & - sw_optical_props_clrsky ! RRTMGP DDT: shortwave clear-sky radiative properties - type(ty_optical_props_2str),intent(in) :: & - sw_optical_props_clouds, & ! RRTMGP DDT: shortwave cloud optical properties - sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: shortwave convecive cloud optical properties - sw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: shortwave MYNN-EDMF PBL cloud optical properties - sw_optical_props_precipByBand, & ! RRTMGP DDT: shortwave precipitation optical properties - sw_optical_props_aerosol ! RRTMGP DDT: shortwave aerosol optical properties - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - real(kind_phys), dimension(:,:), intent(inout) :: & - fluxswUP_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2) - fluxswDOWN_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2) - fluxswUP_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2) - fluxswDOWN_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2) - type(cmpfsw_type), dimension(:), intent(inout) :: & - scmpsw ! 2D surface fluxes, components: - ! uvbfc - total sky downward uv-b flux (W/m2) - ! uvbf0 - clear sky downward uv-b flux (W/m2) - ! nirbm - downward nir direct beam flux (W/m2) - ! nirdf - downward nir diffused flux (W/m2) - ! visbm - downward uv+vis direct beam flux (W/m2) - ! visdf - downward uv+vis diffused flux (W/m2) - - ! Local variables - real(kind_phys), dimension(sw_gas_props%get_nband(),nday) :: & - sfc_alb_dir,sfc_alb_dif - type(ty_fluxes_byband) :: & - flux_allsky, & ! All-sky flux (W/m2) - flux_clrsky ! Clear-sky flux (W/m2) - real(kind_phys), dimension(nday,NLev+1,sw_gas_props%get_nband()),target :: & - fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_allsky, fluxSW_dn_clrsky, fluxSW_dn_dir_allsky - real(kind_phys), dimension(ncol,NLev) :: vmrTemp - integer :: iBand, iDay,ibd - real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits - real(kind_phys), dimension(2), parameter :: nIR_uvvis_bnd = (/12850,16000/) - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - if (nDay .gt. 0) then - - ! Initialize RRTMGP DDT containing 2D(3D) fluxes - flux_allsky%bnd_flux_up => fluxSW_up_allsky - flux_allsky%bnd_flux_dn => fluxSW_dn_allsky - flux_allsky%bnd_flux_dn_dir => fluxSW_dn_dir_allsky - flux_clrsky%bnd_flux_up => fluxSW_up_clrsky - flux_clrsky%bnd_flux_dn => fluxSW_dn_clrsky - - ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1 - ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1 - ! For overlapping band, average near-IR and us-vis albedos. - bandlimits = sw_gas_props%get_band_lims_wavenumber() - do iBand=1,sw_gas_props%get_nband() - if (bandlimits(1,iBand) .lt. nIR_uvvis_bnd(1)) then - sfc_alb_dir(iBand,:) = sfc_alb_nir_dir(idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_nir_dif(idxday(1:nday)) - endif - if (bandlimits(1,iBand) .eq. nIR_uvvis_bnd(1)) then - sfc_alb_dir(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dir(idxday(1:nday)) + sfc_alb_uvvis_dir(idxday(1:nday))) - sfc_alb_dif(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dif(idxday(1:nday)) + sfc_alb_uvvis_dif(idxday(1:nday))) - ibd = iBand - endif - if (bandlimits(1,iBand) .ge. nIR_uvvis_bnd(2)) then - sfc_alb_dir(iBand,:) = sfc_alb_uvvis_dir(idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_uvvis_dif(idxday(1:nday)) - endif - enddo - - ! - ! Compute clear-sky fluxes (if requested) - ! - - ! Clear-sky fluxes (gas+aerosol) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_aerosol%increment(sw_optical_props_clrsky)) - ! Delta-scale optical properties - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clrsky%delta_scale()) - if (doSWclrsky) then - call check_error_msg('rrtmgp_sw_rte_run',rte_sw( & - sw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - coszen(idxday(1:nday)), & ! IN - Cosine of solar zenith angle - toa_src_sw(idxday(1:nday),:), & ! IN - incident solar flux at TOA - sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) - sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) - flux_clrsky)) ! OUT - Fluxes, clear-sky, 3D (nCol,NLev,nBand) - ! Store fluxes - fluxswUP_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_up,dim=3) - fluxswDOWN_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_dn,dim=3) - endif - - ! - ! Compute all-sky fluxes - ! - - ! Include convective cloud? - if (doGP_sgs_cnv) then - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_cnvcloudsByBand%increment(sw_optical_props_clrsky)) - endif - - ! Include MYNN-EDMF PBL cloud? - if (doGP_sgs_mynn) then - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_MYNNcloudsByBand%increment(sw_optical_props_clrsky)) - endif - - ! All-sky fluxes (clear-sky + clouds + precipitation) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_precipByBand%increment(sw_optical_props_clrsky)) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clouds%increment(sw_optical_props_clrsky)) - - ! Delta-scale optical properties - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clrsky%delta_scale()) - call check_error_msg('rrtmgp_sw_rte_run',rte_sw( & - sw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - coszen(idxday(1:nday)), & ! IN - Cosine of solar zenith angle - toa_src_sw(idxday(1:nday),:), & ! IN - incident solar flux at TOA - sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) - sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) - flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (nCol,NLev,nBand) - - ! Store fluxes - fluxswUP_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_up,dim=3) - fluxswDOWN_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_dn,dim=3) - do iDay=1,nDay - ! Near IR - scmpsw(idxday(iDay))%nirbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. - scmpsw(idxday(iDay))%nirdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2.) - & - (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) - ! UV-VIS - scmpsw(idxday(iDay))%visbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. - scmpsw(idxday(iDay))%visdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2. ) - & - (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) - enddo - else - fluxswUP_allsky(:,:) = 0._kind_phys - fluxswDOWN_allsky(:,:) = 0._kind_phys - fluxswUP_clrsky(:,:) = 0._kind_phys - fluxswDOWN_clrsky(:,:) = 0._kind_phys - scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) - endif - - end subroutine rrtmgp_sw_rte_run -!> @} -end module rrtmgp_sw_rte diff --git a/physics/rrtmgp_sw_rte.meta b/physics/rrtmgp_sw_rte.meta deleted file mode 100644 index 9ab24c8b3..000000000 --- a/physics/rrtmgp_sw_rte.meta +++ /dev/null @@ -1,240 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_rte - type = scheme - dependencies = machine.F,radsw_param.f,rte-rrtmgp/rte/mo_rte_sw.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,radiation_tools.F90 - dependencies = rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_rte_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = flag to calculate SW irradiances - units = flag - dimensions = () - type = logical - intent = in -[doSWclrsky] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output sw heating rate (Radtend%swhc) - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[coszen] - standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep - long_name = mean cos of zenith angle over rad call period - units = none - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_cnv] - standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP - long_name = logical flag to control sgs convective cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_mynn] - standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP - long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[iSFC] - standard_name = vertical_index_for_surface_in_RRTMGP - long_name = index for surface layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[sw_optical_props_clrsky] - standard_name = shortwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[sw_optical_props_clouds] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_MYNNcloudsByBand] - standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_aerosol] - standard_name = shortwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sfc_alb_nir_dir] - standard_name = surface_albedo_due_to_near_IR_direct - long_name = surface albedo due to near IR direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dif] - standard_name = surface_albedo_due_to_near_IR_diffused - long_name = surface albedo due to near IR diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dir] - standard_name = surface_albedo_due_to_UV_and_VIS_direct - long_name = surface albedo due to UV+VIS direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dif] - standard_name = surface_albedo_due_to_UV_and_VIS_diffused - long_name = surface albedo due to UV+VIS diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[toa_src_sw] - standard_name = toa_incident_sw_flux_by_spectral_point - long_name = TOA shortwave incident flux at each spectral points - units = W m-2 - dimensions = (horizontal_loop_extent,number_of_shortwave_spectral_points) - type = real - kind = kind_phys - intent = in -[scmpsw] - standard_name = components_of_surface_downward_shortwave_fluxes - long_name = derived type for special components of surface downward shortwave fluxes - units = W m-2 - dimensions = (horizontal_loop_extent) - type = cmpfsw_type - intent = inout -[fluxswUP_allsky] - standard_name = RRTMGP_sw_flux_profile_upward_allsky - long_name = RRTMGP upward shortwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswDOWN_allsky] - standard_name = RRTMGP_sw_flux_profile_downward_allsky - long_name = RRTMGP downward shortwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswUP_clrsky] - standard_name = RRTMGP_sw_flux_profile_upward_clrsky - long_name = RRTMGP upward shortwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswDOWN_clrsky] - standard_name = RRTMGP_sw_flux_profile_downward_clrsky - long_name = RRTMGP downward shortwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rte-rrtmgp b/physics/rte-rrtmgp index 7f01618c9..0dc54f5ec 160000 --- a/physics/rte-rrtmgp +++ b/physics/rte-rrtmgp @@ -1 +1 @@ -Subproject commit 7f01618c92409658bddd3afa9acb004c608f6a0d +Subproject commit 0dc54f5ecaeb1e1e342efd1e02d0bcd41737bde2 From 6760693df8390074a8d6c64c2a0ae330e7bb0dbf Mon Sep 17 00:00:00 2001 From: Grant Firl Date: Mon, 30 Jan 2023 09:24:50 -0500 Subject: [PATCH 31/58] Merge pull request #35 from ChunxiZhang-NOAA/bugfix/cloud_rad Bug fix for cloud effective radius for convective clouds (HR1) --- physics/radiation_clouds.f | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 81a845fd2..ca9ea6e81 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -2127,10 +2127,16 @@ subroutine progcld_thompson_wsm6 & !> The total condensate includes convective condensate. do k = 1, NLAY-1 do i = 1, IX - cwp(i,k) = max(0.0, (clw(i,k,ntcw)+cnvw(i,k)* - & (1.-tem2d(i,k))) * gfac * delp(i,k)) - cip(i,k) = max(0.0, (clw(i,k,ntiw) + cnvw(i,k)* - & tem2d(i,k)) *gfac * delp(i,k)) + tem1 = cnvw(i,k)*(1.-tem2d(i,k)) + cwp(i,k) = max(0.0, (clw(i,k,ntcw)+tem1) * + & gfac * delp(i,k)) + if(tem1 > 1.e-12 .and. clw(i,k,ntcw) < 1.e-12) + & rew(i,k)=reliq_def + tem2 = cnvw(i,k)*tem2d(i,k) + cip(i,k) = max(0.0, (clw(i,k,ntiw) + tem2 ) + & *gfac * delp(i,k)) + if(tem2 > 1.e-12 .and. clw(i,k,ntiw) < 1.e-12) + & rei(i,k)=reice_def crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) csp(i,k) = max(0.0, clw(i,k,ntsw) * gfac * delp(i,k)) enddo From e1679258e2ab5bd9b0c2761fa6de6d3a88c3443d Mon Sep 17 00:00:00 2001 From: Grant Firl Date: Wed, 22 Feb 2023 10:01:32 -0500 Subject: [PATCH 32/58] Merge pull request #40 from mdtoyNOAA/ufs/dev_drag_suite_intent_mods Changed UGWP diagnostic variable declaration intents from 'out' to 'inout' --- physics/drag_suite.F90 | 4 ++-- physics/drag_suite.meta | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/physics/drag_suite.F90 b/physics/drag_suite.F90 index 4c65a91ce..5cb49acff 100644 --- a/physics/drag_suite.F90 +++ b/physics/drag_suite.F90 @@ -383,12 +383,12 @@ subroutine drag_suite_run( & real(kind=kind_phys), intent(inout) :: & & dusfc(:), dvsfc(:) !Output (optional): - real(kind=kind_phys), intent(out) :: & + real(kind=kind_phys), intent(inout) :: & & dusfc_ms(:),dvsfc_ms(:), & & dusfc_bl(:),dvsfc_bl(:), & & dusfc_ss(:),dvsfc_ss(:), & & dusfc_fd(:),dvsfc_fd(:) - real(kind=kind_phys), intent(out) :: & + real(kind=kind_phys), intent(inout) :: & & dtaux2d_ms(:,:),dtauy2d_ms(:,:), & & dtaux2d_bl(:,:),dtauy2d_bl(:,:), & & dtaux2d_ss(:,:),dtauy2d_ss(:,:), & diff --git a/physics/drag_suite.meta b/physics/drag_suite.meta index 8f33fcc60..ff60290ae 100644 --- a/physics/drag_suite.meta +++ b/physics/drag_suite.meta @@ -277,7 +277,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_ms] standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag long_name = y wind tendency from mesoscale gwd @@ -285,7 +285,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_bl] standard_name = tendency_of_x_wind_due_to_blocking_drag long_name = x wind tendency from blocking drag @@ -293,7 +293,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_bl] standard_name = tendency_of_y_wind_due_to_blocking_drag long_name = y wind tendency from blocking drag @@ -301,7 +301,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_ss] standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag long_name = x wind tendency from small scale gwd @@ -309,7 +309,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_ss] standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag long_name = y wind tendency from small scale gwd @@ -317,7 +317,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_fd] standard_name = tendency_of_x_wind_due_to_form_drag long_name = x wind tendency from form drag @@ -325,7 +325,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_fd] standard_name = tendency_of_y_wind_due_to_form_drag long_name = y wind tendency from form drag @@ -333,7 +333,7 @@ dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dusfc] standard_name = instantaneous_x_stress_due_to_gravity_wave_drag long_name = zonal surface stress due to orographic gravity wave drag @@ -357,7 +357,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_ms] standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag long_name = integrated y momentum flux from mesoscale gwd @@ -365,7 +365,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_bl] standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag long_name = integrated x momentum flux from blocking drag @@ -373,7 +373,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_bl] standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag long_name = integrated y momentum flux from blocking drag @@ -381,7 +381,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_ss] standard_name = vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag long_name = integrated x momentum flux from small scale gwd @@ -389,7 +389,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_ss] standard_name = vertically_integrated_y_momentum_flux_due_to_small_scale_gravity_wave_drag long_name = integrated y momentum flux from small scale gwd @@ -397,7 +397,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_fd] standard_name = vertically_integrated_x_momentum_flux_due_to_form_drag long_name = integrated x momentum flux from form drag @@ -405,7 +405,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_fd] standard_name = vertically_integrated_y_momentum_flux_due_to_form_drag long_name = integrated y momentum flux from form drag @@ -413,7 +413,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [slmsk] standard_name = area_type long_name = landmask: sea/land/ice=0/1/2 From 2b504ec5cb7e7eafda0049c76a7a605f67353a8b Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 16 Mar 2023 13:27:37 -0600 Subject: [PATCH 33/58] Fix missed change in merge. --- physics/rrtmgp_lw_main.meta | 4 ++-- physics/rrtmgp_sw_main.meta | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/physics/rrtmgp_lw_main.meta b/physics/rrtmgp_lw_main.meta index a1a384b25..48db72e37 100644 --- a/physics/rrtmgp_lw_main.meta +++ b/physics/rrtmgp_lw_main.meta @@ -149,8 +149,8 @@ type = logical intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/rrtmgp_sw_main.meta b/physics/rrtmgp_sw_main.meta index 4ca6cc716..dbb93a5df 100644 --- a/physics/rrtmgp_sw_main.meta +++ b/physics/rrtmgp_sw_main.meta @@ -149,8 +149,8 @@ type = logical intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical From 4c60a2f50b163cb52495c3815a41ade7e536de39 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Tue, 23 May 2023 14:00:52 -0600 Subject: [PATCH 34/58] Reorganize NRL ozone physics scheme into CCPP phases. Make scheme (memory) stateless. --- physics/GFS_phys_time_vary.fv3.F90 | 80 ++----- physics/GFS_phys_time_vary.fv3.meta | 76 +----- physics/GFS_phys_time_vary.scm.F90 | 68 ++---- physics/GFS_phys_time_vary.scm.meta | 76 +----- physics/GFS_rrtmg_pre.F90 | 11 +- physics/GFS_rrtmg_pre.meta | 30 +++ physics/GFS_rrtmg_setup.F90 | 7 +- physics/GFS_rrtmg_setup.meta | 21 ++ physics/ozinterp.f90 | 212 ----------------- physics/ozne_def.f | 24 -- physics/ozne_def.meta | 29 --- physics/ozphys_2015.F90 | 343 ++++++++++++++++++++++++++++ physics/ozphys_2015.f | 190 --------------- physics/ozphys_2015.meta | 203 ++++++++++++++-- physics/radiation_gases.f | 13 +- 15 files changed, 635 insertions(+), 748 deletions(-) delete mode 100644 physics/ozinterp.f90 delete mode 100644 physics/ozne_def.f delete mode 100644 physics/ozne_def.meta create mode 100644 physics/ozphys_2015.F90 delete mode 100644 physics/ozphys_2015.f diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 42f2bbc15..334228afe 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -2,7 +2,7 @@ !! Contains code related to GFS physics suite setup (physics part of time_vary_step) !>\defgroup mod_GFS_phys_time_vary GFS Physics Time Update -!! This module contains GFS physics time vary subroutines including ozone, stratospheric water vapor, +!! This module contains GFS physics time vary subroutines including stratospheric water vapor, !! aerosol, IN&CCN and surface properties updates. module GFS_phys_time_vary @@ -14,9 +14,6 @@ module GFS_phys_time_vary use mersenne_twister, only: random_setseed, random_number - use ozne_def, only : levozp, oz_coeff, oz_lat, oz_pres, oz_time, ozplin - use ozinterp, only : read_o3data, setindxoz, ozinterpol - use h2o_def, only : levh2o, h2o_coeff, h2o_lat, h2o_pres, h2o_time, h2oplin use h2ointerp, only : read_h2odata, setindxh2o, h2ointerpol @@ -66,9 +63,9 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !> @{ subroutine GFS_phys_time_vary_init ( & - me, master, ntoz, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & + me, master, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & nx, ny, idate, xlat_d, xlon_d, & - jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & + jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, imap, jmap, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, & @@ -85,15 +82,15 @@ subroutine GFS_phys_time_vary_init ( implicit none ! Interface variables - integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs, iaermdl + integer, intent(in) :: me, master, iccn, iflip, im, nx, ny, levs, iaermdl logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhour real(kind_phys), intent(in) :: xlat_d(:), xlon_d(:) - integer, intent(inout) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(inout) :: ddy_o3(:), ddy_h(:) - real(kind_phys), intent(in) :: ozpl(:,:,:), h2opl(:,:,:) + integer, intent(inout) :: jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(inout) :: ddy_h(:) + real(kind_phys), intent(in) :: h2opl(:,:,:) integer, intent(inout) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(inout) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(out) :: aer_nm(:,:,:) @@ -196,13 +193,12 @@ subroutine GFS_phys_time_vary_init ( jamax=-999 !$OMP parallel num_threads(nthrds) default(none) & -!$OMP shared (me,master,ntoz,h2o_phys,im,nx,ny,levs,idate) & +!$OMP shared (me,master,h2o_phys,im,nx,ny,levs,idate) & !$OMP shared (xlat_d,xlon_d,imap,jmap,errmsg,errflg) & -!$OMP shared (levozp,oz_coeff,oz_pres,ozpl) & !$OMP shared (levh2o,h2o_coeff,h2o_pres,h2opl) & !$OMP shared (iamin, iamax, jamin, jamax) & !$OMP shared (iaerclm,iaermdl,ntrcaer,aer_nm,iflip,iccn) & -!$OMP shared (jindx1_o3,jindx2_o3,ddy_o3,jindx1_h,jindx2_h,ddy_h) & +!$OMP shared (jindx1_h,jindx2_h,ddy_h) & !$OMP shared (jindx1_aer,jindx2_aer,ddy_aer,iindx1_aer,iindx2_aer,ddx_aer) & !$OMP shared (jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci,ddx_ci) & !$OMP shared (do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau,ddy_j2tau) & @@ -212,32 +208,12 @@ subroutine GFS_phys_time_vary_init ( !$OMP sections -!$OMP section -!> - Call read_o3data() to read ozone data - call read_o3data (ntoz, me, master) - - ! Consistency check that the hardcoded values for levozp and - ! oz_coeff in GFS_typedefs.F90 match what is set by read_o3data - ! in GFS_typedefs.F90: allocate (Tbd%ozpl (IM,levozp,oz_coeff)) - if (size(ozpl, dim=2).ne.levozp) then - write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & - "levozp from read_o3data does not match value in GFS_typedefs.F90: ", & - levozp, " /= ", size(ozpl, dim=2) - errflg = 1 - end if - if (size(ozpl, dim=3).ne.oz_coeff) then - write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & - "oz_coeff from read_o3data does not match value in GFS_typedefs.F90: ", & - oz_coeff, " /= ", size(ozpl, dim=3) - errflg = 1 - end if - !$OMP section !> - Call read_h2odata() to read stratospheric water vapor data call read_h2odata (h2o_phys, me, master) ! Consistency check that the hardcoded values for levh2o and - ! h2o_coeff in GFS_typedefs.F90 match what is set by read_o3data + ! h2o_coeff in GFS_typedefs.F90 match what is set by read_h2odata ! in GFS_typedefs.F90: allocate (Tbd%h2opl (IM,levh2o,h2o_coeff)) if (size(h2opl, dim=2).ne.levh2o) then write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & @@ -295,12 +271,6 @@ subroutine GFS_phys_time_vary_init ( !$OMP sections -!$OMP section -!> - Call setindxoz() to initialize ozone data - if (ntoz > 0) then - call setindxoz (im, xlat_d, jindx1_o3, jindx2_o3, ddy_o3) - endif - !$OMP section !> - Call setindxh2o() to initialize stratospheric water vapor data if (h2o_phys) then @@ -708,8 +678,8 @@ end subroutine GFS_phys_time_vary_init !> @{ subroutine GFS_phys_time_vary_timestep_init ( & me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, nsswr, fhswr, lsswr, fhour, & - imfdeepcnv, cal_pre, random_clds, nscyc, ntoz, h2o_phys, iaerclm, iccn, clstp, & - jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & + imfdeepcnv, cal_pre, random_clds, nscyc, h2o_phys, iaerclm, iccn, clstp, & + jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, fn_nml, & imap, jmap, prsl, seed0, rann, nthrds, nx, ny, nsst, tile_num, nlunit, lsoil, lsoil_lsm,& @@ -724,14 +694,14 @@ subroutine GFS_phys_time_vary_timestep_init ( ! Interface variables integer, intent(in) :: me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, & - nsswr, imfdeepcnv, iccn, nscyc, ntoz, iflip + nsswr, imfdeepcnv, iccn, nscyc, iflip integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhswr, fhour logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm real(kind_phys), intent(out) :: clstp - integer, intent(in) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(in) :: ddy_o3(:), ddy_h(:) - real(kind_phys), intent(inout) :: ozpl(:,:,:), h2opl(:,:,:) + integer, intent(in) :: jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(in) :: ddy_h(:) + real(kind_phys), intent(inout) :: h2opl(:,:,:) integer, intent(in) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(in) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(inout) :: aer_nm(:,:,:) @@ -788,8 +758,8 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP parallel num_threads(nthrds) default(none) & !$OMP shared(kdt,nsswr,lsswr,clstp,imfdeepcnv,cal_pre,random_clds) & !$OMP shared(fhswr,fhour,seed0,cnx,cny,nrcm,wrk,rannie,rndval) & -!$OMP shared(rann,im,isc,jsc,imap,jmap,ntoz,me,idate,jindx1_o3,jindx2_o3) & -!$OMP shared(ozpl,ddy_o3,h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & +!$OMP shared(rann,im,isc,jsc,imap,jmap,me,idate) & +!$OMP shared(h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & !$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & !$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & !$OMP shared(ddy_j2tau,tau_amf,iflip) & @@ -842,14 +812,6 @@ subroutine GFS_phys_time_vary_timestep_init ( endif ! imfdeepcnv, cal_re, random_clds -!$OMP section -!> - Call ozinterpol() to make ozone interpolation - if (ntoz > 0) then - call ozinterpol (me, im, idate, fhour, & - jindx1_o3, jindx2_o3, & - ozpl, ddy_o3) - endif - !$OMP section !> - Call h2ointerpol() to make stratospheric water vapor data interpolation if (h2o_phys) then @@ -944,12 +906,6 @@ subroutine GFS_phys_time_vary_finalize(errmsg, errflg) if (.not.is_initialized) return - ! Deallocate ozone arrays - if (allocated(oz_lat) ) deallocate(oz_lat) - if (allocated(oz_pres) ) deallocate(oz_pres) - if (allocated(oz_time) ) deallocate(oz_time) - if (allocated(ozplin) ) deallocate(ozplin) - ! Deallocate h2o arrays if (allocated(h2o_lat) ) deallocate(h2o_lat) if (allocated(h2o_pres)) deallocate(h2o_pres) diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index ce8c6c54b..654b5afd8 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -2,7 +2,7 @@ name = GFS_phys_time_vary type = scheme dependencies = aerclm_def.F,aerinterp.F90,gcycle.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f - dependencies = namelist_soilveg.f,set_soilveg.f,ozinterp.f90,ozne_def.f,sfcsub.F,cires_tauamf_data.F90,noahmp_tables.f90 + dependencies = namelist_soilveg.f,set_soilveg.f,sfcsub.F,cires_tauamf_data.F90,noahmp_tables.f90 ######################################################################## [ccpp-arg-table] @@ -23,13 +23,6 @@ dimensions = () type = integer intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -116,36 +109,6 @@ type = real kind = kind_phys intent = in -[jindx1_o3] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[jindx2_o3] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[ddy_o3] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = inout -[ozpl] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) - type = real - kind = kind_phys - intent = in [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor @@ -1077,13 +1040,6 @@ dimensions = () type = integer intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -1113,36 +1069,6 @@ type = real kind = kind_phys intent = out -[jindx1_o3] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[jindx2_o3] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[ddy_o3] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[ozpl] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) - type = real - kind = kind_phys - intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor diff --git a/physics/GFS_phys_time_vary.scm.F90 b/physics/GFS_phys_time_vary.scm.F90 index 74b34e974..97460ac98 100644 --- a/physics/GFS_phys_time_vary.scm.F90 +++ b/physics/GFS_phys_time_vary.scm.F90 @@ -2,7 +2,7 @@ !! Contains code related to GFS physics suite setup (physics part of time_vary_step) !>\defgroup mod_GFS_phys_time_vary GFS Physics Time Update -!! This module contains GFS physics time vary subroutines including ozone, stratospheric water vapor, +!! This module contains GFS physics time vary subroutines including, stratospheric water vapor, !! aerosol, IN&CCN and surface properties updates. !> @{ module GFS_phys_time_vary @@ -11,9 +11,6 @@ module GFS_phys_time_vary use mersenne_twister, only: random_setseed, random_number - use ozne_def, only : levozp, oz_coeff, oz_lat, oz_pres, oz_time, ozplin - use ozinterp, only : read_o3data, setindxoz, ozinterpol - use h2o_def, only : levh2o, h2o_coeff, h2o_lat, h2o_pres, h2o_time, h2oplin use h2ointerp, only : read_h2odata, setindxh2o, h2ointerpol @@ -61,8 +58,8 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !! @{ subroutine GFS_phys_time_vary_init ( & - me, master, ntoz, h2o_phys, iaerclm, iccn, iflip, im, nx, ny, idate, xlat_d, xlon_d, & - jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & + me, master, h2o_phys, iaerclm, iccn, iflip, im, nx, ny, idate, xlat_d, xlon_d, & + jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, imap, jmap, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, & @@ -79,15 +76,15 @@ subroutine GFS_phys_time_vary_init ( implicit none ! Interface variables - integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny + integer, intent(in) :: me, master, iccn, iflip, im, nx, ny logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhour real(kind_phys), intent(in) :: xlat_d(:), xlon_d(:) - integer, intent(inout) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(inout) :: ddy_o3(:), ddy_h(:) - real(kind_phys), intent(in) :: ozpl(:,:,:), h2opl(:,:,:) + integer, intent(inout) :: jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(inout) :: ddy_h(:) + real(kind_phys), intent(in) :: h2opl(:,:,:) integer, intent(inout) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(inout) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(in) :: aer_nm(:,:,:) @@ -189,30 +186,11 @@ subroutine GFS_phys_time_vary_init ( jamin=999 jamax=-999 -!> - Call read_o3data() to read ozone data - call read_o3data (ntoz, me, master) - - ! Consistency check that the hardcoded values for levozp and - ! oz_coeff in GFS_typedefs.F90 match what is set by read_o3data - ! in GFS_typedefs.F90: allocate (Tbd%ozpl (IM,levozp,oz_coeff)) - if (size(ozpl, dim=2).ne.levozp) then - write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & - "levozp from read_o3data does not match value in GFS_typedefs.F90: ", & - levozp, " /= ", size(ozpl, dim=2) - errflg = 1 - end if - if (size(ozpl, dim=3).ne.oz_coeff) then - write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & - "oz_coeff from read_o3data does not match value in GFS_typedefs.F90: ", & - oz_coeff, " /= ", size(ozpl, dim=3) - errflg = 1 - end if - !> - Call read_h2odata() to read stratospheric water vapor data call read_h2odata (h2o_phys, me, master) ! Consistency check that the hardcoded values for levh2o and - ! h2o_coeff in GFS_typedefs.F90 match what is set by read_o3data + ! h2o_coeff in GFS_typedefs.F90 match what is set by read_h2odata ! in GFS_typedefs.F90: allocate (Tbd%h2opl (IM,levh2o,h2o_coeff)) if (size(h2opl, dim=2).ne.levh2o) then write(errmsg,'(2a,i0,a,i0)') "Value error in GFS_phys_time_vary_init: ", & @@ -266,11 +244,6 @@ subroutine GFS_phys_time_vary_init ( !> - Initialize soil vegetation (needed for sncovr calculation further down) call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) -!> - Call setindxoz() to initialize ozone data - if (ntoz > 0) then - call setindxoz (im, xlat_d, jindx1_o3, jindx2_o3, ddy_o3) - endif - !> - Call setindxh2o() to initialize stratospheric water vapor data if (h2o_phys) then call setindxh2o (im, xlat_d, jindx1_h, jindx2_h, ddy_h) @@ -652,8 +625,8 @@ end subroutine GFS_phys_time_vary_init !! @{ subroutine GFS_phys_time_vary_timestep_init ( & me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, nsswr, fhswr, lsswr, fhour, & - imfdeepcnv, cal_pre, random_clds, ntoz, h2o_phys, iaerclm, iccn, clstp, & - jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & + imfdeepcnv, cal_pre, random_clds, h2o_phys, iaerclm, iccn, clstp, & + jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, & imap, jmap, prsl, seed0, rann, do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau,& @@ -663,14 +636,14 @@ subroutine GFS_phys_time_vary_timestep_init ( ! Interface variables integer, intent(in) :: me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, & - nsswr, imfdeepcnv, iccn, ntoz, iflip + nsswr, imfdeepcnv, iccn, iflip integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhswr, fhour logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm real(kind_phys), intent(out) :: clstp - integer, intent(in) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(in) :: ddy_o3(:), ddy_h(:) - real(kind_phys), intent(inout) :: ozpl(:,:,:), h2opl(:,:,:) + integer, intent(in) :: jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(in) :: ddy_h(:) + real(kind_phys), intent(inout) :: h2opl(:,:,:) integer, intent(in) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(in) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(inout) :: aer_nm(:,:,:) @@ -748,13 +721,6 @@ subroutine GFS_phys_time_vary_timestep_init ( endif ! imfdeepcnv, cal_re, random_clds -!> - Call ozinterpol() to make ozone interpolation - if (ntoz > 0) then - call ozinterpol (me, im, idate, fhour, & - jindx1_o3, jindx2_o3, & - ozpl, ddy_o3) - endif - !> - Call h2ointerpol() to make stratospheric water vapor data interpolation if (h2o_phys) then call h2ointerpol (me, im, idate, fhour, & @@ -844,12 +810,6 @@ subroutine GFS_phys_time_vary_finalize(errmsg, errflg) if (.not.is_initialized) return - ! Deallocate ozone arrays - if (allocated(oz_lat) ) deallocate(oz_lat) - if (allocated(oz_pres) ) deallocate(oz_pres) - if (allocated(oz_time) ) deallocate(oz_time) - if (allocated(ozplin) ) deallocate(ozplin) - ! Deallocate h2o arrays if (allocated(h2o_lat) ) deallocate(h2o_lat) if (allocated(h2o_pres)) deallocate(h2o_pres) diff --git a/physics/GFS_phys_time_vary.scm.meta b/physics/GFS_phys_time_vary.scm.meta index 8b59e4bed..21d1f2736 100644 --- a/physics/GFS_phys_time_vary.scm.meta +++ b/physics/GFS_phys_time_vary.scm.meta @@ -2,7 +2,7 @@ name = GFS_phys_time_vary type = scheme dependencies = aerclm_def.F,aerinterp.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f - dependencies = namelist_soilveg.f,set_soilveg.f,ozinterp.f90,ozne_def.f,cires_tauamf_data.F90,noahmp_tables.f90 + dependencies = namelist_soilveg.f,set_soilveg.f,cires_tauamf_data.F90,noahmp_tables.f90 ######################################################################## [ccpp-arg-table] @@ -23,13 +23,6 @@ dimensions = () type = integer intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -102,36 +95,6 @@ type = real kind = kind_phys intent = in -[jindx1_o3] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[jindx2_o3] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[ddy_o3] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = inout -[ozpl] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) - type = real - kind = kind_phys - intent = in [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor @@ -1056,13 +1019,6 @@ dimensions = () type = logical intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -1092,36 +1048,6 @@ type = real kind = kind_phys intent = out -[jindx1_o3] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[jindx2_o3] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[ddy_o3] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[ozpl] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) - type = real - kind = kind_phys - intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index c45bec3e3..ae88ca0fc 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -45,7 +45,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & - aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, errmsg, errflg) + aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, latsozp, levozp, & + blatc, dphiozc, errmsg, errflg) use machine, only: kind_phys @@ -101,7 +102,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& imp_physics_mg, imp_physics_wsm6, & imp_physics_nssl, & imp_physics_fer_hires, & - yearlen, icloud, iaermdl, iaerflg + yearlen, icloud, iaermdl, iaerflg, & + latsozp, levozp integer, intent(in) :: & iovr, & ! choice of cloud-overlap method @@ -132,7 +134,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& integer, intent(in) :: spp_rad real(kind_phys), intent(in) :: spp_wts_rad(:,:) - real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con + real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con, blatc, dphiozc real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g, con_ttp, con_thgni real(kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlat, xlon, & @@ -429,8 +431,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo enddo else ! climatological ozone - call getozn (prslk1, xlat, im, lmk, top_at_1, & ! --- inputs - olyr) ! --- outputs + call getozn (prslk1, xlat, im, lmk, top_at_1, latsozp, levozp, blatc, dphiozc, olyr) endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index d7feaeb3f..88363ef18 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1496,6 +1496,36 @@ dimensions = () type = integer intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[dphiozc] + standard_name = ozone_data_parameter_1 + long_name = ozone data parameter 1 + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[blatc] + standard_name = ozone_data_parameter_2 + long_name = ozone data parameter 2 + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 384d5252d..30917b961 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -44,7 +44,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd, co2usr_file, & co2cyc_file, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw,& - iswmode, ipsd0, ltp, lextop, errmsg, errflg) + iswmode, latsozp, levozp, timeozp, ipsd0, ltp, lextop, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -155,7 +155,8 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & ltp, npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, iovr_max, & iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, imp_physics, & - iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode + iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode, & + latsozp, levozp, timeozp integer, intent(in) :: idate(:) logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & inc_minor_gas, lextop @@ -219,7 +220,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, & con_pi, con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & - con_pi, errflg, errmsg) + con_pi, latsozp, levozp, timeozp, errflg, errmsg) call cld_init ( si, levr, imp_physics, me, con_g, con_rd, errflg, errmsg) call rlwinit ( me, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, & iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index adf6d8750..42b999c82 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -173,6 +173,27 @@ dimensions = () type = integer intent = in +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[timeozp] + standard_name = number_of_times_in_ozone_data + long_name = number of times in ozone data + units = count + dimensions = () + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in [icliq_sw] standard_name = control_for_shortwave_radiation_liquid_clouds long_name = sw optical property for liquid clouds diff --git a/physics/ozinterp.f90 b/physics/ozinterp.f90 deleted file mode 100644 index 5b3149d61..000000000 --- a/physics/ozinterp.f90 +++ /dev/null @@ -1,212 +0,0 @@ -!>\file ozinterp.f90 -!! This file contains ozone climatology interpolation subroutines. - -!>\ingroup mod_GFS_phys_time_vary -!! This module contains subroutines of reading and interpolating ozone coefficients. -module ozinterp - - implicit none - - private - - public :: read_o3data, setindxoz, ozinterpol - -contains - - SUBROUTINE read_o3data (ntoz, me, master) - use machine, only: kind_phys - use ozne_def -!--- in/out - integer, intent(in) :: ntoz - integer, intent(in) :: me - integer, intent(in) :: master -!--- locals - integer :: i, n, k - real(kind=4), allocatable, dimension(:) :: oz_lat4, oz_pres4 - real(kind=4), allocatable, dimension(:) :: oz_time4, tempin - real(kind=4) :: blatc4 - - if (ntoz <= 0) then ! Diagnostic ozone - rewind (kozc) - read (kozc,end=101) latsozc, levozc, timeozc, blatc4 - 101 if (levozc < 10 .or. levozc > 100) then - rewind (kozc) - levozc = 17 - latsozc = 18 - blatc = -85.0 - else - blatc = blatc4 - endif - latsozp = 2 - levozp = 1 - timeoz = 1 - oz_coeff = 0 - dphiozc = -(blatc+blatc)/(latsozc-1) - return - endif - - open(unit=kozpl,file='global_o3prdlos.f77', form='unformatted', convert='big_endian') - -!--- read in indices -!--- - read (kozpl) oz_coeff, latsozp, levozp, timeoz - if (me == master) then - write(*,*) 'Reading in o3data from global_o3prdlos.f77 ' - write(*,*) ' oz_coeff = ', oz_coeff - write(*,*) ' latsozp = ', latsozp - write(*,*) ' levozp = ', levozp - write(*,*) ' timeoz = ', timeoz - endif - -!--- read in data -!--- oz_lat - latitude of data (-90 to 90) -!--- oz_pres - vertical pressure level (mb) -!--- oz_time - time coordinate (days) -!--- - allocate (oz_lat(latsozp), oz_pres(levozp),oz_time(timeoz+1)) - allocate (oz_lat4(latsozp), oz_pres4(levozp),oz_time4(timeoz+1)) - rewind (kozpl) - read (kozpl) oz_coeff, latsozp, levozp, timeoz, oz_lat4, oz_pres4, oz_time4 - oz_pres(:) = oz_pres4(:) -!--- convert pressure levels from mb to ln(Pa) - oz_pres(:) = log(100.0*oz_pres(:)) - oz_lat(:) = oz_lat4(:) - oz_time(:) = oz_time4(:) - deallocate (oz_lat4, oz_pres4, oz_time4) - -!--- read in ozplin which is in order of (lattitudes, ozone levels, coeff number, time) -!--- assume latitudes is on a uniform gaussian grid -!--- - allocate (tempin(latsozp)) - allocate (ozplin(latsozp,levozp,oz_coeff,timeoz)) - DO i=1,timeoz - DO n=1,oz_coeff - DO k=1,levozp - READ(kozpl) tempin - ozplin(:,k,n,i) = tempin(:) - ENDDO - ENDDO - ENDDO - deallocate (tempin) - - close(kozpl) - - END SUBROUTINE read_o3data -! -!********************************************************************** -! - SUBROUTINE setindxoz(npts,dlat,jindx1,jindx2,ddy) -! - USE MACHINE, ONLY: kind_phys - USE OZNE_DEF, ONLY: jo3 => latsozp, oz_lat -! - implicit none -! - integer npts, JINDX1(npts),JINDX2(npts) - real(kind=kind_phys) dlat(npts),DDY(npts) -! - integer i,j,lat -! - DO J=1,npts - jindx2(j) = jo3 + 1 - do i=1,jo3 - if (dlat(j) < oz_lat(i)) then - jindx2(j) = i - exit - endif - enddo - jindx1(j) = max(jindx2(j)-1,1) - jindx2(j) = min(jindx2(j),jo3) - if (jindx2(j) .ne. jindx1(j)) then - DDY(j) = (dlat(j) - oz_lat(jindx1(j))) & - / (oz_lat(jindx2(j)) - oz_lat(jindx1(j))) - else - ddy(j) = 1.0 - endif -! print *,' j=',j,' dlat=',dlat(j),' jindx12=',jindx1(j), & -! jjindx2(j),' oz_lat=',oz_lat(jindx1(j)), & -! oz_lat(jindx2(j)),' ddy=',ddy(j) - ENDDO - - RETURN - END SUBROUTINE setindxoz -! -!********************************************************************** -! - SUBROUTINE ozinterpol(me,npts,IDATE,FHOUR,jindx1,jindx2,ozplout,ddy) -! - USE MACHINE, ONLY : kind_phys - USE OZNE_DEF - implicit none - integer iday,j,j1,j2,l,npts,nc,n1,n2 - real(kind=kind_phys) fhour,tem, tx1, tx2 -! - - integer JINDX1(npts), JINDX2(npts) - integer me, idate(4), IDAT(8),JDAT(8) -! - real(kind=kind_phys) DDY(npts) - real(kind=kind_phys) ozplout(npts,levozp,oz_coeff) - real(kind=kind_phys) rjday - integer jdow, jdoy, jday - real(8) rinc(5) - real(4) rinc4(5) - integer w3kindreal,w3kindint -! - IDAT=0 - IDAT(1)=IDATE(4) - IDAT(2)=IDATE(2) - IDAT(3)=IDATE(3) - IDAT(5)=IDATE(1) - RINC=0. - RINC(2)=FHOUR - call w3kind(w3kindreal,w3kindint) - if(w3kindreal==4) then - rinc4=rinc - CALL W3MOVDAT(RINC4,IDAT,JDAT) - else - CALL W3MOVDAT(RINC,IDAT,JDAT) - endif -! - jdow = 0 - jdoy = 0 - jday = 0 - call w3doxdat(jdat,jdow,jdoy,jday) - rjday = jdoy + jdat(5) / 24. - IF (RJDAY < oz_time(1)) RJDAY = RJDAY + 365. -! - n2 = timeoz + 1 - do j=2,timeoz - if (rjday < oz_time(j)) then - n2 = j - exit - endif - enddo - n1 = n2 - 1 -! -! if (me == 0) print *,' n1=',n1,' n2=',n2,' rjday=',rjday -! &,'oz_time=',oz_time(n1),oz_time(n2) -! - - tx1 = (oz_time(n2) - rjday) / (oz_time(n2) - oz_time(n1)) - tx2 = 1.0 - tx1 - - if (n2 > timeoz) n2 = n2 - timeoz -! - do nc=1,oz_coeff - DO L=1,levozp - DO J=1,npts - J1 = JINDX1(J) - J2 = JINDX2(J) - TEM = 1.0 - DDY(J) - ozplout(j,L,nc) = & - tx1*(TEM*ozplin(J1,L,nc,n1)+DDY(J)*ozplin(J2,L,nc,n1)) & - + tx2*(TEM*ozplin(J1,L,nc,n2)+DDY(J)*ozplin(J2,L,nc,n2)) - ENDDO - ENDDO - enddo -! - RETURN - END SUBROUTINE ozinterpol - -end module ozinterp diff --git a/physics/ozne_def.f b/physics/ozne_def.f deleted file mode 100644 index 8f3af6240..000000000 --- a/physics/ozne_def.f +++ /dev/null @@ -1,24 +0,0 @@ -!>\file ozne_def.f -!! This file contains the ozone array definition used in ozone physics. - -!>\ingroup mod_GFS_phys_time_vary -!! This module defines arrays in Ozone scheme. - module ozne_def - -!> \section arg_table_ozne_def -!! \htmlinclude ozne_def.html -!! - - use machine , only : kind_phys - implicit none - - integer, parameter :: kozpl=28, kozc=48 - - integer latsozp, levozp, timeoz, latsozc, levozc, timeozc - &, oz_coeff - real (kind=kind_phys) blatc, dphiozc - real (kind=kind_phys), allocatable :: oz_lat(:), oz_pres(:) - &, oz_time(:) - real (kind=kind_phys), allocatable :: ozplin(:,:,:,:) - - end module ozne_def diff --git a/physics/ozne_def.meta b/physics/ozne_def.meta deleted file mode 100644 index 3cad9c14d..000000000 --- a/physics/ozne_def.meta +++ /dev/null @@ -1,29 +0,0 @@ -[ccpp-table-properties] - name = ozne_def - type = module - dependencies = machine.F - -[ccpp-arg-table] - name = ozne_def - type = module - -[levozp] - standard_name = vertical_dimension_of_ozone_forcing_data - long_name = number of vertical layers in ozone forcing data - units = count - dimensions = () - type = integer -[oz_coeff] - standard_name = number_of_coefficients_in_ozone_forcing_data - long_name = number of coefficients in ozone forcing data - units = index - dimensions = () - type = integer -[oz_pres] - standard_name = natural_log_of_ozone_forcing_data_pressure_levels - long_name = natural log of ozone forcing data pressure levels in Pa - units = 1 - dimensions = (vertical_dimension_of_ozone_forcing_data) - type = real - kind = kind_phys - active = (index_of_ozone_mixing_ratio_in_tracer_concentration_array>0) diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 new file mode 100644 index 000000000..17f2178a4 --- /dev/null +++ b/physics/ozphys_2015.F90 @@ -0,0 +1,343 @@ +! ########################################################################################### +!> \file ozphys_2015.F90 +!! +! ########################################################################################### +module ozphys_2015 + use machine , only : kind_phys + implicit none + public ozphys_2015_init, ozphys_2015_timestep_init, ozphys_2015_run +contains + +! ########################################################################################### +!>\defgroup GFS_ozphys_2015 GFS Ozone Photochemistry (2015) Module +!! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. +!> @{ +!> \section arg_table_ozphys_2015_init Argument Table +!! \htmlinclude ozphys_2015_init.html +!! +! ########################################################################################### + subroutine ozphys_2015_init(oz_phys_2015, nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & + ddy, errmsg, errflg) + ! Inputs + logical, intent(in) :: & + oz_phys_2015 ! Control flag for NRL 2015 ozone physics scheme + integer, intent(in) :: & + nPts, & ! Horizontal dimension + latsozp ! Number of latitudes in ozone data + real(kind_phys), intent(in), dimension(:) :: & + oz_lat, & ! Latitudes of ozone data + dlat ! Latitudes of grid + ! Outputs + integer, intent(out), dimension(:) :: & + jindx1, & ! Interpolation index (low) for ozone data + jindx2 ! Interpolation index (high) for ozone data + real(kind_phys), intent(out), dimension(:) :: & + ddy ! Interpolation high index for ozone data + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local + integer i,j + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Sanity check + if (.not.oz_phys_2015) then + write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' + errflg = 1 + return + endif + + ! Set indices + do j=1,nPts + jindx2(j) = latsozp + 1 + do i=1,latsozp + if (dlat(j) < oz_lat(i)) then + jindx2(j) = i + exit + endif + enddo + jindx1(j) = max(jindx2(j)-1,1) + jindx2(j) = min(jindx2(j),latsozp) + if (jindx2(j) .ne. jindx1(j)) then + ddy(j) = (dlat(j) - oz_lat(jindx1(j))) / (oz_lat(jindx2(j)) - oz_lat(jindx1(j))) + else + ddy(j) = 1.0 + endif + enddo + + end subroutine ozphys_2015_init + +! ########################################################################################### +!> \section arg_table_ozphys_2015_timestep_init Argument Table +!! \htmlinclude ozphys_2015_timestep_init.html +!! +! ########################################################################################### + subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp, levozp, & + oz_coeff, timeoz, ozplin, oz_time, oz_pres, oz_lat, ddy, ozplout, errmsg, errflg) + ! Inputs + integer, intent(in) :: & + nPts, & ! Horizontal dimension + latsozp, & ! Number of latitudes in ozone data + levozp, & ! Number of levels in ozone data + oz_coeff, & ! Number of coefficients in ozone data + timeoz ! Number of times in ozone data + integer, intent(in),dimension(:) :: & + idate, & ! Initial date with different size and ordering + jindx1, & ! Interpolation index (low) for ozone + jindx2 ! Interpolation index (high) for ozone + real(kind_phys), intent(in) :: & + fhour ! Forecast hour + real(kind_phys), intent(in), dimension(:) :: & + ddy, & ! Interpolation high index for ozone data + oz_lat, & ! Latitudes for ozone data + oz_pres, & ! Levels for ozone data + oz_time ! Time for ozone data + real(kind_phys), intent(in), dimension(:,:,:,:) :: & + ozplin ! Ozone data + + ! Outputs + real(kind_phys), intent(out), dimension(:,:,:) :: & + ozplout ! Ozone forcing data + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local + integer :: idat(8),jdat(8),iday,j,j1,j2,l,nc,n1,n2,jdow,jdoy,& + jday,w3kindreal,w3kindint + real(kind_phys) :: tem, tx1, tx2, rjday + real(8) :: rinc(5) + real(4) :: rinc4(5) + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! + idat=0 + idat(1)=idate(4) + idat(2)=idate(2) + idat(3)=idate(3) + idat(5)=idate(1) + rinc=0. + rinc(2)=fhour + call w3kind(w3kindreal,w3kindint) + if(w3kindreal==4) then + rinc4=rinc + CALL w3movdat(rinc4,idat,jdat) + else + CALL w3movdat(rinc,idat,jdat) + endif + ! + jdow = 0 + jdoy = 0 + jday = 0 + call w3doxdat(jdat,jdow,jdoy,jday) + rjday = jdoy + jdat(5) / 24. + IF (RJDAY < oz_time(1)) RJDAY = RJDAY + 365. + ! + n2 = timeoz + 1 + do j=2,timeoz + if (rjday < oz_time(j)) then + n2 = j + exit + endif + enddo + n1 = n2 - 1 + + tx1 = (oz_time(n2) - rjday) / (oz_time(n2) - oz_time(n1)) + tx2 = 1.0 - tx1 + + if (n2 > timeoz) n2 = n2 - timeoz + ! + do nc=1,oz_coeff + do L=1,levozp + do J=1,npts + J1 = jindx1(J) + J2 = jindx2(J) + TEM = 1.0 - ddy(J) + ozplout(j,L,nc) = tx1*(TEM*ozplin(J1,L,nc,n1)+ddy(J)*ozplin(J2,L,nc,n1)) & + + tx2*(TEM*ozplin(J1,L,nc,n2)+ddy(J)*ozplin(J2,L,nc,n2)) + enddo + enddo + enddo + + ! + return + + end subroutine ozphys_2015_timestep_init + +! ########################################################################################### +!> The operational GFS currently parameterizes ozone production and +!! destruction based on monthly mean coefficients ( +!! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval +!! Research Laboratory through CHEM2D chemistry model +!! (McCormack et al. (2006) \cite mccormack_et_al_2006). +!! \section arg_table_ozphys_2015_run Argument Table +!! \htmlinclude ozphys_2015_run.html +!! +!> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm +!> - This code assumes that both prsl and po3 are from bottom to top +!! as are all other variables. +!> - This code is specifically for NRL parameterization and +!! climatological T and O3 are in location 5 and 6 of prdout array +!!\author June 2015 - Shrinivas Moorthi +! ########################################################################################### + subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_coeff, & + delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & + index_of_process_ozmix, index_of_process_temp, index_of_process_overhead_ozone, & + con_g, errmsg, errflg) + + ! Inputs + logical, intent(in) :: & + ldiag3d + real(kind_phys),intent(in) :: & + con_g + integer, intent(in) :: & + im, & ! + levs, & ! + ko3, & ! + pl_coeff, & ! + ntoz, & ! + index_of_process_prod_loss, & ! + index_of_process_ozmix, & ! + index_of_process_temp, & + index_of_process_overhead_ozone + integer, intent(in), dimension(:,:) :: & + dtidx ! + real(kind_phys), intent(in) :: & + dt ! + real(kind_phys), intent(in), dimension(:) :: & + po3 ! + real(kind_phys), intent(in), dimension(:,:) :: & + prsl, & ! + tin, & ! + delp ! + real(kind_phys), intent(in), dimension(:,:,:) :: & + prdout ! + + ! In/Outs + real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & + dtend ! + + ! Outputs + real(kind=kind_phys), intent(inout), dimension(:,:) :: & + oz ! + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Locals + integer :: k, kmax, kmin, l, i, j + integer, dimension(4) :: idtend + logical, dimension(im) :: flg + real :: gravi + real(kind_phys) :: pmax, pmin, tem, temp + real(kind_phys), dimension(im) :: wk1, wk2, wk3, ozib + real(kind_phys), dimension(im,pl_coeff) :: prod + real(kind_phys), dimension(im,levs) :: ozi + real(kind_phys), dimension(im,levs+1) :: colo3, coloz + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Are UFS diagnostic tendencies requested? If so, set up bookeeping indices... + if(ldiag3d) then + idtend(1) = dtidx(100+ntoz,index_of_process_prod_loss) ! was ozp1 + idtend(2) = dtidx(100+ntoz,index_of_process_ozmix) ! was ozp2 + idtend(3) = dtidx(100+ntoz,index_of_process_temp) ! was ozp3 + idtend(4) = dtidx(100+ntoz,index_of_process_overhead_ozone) ! was ozp4 + else + idtend=0 + endif + + ! Temporaries + ozi = oz + gravi=1.0/con_g + + colo3(:,levs+1) = 0.0 + coloz(:,levs+1) = 0.0 + + do l=levs,1,-1 + pmin = 1.0e10 + pmax = -1.0e10 + + do i=1,im + wk1(i) = log(prsl(i,l)) + pmin = min(wk1(i), pmin) + pmax = max(wk1(i), pmax) + prod(i,:) = 0.0 + enddo + kmax = 1 + kmin = 1 + do k=1,ko3-1 + if (pmin < po3(k)) kmax = k + if (pmax < po3(k)) kmin = k + enddo + ! + do k=kmin,kmax + temp = 1.0 / (po3(k) - po3(k+1)) + do i=1,im + flg(i) = .false. + if (wk1(i) < po3(k) .and. wk1(i) >= po3(k+1)) then + flg(i) = .true. + wk2(i) = (wk1(i) - po3(k+1)) * temp + wk3(i) = 1.0 - wk2(i) + endif + enddo + do j=1,pl_coeff + do i=1,im + if (flg(i)) then + prod(i,j) = wk2(i) * prdout(i,k,j) + wk3(i) * prdout(i,k+1,j) + endif + enddo + enddo + enddo + + do j=1,pl_coeff + do i=1,im + if (wk1(i) < po3(ko3)) then + prod(i,j) = prdout(i,ko3,j) + endif + if (wk1(i) >= po3(1)) then + prod(i,j) = prdout(i,1,j) + endif + enddo + enddo + do i=1,im + colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*gravi + coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*gravi + prod(i,2) = min(prod(i,2), 0.0) + enddo + do i=1,im + ozib(i) = ozi(i,l) ! no filling + tem = prod(i,1) - prod(i,2) * prod(i,6) + prod(i,3) * (tin(i,l) - prod(i,5)) & + + prod(i,4) * (colo3(i,l)-coloz(i,l)) + oz(i,l) = (ozib(i) + tem*dt) / (1.0 - prod(i,2)*dt) + enddo + if(idtend(1)>=1) then + dtend(:,l,idtend(1)) = dtend(:,l,idtend(1)) + (prod(:,1)-prod(:,2)*prod(:,6))*dt + endif + if(idtend(2)>=1) then + dtend(:,l,idtend(2)) = dtend(:,l,idtend(2)) + (oz(:,l) - ozib(:)) + endif + if(idtend(3)>=1) then + dtend(:,l,idtend(3)) = dtend(:,l,idtend(3)) + prod(:,3)*(tin(:,l)-prod(:,5))*dt + endif + if(idtend(4)>=1) then + dtend(:,l,idtend(4)) = dtend(:,l,idtend(4)) + prod(:,4) * (colo3(:,l)-coloz(:,l))*dt + endif + enddo + + return + end subroutine ozphys_2015_run +!> @} +end module ozphys_2015 diff --git a/physics/ozphys_2015.f b/physics/ozphys_2015.f deleted file mode 100644 index 85c79f733..000000000 --- a/physics/ozphys_2015.f +++ /dev/null @@ -1,190 +0,0 @@ -!> \file ozphys_2015.f -!! This file is ozone sources and sinks. - - - module ozphys_2015 - - contains - -!>\defgroup GFS_ozphys_2015 GFS Ozone Photochemistry (2015) Module -!! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. -!> @{ -!> \section arg_table_ozphys_2015_init Argument Table -!! \htmlinclude ozphys_2015_init.html -!! - subroutine ozphys_2015_init(oz_phys_2015, errmsg, errflg) - - implicit none - logical, intent(in) :: oz_phys_2015 - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not.oz_phys_2015) then - write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' - errflg = 1 - return - endif - - end subroutine ozphys_2015_init - -!> The operational GFS currently parameterizes ozone production and -!! destruction based on monthly mean coefficients ( -!! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval -!! Research Laboratory through CHEM2D chemistry model -!! (McCormack et al. (2006) \cite mccormack_et_al_2006). -!! \section arg_table_ozphys_2015_run Argument Table -!! \htmlinclude ozphys_2015_run.html -!! -!> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm -!> - This code assumes that both prsl and po3 are from bottom to top -!! as are all other variables. -!> - This code is specifically for NRL parameterization and -!! climatological T and O3 are in location 5 and 6 of prdout array -!!\author June 2015 - Shrinivas Moorthi - subroutine ozphys_2015_run ( & - & im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_coeff, & - & delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss& - & , index_of_process_ozmix, index_of_process_temp, & - & index_of_process_overhead_ozone, con_g, me, errmsg, errflg) -! -! - use machine , only : kind_phys - implicit none -! - real(kind=kind_phys),intent(in) :: con_g - real :: gravi - integer, intent(in) :: im, levs, ko3, pl_coeff,me - real(kind=kind_phys), intent(in) :: po3(:), & - & prsl(:,:), tin(:,:), & - & delp(:,:), & - & prdout(:,:,:), dt - real(kind=kind_phys), intent(inout) :: dtend(:,:,:) - integer, intent(in) :: dtidx(:,:), ntoz, & - & index_of_process_prod_loss, index_of_process_ozmix, & - & index_of_process_temp, index_of_process_overhead_ozone - real(kind=kind_phys), intent(inout) :: oz(im,levs) - - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - integer k,kmax,kmin,l,i,j, idtend(4) - logical ldiag3d, flg(im), qdiag3d - real(kind=kind_phys) pmax, pmin, tem, temp - real(kind=kind_phys) wk1(im), wk2(im), wk3(im),prod(im,pl_coeff), & - & ozib(im), colo3(im,levs+1), coloz(im,levs+1),& - & ozi(im,levs) -! - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if(ldiag3d) then - idtend(1) = dtidx(100+ntoz,index_of_process_prod_loss) ! was ozp1 - idtend(2) = dtidx(100+ntoz,index_of_process_ozmix) ! was ozp2 - idtend(3) = dtidx(100+ntoz,index_of_process_temp) ! was ozp3 - idtend(4) = dtidx(100+ntoz,index_of_process_overhead_ozone) ! was ozp4 - else - idtend=0 - endif - -!ccpp: save input oz in ozi - ozi = oz - gravi=1.0/con_g - - colo3(:,levs+1) = 0.0 - coloz(:,levs+1) = 0.0 -! - do l=levs,1,-1 - pmin = 1.0e10 - pmax = -1.0e10 -! - do i=1,im - wk1(i) = log(prsl(i,l)) - pmin = min(wk1(i), pmin) - pmax = max(wk1(i), pmax) - prod(i,:) = 0.0 - enddo - kmax = 1 - kmin = 1 - do k=1,ko3-1 - if (pmin < po3(k)) kmax = k - if (pmax < po3(k)) kmin = k - enddo -! - do k=kmin,kmax - temp = 1.0 / (po3(k) - po3(k+1)) - do i=1,im - flg(i) = .false. - if (wk1(i) < po3(k) .and. wk1(i) >= po3(k+1)) then - flg(i) = .true. - wk2(i) = (wk1(i) - po3(k+1)) * temp - wk3(i) = 1.0 - wk2(i) - endif - enddo - do j=1,pl_coeff - do i=1,im - if (flg(i)) then - prod(i,j) = wk2(i) * prdout(i,k,j) - & + wk3(i) * prdout(i,k+1,j) - endif - enddo - enddo - enddo -! - do j=1,pl_coeff - do i=1,im - if (wk1(i) < po3(ko3)) then - prod(i,j) = prdout(i,ko3,j) - endif - if (wk1(i) >= po3(1)) then - prod(i,j) = prdout(i,1,j) - endif - enddo - enddo - do i=1,im - colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*gravi - coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*gravi - prod(i,2) = min(prod(i,2), 0.0) - enddo -! write(1000+me,*) ' colo3=',colo3(1,l),' coloz=',coloz(1,l) -! &,' l=',l - do i=1,im - ozib(i) = ozi(i,l) ! no filling - tem = prod(i,1) - prod(i,2) * prod(i,6) - & + prod(i,3) * (tin(i,l) - prod(i,5)) - & + prod(i,4) * (colo3(i,l)-coloz(i,l)) - -! if (me .eq. 0) print *,'ozphys_2015 tem=',tem,' prod=',prod(i,:) -! &,' ozib=',ozib(i),' l=',l,' tin=',tin(i,l),'colo3=',colo3(i,l+1) - -!ccpp ozo(i,l) = (ozib(i) + tem*dt) / (1.0 - prod(i,2)*dt) - oz(i,l) = (ozib(i) + tem*dt) / (1.0 - prod(i,2)*dt) - enddo - if(idtend(1)>=1) then - dtend(:,l,idtend(1)) = dtend(:,l,idtend(1)) + ! was ozp1 - & (prod(:,1)-prod(:,2)*prod(:,6))*dt - endif - if(idtend(2)>=1) then - dtend(:,l,idtend(2)) = dtend(:,l,idtend(2)) + ! was ozp2 - & (oz(:,l) - ozib(:)) - endif - if(idtend(3)>=1) then - dtend(:,l,idtend(3)) = dtend(:,l,idtend(3)) + ! was ozp3 - & prod(:,3)*(tin(:,l)-prod(:,5))*dt - endif - if(idtend(4)>=1) then - dtend(:,l,idtend(4)) = dtend(:,l,idtend(4)) + ! was ozp4 - & prod(:,4) * (colo3(:,l)-coloz(:,l))*dt - endif - enddo ! vertical loop -! - return - end subroutine ozphys_2015_run - -!> @} - - end module ozphys_2015 diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index 8bce7defe..59621b386 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -7,6 +7,20 @@ [ccpp-arg-table] name = ozphys_2015_init type = scheme +[nPts] + standard_name = horizontal_dimension + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in [oz_phys_2015] standard_name = flag_for_nrl_2015_ozone_scheme long_name = flag for new (2015) ozone physics @@ -14,6 +28,176 @@ dimensions = () type = logical intent = in +[oz_lat] + standard_name = ozone_data_latitude + long_name = ozone data latitude + units = deg + dimensions = (number_of_latitudes_in_ozone_data) + type = real + kind = kind_phys + intent = in +[dlat] + standard_name = latitude_in_degree + long_name = latitude in degree north + units = degree_north + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[jindx1] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = out +[jindx2] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = out +[ddy] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = out +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = ozphys_2015_timestep_init + type = scheme +[nPts] + standard_name = horizontal_dimension + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[idate] + standard_name = date_and_time_at_model_initialization_in_united_states_order + long_name = initial date with different size and ordering + units = none + dimensions = (4) + type = integer + intent = in +[fhour] + standard_name = forecast_time + long_name = current forecast time + units = h + dimensions = () + type = real + kind = kind_phys + intent = in +[jindx1] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[jindx2] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[oz_coeff] + standard_name = number_of_coefficients_in_ozone_data + long_name = number of coefficients in ozone data + units = count + dimensions = () + type = integer + intent = in +[timeoz] + standard_name = number_of_times_in_ozone_data + long_name = number of times in ozone data + units = count + dimensions = () + type = integer + intent = in +[ozplin] + standard_name = ozone_data + long_name = ozone data + units = 1 + dimensions = (number_of_latitudes_in_ozone_data,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data,number_of_times_in_ozone_data) + type = real + kind = kind_phys + intent = in +[oz_time] + standard_name = ozone_data_time + long_name = ozone data time + units = none + dimensions = (13) + type = real + kind = kind_phys + intent = in +[oz_pres] + standard_name = ozone_data_level_pressure + long_name = ozone data level pressure + units = Pa + dimensions = (number_of_levels_in_ozone_data) + type = real + kind = kind_phys + intent = in +[oz_lat] + standard_name = ozone_data_latitude + long_name = ozone data latitude + units = deg + dimensions = (number_of_latitudes_in_ozone_data) + type = real + kind = kind_phys + intent = in +[ddy] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[ozplout] + standard_name = ozone_forcing + long_name = ozone forcing data + units = mixed + dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + type = real + kind = kind_phys + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -49,7 +233,7 @@ type = integer intent = in [ko3] - standard_name = vertical_dimension_of_ozone_forcing_data + standard_name = number_of_levels_in_ozone_data long_name = number of vertical layers in ozone forcing data units = count dimensions = () @@ -80,10 +264,10 @@ kind = kind_phys intent = in [po3] - standard_name = natural_log_of_ozone_forcing_data_pressure_levels + standard_name = natural_log_of_ozone_data_pressure_levels long_name = natural log of ozone forcing data pressure levels units = 1 - dimensions = (vertical_dimension_of_ozone_forcing_data) + dimensions = (number_of_levels_in_ozone_data) type = real kind = kind_phys intent = in @@ -99,14 +283,14 @@ standard_name = ozone_forcing long_name = ozone forcing data units = mixed - dimensions = (horizontal_loop_extent,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) + dimensions = (horizontal_loop_extent,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) type = real kind = kind_phys intent = in [pl_coeff] - standard_name = number_of_coefficients_in_ozone_forcing_data + standard_name = number_of_coefficients_in_ozone_data long_name = number of coefficients in ozone forcing data - units = index + units = count dimensions = () type = integer intent = in @@ -183,13 +367,6 @@ type = real kind = kind_phys intent = in -[me] - standard_name = mpi_rank - long_name = rank of the current MPI task - units = index - dimensions = () - type = integer - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index ccc3b598a..5f017598f 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -142,9 +142,6 @@ module module_radiation_gases use machine, only : kind_phys, kind_io4 use funcphys, only : fpkapx - use ozne_def, only : JMR => latsozc, LOZ => levozc, & - & blte => blatc, dlte=> dphiozc, & - & timeozc => timeozc use module_iounitdef, only : NIO3CLM, NICO2CN ! implicit none @@ -233,7 +230,7 @@ module module_radiation_gases !>\section gas_init_gen gas_init General Algorithm !----------------------------------- subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & - & ictmflg, ioznflg, con_pi, errflg, errmsg) + & ictmflg, ioznflg, con_pi, JMR, LOZ, timeozc, errflg, errmsg) ! =================================================================== ! ! ! @@ -283,8 +280,10 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & ! --- inputs: integer, intent(in) :: me, ictmflg, ioznflg, ico2flg + integer, intent(in) :: JMR, LOZ, timeozc character(len=26),intent(in) :: co2usr_file,co2cyc_file real(kind=kind_phys), intent(in) :: con_pi + ! --- output: character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -1115,7 +1114,8 @@ end subroutine getgases !! ratio (g/g) !>\section getozn_gen getozn General Algorithm !----------------------------------- - subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, o3mmr) + subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, JMR, LOZ, blte,& + & dlte, o3mmr) ! =================================================================== ! ! ! @@ -1144,7 +1144,8 @@ subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, o3mmr) implicit none ! --- inputs: - integer, intent(in) :: IMAX, LM + integer, intent(in) :: IMAX, LM, JMR, LOZ + real(kind=kind_phys), intent(in) :: blte, dlte logical, intent(in) :: top_at_1 real (kind=kind_phys), intent(in) :: prslk(:,:), xlat(:) From 70b9d7e5ddaf8a4308415ea601a1f8366f62e9d1 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 25 May 2023 10:27:12 -0600 Subject: [PATCH 35/58] RRTMGP changes for refactored NRL ozone physics. --- physics/GFS_rrtmgp_pre.F90 | 13 +++++++--- physics/GFS_rrtmgp_pre.meta | 30 ++++++++++++++++++++++ physics/GFS_rrtmgp_setup.F90 | 13 +++++----- physics/GFS_rrtmgp_setup.meta | 21 ++++++++++++++++ physics/ozphys_2015.F90 | 47 ++++++++++++++++++----------------- 5 files changed, 91 insertions(+), 33 deletions(-) diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 009eb8c38..e9cbc3d23 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -117,7 +117,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl vmr_n2o, vmr_co2, tsfg, tsfa, qs_lay, q_lay, tv_lay, & relhum, deltaZ, deltaZc, deltaP, active_gases_array, & tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, nDay, idxday, semis, & - sfc_emiss_byband, ico2, con_pi, errmsg, errflg) + sfc_emiss_byband, ico2, latsozp, levozp, blatc, dphiozc, con_pi, errmsg, errflg) ! Inputs integer, intent(in) :: & @@ -125,13 +125,17 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers ico2, & ! Flag for co2 radiation scheme - i_o3 ! Index into tracer array for ozone + i_o3, & ! Index into tracer array for ozone + latsozp, & ! + levozp logical, intent(in) :: & doSWrad, & ! Call SW radiation? doLWrad ! Call LW radiation real(kind_phys), intent(in) :: & fhswr, & ! Frequency of SW radiation call. - fhlwr ! Frequency of LW radiation call. + fhlwr, & ! Frequency of LW radiation call. + blatc, & ! + dphiozc real(kind_phys), intent(in) :: & con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air @@ -350,7 +354,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl enddo ! OR Use climatological ozone data else - call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, o3_lay) + call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, latsozp, levozp, blatc, & + dphiozc, o3_lay) endif ! ####################################################################################### diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index abb07b825..47980b513 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -503,6 +503,36 @@ dimensions = (horizontal_loop_extent) type = integer intent = inout +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[dphiozc] + standard_name = ozone_data_parameter_1 + long_name = ozone data parameter 1 + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[blatc] + standard_name = ozone_data_parameter_2 + long_name = ozone data parameter 2 + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 76db14279..7b5479e60 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -37,9 +37,10 @@ module GFS_rrtmgp_setup subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & - ntcw, ntoz, iovr, isubc_sw, isubc_lw, lalw1bd, idate, me, aeros_file, & - iaermdl, iaerflg, con_pi, con_t0c, con_c, con_boltz, con_plnk, solar_file, & - con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, ipsd0, errmsg, errflg) + ntcw, ntoz, iovr, latsozp, levozp, timeozp, isubc_sw, isubc_lw, lalw1bd, idate, & + me, aeros_file, iaermdl, iaerflg, con_pi, con_t0c, con_c, con_boltz, con_plnk, & + solar_file, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, ipsd0, & + errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -57,8 +58,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, real(kind_phys), dimension(:), intent(in) :: & si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & - ntcw, ntoz, iovr, isubc_sw, isubc_lw, & - me + ntcw, ntoz, iovr, isubc_sw, isubc_lw, latsozp, levozp, timeozp, me logical, intent(in) :: & lalw1bd integer, intent(in), dimension(:) :: & @@ -129,7 +129,8 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, errflg, errmsg ) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, latsozp, & + levozp, timeozp, errflg, errmsg ) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index c4f7cfaa5..567294d4a 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -266,6 +266,27 @@ dimensions = () type = integer intent = inout +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[timeozp] + standard_name = number_of_times_in_ozone_data + long_name = number of times in ozone data + units = count + dimensions = () + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in [iaermdl] standard_name = control_for_aerosol_radiation_scheme long_name = control of aerosol scheme in radiation diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 17f2178a4..4e73a5262 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -83,7 +83,7 @@ subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp integer, intent(in) :: & nPts, & ! Horizontal dimension latsozp, & ! Number of latitudes in ozone data - levozp, & ! Number of levels in ozone data + levozp, & ! Number of vertical layers in ozone data oz_coeff, & ! Number of coefficients in ozone data timeoz ! Number of times in ozone data integer, intent(in),dimension(:) :: & @@ -188,6 +188,7 @@ end subroutine ozphys_2015_timestep_init !> - This code is specifically for NRL parameterization and !! climatological T and O3 are in location 5 and 6 of prdout array !!\author June 2015 - Shrinivas Moorthi +!!\author May 2023 - Dustin Swales ! ########################################################################################### subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_coeff, & delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & @@ -196,43 +197,43 @@ subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_c ! Inputs logical, intent(in) :: & - ldiag3d + ldiag3d ! Flag to output GFS diagnostic tendencies real(kind_phys),intent(in) :: & - con_g + con_g ! Physical constant: Gravitational acceleration (ms-2) integer, intent(in) :: & - im, & ! - levs, & ! - ko3, & ! - pl_coeff, & ! - ntoz, & ! - index_of_process_prod_loss, & ! - index_of_process_ozmix, & ! - index_of_process_temp, & - index_of_process_overhead_ozone + im, & ! Horizontal dimension + levs, & ! Number of vertical layers + ko3, & ! Number of vertical layers in ozone forcing data + pl_coeff, & ! Number of coefficients in ozone forcing data + ntoz, & ! Index for ozone mixing ratio + index_of_process_prod_loss, & ! Index for process in diagnostic tendency output + index_of_process_ozmix, & ! Index for process in diagnostic tendency output + index_of_process_temp, & ! Index for process in diagnostic tendency output + index_of_process_overhead_ozone ! Index for process in diagnostic tendency output integer, intent(in), dimension(:,:) :: & - dtidx ! + dtidx ! Bookkeeping indices for GFS diagnostic tendencies real(kind_phys), intent(in) :: & - dt ! + dt ! Physics timestep (seconds) real(kind_phys), intent(in), dimension(:) :: & - po3 ! + po3 ! Natural log of ozone forcing data pressure levels real(kind_phys), intent(in), dimension(:,:) :: & - prsl, & ! - tin, & ! - delp ! + prsl, & ! Air-pressure (Pa) + tin, & ! Temperature of new-state (K) + delp ! Difference between mid-layer pressures (Pa) real(kind_phys), intent(in), dimension(:,:,:) :: & - prdout ! + prdout ! Ozone forcing data ! In/Outs real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & - dtend ! + dtend ! Diagnostic tendencies for state variables ! Outputs real(kind=kind_phys), intent(inout), dimension(:,:) :: & - oz ! + oz ! Ozone concentration updated by physics character(len=*), intent(out) :: & - errmsg ! CCPP error message + errmsg ! CCPP error message integer, intent(out) :: & - errflg ! CCPP error flag + errflg ! CCPP error flag ! Locals integer :: k, kmax, kmin, l, i, j From 6ff8689d3e1ed9ccaec7c09db6d8b12f633e59c1 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 25 May 2023 11:34:29 -0600 Subject: [PATCH 36/58] Revert change to CI test from NCAR->UWM merge --- .github/workflows/ci_fv3_ccpp_prebuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_fv3_ccpp_prebuild.yml b/.github/workflows/ci_fv3_ccpp_prebuild.yml index b23c9977e..a5c2f8092 100644 --- a/.github/workflows/ci_fv3_ccpp_prebuild.yml +++ b/.github/workflows/ci_fv3_ccpp_prebuild.yml @@ -24,7 +24,7 @@ jobs: run: echo "GIT_REMOTE_HASH=`git rev-parse HEAD`" >> $GITHUB_ENV - name: Checkout latest fv3atm - run: git clone https://github.com/NCAR/fv3atm.git + run: git clone https://github.com/NOAA-EMC/fv3atm.git - name: Initialize submodules run: | From 9859339985948e4d1fe2c721f7fab7830101dd72 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Thu, 15 Jun 2023 11:17:35 -0600 Subject: [PATCH 37/58] Some changes --- physics/GFS_rrtmg_pre.F90 | 6 +++--- physics/GFS_rrtmg_pre.meta | 12 ++++++------ physics/GFS_rrtmgp_pre.F90 | 8 ++++---- physics/GFS_rrtmgp_pre.meta | 12 ++++++------ physics/ozphys_2015.F90 | 7 ++++--- physics/ozphys_2015.meta | 8 -------- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index ae88ca0fc..cf9bbb6aa 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -45,7 +45,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & - aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, latsozp, levozp, & + aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, latsozc, levozc, & blatc, dphiozc, errmsg, errflg) use machine, only: kind_phys @@ -103,7 +103,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& imp_physics_nssl, & imp_physics_fer_hires, & yearlen, icloud, iaermdl, iaerflg, & - latsozp, levozp + latsozc, levozc integer, intent(in) :: & iovr, & ! choice of cloud-overlap method @@ -431,7 +431,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo enddo else ! climatological ozone - call getozn (prslk1, xlat, im, lmk, top_at_1, latsozp, levozp, blatc, dphiozc, olyr) + call getozn (prslk1, xlat, im, lmk, top_at_1, latsozc, levozc, blatc, dphiozc, olyr) endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 88363ef18..3b4d35c6d 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -1496,16 +1496,16 @@ dimensions = () type = integer intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data +[latsozc] + standard_name = number_of_latitudes_in_ozone_climotology_data + long_name = number of latitude in ozone climotology data units = count dimensions = () type = integer intent = in -[levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data +[levozc] + standard_name = number_of_levels_in_ozone_climotology_data + long_name = number of levels in ozone climotology data units = count dimensions = () type = integer diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index e9cbc3d23..dd72a6a1c 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -117,7 +117,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl vmr_n2o, vmr_co2, tsfg, tsfa, qs_lay, q_lay, tv_lay, & relhum, deltaZ, deltaZc, deltaP, active_gases_array, & tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, nDay, idxday, semis, & - sfc_emiss_byband, ico2, latsozp, levozp, blatc, dphiozc, con_pi, errmsg, errflg) + sfc_emiss_byband, ico2, latsozc, levozc, blatc, dphiozc, con_pi, errmsg, errflg) ! Inputs integer, intent(in) :: & @@ -126,8 +126,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl nLev, & ! Number of vertical layers ico2, & ! Flag for co2 radiation scheme i_o3, & ! Index into tracer array for ozone - latsozp, & ! - levozp + latsozc, & ! + levozc logical, intent(in) :: & doSWrad, & ! Call SW radiation? doLWrad ! Call LW radiation @@ -354,7 +354,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl enddo ! OR Use climatological ozone data else - call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, latsozp, levozp, blatc, & + call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, latsozc, levozc, blatc, & dphiozc, o3_lay) endif diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 47980b513..1a96eee1b 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -503,16 +503,16 @@ dimensions = (horizontal_loop_extent) type = integer intent = inout -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data +[latsozc] + standard_name = number_of_latitudes_in_ozone_climotology_data + long_name = number of latitude in ozone climotology data units = count dimensions = () type = integer intent = in -[levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data +[levozc] + standard_name = number_of_levels_in_ozone_climotology_data + long_name = number of levels in ozone climotology data units = count dimensions = () type = integer diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 4e73a5262..fda87611c 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -3,7 +3,7 @@ !! ! ########################################################################################### module ozphys_2015 - use machine , only : kind_phys + use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec implicit none public ozphys_2015_init, ozphys_2015_timestep_init, ozphys_2015_run contains @@ -78,7 +78,7 @@ end subroutine ozphys_2015_init !! ! ########################################################################################### subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp, levozp, & - oz_coeff, timeoz, ozplin, oz_time, oz_pres, oz_lat, ddy, ozplout, errmsg, errflg) + oz_coeff, timeoz, ozplin, oz_time, oz_lat, ddy, ozplout, errmsg, errflg) ! Inputs integer, intent(in) :: & nPts, & ! Horizontal dimension @@ -95,7 +95,6 @@ subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp real(kind_phys), intent(in), dimension(:) :: & ddy, & ! Interpolation high index for ozone data oz_lat, & ! Latitudes for ozone data - oz_pres, & ! Levels for ozone data oz_time ! Time for ozone data real(kind_phys), intent(in), dimension(:,:,:,:) :: & ozplin ! Ozone data @@ -114,6 +113,8 @@ subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp real(kind_phys) :: tem, tx1, tx2, rjday real(8) :: rinc(5) real(4) :: rinc4(5) + !real(kind_dbl_prec) :: rinc(5) + !real(kind_sngl_prec) :: rinc4(5) ! Initialize CCPP error handling variables errmsg = '' diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index 59621b386..eab24baf1 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -166,14 +166,6 @@ type = real kind = kind_phys intent = in -[oz_pres] - standard_name = ozone_data_level_pressure - long_name = ozone data level pressure - units = Pa - dimensions = (number_of_levels_in_ozone_data) - type = real - kind = kind_phys - intent = in [oz_lat] standard_name = ozone_data_latitude long_name = ozone data latitude From 8188e26897b91083b315a0c8f83e32f54209c96d Mon Sep 17 00:00:00 2001 From: dustinswales Date: Tue, 1 Aug 2023 16:01:38 -0600 Subject: [PATCH 38/58] Split ozone physics into time_vary and run components --- physics/GFS_rrtmg_setup.meta | 12 +- physics/GFS_rrtmgp_setup.meta | 12 +- physics/ozphys_2015.F90 | 181 ++--------------------------- physics/ozphys_2015.meta | 205 +-------------------------------- physics/ozphys_time_vary.F90 | 177 +++++++++++++++++++++++++++++ physics/ozphys_time_vary.meta | 207 ++++++++++++++++++++++++++++++++++ 6 files changed, 406 insertions(+), 388 deletions(-) create mode 100644 physics/ozphys_time_vary.F90 create mode 100644 physics/ozphys_time_vary.meta diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 42b999c82..f92d6f8db 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -174,22 +174,22 @@ type = integer intent = in [levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data + standard_name = number_of_levels_in_ozone_climotology_data + long_name = number of levels in ozone climotology data units = count dimensions = () type = integer intent = in [timeozp] - standard_name = number_of_times_in_ozone_data - long_name = number of times in ozone data + standard_name = number_of_times_in_ozone_climotology_data + long_name = number of times in ozone climotology data units = count dimensions = () type = integer intent = in [latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data + standard_name = number_of_latitudes_in_ozone_climotology_data + long_name = number of latitude in ozone climotology data units = count dimensions = () type = integer diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 567294d4a..c8ed60650 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -267,22 +267,22 @@ type = integer intent = inout [levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data + standard_name = number_of_levels_in_ozone_climotology_data + long_name = number of levels in ozone climotology data units = count dimensions = () type = integer intent = in [timeozp] - standard_name = number_of_times_in_ozone_data - long_name = number of times in ozone data + standard_name = number_of_times_in_ozone_climotology_data + long_name = number of times in ozone climotology data units = count dimensions = () type = integer intent = in [latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data + standard_name = number_of_latitudes_in_ozone_climotology_data + long_name = number of latitude in ozone climotology data units = count dimensions = () type = integer diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index fda87611c..82ade0cbd 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -5,176 +5,13 @@ module ozphys_2015 use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec implicit none - public ozphys_2015_init, ozphys_2015_timestep_init, ozphys_2015_run + public ozphys_2015_run contains ! ########################################################################################### !>\defgroup GFS_ozphys_2015 GFS Ozone Photochemistry (2015) Module !! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. !> @{ -!> \section arg_table_ozphys_2015_init Argument Table -!! \htmlinclude ozphys_2015_init.html -!! -! ########################################################################################### - subroutine ozphys_2015_init(oz_phys_2015, nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & - ddy, errmsg, errflg) - ! Inputs - logical, intent(in) :: & - oz_phys_2015 ! Control flag for NRL 2015 ozone physics scheme - integer, intent(in) :: & - nPts, & ! Horizontal dimension - latsozp ! Number of latitudes in ozone data - real(kind_phys), intent(in), dimension(:) :: & - oz_lat, & ! Latitudes of ozone data - dlat ! Latitudes of grid - ! Outputs - integer, intent(out), dimension(:) :: & - jindx1, & ! Interpolation index (low) for ozone data - jindx2 ! Interpolation index (high) for ozone data - real(kind_phys), intent(out), dimension(:) :: & - ddy ! Interpolation high index for ozone data - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local - integer i,j - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Sanity check - if (.not.oz_phys_2015) then - write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' - errflg = 1 - return - endif - - ! Set indices - do j=1,nPts - jindx2(j) = latsozp + 1 - do i=1,latsozp - if (dlat(j) < oz_lat(i)) then - jindx2(j) = i - exit - endif - enddo - jindx1(j) = max(jindx2(j)-1,1) - jindx2(j) = min(jindx2(j),latsozp) - if (jindx2(j) .ne. jindx1(j)) then - ddy(j) = (dlat(j) - oz_lat(jindx1(j))) / (oz_lat(jindx2(j)) - oz_lat(jindx1(j))) - else - ddy(j) = 1.0 - endif - enddo - - end subroutine ozphys_2015_init - -! ########################################################################################### -!> \section arg_table_ozphys_2015_timestep_init Argument Table -!! \htmlinclude ozphys_2015_timestep_init.html -!! -! ########################################################################################### - subroutine ozphys_2015_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp, levozp, & - oz_coeff, timeoz, ozplin, oz_time, oz_lat, ddy, ozplout, errmsg, errflg) - ! Inputs - integer, intent(in) :: & - nPts, & ! Horizontal dimension - latsozp, & ! Number of latitudes in ozone data - levozp, & ! Number of vertical layers in ozone data - oz_coeff, & ! Number of coefficients in ozone data - timeoz ! Number of times in ozone data - integer, intent(in),dimension(:) :: & - idate, & ! Initial date with different size and ordering - jindx1, & ! Interpolation index (low) for ozone - jindx2 ! Interpolation index (high) for ozone - real(kind_phys), intent(in) :: & - fhour ! Forecast hour - real(kind_phys), intent(in), dimension(:) :: & - ddy, & ! Interpolation high index for ozone data - oz_lat, & ! Latitudes for ozone data - oz_time ! Time for ozone data - real(kind_phys), intent(in), dimension(:,:,:,:) :: & - ozplin ! Ozone data - - ! Outputs - real(kind_phys), intent(out), dimension(:,:,:) :: & - ozplout ! Ozone forcing data - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local - integer :: idat(8),jdat(8),iday,j,j1,j2,l,nc,n1,n2,jdow,jdoy,& - jday,w3kindreal,w3kindint - real(kind_phys) :: tem, tx1, tx2, rjday - real(8) :: rinc(5) - real(4) :: rinc4(5) - !real(kind_dbl_prec) :: rinc(5) - !real(kind_sngl_prec) :: rinc4(5) - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! - idat=0 - idat(1)=idate(4) - idat(2)=idate(2) - idat(3)=idate(3) - idat(5)=idate(1) - rinc=0. - rinc(2)=fhour - call w3kind(w3kindreal,w3kindint) - if(w3kindreal==4) then - rinc4=rinc - CALL w3movdat(rinc4,idat,jdat) - else - CALL w3movdat(rinc,idat,jdat) - endif - ! - jdow = 0 - jdoy = 0 - jday = 0 - call w3doxdat(jdat,jdow,jdoy,jday) - rjday = jdoy + jdat(5) / 24. - IF (RJDAY < oz_time(1)) RJDAY = RJDAY + 365. - ! - n2 = timeoz + 1 - do j=2,timeoz - if (rjday < oz_time(j)) then - n2 = j - exit - endif - enddo - n1 = n2 - 1 - - tx1 = (oz_time(n2) - rjday) / (oz_time(n2) - oz_time(n1)) - tx2 = 1.0 - tx1 - - if (n2 > timeoz) n2 = n2 - timeoz - ! - do nc=1,oz_coeff - do L=1,levozp - do J=1,npts - J1 = jindx1(J) - J2 = jindx2(J) - TEM = 1.0 - ddy(J) - ozplout(j,L,nc) = tx1*(TEM*ozplin(J1,L,nc,n1)+ddy(J)*ozplin(J2,L,nc,n1)) & - + tx2*(TEM*ozplin(J1,L,nc,n2)+ddy(J)*ozplin(J2,L,nc,n2)) - enddo - enddo - enddo - - ! - return - - end subroutine ozphys_2015_timestep_init - -! ########################################################################################### !> The operational GFS currently parameterizes ozone production and !! destruction based on monthly mean coefficients ( !! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval @@ -187,11 +24,11 @@ end subroutine ozphys_2015_timestep_init !> - This code assumes that both prsl and po3 are from bottom to top !! as are all other variables. !> - This code is specifically for NRL parameterization and -!! climatological T and O3 are in location 5 and 6 of prdout array -!!\author June 2015 - Shrinivas Moorthi -!!\author May 2023 - Dustin Swales +!! climatological T and O3 are in location 5 and 6 of oz_data array +!!\author June 2015 - Shrinivas Moorthi +!!\modified May 2023 - Dustin Swales ! ########################################################################################### - subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_coeff, & + subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, pl_coeff, & delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & index_of_process_ozmix, index_of_process_temp, index_of_process_overhead_ozone, & con_g, errmsg, errflg) @@ -222,7 +59,7 @@ subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_c tin, & ! Temperature of new-state (K) delp ! Difference between mid-layer pressures (Pa) real(kind_phys), intent(in), dimension(:,:,:) :: & - prdout ! Ozone forcing data + oz_data ! Ozone forcing data ! In/Outs real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & @@ -298,7 +135,7 @@ subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_c do j=1,pl_coeff do i=1,im if (flg(i)) then - prod(i,j) = wk2(i) * prdout(i,k,j) + wk3(i) * prdout(i,k+1,j) + prod(i,j) = wk2(i) * oz_data(i,k,j) + wk3(i) * oz_data(i,k+1,j) endif enddo enddo @@ -307,10 +144,10 @@ subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, prdout, pl_c do j=1,pl_coeff do i=1,im if (wk1(i) < po3(ko3)) then - prod(i,j) = prdout(i,ko3,j) + prod(i,j) = oz_data(i,ko3,j) endif if (wk1(i) >= po3(1)) then - prod(i,j) = prdout(i,1,j) + prod(i,j) = oz_data(i,1,j) endif enddo enddo diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index eab24baf1..ea82defaa 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -3,209 +3,6 @@ type = scheme dependencies = machine.F -######################################################################## -[ccpp-arg-table] - name = ozphys_2015_init - type = scheme -[nPts] - standard_name = horizontal_dimension - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data - units = count - dimensions = () - type = integer - intent = in -[oz_phys_2015] - standard_name = flag_for_nrl_2015_ozone_scheme - long_name = flag for new (2015) ozone physics - units = flag - dimensions = () - type = logical - intent = in -[oz_lat] - standard_name = ozone_data_latitude - long_name = ozone data latitude - units = deg - dimensions = (number_of_latitudes_in_ozone_data) - type = real - kind = kind_phys - intent = in -[dlat] - standard_name = latitude_in_degree - long_name = latitude in degree north - units = degree_north - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[jindx1] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = out -[jindx2] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = out -[ddy] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = ozphys_2015_timestep_init - type = scheme -[nPts] - standard_name = horizontal_dimension - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[idate] - standard_name = date_and_time_at_model_initialization_in_united_states_order - long_name = initial date with different size and ordering - units = none - dimensions = (4) - type = integer - intent = in -[fhour] - standard_name = forecast_time - long_name = current forecast time - units = h - dimensions = () - type = real - kind = kind_phys - intent = in -[jindx1] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[jindx2] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data - units = count - dimensions = () - type = integer - intent = in -[levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data - units = count - dimensions = () - type = integer - intent = in -[oz_coeff] - standard_name = number_of_coefficients_in_ozone_data - long_name = number of coefficients in ozone data - units = count - dimensions = () - type = integer - intent = in -[timeoz] - standard_name = number_of_times_in_ozone_data - long_name = number of times in ozone data - units = count - dimensions = () - type = integer - intent = in -[ozplin] - standard_name = ozone_data - long_name = ozone data - units = 1 - dimensions = (number_of_latitudes_in_ozone_data,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data,number_of_times_in_ozone_data) - type = real - kind = kind_phys - intent = in -[oz_time] - standard_name = ozone_data_time - long_name = ozone data time - units = none - dimensions = (13) - type = real - kind = kind_phys - intent = in -[oz_lat] - standard_name = ozone_data_latitude - long_name = ozone data latitude - units = deg - dimensions = (number_of_latitudes_in_ozone_data) - type = real - kind = kind_phys - intent = in -[ddy] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[ozplout] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - ######################################################################## [ccpp-arg-table] name = ozphys_2015_run @@ -271,7 +68,7 @@ type = real kind = kind_phys intent = in -[prdout] +[oz_data] standard_name = ozone_forcing long_name = ozone forcing data units = mixed diff --git a/physics/ozphys_time_vary.F90 b/physics/ozphys_time_vary.F90 new file mode 100644 index 000000000..5b36f88b9 --- /dev/null +++ b/physics/ozphys_time_vary.F90 @@ -0,0 +1,177 @@ +! ########################################################################################### +!> \file ozphys_time_vary.F90 +!! +! ########################################################################################### +module ozphys_time_vary + use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec + implicit none + public ozphys_time_vary_init, ozphys_time_vary_timestep_init +contains + +! ########################################################################################### +!>\defgroup GFS Ozone Photochemistry (2015) Module +!! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. +!> @{ +!> \section arg_table_ozphys_time_vary_init Argument Table +!! \htmlinclude ozphys_time_vary_init.html +!! +! ########################################################################################### + subroutine ozphys_time_vary_init(oz_phys, nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & + ddy, errmsg, errflg) + ! Inputs + logical, intent(in) :: & + oz_phys ! Control flag for NRL ozone scheme + integer, intent(in) :: & + nPts, & ! Horizontal dimension + latsozp ! Number of latitudes in ozone data + real(kind_phys), intent(in), dimension(:) :: & + oz_lat, & ! Latitudes of ozone data + dlat ! Latitudes of grid + ! Outputs + integer, intent(inout), dimension(:) :: & + jindx1, & ! Interpolation index (low) for ozone data + jindx2 ! Interpolation index (high) for ozone data + real(kind_phys), intent(inout), dimension(:) :: & + ddy ! Interpolation high index for ozone data + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local + integer i,j + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Sanity check + if (.not.oz_phys) then + write (errmsg,'(*(a))') 'Logic error: oz_phys == .false.' + errflg = 1 + return + endif + + ! Set indices + do j=1,nPts + jindx2(j) = latsozp + 1 + do i=1,latsozp + if (dlat(j) < oz_lat(i)) then + jindx2(j) = i + exit + endif + enddo + jindx1(j) = max(jindx2(j)-1,1) + jindx2(j) = min(jindx2(j),latsozp) + if (jindx2(j) .ne. jindx1(j)) then + ddy(j) = (dlat(j) - oz_lat(jindx1(j))) / (oz_lat(jindx2(j)) - oz_lat(jindx1(j))) + else + ddy(j) = 1.0 + endif + enddo + + end subroutine ozphys_time_vary_init + +! ########################################################################################### +!> \section arg_table_ozphys_time_vary_timestep_init Argument Table +!! \htmlinclude ozphys_time_vary_timestep_init.html +!! +! ########################################################################################### + subroutine ozphys_time_vary_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp, & + levozp, oz_coeff, timeoz, ozplin, oz_time, oz_lat, ddy, oz_data, errmsg, errflg) + ! Inputs + integer, intent(in) :: & + nPts, & ! Horizontal dimension + latsozp, & ! Number of latitudes in ozone data + levozp, & ! Number of vertical layers in ozone data + oz_coeff, & ! Number of coefficients in ozone data + timeoz ! Number of times in ozone data + integer, intent(in),dimension(:) :: & + idate, & ! Initial date with different size and ordering + jindx1, & ! Interpolation index (low) for ozone + jindx2 ! Interpolation index (high) for ozone + real(kind_phys), intent(in) :: & + fhour ! Forecast hour + real(kind_phys), intent(in), dimension(:) :: & + ddy, & ! Interpolation high index for ozone data + oz_lat, & ! Latitudes for ozone data + oz_time ! Time for ozone data + real(kind_phys), intent(in), dimension(:,:,:,:) :: & + ozplin ! Ozone data + + ! Outputs + real(kind_phys), intent(inout), dimension(:,:,:) :: & + oz_data ! Ozone forcing data + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local + integer :: idat(8),jdat(8),iday,j,j1,j2,l,nc,n1,n2,jdow,jdoy,& + jday,w3kindreal,w3kindint + real(kind_phys) :: tem, tx1, tx2, rjday + real(8) :: rinc(5) + real(4) :: rinc4(5) + !real(kind_dbl_prec) :: rinc(5) + !real(kind_sngl_prec) :: rinc4(5) + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! + idat=0 + idat(1)=idate(4) + idat(2)=idate(2) + idat(3)=idate(3) + idat(5)=idate(1) + rinc=0. + rinc(2)=fhour + call w3kind(w3kindreal,w3kindint) + if(w3kindreal==4) then + rinc4=rinc + CALL w3movdat(rinc4,idat,jdat) + else + CALL w3movdat(rinc,idat,jdat) + endif + ! + jdow = 0 + jdoy = 0 + jday = 0 + call w3doxdat(jdat,jdow,jdoy,jday) + rjday = jdoy + jdat(5) / 24. + IF (RJDAY < oz_time(1)) RJDAY = RJDAY + 365. + ! + n2 = timeoz + 1 + do j=2,timeoz + if (rjday < oz_time(j)) then + n2 = j + exit + endif + enddo + n1 = n2 - 1 + + tx1 = (oz_time(n2) - rjday) / (oz_time(n2) - oz_time(n1)) + tx2 = 1.0 - tx1 + + if (n2 > timeoz) n2 = n2 - timeoz + ! + do nc=1,oz_coeff + do L=1,levozp + do J=1,npts + J1 = jindx1(J) + J2 = jindx2(J) + TEM = 1.0 - ddy(J) + oz_data(j,L,nc) = tx1*(TEM*ozplin(J1,L,nc,n1)+ddy(J)*ozplin(J2,L,nc,n1)) & + + tx2*(TEM*ozplin(J1,L,nc,n2)+ddy(J)*ozplin(J2,L,nc,n2)) + enddo + enddo + enddo + + ! + return + + end subroutine ozphys_time_vary_timestep_init +!> @} +end module ozphys_time_vary diff --git a/physics/ozphys_time_vary.meta b/physics/ozphys_time_vary.meta new file mode 100644 index 000000000..93aa4a3b0 --- /dev/null +++ b/physics/ozphys_time_vary.meta @@ -0,0 +1,207 @@ +[ccpp-table-properties] + name = ozphys_time_vary + type = scheme + dependencies = machine.F + +######################################################################## +[ccpp-arg-table] + name = ozphys_time_vary_init + type = scheme +[nPts] + standard_name = horizontal_dimension + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in +[oz_phys] + standard_name = flag_for_nrl_2015_ozone_scheme + long_name = flag for new (2015) ozone physics + units = flag + dimensions = () + type = logical + intent = in +[oz_lat] + standard_name = ozone_data_latitude + long_name = ozone data latitude + units = deg + dimensions = (number_of_latitudes_in_ozone_data) + type = real + kind = kind_phys + intent = in +[dlat] + standard_name = latitude_in_degree + long_name = latitude in degree north + units = degree_north + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[jindx1] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[jindx2] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[ddy] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = ozphys_time_vary_timestep_init + type = scheme +[nPts] + standard_name = horizontal_dimension + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[idate] + standard_name = date_and_time_at_model_initialization_in_united_states_order + long_name = initial date with different size and ordering + units = none + dimensions = (4) + type = integer + intent = in +[fhour] + standard_name = forecast_time + long_name = current forecast time + units = h + dimensions = () + type = real + kind = kind_phys + intent = in +[jindx1] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[jindx2] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[latsozp] + standard_name = number_of_latitudes_in_ozone_data + long_name = number of latitude in ozone data + units = count + dimensions = () + type = integer + intent = in +[levozp] + standard_name = number_of_levels_in_ozone_data + long_name = number of levels in ozone data + units = count + dimensions = () + type = integer + intent = in +[oz_coeff] + standard_name = number_of_coefficients_in_ozone_data + long_name = number of coefficients in ozone data + units = count + dimensions = () + type = integer + intent = in +[timeoz] + standard_name = number_of_times_in_ozone_data + long_name = number of times in ozone data + units = count + dimensions = () + type = integer + intent = in +[ozplin] + standard_name = ozone_data + long_name = ozone data + units = 1 + dimensions = (number_of_latitudes_in_ozone_data,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data,number_of_times_in_ozone_data) + type = real + kind = kind_phys + intent = in +[oz_time] + standard_name = ozone_data_time + long_name = ozone data time + units = none + dimensions = (13) + type = real + kind = kind_phys + intent = in +[oz_lat] + standard_name = ozone_data_latitude + long_name = ozone data latitude + units = deg + dimensions = (number_of_latitudes_in_ozone_data) + type = real + kind = kind_phys + intent = in +[ddy] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[oz_data] + standard_name = ozone_forcing + long_name = ozone forcing data + units = mixed + dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out From 0bfac2ac51d8c460b84cc49fd5240407bcaea6ba Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 2 Aug 2023 17:03:36 +0000 Subject: [PATCH 39/58] Some cleanup. Now working --- physics/GFS_rrtmg_pre.F90 | 2 +- physics/ozphys_2015.F90 | 52 +++++++++++++++++++++++++++++++---- physics/ozphys_2015.meta | 34 +++++++++++++++++++++++ physics/ozphys_time_vary.F90 | 22 ++++----------- physics/ozphys_time_vary.meta | 7 ----- 5 files changed, 87 insertions(+), 30 deletions(-) diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 4a2c3b290..f2183919f 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -44,7 +44,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_o2, gasvmr_co, gasvmr_cfc11, gasvmr_cfc12, gasvmr_cfc22, & gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & - faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, rrfs_sd & + faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, rrfs_sd, & aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, latsozc, levozc, & blatc, dphiozc, errmsg, errflg) diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 82ade0cbd..110ba02e2 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -5,7 +5,7 @@ module ozphys_2015 use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec implicit none - public ozphys_2015_run + public ozphys_2015_init, ozphys_2015_run contains ! ########################################################################################### @@ -17,8 +17,6 @@ module ozphys_2015 !! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval !! Research Laboratory through CHEM2D chemistry model !! (McCormack et al. (2006) \cite mccormack_et_al_2006). -!! \section arg_table_ozphys_2015_run Argument Table -!! \htmlinclude ozphys_2015_run.html !! !> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm !> - This code assumes that both prsl and po3 are from bottom to top @@ -28,13 +26,50 @@ module ozphys_2015 !!\author June 2015 - Shrinivas Moorthi !!\modified May 2023 - Dustin Swales ! ########################################################################################### - subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, pl_coeff, & - delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & + +! ########################################################################################### +! SUBROUTINE ozphys_2015_init +! ########################################################################################### +!! \section arg_table_ozphys_2015_init Argument Table +!! \htmlinclude ozphys_2015_init.html +!! + subroutine ozphys_2015_init(oz_phys, errmsg, errflg) + ! Inputs + logical, intent(in) :: & + oz_phys + ! Outputs + character(len=*), intent(out) :: & + errmsg + integer, intent(out) :: & + errflg + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Sanity check + if (.not.oz_phys) then + write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' + errflg = 1 + return + endif + + end subroutine ozphys_2015_init + +! ########################################################################################### +! SUBROUTINE ozphys_2015_run +! ########################################################################################### +!! \section arg_table_ozphys_2015_run Argument Table +!! \htmlinclude ozphys_2015_run.html +!! + subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, & + pl_coeff, delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & index_of_process_ozmix, index_of_process_temp, index_of_process_overhead_ozone, & con_g, errmsg, errflg) ! Inputs logical, intent(in) :: & + oz_phys, & ! ldiag3d ! Flag to output GFS diagnostic tendencies real(kind_phys),intent(in) :: & con_g ! Physical constant: Gravitational acceleration (ms-2) @@ -88,6 +123,13 @@ subroutine ozphys_2015_run ( im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, pl_ errmsg = '' errflg = 0 + ! Sanity checkt + if (.not.oz_phys) then + write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' + errflg = 1 + return + endif + ! Are UFS diagnostic tendencies requested? If so, set up bookeeping indices... if(ldiag3d) then idtend(1) = dtidx(100+ntoz,index_of_process_prod_loss) ! was ozp1 diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index ea82defaa..4b19f2c04 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -3,10 +3,44 @@ type = scheme dependencies = machine.F +######################################################################## +[ccpp-arg-table] + name = ozphys_2015_init + type = scheme +[oz_phys] + standard_name = flag_for_nrl_2015_ozone_scheme + long_name = flag for new (2015) ozone physics + units = flag + dimensions = () + type = logical + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + ######################################################################## [ccpp-arg-table] name = ozphys_2015_run type = scheme +[oz_phys] + standard_name = flag_for_nrl_2015_ozone_scheme + long_name = flag for new (2015) ozone physics + units = flag + dimensions = () + type = logical + intent = in [im] standard_name = horizontal_loop_extent long_name = horizontal loop extent diff --git a/physics/ozphys_time_vary.F90 b/physics/ozphys_time_vary.F90 index 5b36f88b9..a0a778c36 100644 --- a/physics/ozphys_time_vary.F90 +++ b/physics/ozphys_time_vary.F90 @@ -9,18 +9,16 @@ module ozphys_time_vary contains ! ########################################################################################### -!>\defgroup GFS Ozone Photochemistry (2015) Module -!! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. +!>\defgroup GFS Ozone Data Module +!! This module updates the ozone data used by physics. !> @{ !> \section arg_table_ozphys_time_vary_init Argument Table !! \htmlinclude ozphys_time_vary_init.html !! ! ########################################################################################### - subroutine ozphys_time_vary_init(oz_phys, nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & + subroutine ozphys_time_vary_init(nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & ddy, errmsg, errflg) ! Inputs - logical, intent(in) :: & - oz_phys ! Control flag for NRL ozone scheme integer, intent(in) :: & nPts, & ! Horizontal dimension latsozp ! Number of latitudes in ozone data @@ -44,13 +42,6 @@ subroutine ozphys_time_vary_init(oz_phys, nPts, latsozp, oz_lat, dlat, jindx1, j ! Initialize CCPP error handling variables errmsg = '' errflg = 0 - - ! Sanity check - if (.not.oz_phys) then - write (errmsg,'(*(a))') 'Logic error: oz_phys == .false.' - errflg = 1 - return - endif ! Set indices do j=1,nPts @@ -111,10 +102,8 @@ subroutine ozphys_time_vary_timestep_init(nPts, idate, fhour, jindx1, jindx2, la integer :: idat(8),jdat(8),iday,j,j1,j2,l,nc,n1,n2,jdow,jdoy,& jday,w3kindreal,w3kindint real(kind_phys) :: tem, tx1, tx2, rjday - real(8) :: rinc(5) - real(4) :: rinc4(5) - !real(kind_dbl_prec) :: rinc(5) - !real(kind_sngl_prec) :: rinc4(5) + real(kind_dbl_prec) :: rinc(5) + real(kind_sngl_prec) :: rinc4(5) ! Initialize CCPP error handling variables errmsg = '' @@ -169,7 +158,6 @@ subroutine ozphys_time_vary_timestep_init(nPts, idate, fhour, jindx1, jindx2, la enddo enddo - ! return end subroutine ozphys_time_vary_timestep_init diff --git a/physics/ozphys_time_vary.meta b/physics/ozphys_time_vary.meta index 93aa4a3b0..75b8b8e4f 100644 --- a/physics/ozphys_time_vary.meta +++ b/physics/ozphys_time_vary.meta @@ -21,13 +21,6 @@ dimensions = () type = integer intent = in -[oz_phys] - standard_name = flag_for_nrl_2015_ozone_scheme - long_name = flag for new (2015) ozone physics - units = flag - dimensions = () - type = logical - intent = in [oz_lat] standard_name = ozone_data_latitude long_name = ozone data latitude From bea77c8dd21b60b8af7603e494aed45abcccec40 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 10 Aug 2023 17:32:59 +0000 Subject: [PATCH 40/58] More reorganization. --- physics/GFS_physics_diagnostics.F90 | 97 +++++++++++++++++++ physics/GFS_physics_diagnostics.meta | 140 +++++++++++++++++++++++++++ physics/ozphys_2015.F90 | 80 ++++++--------- physics/ozphys_2015.meta | 91 +++++++---------- physics/ozphys_time_vary.F90 | 4 +- physics/physcons.F90 | 1 + 6 files changed, 300 insertions(+), 113 deletions(-) create mode 100644 physics/GFS_physics_diagnostics.F90 create mode 100644 physics/GFS_physics_diagnostics.meta diff --git a/physics/GFS_physics_diagnostics.F90 b/physics/GFS_physics_diagnostics.F90 new file mode 100644 index 000000000..0c6197bc2 --- /dev/null +++ b/physics/GFS_physics_diagnostics.F90 @@ -0,0 +1,97 @@ +! ########################################################################################### +!> \file GFS_physics_diagnostics.F90 +!! +! ########################################################################################### +module GFS_physics_diagnostics + use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec + implicit none + public GFS_physics_diagnostics_init, GFS_physics_diagnostics_run +contains + +! ########################################################################################### +! SUBROUTINE GFS_physics_diagnostics_init +! ########################################################################################### +!! \section arg_table_GFS_physics_diagnostics_init Argument Table +!! \htmlinclude GFS_physics_diagnostics_init.html +!! + subroutine GFS_physics_diagnostics_init(errmsg, errflg) + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + end subroutine GFS_physics_diagnostics_init + +! ########################################################################################### +! SUBROUTINE GFS_physics_diagnostics_run +! ########################################################################################### +!! \section arg_table_GFS_physics_diagnostics_run Argument Table +!! \htmlinclude GFS_physics_diagnostics_run.html +!! + subroutine GFS_physics_diagnostics_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, & + ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, dtend,& + errmsg, errflg) + ! Inputs + integer, intent(in) :: & + nCol, & ! Horizontal dimension + nLev, & ! Number of vertical layers + ntoz, & ! Index for ozone mixing ratio + ip_prod_loss, & ! Index for process in diagnostic tendency output + ip_ozmix, & ! Index for process in diagnostic tendency output + ip_temp, & ! Index for process in diagnostic tendency output + ip_overhead_ozone ! Index for process in diagnostic tendency output + integer, intent(in), dimension(:,:) :: & + dtidx ! Bookkeeping indices for GFS diagnostic tendencies + + ! Inputs (optional) + real(kind=kind_phys), intent(in), dimension(:,:), pointer, optional :: & + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect + + ! Outputs + real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & + dtend ! Diagnostic tendencies for state variables + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Locals + integer :: idtend + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! ####################################################################################### + ! + ! Ozone physics diagnostics + ! + ! ####################################################################################### + idtend = dtidx(100+ntoz,ip_prod_loss) + if (idtend >= 1 .and. associated(do3_dt_prd)) then + dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_prd + endif + ! + idtend = dtidx(100+ntoz,ip_ozmix) + if (idtend >= 1 .and. associated(do3_dt_ozmx)) then + dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_ozmx + endif + ! + idtend = dtidx(100+ntoz,ip_temp) + if (idtend >= 1 .and. associated(do3_dt_temp)) then + dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_temp + endif + ! + idtend = dtidx(100+ntoz,ip_overhead_ozone) + if (idtend >= 1 .and. associated(do3_dt_ohoz)) then + dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_ohoz + endif + + end subroutine GFS_physics_diagnostics_run + +end module GFS_physics_diagnostics diff --git a/physics/GFS_physics_diagnostics.meta b/physics/GFS_physics_diagnostics.meta new file mode 100644 index 000000000..b6036b0c9 --- /dev/null +++ b/physics/GFS_physics_diagnostics.meta @@ -0,0 +1,140 @@ +[ccpp-table-properties] + name = GFS_physics_diagnostics + type = scheme + dependencies = machine.F + +######################################################################## +[ccpp-arg-table] + name = GFS_physics_diagnostics_init + type = scheme +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = GFS_physics_diagnostics_run + type = scheme +[nCol] + standard_name = horizontal_loop_extent + long_name = horizontal loop extent + units = count + dimensions = () + type = integer + intent = in +[nLev] + standard_name = vertical_layer_dimension + long_name = number of vertical layers + units = count + dimensions = () + type = integer + intent = in +[dtend] + standard_name = cumulative_change_of_state_variables + long_name = diagnostic tendencies for state variables + units = mixed + dimensions = (horizontal_loop_extent,vertical_layer_dimension,cumulative_change_of_state_variables_outer_index_max) + type = real + kind = kind_phys + intent = inout +[dtidx] + standard_name = cumulative_change_of_state_variables_outer_index + long_name = index of state-variable and process in last dimension of diagnostic tendencies array AKA cumulative_change_index + units = index + dimensions = (number_of_tracers_plus_one_hundred,number_of_cumulative_change_processes) + type = integer + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in +[ip_prod_loss] + standard_name = index_of_production_and_loss_process_in_cumulative_change_index + long_name = index of production and loss effect in photochemistry process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[ip_ozmix] + standard_name = index_of_ozone_mixing_ratio_process_in_cumulative_change_index + long_name = index of ozone mixing ratio effect in photochemistry process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[ip_temp] + standard_name = index_of_temperature_process_in_cumulative_change_index + long_name = index of temperature effect in photochemistry process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[ip_overhead_ozone] + standard_name = index_of_overhead_process_in_cumulative_change_index + long_name = index of overhead ozone effect in photochemistry process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[do3_dt_prd] + standard_name = ozone_tendency_due_to_production_and_loss_rate + long_name = ozone tendency due to production and loss rate + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[do3_dt_ozmx] + standard_name = ozone_tendency_due_to_ozone_mixing_ratio + long_name = ozone tendency due to ozone mixing ratio + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[do3_dt_temp] + standard_name = ozone_tendency_due_to_temperature + long_name = ozone tendency due to temperature + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[do3_dt_ohoz] + standard_name = ozone_tendency_due_to_overhead_ozone_column + long_name = ozone tendency due to overhead ozone column + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out \ No newline at end of file diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 110ba02e2..9898c71e4 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -63,42 +63,35 @@ end subroutine ozphys_2015_init !! \htmlinclude ozphys_2015_run.html !! subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, & - pl_coeff, delp, ldiag3d, dtend, dtidx, ntoz, index_of_process_prod_loss, & - index_of_process_ozmix, index_of_process_temp, index_of_process_overhead_ozone, & - con_g, errmsg, errflg) + pl_coeff, delp, con_1ovg, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, errmsg, errflg) ! Inputs logical, intent(in) :: & - oz_phys, & ! - ldiag3d ! Flag to output GFS diagnostic tendencies + oz_phys ! Flag for ozone_physics_2015 scheme. real(kind_phys),intent(in) :: & - con_g ! Physical constant: Gravitational acceleration (ms-2) + con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) integer, intent(in) :: & - im, & ! Horizontal dimension - levs, & ! Number of vertical layers - ko3, & ! Number of vertical layers in ozone forcing data - pl_coeff, & ! Number of coefficients in ozone forcing data - ntoz, & ! Index for ozone mixing ratio - index_of_process_prod_loss, & ! Index for process in diagnostic tendency output - index_of_process_ozmix, & ! Index for process in diagnostic tendency output - index_of_process_temp, & ! Index for process in diagnostic tendency output - index_of_process_overhead_ozone ! Index for process in diagnostic tendency output - integer, intent(in), dimension(:,:) :: & - dtidx ! Bookkeeping indices for GFS diagnostic tendencies + im, & ! Horizontal dimension + levs, & ! Number of vertical layers + ko3, & ! Number of vertical layers in ozone forcing data + pl_coeff ! Number of coefficients in ozone forcing data real(kind_phys), intent(in) :: & - dt ! Physics timestep (seconds) + dt ! Physics timestep (seconds) real(kind_phys), intent(in), dimension(:) :: & - po3 ! Natural log of ozone forcing data pressure levels + po3 ! Natural log of ozone forcing data pressure levels real(kind_phys), intent(in), dimension(:,:) :: & - prsl, & ! Air-pressure (Pa) - tin, & ! Temperature of new-state (K) - delp ! Difference between mid-layer pressures (Pa) + prsl, & ! Air-pressure (Pa) + tin, & ! Temperature of new-state (K) + delp ! Difference between mid-layer pressures (Pa) real(kind_phys), intent(in), dimension(:,:,:) :: & - oz_data ! Ozone forcing data + oz_data ! Ozone forcing data - ! In/Outs - real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & - dtend ! Diagnostic tendencies for state variables + ! Outputs (optional) + real(kind=kind_phys), intent(inout), dimension(:,:), pointer, optional :: & + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect ! Outputs real(kind=kind_phys), intent(inout), dimension(:,:) :: & @@ -110,9 +103,7 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d ! Locals integer :: k, kmax, kmin, l, i, j - integer, dimension(4) :: idtend logical, dimension(im) :: flg - real :: gravi real(kind_phys) :: pmax, pmin, tem, temp real(kind_phys), dimension(im) :: wk1, wk2, wk3, ozib real(kind_phys), dimension(im,pl_coeff) :: prod @@ -130,19 +121,8 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d return endif - ! Are UFS diagnostic tendencies requested? If so, set up bookeeping indices... - if(ldiag3d) then - idtend(1) = dtidx(100+ntoz,index_of_process_prod_loss) ! was ozp1 - idtend(2) = dtidx(100+ntoz,index_of_process_ozmix) ! was ozp2 - idtend(3) = dtidx(100+ntoz,index_of_process_temp) ! was ozp3 - idtend(4) = dtidx(100+ntoz,index_of_process_overhead_ozone) ! was ozp4 - else - idtend=0 - endif - ! Temporaries ozi = oz - gravi=1.0/con_g colo3(:,levs+1) = 0.0 coloz(:,levs+1) = 0.0 @@ -194,8 +174,8 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d enddo enddo do i=1,im - colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*gravi - coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*gravi + colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*con_1ovg + coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*con_1ovg prod(i,2) = min(prod(i,2), 0.0) enddo do i=1,im @@ -204,18 +184,12 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d + prod(i,4) * (colo3(i,l)-coloz(i,l)) oz(i,l) = (ozib(i) + tem*dt) / (1.0 - prod(i,2)*dt) enddo - if(idtend(1)>=1) then - dtend(:,l,idtend(1)) = dtend(:,l,idtend(1)) + (prod(:,1)-prod(:,2)*prod(:,6))*dt - endif - if(idtend(2)>=1) then - dtend(:,l,idtend(2)) = dtend(:,l,idtend(2)) + (oz(:,l) - ozib(:)) - endif - if(idtend(3)>=1) then - dtend(:,l,idtend(3)) = dtend(:,l,idtend(3)) + prod(:,3)*(tin(:,l)-prod(:,5))*dt - endif - if(idtend(4)>=1) then - dtend(:,l,idtend(4)) = dtend(:,l,idtend(4)) + prod(:,4) * (colo3(:,l)-coloz(:,l))*dt - endif + + ! Diagnostics (optional) + if (associated(do3_dt_prd)) do3_dt_prd(:,l) = (prod(:,1)-prod(:,2)*prod(:,6))*dt + if (associated(do3_dt_ozmx)) do3_dt_ozmx(:,l) = (oz(:,l) - ozib(:)) + if (associated(do3_dt_temp)) do3_dt_temp(:,l) = prod(:,3)*(tin(:,l)-prod(:,5))*dt + if (associated(do3_dt_ohoz)) do3_dt_ohoz(:,l) = prod(:,4) * (colo3(:,l)-coloz(:,l))*dt enddo return diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index 4b19f2c04..1d8fba74e 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -125,71 +125,46 @@ type = real kind = kind_phys intent = in -[ldiag3d] - standard_name = flag_for_diagnostics_3D - long_name = flag for calculating 3-D diagnostic fields - units = flag +[con_1ovg] + standard_name = one_divided_by_the_gravitational_acceleration + long_name = inverse of gravitational acceleration + units = s2 m-1 dimensions = () - type = logical + type = real + kind = kind_phys intent = in -[dtend] - standard_name = cumulative_change_of_state_variables - long_name = diagnostic tendencies for state variables - units = mixed - dimensions = (horizontal_loop_extent,vertical_layer_dimension,cumulative_change_of_state_variables_outer_index_max) +[do3_dt_prd] + standard_name = ozone_tendency_due_to_production_and_loss_rate + long_name = ozone tendency due to production and loss rate + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = inout -[dtidx] - standard_name = cumulative_change_of_state_variables_outer_index - long_name = index of state-variable and process in last dimension of diagnostic tendencies array AKA cumulative_change_index - units = index - dimensions = (number_of_tracers_plus_one_hundred,number_of_cumulative_change_processes) - type = integer - intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in -[index_of_process_prod_loss] - standard_name = index_of_production_and_loss_process_in_cumulative_change_index - long_name = index of production and loss effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_ozmix] - standard_name = index_of_ozone_mixing_ratio_process_in_cumulative_change_index - long_name = index of ozone mixing ratio effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_temp] - standard_name = index_of_temperature_process_in_cumulative_change_index - long_name = index of temperature effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_overhead_ozone] - standard_name = index_of_overhead_process_in_cumulative_change_index - long_name = index of overhead ozone effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[con_g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () +[do3_dt_ozmx] + standard_name = ozone_tendency_due_to_ozone_mixing_ratio + long_name = ozone tendency due to ozone mixing ratio + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = in + intent = inout +[do3_dt_temp] + standard_name = ozone_tendency_due_to_temperature + long_name = ozone tendency due to temperature + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[do3_dt_ohoz] + standard_name = ozone_tendency_due_to_overhead_ozone_column + long_name = ozone tendency due to overhead ozone column + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/ozphys_time_vary.F90 b/physics/ozphys_time_vary.F90 index a0a778c36..ddac1dcd4 100644 --- a/physics/ozphys_time_vary.F90 +++ b/physics/ozphys_time_vary.F90 @@ -16,8 +16,8 @@ module ozphys_time_vary !! \htmlinclude ozphys_time_vary_init.html !! ! ########################################################################################### - subroutine ozphys_time_vary_init(nPts, latsozp, oz_lat, dlat, jindx1, jindx2, & - ddy, errmsg, errflg) + subroutine ozphys_time_vary_init(nPts, latsozp, oz_lat, dlat, jindx1, jindx2, ddy, & + errmsg, errflg) ! Inputs integer, intent(in) :: & nPts, & ! Horizontal dimension diff --git a/physics/physcons.F90 b/physics/physcons.F90 index e7ec8fb77..19a03ef20 100644 --- a/physics/physcons.F90 +++ b/physics/physcons.F90 @@ -97,6 +97,7 @@ module physcons real(kind=kind_phys),parameter:: con_dldt =con_cvap-con_cliq real(kind=kind_phys),parameter:: con_xpona =-con_dldt/con_rv real(kind=kind_phys),parameter:: con_xponb =-con_dldt/con_rv+con_hvap/(con_rv*con_ttp) + real(kind=kind_phys),parameter:: con_1ovg = 1._kind_phys/con_g !> \name Other Physics/Chemistry constants (source: 2002 CODATA) real(kind=kind_phys),parameter:: con_c =2.99792458e+8_kind_phys !< speed of light (\f$m/s\f$) From 26ca9f9c3d08aa5ddc5cb414c1a0377d1fb5fae2 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 6 Sep 2023 10:57:28 -0600 Subject: [PATCH 41/58] Renamed file --- ...s_diagnostics.F90 => GFS_physics_post.F90} | 30 +++++++++---------- ...diagnostics.meta => GFS_physics_post.meta} | 6 ++-- physics/ozphys_2015.F90 | 1 + 3 files changed, 19 insertions(+), 18 deletions(-) rename physics/{GFS_physics_diagnostics.F90 => GFS_physics_post.F90} (81%) rename physics/{GFS_physics_diagnostics.meta => GFS_physics_post.meta} (97%) diff --git a/physics/GFS_physics_diagnostics.F90 b/physics/GFS_physics_post.F90 similarity index 81% rename from physics/GFS_physics_diagnostics.F90 rename to physics/GFS_physics_post.F90 index 0c6197bc2..d034c1999 100644 --- a/physics/GFS_physics_diagnostics.F90 +++ b/physics/GFS_physics_post.F90 @@ -1,20 +1,20 @@ ! ########################################################################################### -!> \file GFS_physics_diagnostics.F90 +!> \file GFS_physics_post.F90 !! ! ########################################################################################### -module GFS_physics_diagnostics +module GFS_physics_post use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec implicit none - public GFS_physics_diagnostics_init, GFS_physics_diagnostics_run + public GFS_physics_post_init, GFS_physics_post_run contains ! ########################################################################################### -! SUBROUTINE GFS_physics_diagnostics_init +! SUBROUTINE GFS_physics_post_init ! ########################################################################################### -!! \section arg_table_GFS_physics_diagnostics_init Argument Table -!! \htmlinclude GFS_physics_diagnostics_init.html +!! \section arg_table_GFS_physics_post_init Argument Table +!! \htmlinclude GFS_physics_post_init.html !! - subroutine GFS_physics_diagnostics_init(errmsg, errflg) + subroutine GFS_physics_post_init(errmsg, errflg) ! Outputs character(len=*), intent(out) :: & @@ -22,15 +22,15 @@ subroutine GFS_physics_diagnostics_init(errmsg, errflg) integer, intent(out) :: & errflg ! CCPP error flag - end subroutine GFS_physics_diagnostics_init + end subroutine GFS_physics_post_init ! ########################################################################################### -! SUBROUTINE GFS_physics_diagnostics_run +! SUBROUTINE GFS_physics_post_run ! ########################################################################################### -!! \section arg_table_GFS_physics_diagnostics_run Argument Table -!! \htmlinclude GFS_physics_diagnostics_run.html +!! \section arg_table_GFS_physics_post_run Argument Table +!! \htmlinclude GFS_physics_post_run.html !! - subroutine GFS_physics_diagnostics_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, & + subroutine GFS_physics_post_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, & ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, dtend,& errmsg, errflg) ! Inputs @@ -69,7 +69,7 @@ subroutine GFS_physics_diagnostics_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip ! ####################################################################################### ! - ! Ozone physics diagnostics + ! Ozone physics diagnostic ! ! ####################################################################################### idtend = dtidx(100+ntoz,ip_prod_loss) @@ -92,6 +92,6 @@ subroutine GFS_physics_diagnostics_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_ohoz endif - end subroutine GFS_physics_diagnostics_run + end subroutine GFS_physics_post_run -end module GFS_physics_diagnostics +end module GFS_physics_post diff --git a/physics/GFS_physics_diagnostics.meta b/physics/GFS_physics_post.meta similarity index 97% rename from physics/GFS_physics_diagnostics.meta rename to physics/GFS_physics_post.meta index b6036b0c9..8b5120b9e 100644 --- a/physics/GFS_physics_diagnostics.meta +++ b/physics/GFS_physics_post.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = GFS_physics_diagnostics + name = GFS_physics_post type = scheme dependencies = machine.F ######################################################################## [ccpp-arg-table] - name = GFS_physics_diagnostics_init + name = GFS_physics_post_init type = scheme [errmsg] standard_name = ccpp_error_message @@ -25,7 +25,7 @@ ######################################################################## [ccpp-arg-table] - name = GFS_physics_diagnostics_run + name = GFS_physics_post_run type = scheme [nCol] standard_name = horizontal_loop_extent diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 9898c71e4..47386bd6e 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -17,6 +17,7 @@ module ozphys_2015 !! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval !! Research Laboratory through CHEM2D chemistry model !! (McCormack et al. (2006) \cite mccormack_et_al_2006). +!! (https://doi.org/10.5194/acp-6-4943-2006) !! !> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm !> - This code assumes that both prsl and po3 are from bottom to top From c0ec619536bd29740627cb2dc1da106b61dd435c Mon Sep 17 00:00:00 2001 From: Michael Toy Date: Tue, 19 Sep 2023 02:36:14 +0000 Subject: [PATCH 42/58] Added tendency limiter for mesosphere and horizontal wave number filter for orographic gravity wave drag in UGWP -- Issue #95 --- physics/drag_suite.F90 | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/physics/drag_suite.F90 b/physics/drag_suite.F90 index 22f122e71..ff68f4216 100644 --- a/physics/drag_suite.F90 +++ b/physics/drag_suite.F90 @@ -460,6 +460,8 @@ subroutine drag_suite_run( & real(kind=kind_phys), parameter :: ce = 0.8 real(kind=kind_phys), parameter :: cg = 0.5 real(kind=kind_phys), parameter :: sgmalolev = 0.5 ! max sigma lvl for dtfac + real(kind=kind_phys), parameter :: plolevmeso = 70.0 ! pres lvl for mesosphere OGWD reduction (Pa) + real(kind=kind_phys), parameter :: facmeso = 0.5 ! fractional velocity reduction for OGWD integer,parameter :: kpblmin = 2 ! @@ -472,7 +474,7 @@ subroutine drag_suite_run( & rcsks,wdir,ti,rdz,tem2,dw2,shr2, & bvf2,rdelks,wtkbj,tem,gfobnv,hd,fro, & rim,temc,tem1,efact,temv,dtaux,dtauy, & - dtauxb,dtauyb,eng0,eng1 + dtauxb,dtauyb,eng0,eng1,ksmax,dtfac_meso ! logical :: ldrag(im),icrilv(im), & flag(im),kloop1(im) @@ -887,6 +889,14 @@ subroutine drag_suite_run( & ldrag(i) = ldrag(i) .or. bnv2(i,1).le.0.0 ldrag(i) = ldrag(i) .or. ulow(i).eq.1.0 ldrag(i) = ldrag(i) .or. var_stoch(i) .le. 0.0 +! Check if mesoscale gravity waves will propagate vertically or be evanescent +! and not impart a drag force -- consider the maximum sub-grid horizontal +! topographic wavelength to be one-half the horizontal grid spacing -- calculate +! ksmax accordingly + ksmax = 4.0*pi/dx(i) ! based on wavelength = 0.5*dx(i) + if ( bnv2(i,1).gt.0.0 ) then + ldrag(i) = ldrag(i) .or. sqrt(bnv2(i,1))*rulow(i).lt.ksmax + endif ! ! set all ri low level values to the low level value ! @@ -1106,7 +1116,19 @@ subroutine drag_suite_run( & enddo ! do k = kts,km - taud_ms(i,k) = taud_ms(i,k)*dtfac(i)* ls_taper(i) *(1.-rstoch(i)) + + ! Check if well into mesosphere -- if so, perform similar reduction of + ! velocity tendency due to mesoscale GWD to prevent sudden reversal of + ! wind direction (similar to above) + dtfac_meso = 1.0 + if (prsl(i,k).le.plolevmeso) then + if (taud_ms(i,k).ne.0.) & + dtfac_meso = min(dtfac_meso,facmeso*abs(velco(i,k) & + /(deltim*rcs*taud_ms(i,k)))) + end if + + taud_ms(i,k) = taud_ms(i,k)*dtfac(i)*dtfac_meso* & + ls_taper(i) *(1.-rstoch(i)) taud_bl(i,k) = taud_bl(i,k)*dtfac(i)* ls_taper(i) *(1.-rstoch(i)) dtaux = taud_ms(i,k) * xn(i) From a110a5b93bce92bab083fdaa07bd21ba5cae8720 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 14:04:50 -0600 Subject: [PATCH 43/58] Getting real close... --- physics/GFS_phys_time_vary.fv3.F90 | 105 ++++-- physics/GFS_phys_time_vary.fv3.meta | 83 ++++- physics/GFS_rrtmg_pre.F90 | 19 +- physics/GFS_rrtmg_pre.meta | 39 +-- physics/GFS_rrtmg_setup.F90 | 26 +- physics/GFS_rrtmg_setup.meta | 30 +- physics/GFS_rrtmgp_pre.F90 | 22 +- physics/GFS_rrtmgp_pre.meta | 35 +- physics/GFS_rrtmgp_setup.F90 | 20 +- physics/GFS_rrtmgp_setup.meta | 30 +- physics/module_ozphys.F90 | 476 ++++++++++++++++++++++++++++ physics/module_ozphys.meta | 24 ++ physics/ozphys_2015.F90 | 126 +++----- physics/ozphys_2015.meta | 62 +--- physics/ozphys_time_vary.F90 | 165 ---------- physics/ozphys_time_vary.meta | 200 ------------ physics/radiation_gases.f | 313 ++---------------- physics/rrtmgp_lw_main.F90 | 1 - 18 files changed, 815 insertions(+), 961 deletions(-) create mode 100644 physics/module_ozphys.F90 create mode 100644 physics/module_ozphys.meta delete mode 100644 physics/ozphys_time_vary.F90 delete mode 100644 physics/ozphys_time_vary.meta diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index d82f22399..af2dd9b00 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -10,10 +10,12 @@ module GFS_phys_time_vary use omp_lib #endif - use machine, only : kind_phys + use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec use mersenne_twister, only: random_setseed, random_number + use module_ozphys, only: ty_ozphys + use h2o_def, only : levh2o, h2o_coeff, h2o_lat, h2o_pres, h2o_time, h2oplin use h2ointerp, only : read_h2odata, setindxh2o, h2ointerpol @@ -64,9 +66,9 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !> @{ subroutine GFS_phys_time_vary_init ( & - me, master, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & + me, master, ntoz, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & nx, ny, idate, xlat_d, xlon_d, & - jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & + jindx1_o3, jindx2_o3, ddy_o3, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, imap, jmap, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, & @@ -79,12 +81,12 @@ subroutine GFS_phys_time_vary_init ( smcwtdxy, deeprechxy, rechxy, snowxy, snicexy, snliqxy, tsnoxy , smoiseq, zsnsoxy, & slc, smc, stc, tsfcl, snowd, canopy, tg3, stype, con_t0c, lsm_cold_start, nthrds, & lkm, use_lake_model, lakefrac, lakedepth, iopt_lake, iopt_lake_clm, iopt_lake_flake, & - lakefrac_threshold, lakedepth_threshold, errmsg, errflg) + lakefrac_threshold, lakedepth_threshold, ozphys, errmsg, errflg) implicit none ! Interface variables - integer, intent(in) :: me, master, iccn, iflip, im, nx, ny, levs, iaermdl + integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs, iaermdl logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:), iopt_lake, iopt_lake_clm, iopt_lake_flake real(kind_phys), intent(in) :: fhour, lakefrac_threshold, lakedepth_threshold @@ -93,8 +95,8 @@ subroutine GFS_phys_time_vary_init ( integer, intent(in) :: lkm integer, intent(inout) :: use_lake_model(:) real(kind=kind_phys), intent(in ) :: lakefrac(:), lakedepth(:) - integer, intent(inout) :: jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(inout) :: ddy_h(:) + integer, intent(inout) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(inout) :: ddy_o3(:), ddy_h(:) real(kind_phys), intent(in) :: h2opl(:,:,:) integer, intent(inout) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) @@ -113,6 +115,7 @@ subroutine GFS_phys_time_vary_init ( real(kind_phys), intent(in) :: min_seaice, fice(:) real(kind_phys), intent(in) :: landfrac(:) real(kind_phys), intent(inout) :: weasd(:) + type(ty_ozphys), intent(in) :: ozphys ! NoahMP - only allocated when NoahMP is used integer, intent(in) :: lsoil, lsnow_lsm_lbound, lsnow_lsm_ubound @@ -200,21 +203,30 @@ subroutine GFS_phys_time_vary_init ( jamax=-999 !$OMP parallel num_threads(nthrds) default(none) & -!$OMP shared (me,master,h2o_phys,im,nx,ny,levs,idate) & +!$OMP shared (me,master,ntoz,h2o_phys,im,nx,ny,levs,idate) & !$OMP shared (xlat_d,xlon_d,imap,jmap,errmsg,errflg) & !$OMP shared (levh2o,h2o_coeff,h2o_pres,h2opl) & !$OMP shared (iamin, iamax, jamin, jamax) & !$OMP shared (iaerclm,iaermdl,ntrcaer,aer_nm,iflip,iccn) & -!$OMP shared (jindx1_h,jindx2_h,ddy_h) & +!$OMP shared (jindx1_o3,jindx2_o3,ddy_o3,jindx1_h,jindx2_h,ddy_h) & !$OMP shared (jindx1_aer,jindx2_aer,ddy_aer,iindx1_aer,iindx2_aer,ddx_aer) & !$OMP shared (jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci,ddx_ci) & !$OMP shared (do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau,ddy_j2tau) & !$OMP shared (isot,ivegsrc,nlunit,sncovr,sncovr_ice,lsm,lsm_ruc) & !$OMP shared (min_seaice,fice,landfrac,vtype,weasd,snupx,salp_data) & +!$OMP shared (ozphys) & !$OMP private (ix,i,j,rsnow,vegtyp) !$OMP sections +!$OMP section +!> - Setup spatial interpolation indices for ozone physics. + if (ntoz > 0) then + !$OMP CRITICAL + call ozphys%setup_forcing(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) + !$OMP END CRITICAL + endif + !$OMP section !> - Call read_h2odata() to read stratospheric water vapor data call read_h2odata (h2o_phys, me, master) @@ -710,8 +722,8 @@ end subroutine GFS_phys_time_vary_init !> @{ subroutine GFS_phys_time_vary_timestep_init ( & me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, nsswr, fhswr, lsswr, fhour, & - imfdeepcnv, cal_pre, random_clds, nscyc, h2o_phys, iaerclm, iccn, clstp, & - jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & + imfdeepcnv, cal_pre, random_clds, nscyc, ntoz, h2o_phys, iaerclm, iccn, clstp, & + jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, fn_nml, & imap, jmap, prsl, seed0, rann, nthrds, nx, ny, nsst, tile_num, nlunit, lsoil, lsoil_lsm,& @@ -719,21 +731,21 @@ subroutine GFS_phys_time_vary_timestep_init ( lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, & tsfc, tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, zorli, zorll, & zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, stype,scolor, shdmin, shdmax, snowd, & - cv, cvb, cvt, oro, oro_uf, xlat_d, xlon_d, slmsk, landfrac, & + cv, cvb, cvt, oro, oro_uf, xlat_d, xlon_d, slmsk, landfrac, ozphys, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, tau_amf, errmsg, errflg) implicit none ! Interface variables integer, intent(in) :: me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, & - nsswr, imfdeepcnv, iccn, nscyc, iflip + nsswr, imfdeepcnv, iccn, nscyc, ntoz, iflip integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhswr, fhour logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm real(kind_phys), intent(out) :: clstp - integer, intent(in) :: jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(in) :: ddy_h(:) - real(kind_phys), intent(inout) :: h2opl(:,:,:) + integer, intent(in) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(in) :: ddy_o3(:), ddy_h(:) + real(kind_phys), intent(inout) :: ozpl(:,:,:), h2opl(:,:,:) integer, intent(in) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(in) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(inout) :: aer_nm(:,:,:) @@ -749,6 +761,7 @@ subroutine GFS_phys_time_vary_timestep_init ( integer, intent(in) :: jindx1_tau(:), jindx2_tau(:) real(kind_phys), intent(in) :: ddy_j1tau(:), ddy_j2tau(:) real(kind_phys), intent(inout) :: tau_amf(:) + type(ty_ozphys), intent(in) :: ozphys ! For gcycle only integer, intent(in) :: nthrds, nx, ny, nsst, tile_num, nlunit, lsoil @@ -771,10 +784,13 @@ subroutine GFS_phys_time_vary_timestep_init ( integer, intent(out) :: errflg ! Local variables - integer :: i, j, k, iseed, iskip, ix - real(kind=kind_phys) :: wrk(1) - real(kind=kind_phys) :: rannie(cny) - real(kind=kind_phys) :: rndval(cnx*cny*nrcm) + integer :: i, j, k, iseed, iskip, ix, idat(8), jdat(8), iday, j1, j2, nc, n1, n2, jdow, & + jdoy, jday, w3kindreal, w3kindint + real(kind_phys) :: wrk(1), tem, tx1, tx2, rjday + real(kind_phys) :: rannie(cny) + real(kind_phys) :: rndval(cnx*cny*nrcm) + real(kind_dbl_prec) :: rinc(5) + real(kind_sngl_prec) :: rinc4(5) ! Initialize CCPP error handling variables errmsg = '' @@ -790,15 +806,56 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP parallel num_threads(nthrds) default(none) & !$OMP shared(kdt,nsswr,lsswr,clstp,imfdeepcnv,cal_pre,random_clds) & !$OMP shared(fhswr,fhour,seed0,cnx,cny,nrcm,wrk,rannie,rndval) & -!$OMP shared(rann,im,isc,jsc,imap,jmap,me,idate) & -!$OMP shared(h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & +!$OMP shared(rann,im,isc,jsc,imap,jmap,ntoz,me,idate,jindx1_o3,jindx2_o3) & +!$OMP shared(ozpl,ddy_o3,h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & !$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & !$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & -!$OMP shared(ddy_j2tau,tau_amf,iflip) & -!$OMP private(iseed,iskip,i,j,k) +!$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & +!$OMP private(iseed,iskip,i,j,rjday,idat,rinc,w3kindreal,w3kindint,jdat)& +!$OMP private(jdow,jdoy,jday,rinc4,n1,n2) !$OMP sections +!$OMP section +!> - Compute temporal interpolation indices for updating gas concentrations. + idat=0 + idat(1)=idate(4) + idat(2)=idate(2) + idat(3)=idate(3) + idat(5)=idate(1) + rinc=0. + rinc(2)=fhour + call w3kind(w3kindreal,w3kindint) + if(w3kindreal==4) then + rinc4=rinc + CALL w3movdat(rinc4,idat,jdat) + else + CALL w3movdat(rinc,idat,jdat) + endif + jdow = 0 + jdoy = 0 + jday = 0 + call w3doxdat(jdat,jdow,jdoy,jday) + rjday = jdoy + jdat(5) / 24. + if (rjday < ozphys%time(1)) rjday = rjday + 365. + + n2 = ozphys%ntime + 1 + do j=2,ozphys%ntime + if (rjday < ozphys%time(j)) then + n2 = j + exit + endif + enddo + n1 = n2 - 1 + if (n2 > ozphys%ntime) n2 = n2 - ozphys%ntime + + !> - Update ozone concentration. + if (ntoz > 0) then + !$OMP CRITICAL + call ozphys%update_forcing(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) + !$OMP END CRITICAL + endif + !$OMP section !--- switch for saving convective clouds - cnvc90.f diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index 6ef6e226c..bf5a3fa04 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -2,7 +2,7 @@ name = GFS_phys_time_vary type = scheme dependencies = aerclm_def.F,aerinterp.F90,gcycle.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f - dependencies = namelist_soilveg.f,set_soilveg.f,sfcsub.F,cires_tauamf_data.F90,noahmp_tables.f90 + dependencies = namelist_soilveg.f,set_soilveg.f,sfcsub.F,cires_tauamf_data.F90,noahmp_tables.f90,module_ozphys.F90 ######################################################################## [ccpp-arg-table] @@ -72,6 +72,36 @@ dimensions = () type = integer intent = in + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in +[jindx1_o3] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[jindx2_o3] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[ddy_o3] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in [nx] standard_name = number_of_points_in_x_direction_for_this_MPI_rank long_name = number of points in x direction for this MPI rank @@ -932,6 +962,13 @@ type = real kind = kind_phys intent = in +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -1107,6 +1144,13 @@ dimensions = () type = integer intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -1136,6 +1180,36 @@ type = real kind = kind_phys intent = out +[jindx1_o3] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[jindx2_o3] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[ddy_o3] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[ozpl] + standard_name = ozone_forcing + long_name = ozone forcing data + units = mixed + dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + type = real + kind = kind_phys + intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor @@ -1868,6 +1942,13 @@ type = real kind = kind_phys intent = inout +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index f2183919f..69be4f8d0 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -45,8 +45,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, rrfs_sd, & - aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, latsozc, levozc, & - blatc, dphiozc, errmsg, errflg) + aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, ozphys, & + errmsg, errflg) use machine, only: kind_phys @@ -54,7 +54,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& use funcphys, only: fpvs use module_radiation_astronomy,only: coszmn ! sol_init, sol_update - use module_radiation_gases, only: NF_VGAS, getgases, getozn ! gas_init, gas_update, + use module_radiation_gases, only: NF_VGAS, getgases ! gas_init, gas_update, use module_radiation_aerosols, only: NF_AESW, NF_AELW, setaer, & ! aer_init, aer_update, & NSPC1 use module_radiation_clouds, only: NF_CLDS, & ! cld_init @@ -81,6 +81,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& make_IceNumber, & make_DropletNumber, & make_RainNumber + ! For NRL Ozone + use module_ozphys, only: ty_ozphys implicit none integer, intent(in) :: im, levs, lm, lmk, lmp, ltp, & @@ -102,8 +104,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& imp_physics_mg, imp_physics_wsm6, & imp_physics_nssl, & imp_physics_fer_hires, & - yearlen, icloud, iaermdl, iaerflg, & - latsozc, levozc + yearlen, icloud, iaermdl, iaerflg integer, intent(in) :: & iovr, & ! choice of cloud-overlap method @@ -134,7 +135,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& integer, intent(in) :: spp_rad real(kind_phys), intent(in) :: spp_wts_rad(:,:) - real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con, blatc, dphiozc + real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g, con_ttp, con_thgni real(kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlat, xlon, & @@ -252,6 +253,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& integer :: iflag integer :: islmsk + ! For NRL Ozone + type(ty_ozphys),intent(in) :: ozphys + integer :: ids, ide, jds, jde, kds, kde, & ims, ime, jms, jme, kms, kme, & its, ite, jts, jte, kts, kte @@ -422,7 +426,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& !> - Get layer ozone mass mixing ratio (if use ozone climatology data, -!! call getozn()). if (ntoz > 0) then ! interactive ozone generation do k=1,lmk @@ -431,7 +434,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo enddo else ! climatological ozone - call getozn (prslk1, xlat, im, lmk, top_at_1, latsozc, levozc, blatc, dphiozc, olyr) + call ozphys%oz_clim(xlat, prslk1, con_pi, olyr) endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 038f59c27..a29b0ac3c 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,module_mp_radar.F90,module_mp_thompson.F90 - dependencies = module_mp_thompson_make_number_concentrations.F90,radcons.f90,radiation_aerosols.f + dependencies = module_mp_thompson_make_number_concentrations.F90,radcons.f90,radiation_aerosols.f,module_ozphys.F90 dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radlw_param.f,radsw_param.f,surface_perturbation.F90,radiation_cloud_overlap.F90 ######################################################################## @@ -247,6 +247,13 @@ dimensions = () type = integer intent = in +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = in [iaermdl] standard_name = control_for_aerosol_radiation_scheme long_name = control of aerosol scheme in radiation @@ -1503,36 +1510,6 @@ dimensions = () type = integer intent = in -[latsozc] - standard_name = number_of_latitudes_in_ozone_climotology_data - long_name = number of latitude in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[levozc] - standard_name = number_of_levels_in_ozone_climotology_data - long_name = number of levels in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[dphiozc] - standard_name = ozone_data_parameter_1 - long_name = ozone data parameter 1 - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[blatc] - standard_name = ozone_data_parameter_2 - long_name = ozone data parameter 2 - units = none - dimensions = () - type = real - kind = kind_phys - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 30917b961..908a364dc 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -7,7 +7,7 @@ module GFS_rrtmg_setup use machine, only: kind_phys - + use module_ozphys, only: ty_ozphys implicit none public GFS_rrtmg_setup_init, GFS_rrtmg_setup_timestep_init, GFS_rrtmg_setup_finalize @@ -44,7 +44,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd, co2usr_file, & co2cyc_file, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw,& - iswmode, latsozp, levozp, timeozp, ipsd0, ltp, lextop, errmsg, errflg) + iswmode, ipsd0, ltp, lextop, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -155,8 +155,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & ltp, npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, iovr_max, & iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, imp_physics, & - iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode, & - latsozp, levozp, timeozp + iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode integer, intent(in) :: idate(:) logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & inc_minor_gas, lextop @@ -219,8 +218,7 @@ subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, & con_pi, con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & - con_pi, latsozp, levozp, timeozp, errflg, errmsg) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, con_pi, errflg, errmsg ) call cld_init ( si, levr, imp_physics, me, con_g, con_rd, errflg, errmsg) call rlwinit ( me, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, & iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & @@ -246,7 +244,8 @@ end subroutine GFS_rrtmg_setup_init !! subroutine GFS_rrtmg_setup_timestep_init (idate, jdate, deltsw, deltim, & lsswr, me, iaermdl, iaerflg, isol, aeros_file, slag, sdec, cdec, & - solcon, con_pi, co2dat_file, co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) + solcon, con_pi, co2dat_file, co2gbl_file, ictm, ico2, ntoz, ozphys,& + errmsg, errflg) implicit none @@ -259,6 +258,7 @@ subroutine GFS_rrtmg_setup_timestep_init (idate, jdate, deltsw, deltim, & logical, intent(in) :: lsswr integer, intent(in) :: me integer, intent(in) :: iaermdl, iaerflg, isol, ictm, ico2, ntoz + type(ty_ozphys), intent(inout) :: ozphys character(len=26), intent(in) :: aeros_file, co2dat_file, co2gbl_file real(kind=kind_phys), intent(out) :: slag real(kind=kind_phys), intent(out) :: sdec @@ -279,7 +279,7 @@ subroutine GFS_rrtmg_setup_timestep_init (idate, jdate, deltsw, deltim, & errflg = 0 call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl, iaerflg,isol,aeros_file,& - slag,sdec,cdec,solcon,con_pi,co2dat_file,co2gbl_file,ictm,ico2,ntoz,errflg,errmsg) + slag,sdec,cdec,solcon,con_pi,co2dat_file,co2gbl_file,ictm,ico2,ntoz,ozphys,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -327,7 +327,7 @@ end subroutine GFS_rrtmg_setup_finalize !----------------------------------- subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& iaerflg, isol, aeros_file, slag,sdec,cdec,solcon, con_pi, & - co2dat_file,co2gbl_file, ictm, ico2, ntoz, errflg, errmsg) + co2dat_file,co2gbl_file, ictm, ico2, ntoz, ozphys, errflg, errmsg) !................................... ! ================= subprogram documentation block ================ ! @@ -371,6 +371,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& ! --- inputs: integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg, isol, ictm, ntoz, ico2 + type(ty_ozphys),intent(inout) :: ozphys logical, intent(in) :: lsswr character(len=26),intent(in) :: aeros_file,co2dat_file,co2gbl_file @@ -463,8 +464,11 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& lco2_chg = .false. endif - call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me, co2dat_file, & - co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) + call gas_update ( kyear,kmon,kday,khour,lco2_chg, me, co2dat_file, & + co2gbl_file, ictm, ico2, errflg, errmsg ) + if (ntoz == 0) then + call ozphys%update_clim(kmon, kday, khour, loz1st) + endif if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index f92d6f8db..35713757b 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_setup type = scheme dependencies = iounitdef.f,module_bfmicrophysics.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f - dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f,machine.F + dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f,machine.F,module_ozphys.F90 ######################################################################## [ccpp-arg-table] @@ -173,27 +173,6 @@ dimensions = () type = integer intent = in -[levozp] - standard_name = number_of_levels_in_ozone_climotology_data - long_name = number of levels in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[timeozp] - standard_name = number_of_times_in_ozone_climotology_data - long_name = number of times in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_climotology_data - long_name = number of latitude in ozone climotology data - units = count - dimensions = () - type = integer - intent = in [icliq_sw] standard_name = control_for_shortwave_radiation_liquid_clouds long_name = sw optical property for liquid clouds @@ -530,6 +509,13 @@ dimensions = () type = integer intent = in +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = inout [con_pi] standard_name = pi long_name = ratio of a circle's circumference to its diameter diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index dd72a6a1c..9dcc002a0 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -8,7 +8,8 @@ module GFS_rrtmgp_pre use machine, only: kind_phys use funcphys, only: fpvs use module_radiation_astronomy, only: coszmn - use module_radiation_gases, only: NF_VGAS, getgases, getozn + use module_radiation_gases, only: NF_VGAS, getgases + use module_ozphys, only: ty_ozphys use mo_gas_concentrations, only: ty_gas_concs use radiation_tools, only: check_error_msg,cmp_tlev use rrtmgp_lw_gas_optics, only: lw_gas_props @@ -117,25 +118,23 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl vmr_n2o, vmr_co2, tsfg, tsfa, qs_lay, q_lay, tv_lay, & relhum, deltaZ, deltaZc, deltaP, active_gases_array, & tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, nDay, idxday, semis, & - sfc_emiss_byband, ico2, latsozc, levozc, blatc, dphiozc, con_pi, errmsg, errflg) + sfc_emiss_byband, ico2, ozphys, con_pi, errmsg, errflg) - ! Inputs + ! Inputs integer, intent(in) :: & me, & ! MPI rank nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers ico2, & ! Flag for co2 radiation scheme - i_o3, & ! Index into tracer array for ozone - latsozc, & ! - levozc + i_o3 ! Index into tracer array for ozone + type(ty_ozphys),intent(in) :: & + ozphys logical, intent(in) :: & doSWrad, & ! Call SW radiation? doLWrad ! Call LW radiation real(kind_phys), intent(in) :: & fhswr, & ! Frequency of SW radiation call. - fhlwr, & ! Frequency of LW radiation call. - blatc, & ! - dphiozc + fhlwr ! Frequency of LW radiation call. real(kind_phys), intent(in) :: & con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air @@ -353,9 +352,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl enddo enddo ! OR Use climatological ozone data - else - call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, latsozc, levozc, blatc, & - dphiozc, o3_lay) + else + call ozphys%oz_clim(xlat, prslk, con_pi, o3_lay) endif ! ####################################################################################### diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 1a96eee1b..4e2aa3a56 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmgp_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,physcons.F90,radcons.f90,radiation_aerosols.f - dependencies = radiation_astronomy.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90 + dependencies = radiation_astronomy.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90,module_ozphys.F90 ######################################################################## [ccpp-arg-table] @@ -503,35 +503,12 @@ dimensions = (horizontal_loop_extent) type = integer intent = inout -[latsozc] - standard_name = number_of_latitudes_in_ozone_climotology_data - long_name = number of latitude in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[levozc] - standard_name = number_of_levels_in_ozone_climotology_data - long_name = number of levels in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[dphiozc] - standard_name = ozone_data_parameter_1 - long_name = ozone data parameter 1 - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[blatc] - standard_name = ozone_data_parameter_2 - long_name = ozone data parameter 2 - units = none +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed dimensions = () - type = real - kind = kind_phys + type = ty_ozphys intent = in [errmsg] standard_name = ccpp_error_message diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 7b5479e60..3e4f57d13 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -6,6 +6,7 @@ module GFS_rrtmgp_setup use module_radiation_astronomy, only : sol_init, sol_update use module_radiation_aerosols, only : aer_init, aer_update use module_radiation_gases, only : gas_init, gas_update + use module_ozphys, only : ty_ozphys implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize @@ -37,7 +38,7 @@ module GFS_rrtmgp_setup subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & - ntcw, ntoz, iovr, latsozp, levozp, timeozp, isubc_sw, isubc_lw, lalw1bd, idate, & + ntcw, ntoz, iovr, isubc_sw, isubc_lw, lalw1bd, idate, & me, aeros_file, iaermdl, iaerflg, con_pi, con_t0c, con_c, con_boltz, con_plnk, & solar_file, con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, ipsd0, & errmsg, errflg) @@ -57,8 +58,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, con_pi, con_t0c, con_c, con_boltz, con_plnk, con_solr_2008, con_solr_2002 real(kind_phys), dimension(:), intent(in) :: & si - integer, intent(in) :: levr, ictm, isol, ico2, iaer, & - ntcw, ntoz, iovr, isubc_sw, isubc_lw, latsozp, levozp, timeozp, me + integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, ntoz, iovr, isubc_sw, isubc_lw, me logical, intent(in) :: & lalw1bd integer, intent(in), dimension(:) :: & @@ -129,8 +129,7 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & con_c, con_boltz, con_plnk, errflg, errmsg) - call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, latsozp, & - levozp, timeozp, errflg, errmsg ) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, con_pi, errflg, errmsg ) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' @@ -149,7 +148,7 @@ end subroutine GFS_rrtmgp_setup_init !! subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad, me, & iaermdl, aeros_file, isol, slag, sdec, cdec, solcon, con_pi, co2dat_file, & - co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) + co2gbl_file, ictm, ico2, ntoz, ozphys, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) @@ -161,7 +160,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad integer, intent(in) :: me integer, intent(in) :: iaermdl,isol,ictm,ico2,ntoz character(len=26), intent(in) :: aeros_file,co2dat_file,co2gbl_file - + type(ty_ozphys),intent(inout) :: ozphys ! Outputs real(kind_phys), intent(out) :: slag real(kind_phys), intent(out) :: sdec @@ -241,8 +240,11 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad else lco2_chg = .false. endif - call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me, co2dat_file, & - co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) + call gas_update (kyear, kmon, kday, khour, lco2_chg, me, co2dat_file, co2gbl_file, ictm,& + ico2, errflg, errmsg ) + if (ntoz == 0) then + call ozphys%update_clim(kmon, kday, khour, loz1st) + endif if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index c8ed60650..96f7e24e7 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -2,7 +2,7 @@ name = GFS_rrtmgp_setup type = scheme dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,radiation_aerosols.f,radiation_astronomy.f - dependencies = module_mp_thompson.F90,radiation_gases.f + dependencies = module_mp_thompson.F90,radiation_gases.f,module_ozphys.F90 ######################################################################## [ccpp-arg-table] @@ -266,27 +266,6 @@ dimensions = () type = integer intent = inout -[levozp] - standard_name = number_of_levels_in_ozone_climotology_data - long_name = number of levels in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[timeozp] - standard_name = number_of_times_in_ozone_climotology_data - long_name = number of times in ozone climotology data - units = count - dimensions = () - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_climotology_data - long_name = number of latitude in ozone climotology data - units = count - dimensions = () - type = integer - intent = in [iaermdl] standard_name = control_for_aerosol_radiation_scheme long_name = control of aerosol scheme in radiation @@ -410,6 +389,13 @@ dimensions = () type = integer intent = in +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = inout [iaermdl] standard_name = control_for_aerosol_radiation_scheme long_name = control of aerosol scheme in radiation diff --git a/physics/module_ozphys.F90 b/physics/module_ozphys.F90 new file mode 100644 index 000000000..966d27113 --- /dev/null +++ b/physics/module_ozphys.F90 @@ -0,0 +1,476 @@ +! ######################################################################################### +!> \section arg_table_module_ozphys Argument table +!! \htmlinclude module_ozphys.html +!! +! ######################################################################################### +module module_ozphys + use machine, only : kind_phys + use funcphys, only : fpkapx + implicit none + + public ty_ozphys + +! ######################################################################################### +!> \section arg_table_ty_ozphys Argument Table +!! \htmlinclude ty_ozphys.html +!! +!! All data field are ordered from surface-to-toa (j=1=isfc) +!! +! ######################################################################################### + type ty_ozphys + ! Prognostic ozone. + integer :: nlat !< Number of latitudes. + integer :: nlev !< Number of vertical layers. + integer :: ntime !< Number of times. + integer :: ncf !< Number of coefficients. + real(kind_phys), allocatable :: lat(:) !< Latitude. + real(kind_phys), allocatable :: pres(:) !< Pressure levels. + real(kind_phys), allocatable :: po3(:) !< Natural log pressure of levels. + real(kind_phys), allocatable :: time(:) !< Time. + real(kind_phys), allocatable :: data(:,:,:,:) !< Ozone forcing data (raw) + ! Climotological ozone. + integer :: nlatc !< Number of latitudes. + integer :: nlevc !< Number of vertical layers. + integer :: ntimec !< Number of times. + real(kind_phys) :: blatc !< Parameter for ozone climotology + real(kind_phys) :: dphiozc !< Parameter for ozone climotology + real(kind_phys), allocatable :: pkstr(:) !< + real(kind_phys), allocatable :: pstr(:) !< + real(kind_phys), allocatable :: datac(:,:,:) !< Ozone climotological data + integer :: k1oz !< Lower interpolation index in datac(dim=3), time dim + integer :: k2oz !< Upper interpolation index in datac(dim=3), time dim + real(kind_phys) :: facoz !< Parameter for ozone climotology + contains + procedure, public :: load_forcing + procedure, public :: load_clim + procedure, public :: setup_forcing + procedure, public :: update_forcing + procedure, public :: update_clim + procedure, public :: oz_prog_2015 + procedure, public :: oz_prog_2006 + procedure, public :: oz_clim + end type ty_ozphys + +contains + ! ######################################################################################### + ! Procedure (type-bound) for loading ozone forcing data. + ! ######################################################################################### + function load_forcing(this, file, fileID) result (err_message) + class(ty_ozphys), intent(inout) :: this + integer, intent(in) :: fileID + character(len=*), intent(in) :: file + character(len=128) :: err_message + integer :: i1, i2, i3 + real(kind=4), dimension(:), allocatable :: lat4, pres4, time4, tempin + real(kind=4) :: blatc4 + + ! Get dimensions from data file + open(unit=fileID,file=trim(file), form='unformatted', convert='big_endian') + read (fileID) this%ncf, this%nlat, this%nlev, this%ntime + rewind(fileID) + + allocate (this%lat(this%nlat)) + allocate (this%pres(this%nlev)) + allocate (this%po3(this%nlev)) + allocate (this%time(this%ntime+1)) + allocate (this%data(this%nlat,this%nlev,this%ncf,this%ntime)) + + allocate(lat4(this%nlat), pres4(this%nlev), time4(this%ntime+1)) + read (fileID) this%ncf, this%nlat, this%nlev, this%ntime, lat4, pres4, time4 + + ! Store + this%pres(:) = pres4(:) + this%po3(:) = log(100.0*this%pres(:)) ! from mb to ln(Pa) + this%lat(:) = lat4(:) + this%time(:) = time4(:) + deallocate(lat4, pres4, time4) + + allocate(tempin(this%nlat)) + do i1=1,this%ntime + do i2=1,this%ncf + do i3=1,this%nlev + read(fileID) tempin + this%data(:,i3,i2,i1) = tempin(:) + enddo + enddo + enddo + deallocate(tempin) + close(fileID) + + end function load_forcing + + ! ######################################################################################### + ! Procedure for setting up interpolation indices between data and model grid. + ! ######################################################################################### + subroutine setup_forcing(this, lat, idx1, idx2, idxh) + class(ty_ozphys), intent(in) :: this + real(kind_phys), intent(in) :: lat(:) + integer, intent(out) :: idx1(:), idx2(:) + real(kind_phys), intent(out) :: idxh(:) + integer :: i,j + + do j=1,size(lat) + idx2(j) = this%nlat + 1 + do i=1,this%nlat + if (lat(j) < this%lat(i)) then + idx2(j) = i + exit + endif + enddo + idx1(j) = max(idx2(j)-1,1) + idx2(j) = min(idx2(j),this%nlat) + if (idx2(j) .ne. idx1(j)) then + idxh(j) = (lat(j) - this%lat(idx1(j))) / (this%lat(idx2(j)) - this%lat(idx1(j))) + else + idxh(j) = 1.0 + endif + enddo + + end subroutine setup_forcing + + ! ######################################################################################### + ! Procedure (type-bound) for updating ozone data. + ! ######################################################################################### + subroutine update_forcing(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl) + class(ty_ozphys), intent(in) :: this + integer, intent(in) :: idx1(:), idx2(:) + real(kind_phys), intent(in) :: idxh(:) + real(kind_phys), intent(in) :: rjday + integer, intent(in) :: idxt1, idxt2 + real(kind_phys), intent(out) :: ozpl(:,:,:) + integer :: nc, l, j, j1, j2 + real(kind_phys) :: tem, tx1, tx2 + + tx1 = (this%time(idxt2) - rjday) / (this%time(idxt2) - this%time(idxt1)) + tx2 = 1.0 - tx1 + + do nc=1,this%ncf + do l=1,this%nlev + do j=1,size(ozpl(:,1,1)) + j1 = idx1(j) + j2 = idx2(j) + tem = 1.0 - idxh(j) + ozpl(j,l,nc) = tx1*(tem*this%data(j1,l,nc,idxt1)+idxh(j)*this%data(j2,l,nc,idxt1)) & + + tx2*(tem*this%data(j1,l,nc,idxt2)+idxh(j)*this%data(j2,l,nc,idxt2)) + enddo + enddo + enddo + + end subroutine update_forcing + + ! ######################################################################################### + ! Procedure (type-bound) for NRL prognostic ozone (2015). + ! ######################################################################################### + subroutine oz_prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, do3_dt_ozmx, & + do3_dt_temp, do3_dt_ohoz) + class(ty_ozphys), intent(in) :: this + real(kind_phys),intent(in) :: & + con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) + real(kind_phys), intent(in) :: & + dt ! Model timestep (sec) + real(kind_phys), intent(in), dimension(:,:) :: & + p, & ! Model Pressure (Pa) + t, & ! Model temperature (K) + dp ! Model layer thickness (Pa) + real(kind_phys), intent(in), dimension(:,:,:) :: & + ozpl ! Ozone forcing data + real(kind_phys), intent(inout), dimension(:,:) :: & + oz ! Ozone concentration updated by physics + real(kind_phys), intent(inout), dimension(:,:), pointer, optional :: & + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect + + integer :: k, kmax, kmin, iLev, iCol, nCol, nLev, iCf + logical, dimension(size(p,1)) :: flg + real(kind_phys) :: pmax, pmin, tem, temp + real(kind_phys), dimension(size(p,1)) :: wk1, wk2, wk3, ozib + real(kind_phys), dimension(size(p,1),this%ncf) :: prod + real(kind_phys), dimension(size(p,1),size(p,2)) :: ozi + real(kind_phys), dimension(size(p,1),size(p,2)+1) :: colo3, coloz + + ! Dimensions + nCol = size(p,1) + nLev = size(p,2) + + ! Temporaries + ozi = oz + + colo3(:,nLev+1) = 0.0 + coloz(:,nLev+1) = 0.0 + + do iLev=nLev,1,-1 + pmin = 1.0e10 + pmax = -1.0e10 + + do iCol=1,nCol + wk1(iCol) = log(p(iCol,iLev)) + pmin = min(wk1(iCol), pmin) + pmax = max(wk1(iCol), pmax) + prod(iCol,:) = 0._kind_phys + enddo + kmax = 1 + kmin = 1 + do k=1,this%nlev-1 + if (pmin < this%po3(k)) kmax = k + if (pmax < this%po3(k)) kmin = k + enddo + ! + do k=kmin,kmax + temp = 1.0 / (this%po3(k) - this%po3(k+1)) + do iCol=1,nCol + flg(iCol) = .false. + if (wk1(iCol) < this%po3(k) .and. wk1(iCol) >= this%po3(k+1)) then + flg(iCol) = .true. + wk2(iCol) = (wk1(iCol) - this%po3(k+1)) * temp + wk3(iCol) = 1.0 - wk2(iCol) + endif + enddo + do iCf=1,this%ncf + do iCol=1,nCol + if (flg(iCol)) then + prod(iCol,iCf) = wk2(iCol) * ozpl(iCol,k,iCf) + wk3(iCol) * ozpl(iCol,k+1,iCf) + endif + enddo + enddo + enddo + + do iCf=1,this%ncf + do iCol=1,nCol + if (wk1(iCol) < this%po3(this%nlev)) then + prod(iCol,iCf) = ozpl(iCol,this%nlev,iCf) + endif + if (wk1(iCol) >= this%po3(1)) then + prod(iCol,iCf) = ozpl(iCol,1,iCf) + endif + enddo + enddo + do iCol=1,nCol + colo3(iCol,iLev) = colo3(iCol,iLev+1) + ozi(iCol,iLev) * dp(iCol,iLev)*con_1ovg + coloz(iCol,iLev) = coloz(iCol,iLev+1) + prod(iCol,6) * dp(iCol,iLev)*con_1ovg + prod(iCol,2) = min(prod(iCol,2), 0.0) + enddo + do iCol=1,nCol + ozib(iCol) = ozi(iCol,iLev) ! no filling + tem = prod(iCol,1) - prod(iCol,2) * prod(iCol,6) & + + prod(iCol,3) * (t(iCol,iLev) - prod(iCol,5)) & + + prod(iCol,4) * (colo3(iCol,iLev)-coloz(iCol,iLev)) + oz(iCol,iLev) = (ozib(iCol) + tem*dt) / (1.0 - prod(iCol,2)*dt) + enddo + + ! Diagnostics (optional) + if (associated(do3_dt_prd)) do3_dt_prd(:,iLev) = (prod(:,1)-prod(:,2)*prod(:,6))*dt + if (associated(do3_dt_ozmx)) do3_dt_ozmx(:,iLev) = (oz(:,iLev) - ozib(:)) + if (associated(do3_dt_temp)) do3_dt_temp(:,iLev) = prod(:,3)*(t(:,iLev)-prod(:,5))*dt + if (associated(do3_dt_ohoz)) do3_dt_ohoz(:,iLev) = prod(:,4) * (colo3(:,iLev)-coloz(:,iLev))*dt + enddo + + return + end subroutine oz_prog_2015 + + ! ######################################################################################### + ! Procedure (type-bound) for NRL prognostic ozone (2006). + ! ######################################################################################### + subroutine oz_prog_2006(this) + class(ty_ozphys), intent(in) :: this + return + end subroutine oz_prog_2006 + + ! ######################################################################################### + ! Procedure (type-bound) for NRL updating climotological ozone. + ! Build this up from getozn. + ! ######################################################################################### + subroutine oz_clim(this, lat, prslk, con_pi, oz) + class(ty_ozphys), intent(in) :: this + real(kind_phys), intent(in) :: & + con_pi ! Physics constant: Pi + real(kind_phys), intent(in), dimension(:) :: & + lat ! Grid latitude + real(kind_phys), intent(in), dimension(:,:) :: & + prslk ! Exner function + real(kind_phys), intent(out), dimension(:,:) :: & + oz ! Ozone concentration updated by climotology + + integer :: nCol, iCol, nLev, iLev, j, j1, j2, l, ll + real(kind_phys) :: elte, deglat, tem, tem1, tem2, tem3, tem4, temp + real(kind_phys), allocatable :: o3i(:,:),wk1(:) + logical :: top_at_1 + + nCol = size(prslk(:,1)) + nLev = size(prslk(1,:)) + allocate(o3i(nCol, this%nlevc),wk1(nCol)) + + ! What is vertical ordering? + top_at_1 = (prslk(1,1) .lt. prslk(1, nLev)) + + elte = this%blatc + (this%nlatc-1)*this%dphiozc + + do iCol = 1, nCol + deglat = lat(iCol) * 180.0 / con_pi + if (deglat > this%blatc .and. deglat < elte) then + tem1 = (deglat - this%blatc) / this%dphiozc + 1 + j1 = tem1 + j2 = j1 + 1 + tem1 = tem1 - j1 + elseif (deglat <= this%blatc) then + j1 = 1 + j2 = 1 + tem1 = 1.0 + elseif (deglat >= elte) then + j1 = this%nlatc + j2 = this%nlatc + tem1 = 1.0 + endif + + tem2 = 1.0 - tem1 + do j = 1, this%nlevc + tem3 = tem2*this%datac(j1,j,this%k1oz) + tem1*this%datac(j2,j,this%k1oz) + tem4 = tem2*this%datac(j1,j,this%k2oz) + tem1*this%datac(j2,j,this%k2oz) + o3i(iCol,j) = tem4*this%facoz + tem3*(1.0 - this%facoz) + enddo + enddo + + do iLev = 1, nLev + ll = iLev + if (.not. top_at_1) ll = nLev - iLev + 1 + + do iCol = 1, nCol + wk1(iCol) = prslk(iCol,ll) + enddo + + do j = 1, this%nlevc-1 + temp = 1.0 / (this%pkstr(j+1) - this%pkstr(j)) + do iCol = 1, nCol + if (wk1(iCol) > this%pkstr(j) .and. wk1(iCol) <= this%pkstr(j+1)) then + tem = (this%pkstr(j+1) - wk1(iCol)) * temp + oz(iCol,ll) = tem * o3i(iCol,j) + (1.0 - tem) * o3i(iCol,j+1) + endif + enddo + enddo + + do iCol = 1, nCol + if (wk1(iCol) > this%pkstr(this%nlevc)) oz(iCol,ll) = o3i(iCol,this%nlevc) + if (wk1(iCol) < this%pkstr(1)) oz(iCol,ll) = o3i(iCol,1) + enddo + enddo + + return + end subroutine oz_clim + + ! ######################################################################################### + ! Procedure (type-bound) for loading ozone climo data. + ! ######################################################################################### + function load_clim(this, file, fileID) result (err_message) + class(ty_ozphys), intent(inout) :: this + integer, intent(in) :: fileID + character(len=*), intent(in) :: file + character(len=128) :: err_message + + ! Locals + real(kind=4) :: blatc4 + integer :: iLev, iLat, imo + real(kind=4), allocatable :: o3clim4(:,:,:), pstr4(:) + integer, allocatable :: imond(:), ilatt(:,:) + + open(unit=fileID,file=trim(file), form='unformatted', convert='big_endian') + read (fileID,end=101) this%nlatc, this%nlevc, this%ntimec, blatc4 +101 if (this%nlevc < 10 .or. this%nlevc > 100) then + rewind (fileID) + this%nlevc = 17 + this%nlatc = 18 + this%blatc = -85.0 + else + this%blatc = blatc4 + endif + this%nlat = 2 + this%nlev = 1 + this%ntimec = 1 + this%ncf = 0 + this%dphiozc = -(this%blatc+this%blatc)/(this%nlatc-1) + + allocate (o3clim4(this%nlatc,this%nlevc,12), pstr4(this%nlevc), imond(12), ilatt(this%nlatc,12) ) + + allocate (this%pkstr(this%nlevc), this%pstr(this%nlevc), this%datac(this%nlatc,this%nlevc,12)) + if ( this%nlevc == 17 ) then ! For the operational ozone climatology + do iLev = 1, this%nlevc + read (fileID,15) pstr4(iLev) +15 format(f10.3) + enddo + + do imo = 1, 12 + do iLat = 1, this%nlatc + read (fileID,16) imond(imo), ilatt(iLat,imo), (o3clim4(iLat,iLev,imo),iLev=1,10) +16 format(i2,i4,10f6.2) + read (fileID,20) (o3clim4(iLat,iLev,imo),iLev=11,this%nlevc) +20 format(6x,10f6.2) + enddo + enddo + else ! For newer ozone climatology + read (fileID) + do iLev = 1, this%nlevc + read (fileID) pstr4(iLev) + enddo + + do imo = 1, 12 + do iLev = 1, this%nlevc + read (fileID) (o3clim4(iLat,iLev,imo),iLat=1,this%nlatc) + enddo + enddo + endif ! end if_this%nlevc_block + + do imo = 1, 12 + do iLev = 1, this%nlevc + do iLat = 1, this%nlatc + this%datac(iLat,iLev,imo) = o3clim4(iLat,iLev,imo) * 1.655e-6 + enddo + enddo + enddo + + do iLev = 1, this%nlevc + this%pstr(iLev) = pstr4(iLev) + this%pkstr(iLev) = fpkapx(this%pstr(iLev)*100.0) + enddo + + end function load_clim + + ! ######################################################################################### + ! Procedure (type-bound) for updating ozone climotological data. + ! ######################################################################################### + subroutine update_clim(this, imon, iday, ihour, loz1st) + class(ty_ozphys), intent(inout) :: this + integer, intent(in) :: imon, iday, ihour + logical, intent(in) :: loz1st + + integer :: midmon=15, midm=15, midp=45, id + integer, parameter, dimension(13) :: mdays = (/31,28,31,30,31,30,31,31,30,31,30,31,30/) + logical :: change + + midmon = mdays(imon)/2 + 1 + change = loz1st .or. ( (iday==midmon) .and. (ihour==0) ) + + if ( change ) then + if ( iday < midmon ) then + this%k1oz = mod(imon+10, 12) + 1 + midm = mdays(this%k1oz)/2 + 1 + this%k2oz = imon + midp = mdays(this%k1oz) + midmon + else + this%k1oz = imon + midm = midmon + this%k2oz = mod(imon, 12) + 1 + midp = mdays(this%k2oz)/2 + 1 + mdays(this%k1oz) + endif + endif + + if (iday < midmon) then + id = iday + mdays(this%k1oz) + else + id = iday + endif + + this%facoz = float(id - midm) / float(midp - midm) + + end subroutine update_clim + +end module module_ozphys diff --git a/physics/module_ozphys.meta b/physics/module_ozphys.meta new file mode 100644 index 000000000..2922d16d7 --- /dev/null +++ b/physics/module_ozphys.meta @@ -0,0 +1,24 @@ +[ccpp-table-properties] + name = ty_ozphys + type = ddt + dependencies = + +[ccpp-arg-table] + name = ty_ozphys + type = ddt + +######################################################################## +[ccpp-table-properties] + name = module_ozphys + type = module + dependencies = machine.F,funcphys.f90 + +[ccpp-arg-table] + name = module_ozphys + type = module +[ty_ozphys] + standard_name = ty_ozphys + long_name = definition of type ty_ozphys + units = DDT + dimensions = () + type = ty_ozphys \ No newline at end of file diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 index 47386bd6e..1478d0d6e 100644 --- a/physics/ozphys_2015.F90 +++ b/physics/ozphys_2015.F90 @@ -3,89 +3,57 @@ !! ! ########################################################################################### module ozphys_2015 - use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec + use machine, only: kind_phys, kind_dbl_prec, kind_sngl_prec + use module_ozphys, only: ty_ozphys implicit none - public ozphys_2015_init, ozphys_2015_run + public ozphys_2015_run contains ! ########################################################################################### !>\defgroup GFS_ozphys_2015 GFS Ozone Photochemistry (2015) Module !! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. !> @{ -!> The operational GFS currently parameterizes ozone production and -!! destruction based on monthly mean coefficients ( -!! \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by Naval -!! Research Laboratory through CHEM2D chemistry model +!> The operational GFS currently parameterizes ozone production and destruction based on +!! monthly mean coefficients ( \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by +!! Naval Research Laboratory through CHEM2D chemistry model !! (McCormack et al. (2006) \cite mccormack_et_al_2006). !! (https://doi.org/10.5194/acp-6-4943-2006) !! !> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm -!> - This code assumes that both prsl and po3 are from bottom to top -!! as are all other variables. -!> - This code is specifically for NRL parameterization and -!! climatological T and O3 are in location 5 and 6 of oz_data array +!> - This code assumes that both 2D fields are ordered from bottom to top. +!> - This code is specifically for NRL parameterization and climatological T and O3 are in +! location 5 and 6 of ozpl array !!\author June 2015 - Shrinivas Moorthi !!\modified May 2023 - Dustin Swales ! ########################################################################################### -! ########################################################################################### -! SUBROUTINE ozphys_2015_init -! ########################################################################################### -!! \section arg_table_ozphys_2015_init Argument Table -!! \htmlinclude ozphys_2015_init.html -!! - subroutine ozphys_2015_init(oz_phys, errmsg, errflg) - ! Inputs - logical, intent(in) :: & - oz_phys - ! Outputs - character(len=*), intent(out) :: & - errmsg - integer, intent(out) :: & - errflg - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Sanity check - if (.not.oz_phys) then - write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' - errflg = 1 - return - endif - - end subroutine ozphys_2015_init - ! ########################################################################################### ! SUBROUTINE ozphys_2015_run ! ########################################################################################### !! \section arg_table_ozphys_2015_run Argument Table !! \htmlinclude ozphys_2015_run.html !! - subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_data, & - pl_coeff, delp, con_1ovg, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, errmsg, errflg) + subroutine ozphys_2015_run (oz_phys, ozphys, nCol, nLev, dt, oz, tin, prsl, ozpl, & + delp, con_1ovg, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, errmsg, errflg) ! Inputs logical, intent(in) :: & oz_phys ! Flag for ozone_physics_2015 scheme. + type(ty_ozphys),intent(in) :: & + ozphys real(kind_phys),intent(in) :: & con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) integer, intent(in) :: & - im, & ! Horizontal dimension - levs, & ! Number of vertical layers - ko3, & ! Number of vertical layers in ozone forcing data - pl_coeff ! Number of coefficients in ozone forcing data + nCol, & ! Horizontal dimension + nLev ! Number of vertical layers real(kind_phys), intent(in) :: & dt ! Physics timestep (seconds) - real(kind_phys), intent(in), dimension(:) :: & - po3 ! Natural log of ozone forcing data pressure levels real(kind_phys), intent(in), dimension(:,:) :: & prsl, & ! Air-pressure (Pa) tin, & ! Temperature of new-state (K) delp ! Difference between mid-layer pressures (Pa) real(kind_phys), intent(in), dimension(:,:,:) :: & - oz_data ! Ozone forcing data + ozpl ! Ozone forcing data ! Outputs (optional) real(kind=kind_phys), intent(inout), dimension(:,:), pointer, optional :: & @@ -96,26 +64,26 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d ! Outputs real(kind=kind_phys), intent(inout), dimension(:,:) :: & - oz ! Ozone concentration updated by physics + oz ! Ozone concentration updated by physics character(len=*), intent(out) :: & - errmsg ! CCPP error message + errmsg ! CCPP error message integer, intent(out) :: & - errflg ! CCPP error flag + errflg ! CCPP error flag ! Locals integer :: k, kmax, kmin, l, i, j - logical, dimension(im) :: flg + logical, dimension(nCol) :: flg real(kind_phys) :: pmax, pmin, tem, temp - real(kind_phys), dimension(im) :: wk1, wk2, wk3, ozib - real(kind_phys), dimension(im,pl_coeff) :: prod - real(kind_phys), dimension(im,levs) :: ozi - real(kind_phys), dimension(im,levs+1) :: colo3, coloz + real(kind_phys), dimension(nCol) :: wk1, wk2, wk3, ozib + real(kind_phys), dimension(nCol,ozphys%ncf) :: prod + real(kind_phys), dimension(nCol,nLev) :: ozi + real(kind_phys), dimension(nCol,nLev+1) :: colo3, coloz ! Initialize CCPP error handling variables errmsg = '' errflg = 0 - ! Sanity checkt + ! Sanity checks if (.not.oz_phys) then write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' errflg = 1 @@ -125,14 +93,14 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d ! Temporaries ozi = oz - colo3(:,levs+1) = 0.0 - coloz(:,levs+1) = 0.0 + colo3(:,nLev+1) = 0.0 + coloz(:,nLev+1) = 0.0 - do l=levs,1,-1 + do l=nLev,1,-1 pmin = 1.0e10 pmax = -1.0e10 - do i=1,im + do i=1,nCol wk1(i) = log(prsl(i,l)) pmin = min(wk1(i), pmin) pmax = max(wk1(i), pmax) @@ -140,46 +108,46 @@ subroutine ozphys_2015_run (oz_phys, im, levs, ko3, dt, oz, tin, po3, prsl, oz_d enddo kmax = 1 kmin = 1 - do k=1,ko3-1 - if (pmin < po3(k)) kmax = k - if (pmax < po3(k)) kmin = k + do k=1,ozphys%nlev-1 + if (pmin < ozphys%po3(k)) kmax = k + if (pmax < ozphys%po3(k)) kmin = k enddo ! do k=kmin,kmax - temp = 1.0 / (po3(k) - po3(k+1)) - do i=1,im + temp = 1.0 / (ozphys%po3(k) - ozphys%po3(k+1)) + do i=1,nCol flg(i) = .false. - if (wk1(i) < po3(k) .and. wk1(i) >= po3(k+1)) then + if (wk1(i) < ozphys%po3(k) .and. wk1(i) >= ozphys%po3(k+1)) then flg(i) = .true. - wk2(i) = (wk1(i) - po3(k+1)) * temp + wk2(i) = (wk1(i) - ozphys%po3(k+1)) * temp wk3(i) = 1.0 - wk2(i) endif enddo - do j=1,pl_coeff - do i=1,im + do j=1,ozphys%ncf + do i=1,nCol if (flg(i)) then - prod(i,j) = wk2(i) * oz_data(i,k,j) + wk3(i) * oz_data(i,k+1,j) + prod(i,j) = wk2(i) * ozpl(i,k,j) + wk3(i) * ozpl(i,k+1,j) endif enddo enddo enddo - do j=1,pl_coeff - do i=1,im - if (wk1(i) < po3(ko3)) then - prod(i,j) = oz_data(i,ko3,j) + do j=1,ozphys%ncf + do i=1,nCol + if (wk1(i) < ozphys%po3(ozphys%nlev)) then + prod(i,j) = ozpl(i,ozphys%nlev,j) endif - if (wk1(i) >= po3(1)) then - prod(i,j) = oz_data(i,1,j) + if (wk1(i) >= ozphys%po3(1)) then + prod(i,j) = ozpl(i,1,j) endif enddo enddo - do i=1,im + do i=1,nCol colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*con_1ovg coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*con_1ovg prod(i,2) = min(prod(i,2), 0.0) enddo - do i=1,im + do i=1,nCol ozib(i) = ozi(i,l) ! no filling tem = prod(i,1) - prod(i,2) * prod(i,6) + prod(i,3) * (tin(i,l) - prod(i,5)) & + prod(i,4) * (colo3(i,l)-coloz(i,l)) diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta index 1d8fba74e..ca2d56e4e 100644 --- a/physics/ozphys_2015.meta +++ b/physics/ozphys_2015.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] name = ozphys_2015 type = scheme - dependencies = machine.F + dependencies = machine.F,module_ozphys.F90 ######################################################################## [ccpp-arg-table] - name = ozphys_2015_init + name = ozphys_2015_run type = scheme [oz_phys] standard_name = flag_for_nrl_2015_ozone_scheme @@ -14,54 +14,27 @@ dimensions = () type = logical intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = ozphys_2015_run - type = scheme -[oz_phys] - standard_name = flag_for_nrl_2015_ozone_scheme - long_name = flag for new (2015) ozone physics - units = flag +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed dimensions = () - type = logical + type = ty_ozphys intent = in -[im] +[nCol] standard_name = horizontal_loop_extent long_name = horizontal loop extent units = count dimensions = () type = integer intent = in -[levs] +[nLev] standard_name = vertical_layer_dimension long_name = number of vertical layers units = count dimensions = () type = integer intent = in -[ko3] - standard_name = number_of_levels_in_ozone_data - long_name = number of vertical layers in ozone forcing data - units = count - dimensions = () - type = integer - intent = in [dt] standard_name = timestep_for_physics long_name = physics time step @@ -86,14 +59,6 @@ type = real kind = kind_phys intent = in -[po3] - standard_name = natural_log_of_ozone_data_pressure_levels - long_name = natural log of ozone forcing data pressure levels - units = 1 - dimensions = (number_of_levels_in_ozone_data) - type = real - kind = kind_phys - intent = in [prsl] standard_name = air_pressure long_name = mid-layer pressure @@ -102,7 +67,7 @@ type = real kind = kind_phys intent = in -[oz_data] +[ozpl] standard_name = ozone_forcing long_name = ozone forcing data units = mixed @@ -110,13 +75,6 @@ type = real kind = kind_phys intent = in -[pl_coeff] - standard_name = number_of_coefficients_in_ozone_data - long_name = number of coefficients in ozone forcing data - units = count - dimensions = () - type = integer - intent = in [delp] standard_name = air_pressure_difference_between_midlayers long_name = difference between mid-layer pressures diff --git a/physics/ozphys_time_vary.F90 b/physics/ozphys_time_vary.F90 deleted file mode 100644 index ddac1dcd4..000000000 --- a/physics/ozphys_time_vary.F90 +++ /dev/null @@ -1,165 +0,0 @@ -! ########################################################################################### -!> \file ozphys_time_vary.F90 -!! -! ########################################################################################### -module ozphys_time_vary - use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec - implicit none - public ozphys_time_vary_init, ozphys_time_vary_timestep_init -contains - -! ########################################################################################### -!>\defgroup GFS Ozone Data Module -!! This module updates the ozone data used by physics. -!> @{ -!> \section arg_table_ozphys_time_vary_init Argument Table -!! \htmlinclude ozphys_time_vary_init.html -!! -! ########################################################################################### - subroutine ozphys_time_vary_init(nPts, latsozp, oz_lat, dlat, jindx1, jindx2, ddy, & - errmsg, errflg) - ! Inputs - integer, intent(in) :: & - nPts, & ! Horizontal dimension - latsozp ! Number of latitudes in ozone data - real(kind_phys), intent(in), dimension(:) :: & - oz_lat, & ! Latitudes of ozone data - dlat ! Latitudes of grid - ! Outputs - integer, intent(inout), dimension(:) :: & - jindx1, & ! Interpolation index (low) for ozone data - jindx2 ! Interpolation index (high) for ozone data - real(kind_phys), intent(inout), dimension(:) :: & - ddy ! Interpolation high index for ozone data - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local - integer i,j - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Set indices - do j=1,nPts - jindx2(j) = latsozp + 1 - do i=1,latsozp - if (dlat(j) < oz_lat(i)) then - jindx2(j) = i - exit - endif - enddo - jindx1(j) = max(jindx2(j)-1,1) - jindx2(j) = min(jindx2(j),latsozp) - if (jindx2(j) .ne. jindx1(j)) then - ddy(j) = (dlat(j) - oz_lat(jindx1(j))) / (oz_lat(jindx2(j)) - oz_lat(jindx1(j))) - else - ddy(j) = 1.0 - endif - enddo - - end subroutine ozphys_time_vary_init - -! ########################################################################################### -!> \section arg_table_ozphys_time_vary_timestep_init Argument Table -!! \htmlinclude ozphys_time_vary_timestep_init.html -!! -! ########################################################################################### - subroutine ozphys_time_vary_timestep_init(nPts, idate, fhour, jindx1, jindx2, latsozp, & - levozp, oz_coeff, timeoz, ozplin, oz_time, oz_lat, ddy, oz_data, errmsg, errflg) - ! Inputs - integer, intent(in) :: & - nPts, & ! Horizontal dimension - latsozp, & ! Number of latitudes in ozone data - levozp, & ! Number of vertical layers in ozone data - oz_coeff, & ! Number of coefficients in ozone data - timeoz ! Number of times in ozone data - integer, intent(in),dimension(:) :: & - idate, & ! Initial date with different size and ordering - jindx1, & ! Interpolation index (low) for ozone - jindx2 ! Interpolation index (high) for ozone - real(kind_phys), intent(in) :: & - fhour ! Forecast hour - real(kind_phys), intent(in), dimension(:) :: & - ddy, & ! Interpolation high index for ozone data - oz_lat, & ! Latitudes for ozone data - oz_time ! Time for ozone data - real(kind_phys), intent(in), dimension(:,:,:,:) :: & - ozplin ! Ozone data - - ! Outputs - real(kind_phys), intent(inout), dimension(:,:,:) :: & - oz_data ! Ozone forcing data - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local - integer :: idat(8),jdat(8),iday,j,j1,j2,l,nc,n1,n2,jdow,jdoy,& - jday,w3kindreal,w3kindint - real(kind_phys) :: tem, tx1, tx2, rjday - real(kind_dbl_prec) :: rinc(5) - real(kind_sngl_prec) :: rinc4(5) - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! - idat=0 - idat(1)=idate(4) - idat(2)=idate(2) - idat(3)=idate(3) - idat(5)=idate(1) - rinc=0. - rinc(2)=fhour - call w3kind(w3kindreal,w3kindint) - if(w3kindreal==4) then - rinc4=rinc - CALL w3movdat(rinc4,idat,jdat) - else - CALL w3movdat(rinc,idat,jdat) - endif - ! - jdow = 0 - jdoy = 0 - jday = 0 - call w3doxdat(jdat,jdow,jdoy,jday) - rjday = jdoy + jdat(5) / 24. - IF (RJDAY < oz_time(1)) RJDAY = RJDAY + 365. - ! - n2 = timeoz + 1 - do j=2,timeoz - if (rjday < oz_time(j)) then - n2 = j - exit - endif - enddo - n1 = n2 - 1 - - tx1 = (oz_time(n2) - rjday) / (oz_time(n2) - oz_time(n1)) - tx2 = 1.0 - tx1 - - if (n2 > timeoz) n2 = n2 - timeoz - ! - do nc=1,oz_coeff - do L=1,levozp - do J=1,npts - J1 = jindx1(J) - J2 = jindx2(J) - TEM = 1.0 - ddy(J) - oz_data(j,L,nc) = tx1*(TEM*ozplin(J1,L,nc,n1)+ddy(J)*ozplin(J2,L,nc,n1)) & - + tx2*(TEM*ozplin(J1,L,nc,n2)+ddy(J)*ozplin(J2,L,nc,n2)) - enddo - enddo - enddo - - return - - end subroutine ozphys_time_vary_timestep_init -!> @} -end module ozphys_time_vary diff --git a/physics/ozphys_time_vary.meta b/physics/ozphys_time_vary.meta deleted file mode 100644 index 75b8b8e4f..000000000 --- a/physics/ozphys_time_vary.meta +++ /dev/null @@ -1,200 +0,0 @@ -[ccpp-table-properties] - name = ozphys_time_vary - type = scheme - dependencies = machine.F - -######################################################################## -[ccpp-arg-table] - name = ozphys_time_vary_init - type = scheme -[nPts] - standard_name = horizontal_dimension - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data - units = count - dimensions = () - type = integer - intent = in -[oz_lat] - standard_name = ozone_data_latitude - long_name = ozone data latitude - units = deg - dimensions = (number_of_latitudes_in_ozone_data) - type = real - kind = kind_phys - intent = in -[dlat] - standard_name = latitude_in_degree - long_name = latitude in degree north - units = degree_north - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[jindx1] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[jindx2] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = inout -[ddy] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = ozphys_time_vary_timestep_init - type = scheme -[nPts] - standard_name = horizontal_dimension - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[idate] - standard_name = date_and_time_at_model_initialization_in_united_states_order - long_name = initial date with different size and ordering - units = none - dimensions = (4) - type = integer - intent = in -[fhour] - standard_name = forecast_time - long_name = current forecast time - units = h - dimensions = () - type = real - kind = kind_phys - intent = in -[jindx1] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[jindx2] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[latsozp] - standard_name = number_of_latitudes_in_ozone_data - long_name = number of latitude in ozone data - units = count - dimensions = () - type = integer - intent = in -[levozp] - standard_name = number_of_levels_in_ozone_data - long_name = number of levels in ozone data - units = count - dimensions = () - type = integer - intent = in -[oz_coeff] - standard_name = number_of_coefficients_in_ozone_data - long_name = number of coefficients in ozone data - units = count - dimensions = () - type = integer - intent = in -[timeoz] - standard_name = number_of_times_in_ozone_data - long_name = number of times in ozone data - units = count - dimensions = () - type = integer - intent = in -[ozplin] - standard_name = ozone_data - long_name = ozone data - units = 1 - dimensions = (number_of_latitudes_in_ozone_data,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data,number_of_times_in_ozone_data) - type = real - kind = kind_phys - intent = in -[oz_time] - standard_name = ozone_data_time - long_name = ozone data time - units = none - dimensions = (13) - type = real - kind = kind_phys - intent = in -[oz_lat] - standard_name = ozone_data_latitude - long_name = ozone data latitude - units = deg - dimensions = (number_of_latitudes_in_ozone_data) - type = real - kind = kind_phys - intent = in -[ddy] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in -[oz_data] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index 5f017598f..4c626b348 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -1,17 +1,14 @@ !> \file radiation_gases.f -!! This file contains routines that set up ozone climatological -!! profiles and other constant gas profiles, such as co2, ch4, n2o, -!! o2, and those of cfc gases. All data are entered as mixing ratio -!! by volume, except ozone which is mass mixing ratio (g/g). +!! This file contains routines that set up gas profiles, such as co2, +!! ch4, n2o, o2, and those of cfc gases. All data are entered as mixing +!! ratio by volume ! ========================================================== !!!!! ! 'module_radiation_gases' description !!!!! ! ========================================================== !!!!! ! ! -! set up ozone climatological profiles and other constant gas ! -! profiles, such as co2, ch4, n2o, o2, and those of cfc gases. All ! -! data are entered as mixing ratio by volume, except ozone which is ! -! mass mixing ratio (g/g). ! +! set up constant gas profiles, such as co2, ch4, n2o, o2, and those ! +! of cfc gases. All data are entered as mixing ratio by volume ! ! ! ! in the module, the externally callabe subroutines are : ! ! ! @@ -23,16 +20,10 @@ ! ! ! 'gas_update' -- read in data and update with time ! ! input: ! -! ( iyear, imon, iday, ihour, loz1st, ldoco2, me ) ! +! ( iyear, imon, iday, ihour, ldoco2, me ) ! ! output: ! ! ( errflg, errmsg ) ! ! ! -! 'getozn' -- setup climatological ozone profile ! -! input: ! -! ( prslk,xlat, ! -! IMAX, LM ) ! -! output: ! -! ( o3mmr ) ! ! ! ! 'getgases' -- setup constant gas profiles for LW and SW ! ! input: ! @@ -47,7 +38,6 @@ ! 'module module_iounitdef' in 'iounitdef.f' ! ! ! ! unit used for radiative active gases: ! -! ozone : mass mixing ratio (g/g) ! ! co2 : volume mixing ratio (p/p) ! ! n2o : volume mixing ratio (p/p) ! ! ch4 : volume mixing ratio (p/p) ! @@ -81,15 +71,6 @@ ! seasonal cycle calculations ! ! aug 2011 - y-t hou fix a bug in subr getgases doing vertical ! ! co2 mapping. (for top_at_1 case, not affact opr). ! -! aug 2012 - y-t hou modified subr getozn. moved the if-first ! -! block to subr gas_init to ensure threading safe in ! -! climatology ozone applications. (not affect gfs) ! -! also changed the initialization subr into two parts:! -! 'gas_init' is called at the start of run to set up ! -! module parameters; and 'gas_update' is called within! -! the time loop to check and update data sets. defined! -! the climatology ozone parameters k1oz,k2oz,facoz as ! -! module variables and are set in subr 'gas_update' ! ! nov 2012 - y-t hou modified control parameters thru module ! ! 'physparam'. ! ! jan 2013 - z. janjic/y. hou modified ilon (longitude index) ! @@ -105,10 +86,8 @@ !> \defgroup module_radiation_gases_mod Radiation Gases Module !> @{ -!> This module sets up ozone climatological profiles and other constant -!! gas profiles, such as co2, ch4, n2o, o2, and those of cfc gases. All -!! data are entered as mixing ratio by volume, except ozone which is -!! mass mixing ratio (g/g). +!> This module sets up constant gas profiles, such as co2, ch4, n2o, o2, +!! and those of cfc gases. All data are entered as mixing ratio by volume. !!\image html rad_gas_AGGI.png "Figure 1: Atmospheric radiative forcing, relative to 1750, by long-lived greenhouse gases and the 2016 update of the NOAA Annual Greenhouse Gas Index (AGGI)" !! NOAA Annual Greenhouse Gas Index (AGGI) shows that from 1990 to 2016, !! radiative forcing by long-lived greenhouse gases (LLGHGs) increased by @@ -121,10 +100,6 @@ !!\n ICO2=1: use observed global annual mean value !!\n ICO2=2: use observed monthly 2-d data table in \f$15^o\f$ horizontal resolution !! -!! O3 Distribution (namelist control parameter -\b NTOZ): -!!\n NTOZ=0: use seasonal and zonal averaged climatological ozone -!!\n NTOZ>0: use 3-D prognostic ozone -!! !! Trace Gases (currently using the global mean climatology in unit of ppmv): !! \f$CH_4-1.50\times10^{-6}\f$; !! \f$N_2O-0.31\times10^{-6}\f$; @@ -137,8 +112,8 @@ !! !!\version NCEP-Radiation_gases v5.1 Nov 2012 -!> This module sets up ozone climatological profiles and other constant gas -!! profiles, such as co2, ch4, n2o, o2, and those of cfc gases. +!> This module sets up constant gas rofiles, such as co2, ch4, n2o, o2, and those +!! of cfc gases. module module_radiation_gases use machine, only : kind_phys, kind_io4 use funcphys, only : fpkapx @@ -179,22 +154,8 @@ module module_radiation_gases ! gfdl 1999 value real (kind=kind_phys), parameter :: f113vmr_def= 8.2000e-11 -! --- ozone seasonal climatology parameters defined in module ozne_def -! - 4x5 ozone data parameter -! integer, parameter :: JMR=45, LOZ=17 -! real (kind=kind_phys), parameter :: blte=-86.0, dlte=4.0 -! - geos ozone data -! integer, parameter :: JMR=18, LOZ=17 -! real (kind=kind_phys), parameter :: blte=-85.0, dlte=10.0 - ! --- module variables to be set in subroutin gas_init and/or gas_update -! variables for climatology ozone (ioznflg = 0) - - real (kind=kind_phys), allocatable :: pkstr(:), o3r(:,:,:) - integer :: k1oz = 0, k2oz = 0 - real (kind=kind_phys) :: facoz = 0.0 - ! arrays for co2 2-d monthly data and global mean values from observed data real (kind=kind_phys), allocatable :: co2vmr_sav(:,:,:) @@ -209,33 +170,30 @@ module module_radiation_gases ! --- public interfaces - public gas_init, gas_update, getgases, getozn + public gas_init, gas_update, getgases ! ================= contains ! ================= -!> This subroutine sets up ozone, co2, etc. parameters. If climatology -!! ozone then read in monthly ozone data. +!> This subroutine sets up co2, etc. parameters. !!\param me print message control flag !!\param co2usr_file co2 user defined data table !!\param co2cyc_file co2 climotology monthly cycle data table !!\param ictmflg data ic time/date control flag !!\param ico2flg co2 data source control flag -!!\param ioznflg ozone data control flag !!\param con_pi physical constant Pi !!\param errflg error flag !!\param errmsg error message !>\section gas_init_gen gas_init General Algorithm !----------------------------------- subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & - & ictmflg, ioznflg, con_pi, JMR, LOZ, timeozc, errflg, errmsg) + & ictmflg, con_pi, errflg, errmsg) ! =================================================================== ! ! ! -! gas_init sets up ozone, co2, etc. parameters. if climatology ozone ! -! then read in monthly ozone data. ! +! gas_init sets up co2, etc. parameters. ! ! ! ! inputs: ! ! me - print message control flag ! @@ -256,9 +214,6 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & ! further data extrapolation. ! ! =yyyy1: use yyyy data for the fcst. if needed, do ! ! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! -! =0: use climatological ozone profile ! -! >0: use interactive ozone profile ! ! co2usr_file - external co2 user defined data table ! ! co2cyc_file - external co2 climotology monthly cycle data table ! ! con_pi - physical constant Pi ! @@ -267,9 +222,6 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & ! errflg - error flag ! ! errmsg - error message ! ! ! -! internal module variables: ! -! pkstr, o3r - arrays for climatology ozone data ! -! ! ! usage: call gas_init ! ! ! ! subprograms called: none ! @@ -279,8 +231,7 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & implicit none ! --- inputs: - integer, intent(in) :: me, ictmflg, ioznflg, ico2flg - integer, intent(in) :: JMR, LOZ, timeozc + integer, intent(in) :: me, ictmflg, ico2flg character(len=26),intent(in) :: co2usr_file,co2cyc_file real(kind=kind_phys), intent(in) :: con_pi @@ -291,10 +242,7 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & ! --- locals: real (kind=kind_phys), dimension(IMXCO2,JMXCO2) :: co2dat real (kind=kind_phys) :: co2g1, co2g2 - real (kind=kind_phys) :: pstr(LOZ) - real (kind=kind_io4) :: o3clim4(JMR,LOZ,12), pstr4(LOZ) - integer :: imond(12), ilat(JMR,12) integer :: i, j, k, iyr, imo logical :: file_exist, lextpl character :: cline*100, cform*8 @@ -316,78 +264,6 @@ subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & kyrsav = 0 kmonsav = 1 -! --- ... climatology ozone data section - - if ( ioznflg > 0 ) then - if ( me == 0 ) then - print *,' - Using interactive ozone distribution' - endif - else - if ( timeozc /= 12 ) then - print *,' - Using climatology ozone distribution' - print *,' timeozc=',timeozc, ' is not monthly mean', & - & ' - job aborting in subroutin gas_init!!!' - errflg = 1 - errmsg = 'ERROR(gas_init): Climatological o3 distribution '// & - & 'is not monthly mean' - return - endif - - allocate (pkstr(LOZ), o3r(JMR,LOZ,12)) - rewind NIO3CLM - - if ( LOZ == 17 ) then ! For the operational ozone climatology - do k = 1, LOZ - read (NIO3CLM,15) pstr4(k) - 15 format(f10.3) - enddo - - do imo = 1, 12 - do j = 1, JMR - read (NIO3CLM,16) imond(imo), ilat(j,imo), & - & (o3clim4(j,k,imo),k=1,10) - 16 format(i2,i4,10f6.2) - read (NIO3CLM,20) (o3clim4(j,k,imo),k=11,LOZ) - 20 format(6x,10f6.2) - enddo - enddo - else ! For newer ozone climatology - read (NIO3CLM) - do k = 1, LOZ - read (NIO3CLM) pstr4(k) - enddo - - do imo = 1, 12 - do k = 1, LOZ - read (NIO3CLM) (o3clim4(j,k,imo),j=1,JMR) - enddo - enddo - endif ! end if_LOZ_block -! - do imo = 1, 12 - do k = 1, LOZ - do j = 1, JMR - o3r(j,k,imo) = o3clim4(j,k,imo) * 1.655e-6 - enddo - enddo - enddo - - do k = 1, LOZ - pstr(k) = pstr4(k) - enddo - - if ( me == 0 ) then - print *,' - Using climatology ozone distribution' - print *,' Found ozone data for levels pstr=', & - & (pstr(k),k=1,LOZ) -! print *,' O3=',(o3r(15,k,1),k=1,LOZ) - endif - - do k = 1, LOZ - pkstr(k) = fpkapx(pstr(k)*100.0) - enddo - endif ! end if_ioznflg_block - ! --- ... co2 data section co2_glb = co2vmr_def @@ -541,20 +417,18 @@ end subroutine gas_init !!\param imon month of the year !!\param iday day of the month !!\param ihour hour of the day -!!\param loz1st clim ozone 1st time update control flag !!\param ldoco2 co2 update control flag !!\param me print message control flag !!\param co2dat_file co2 2d monthly obsv data table !!\param co2gbl_file co2 global annual mean data table !!\param ictmflg data ic time/date control flag !!\param ico2flg co2 data source control flag -!!\param ioznflg ozone data control flag !!\param errflg error flag !!\param errmsg error message !>\section gen_gas_update gas_update General Algorithm !----------------------------------- - subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & - & me, co2dat_file, co2gbl_file, ictmflg, ico2flg, ioznflg, & + subroutine gas_update(iyear, imon, iday, ihour, ldoco2, & + & me, co2dat_file, co2gbl_file, ictmflg, ico2flg, & & errflg, errmsg ) ! =================================================================== ! @@ -567,7 +441,6 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! imon - month of the year 1 ! ! iday - day of the month 1 ! ! ihour - hour of the day 1 ! -! loz1st - clim ozone 1st time update control flag 1 ! ! ldoco2 - co2 update control flag 1 ! ! me - print message control flag 1 ! ! ico2flg - co2 data source control flag ! @@ -587,9 +460,6 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! further data extrapolation. ! ! =yyyy1: use yyyy data for the fcst. if needed, do ! ! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! -! =0: use climatological ozone profile ! -! >0: use interactive ozone profile ! ! ivflip - vertical profile indexing flag ! ! co2dat_file - external co2 2d monthly obsv data table ! ! co2gbl_file - external co2 global annual mean data table ! @@ -603,8 +473,6 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! co2cyc_sav - monthly cycle co2 vol mixing ratio IMXCO2*JMXCO2*12 ! ! co2_glb - global annual mean co2 mixing ratio ! ! gco2cyc - global monthly mean co2 variation 12 ! -! k1oz,k2oz,facoz ! -! - climatology ozone parameters 1 ! ! ! ! usage: call gas_update ! ! ! @@ -616,9 +484,8 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & ! --- inputs: integer, intent(in) :: iyear,imon,iday,ihour,me,ictmflg,ico2flg - integer, intent(in) :: ioznflg character(len=26),intent(in) :: co2dat_file, co2gbl_file - logical, intent(in) :: loz1st, ldoco2 + logical, intent(in) :: ldoco2 ! --- output: character(len=*), intent(out) :: errmsg @@ -643,35 +510,6 @@ subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & errmsg = '' errflg = 0 -!> - Ozone data section - - if ( ioznflg == 0 ) then - midmon = mdays(imon)/2 + 1 - change = loz1st .or. ( (iday==midmon) .and. (ihour==0) ) -! - if ( change ) then - if ( iday < midmon ) then - k1oz = mod(imon+10, 12) + 1 - midm = mdays(k1oz)/2 + 1 - k2oz = imon - midp = mdays(k1oz) + midmon - else - k1oz = imon - midm = midmon - k2oz = mod(imon, 12) + 1 - midp = mdays(k2oz)/2 + 1 + mdays(k1oz) - endif - endif -! - if (iday < midmon) then - id = iday + mdays(k1oz) - else - id = iday - endif - - facoz = float(id - midm) / float(midp - midm) - endif - !> - co2 data section if ( ico2flg == 0 ) return ! use prescribed global mean co2 data @@ -1103,121 +941,6 @@ subroutine getgases( plvl, xlon, xlat, IMAX, LMAX, ico2flg, & end subroutine getgases !----------------------------------- -!> This subroutine sets up climatological ozone profile for radiation -!! calculation. This code is originally written by Shrinivas Moorthi. -!!\param prslk (IMAX,LM), exner function = \f$(p/p0)^{rocp}\f$ -!!\param xlat (IMAX), latitude in radians, default to pi/2 -> -!! -pi/2 range, otherwise see in-line comment -!!\param IMAX, LM (1), horizontal and vertical dimensions -!!\param top_at_1 (1), vertical profile indexing flag -!!\param o3mmr (IMAX,LM), output ozone profile in mass mixing -!! ratio (g/g) -!>\section getozn_gen getozn General Algorithm -!----------------------------------- - subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, JMR, LOZ, blte,& - & dlte, o3mmr) - -! =================================================================== ! -! ! -! getozn sets up climatological ozone profile for radiation calculation! -! ! -! this code is originally written By Shrinivas Moorthi ! -! ! -! inputs: ! -! prslk (IMAX,LM) - exner function = (p/p0)**rocp ! -! xlat (IMAX) - latitude in radians, default to pi/2 -> -pi/2 ! -! range, otherwise see in-line comment ! -! IMAX, LM - horizontal and vertical dimensions ! -! top_at_1 - vertical profile indexing flag ! -! ! -! outputs: ! -! o3mmr (IMAX,LM) - output ozone profile in mass mixing ratio (g/g)! -! ! -! module variables: ! -! k1oz, k2oz - ozone data interpolation indices ! -! facoz - ozone data interpolation factor ! -! ! -! usage: call getozn ! -! ! -! =================================================================== ! -! - implicit none - -! --- inputs: - integer, intent(in) :: IMAX, LM, JMR, LOZ - real(kind=kind_phys), intent(in) :: blte, dlte - logical, intent(in) :: top_at_1 - real (kind=kind_phys), intent(in) :: prslk(:,:), xlat(:) - -! --- outputs: - real (kind=kind_phys), intent(out) :: o3mmr(:,:) - -! --- locals: - real (kind=kind_phys) :: o3i(IMAX,LOZ), wk1(IMAX), deglat, elte, & - & tem, tem1, tem2, tem3, tem4, temp - integer :: i, j, k, l, j1, j2, ll -! -!===> ... begin here -! - elte = blte + (JMR-1)*dlte - - do i = 1, IMAX - deglat = xlat(i) * raddeg ! if xlat in pi/2 -> -pi/2 range -! deglat = 90.0 - xlat(i)*raddeg ! if xlat in 0 -> pi range - - if (deglat > blte .and. deglat < elte) then - tem1 = (deglat - blte) / dlte + 1 - j1 = tem1 - j2 = j1 + 1 - tem1 = tem1 - j1 - elseif (deglat <= blte) then - j1 = 1 - j2 = 1 - tem1 = 1.0 - elseif (deglat >= elte) then - j1 = JMR - j2 = JMR - tem1 = 1.0 - endif - - tem2 = 1.0 - tem1 - do j = 1, LOZ - tem3 = tem2*o3r(j1,j,k1oz) + tem1*o3r(j2,j,k1oz) - tem4 = tem2*o3r(j1,j,k2oz) + tem1*o3r(j2,j,k2oz) - o3i(i,j) = tem4*facoz + tem3*(1.0 - facoz) - enddo - enddo - - do l = 1, LM - ll = l - if (.not. top_at_1) ll = LM -l + 1 - - do i = 1, IMAX - wk1(i) = prslk(i,ll) - enddo - - do k = 1, LOZ-1 - temp = 1.0 / (pkstr(k+1) - pkstr(k)) - - do i = 1, IMAX - if (wk1(i) > pkstr(k) .and. wk1(i) <= pkstr(k+1)) then - tem = (pkstr(k+1) - wk1(i)) * temp - o3mmr(I,ll) = tem * o3i(i,k) + (1.0 - tem) * o3i(i,k+1) - endif - enddo - enddo - - do i = 1, IMAX - if (wk1(i) > pkstr(LOZ)) o3mmr(i,ll) = o3i(i,LOZ) - if (wk1(i) < pkstr(1)) o3mmr(i,ll) = o3i(i,1) - enddo - enddo -! - return -!................................... - end subroutine getozn -!----------------------------------- - ! !........................................! end module module_radiation_gases ! diff --git a/physics/rrtmgp_lw_main.F90 b/physics/rrtmgp_lw_main.F90 index 67f7f749a..01b25c925 100644 --- a/physics/rrtmgp_lw_main.F90 +++ b/physics/rrtmgp_lw_main.F90 @@ -19,7 +19,6 @@ module rrtmgp_lw_main use rrtmgp_lw_gas_optics, only: lw_gas_props,rrtmgp_lw_gas_optics_init use rrtmgp_lw_cloud_optics, only: lw_cloud_props, rrtmgp_lw_cloud_optics_init, abssnow0, & abssnow1, absrain - use module_radiation_gases, only: NF_VGAS, getgases, getozn use GFS_rrtmgp_pre, only: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, & iStr_o2, iStr_ccl4, iStr_cfc11, iStr_cfc12, iStr_cfc22, & eps, oneminus, ftiny From 2886df96f645f9366d7d0496ac654fc178264e7d Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 14:23:36 -0600 Subject: [PATCH 44/58] Small cosmetic changes --- physics/GFS_phys_time_vary.fv3.F90 | 53 ++++++++++++++---------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index af2dd9b00..f72763c3a 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -219,14 +219,6 @@ subroutine GFS_phys_time_vary_init ( !$OMP sections -!$OMP section -!> - Setup spatial interpolation indices for ozone physics. - if (ntoz > 0) then - !$OMP CRITICAL - call ozphys%setup_forcing(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) - !$OMP END CRITICAL - endif - !$OMP section !> - Call read_h2odata() to read stratospheric water vapor data call read_h2odata (h2o_phys, me, master) @@ -294,6 +286,12 @@ subroutine GFS_phys_time_vary_init ( !$OMP sections +!$OMP section +!> - Setup spatial interpolation indices for ozone physics. + if (ntoz > 0) then + call ozphys%setup_forcing(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) + endif + !$OMP section !> - Call setindxh2o() to initialize stratospheric water vapor data if (h2o_phys) then @@ -803,21 +801,7 @@ subroutine GFS_phys_time_vary_timestep_init ( return end if -!$OMP parallel num_threads(nthrds) default(none) & -!$OMP shared(kdt,nsswr,lsswr,clstp,imfdeepcnv,cal_pre,random_clds) & -!$OMP shared(fhswr,fhour,seed0,cnx,cny,nrcm,wrk,rannie,rndval) & -!$OMP shared(rann,im,isc,jsc,imap,jmap,ntoz,me,idate,jindx1_o3,jindx2_o3) & -!$OMP shared(ozpl,ddy_o3,h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & -!$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & -!$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & -!$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & -!$OMP private(iseed,iskip,i,j,rjday,idat,rinc,w3kindreal,w3kindint,jdat)& -!$OMP private(jdow,jdoy,jday,rinc4,n1,n2) - -!$OMP sections - -!$OMP section -!> - Compute temporal interpolation indices for updating gas concentrations. + !> - Compute temporal interpolation indices for updating gas concentrations. idat=0 idat(1)=idate(4) idat(2)=idate(2) @@ -849,12 +833,17 @@ subroutine GFS_phys_time_vary_timestep_init ( n1 = n2 - 1 if (n2 > ozphys%ntime) n2 = n2 - ozphys%ntime - !> - Update ozone concentration. - if (ntoz > 0) then - !$OMP CRITICAL - call ozphys%update_forcing(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) - !$OMP END CRITICAL - endif +!$OMP parallel num_threads(nthrds) default(none) & +!$OMP shared(kdt,nsswr,lsswr,clstp,imfdeepcnv,cal_pre,random_clds) & +!$OMP shared(fhswr,fhour,seed0,cnx,cny,nrcm,wrk,rannie,rndval) & +!$OMP shared(rann,im,isc,jsc,imap,jmap,ntoz,me,idate,jindx1_o3,jindx2_o3) & +!$OMP shared(ozpl,ddy_o3,h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & +!$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & +!$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & +!$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & +!$OMP private(iseed,iskip,i,j) + +!$OMP sections !$OMP section @@ -901,6 +890,12 @@ subroutine GFS_phys_time_vary_timestep_init ( endif ! imfdeepcnv, cal_re, random_clds +!$OMP section +!> - Update ozone concentration. + if (ntoz > 0) then + call ozphys%update_forcing(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) + endif + !$OMP section !> - Call h2ointerpol() to make stratospheric water vapor data interpolation if (h2o_phys) then From 17b057ce219479a3e46e9c8d7825736a0935083c Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 14:28:52 -0600 Subject: [PATCH 45/58] Housekeeping --- physics/GFS_phys_time_vary.fv3.F90 | 2 +- physics/GFS_phys_time_vary.fv3.meta | 59 ++++++++++++++--------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index f72763c3a..6fa188471 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -841,7 +841,7 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & !$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & !$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & -!$OMP private(iseed,iskip,i,j) +!$OMP private(iseed,iskip,i,j,k) !$OMP sections diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index bf5a3fa04..639e2db6a 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -30,6 +30,13 @@ dimensions = () type = logical intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [iaerclm] standard_name = flag_for_aerosol_input_MG_radiation long_name = flag for using aerosols in Morrison-Gettelman MP_radiation @@ -72,36 +79,6 @@ dimensions = () type = integer intent = in - intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in -[jindx1_o3] - standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation low index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[jindx2_o3] - standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation - long_name = interpolation high index for ozone - units = index - dimensions = (horizontal_dimension) - type = integer - intent = in -[ddy_o3] - standard_name = latitude_interpolation_weight_for_ozone_forcing - long_name = interpolation high index for ozone - units = none - dimensions = (horizontal_dimension) - type = real - kind = kind_phys - intent = in [nx] standard_name = number_of_points_in_x_direction_for_this_MPI_rank long_name = number of points in x direction for this MPI rank @@ -139,6 +116,28 @@ type = real kind = kind_phys intent = in +[jindx1_o3] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[jindx2_o3] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[ddy_o3] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor From 17203fe06a90612ad09a357e8084510c4a277d58 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 14:32:20 -0600 Subject: [PATCH 46/58] Housekeeping --- physics/GFS_phys_time_vary.fv3.meta | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index 639e2db6a..ad543e146 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -23,13 +23,6 @@ dimensions = () type = integer intent = in -[h2o_phys] - standard_name = flag_for_stratospheric_water_vapor_physics - long_name = flag for stratospheric water vapor physics - units = flag - dimensions = () - type = logical - intent = in [ntoz] standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array long_name = tracer index for ozone mixing ratio @@ -37,6 +30,13 @@ dimensions = () type = integer intent = in +[h2o_phys] + standard_name = flag_for_stratospheric_water_vapor_physics + long_name = flag for stratospheric water vapor physics + units = flag + dimensions = () + type = logical + intent = in [iaerclm] standard_name = flag_for_aerosol_input_MG_radiation long_name = flag for using aerosols in Morrison-Gettelman MP_radiation From 3f6168b12443a79adf7abcdf326bcfa6813c8d84 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 15:49:35 -0600 Subject: [PATCH 47/58] More reorg. --- physics/GFS_phys_time_vary.fv3.F90 | 9 +- physics/GFS_rrtmg_pre.F90 | 2 +- physics/GFS_rrtmg_setup.F90 | 2 +- physics/GFS_rrtmgp_pre.F90 | 2 +- physics/GFS_rrtmgp_setup.F90 | 2 +- physics/GFS_suite_stateout_update.F90 | 135 +++++++++++++++---------- physics/GFS_suite_stateout_update.meta | 95 ++++++++++++++++- physics/module_ozphys.F90 | 50 ++++----- 8 files changed, 209 insertions(+), 88 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 6fa188471..70eeb81e1 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -95,6 +95,7 @@ subroutine GFS_phys_time_vary_init ( integer, intent(in) :: lkm integer, intent(inout) :: use_lake_model(:) real(kind=kind_phys), intent(in ) :: lakefrac(:), lakedepth(:) + integer, intent(inout) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) real(kind_phys), intent(inout) :: ddy_o3(:), ddy_h(:) real(kind_phys), intent(in) :: h2opl(:,:,:) @@ -289,7 +290,7 @@ subroutine GFS_phys_time_vary_init ( !$OMP section !> - Setup spatial interpolation indices for ozone physics. if (ntoz > 0) then - call ozphys%setup_forcing(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) + call ozphys%setup_o3prog(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) endif !$OMP section @@ -729,7 +730,7 @@ subroutine GFS_phys_time_vary_timestep_init ( lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, & tsfc, tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, zorli, zorll, & zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, stype,scolor, shdmin, shdmax, snowd, & - cv, cvb, cvt, oro, oro_uf, xlat_d, xlon_d, slmsk, landfrac, ozphys, & + cv, cvb, cvt, oro, oro_uf, xlat_d, xlon_d, slmsk, landfrac, ozphys, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, tau_amf, errmsg, errflg) implicit none @@ -841,7 +842,7 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & !$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & !$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & -!$OMP private(iseed,iskip,i,j,k) +!$OMP private(iseed,iskip,i,j,k,rjday,n1,n2) !$OMP sections @@ -893,7 +894,7 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP section !> - Update ozone concentration. if (ntoz > 0) then - call ozphys%update_forcing(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) + call ozphys%update_o3prog(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) endif !$OMP section diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 69be4f8d0..108d6f407 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -434,7 +434,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& enddo enddo else ! climatological ozone - call ozphys%oz_clim(xlat, prslk1, con_pi, olyr) + call ozphys%run_o3clim(xlat, prslk1, con_pi, olyr) endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 908a364dc..e48a60ac8 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -467,7 +467,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& call gas_update ( kyear,kmon,kday,khour,lco2_chg, me, co2dat_file, & co2gbl_file, ictm, ico2, errflg, errmsg ) if (ntoz == 0) then - call ozphys%update_clim(kmon, kday, khour, loz1st) + call ozphys%update_o3clim(kmon, kday, khour, loz1st) endif if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 9dcc002a0..cbf8d161b 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -353,7 +353,7 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhl enddo ! OR Use climatological ozone data else - call ozphys%oz_clim(xlat, prslk, con_pi, o3_lay) + call ozphys%run_o3clim(xlat, prslk, con_pi, o3_lay) endif ! ####################################################################################### diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 3e4f57d13..9f2b2a9f9 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -243,7 +243,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad call gas_update (kyear, kmon, kday, khour, lco2_chg, me, co2dat_file, co2gbl_file, ictm,& ico2, errflg, errmsg ) if (ntoz == 0) then - call ozphys%update_clim(kmon, kday, khour, loz1st) + call ozphys%update_o3clim(kmon, kday, khour, loz1st) endif if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_suite_stateout_update.F90 b/physics/GFS_suite_stateout_update.F90 index 2771c3e82..41f44e0de 100644 --- a/physics/GFS_suite_stateout_update.F90 +++ b/physics/GFS_suite_stateout_update.F90 @@ -1,63 +1,90 @@ +! ######################################################################################### !> \file GFS_suite_stateout_update.f90 -!! Contains code to update the state variables due to process-split physics from accumulated tendencies during that phase. +!! Update the state variables due to process-split physics from accumulated tendencies +!! during that phase. +!! Update gas concentrations, if using prognostic photolysis schemes. !! Also, set bounds on the mass-weighted rime factor when using Ferrier-Aligo microphysics. - - module GFS_suite_stateout_update - - contains - +! ######################################################################################### +module GFS_suite_stateout_update + use machine, only: kind_phys + use module_ozphys, only: ty_ozphys + implicit none +contains +! ######################################################################################### !> \section arg_table_GFS_suite_stateout_update_run Argument Table !! \htmlinclude GFS_suite_stateout_update_run.html !! - subroutine GFS_suite_stateout_update_run (im, levs, ntrac, dtp, & - tgrs, ugrs, vgrs, qgrs, dudt, dvdt, dtdt, dqdt, & - gt0, gu0, gv0, gq0, ntiw, nqrimef, imp_physics, & - imp_physics_fer_hires, epsq, errmsg, errflg) - - use machine, only: kind_phys - - implicit none - - ! Interface variables - integer, intent(in ) :: im - integer, intent(in ) :: levs - integer, intent(in ) :: ntrac - integer, intent(in ) :: imp_physics,imp_physics_fer_hires - integer, intent(in ) :: ntiw, nqrimef - real(kind=kind_phys), intent(in ) :: dtp, epsq - - real(kind=kind_phys), intent(in ), dimension(:,:) :: tgrs, ugrs, vgrs - real(kind=kind_phys), intent(in ), dimension(:,:,:) :: qgrs - real(kind=kind_phys), intent(in ), dimension(:,:) :: dudt, dvdt, dtdt - real(kind=kind_phys), intent(in ), dimension(:,:,:) :: dqdt - real(kind=kind_phys), intent(out), dimension(:,:) :: gt0, gu0, gv0 - real(kind=kind_phys), intent(out), dimension(:,:,:) :: gq0 - - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - integer :: i, k - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - gt0(:,:) = tgrs(:,:) + dtdt(:,:) * dtp - gu0(:,:) = ugrs(:,:) + dudt(:,:) * dtp - gv0(:,:) = vgrs(:,:) + dvdt(:,:) * dtp - gq0(:,:,:) = qgrs(:,:,:) + dqdt(:,:,:) * dtp - - if (imp_physics == imp_physics_fer_hires) then +! ######################################################################################### + subroutine GFS_suite_stateout_update_run (im, levs, ntrac, dtp, tgrs, ugrs, vgrs, qgrs, & + dudt, dvdt, dtdt, dqdt, gt0, gu0, gv0, gq0, oz0, ntiw, nqrimef, imp_physics, & + imp_physics_fer_hires, epsq, ozphys, oz_phys_2015, oz_phys_2006, con_1ovg, prsl, & + dp, ozpl, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, errmsg, errflg) + + ! Inputs + integer, intent(in ) :: im + integer, intent(in ) :: levs + integer, intent(in ) :: ntrac + integer, intent(in ) :: imp_physics,imp_physics_fer_hires + integer, intent(in ) :: ntiw, nqrimef + real(kind=kind_phys), intent(in ) :: dtp, epsq, con_1ovg + real(kind=kind_phys), intent(in ), dimension(:,:) :: tgrs, ugrs, vgrs, prsl, dp + real(kind=kind_phys), intent(in ), dimension(:,:,:) :: qgrs, ozpl + real(kind=kind_phys), intent(in ), dimension(:,:) :: dudt, dvdt, dtdt + real(kind=kind_phys), intent(in ), dimension(:,:,:) :: dqdt + logical, intent(in) :: oz_phys_2015 + logical, intent(in) :: oz_phys_2006 + type(ty_ozphys), intent(in) :: ozphys + + ! Outputs (optional) + real(kind=kind_phys), intent(inout), dimension(:,:), pointer, optional :: & + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect + + ! Outputs + real(kind=kind_phys), intent(out), dimension(:,:) :: gt0, gu0, gv0, oz0 + real(kind=kind_phys), intent(out), dimension(:,:,:) :: gq0 + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + + ! Locals + integer :: i, k + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Update prognostic state varaibles using accumulated tendencies from "process-split" + ! section of GFS suite. + gt0(:,:) = tgrs(:,:) + dtdt(:,:) * dtp + gu0(:,:) = ugrs(:,:) + dudt(:,:) * dtp + gv0(:,:) = vgrs(:,:) + dvdt(:,:) * dtp + gq0(:,:,:) = qgrs(:,:,:) + dqdt(:,:,:) * dtp + + ! If using photolysis physics schemes, update (prognostic) gas concentrations using + ! updated state. + if (oz_phys_2015) then + call ozphys%run_o3prog_2015(con_1ovg, dtp, prsl, gt0, dp, ozpl, oz0, do3_dt_prd, & + do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz) + endif + if (oz_phys_2006) then + call ozphys%run_o3prog_2006() + endif + + ! If using Ferrier-Aligo microphysics, set bounds on the mass-weighted rime factor. + if (imp_physics == imp_physics_fer_hires) then do k=1,levs - do i=1,im - if(gq0(i,k,ntiw) > epsq) then - gq0(i,k,nqrimef) = max(1., gq0(i,k,nqrimef)/gq0(i,k,ntiw)) - else - gq0(i,k,nqrimef) = 1. - end if - end do + do i=1,im + if(gq0(i,k,ntiw) > epsq) then + gq0(i,k,nqrimef) = max(1., gq0(i,k,nqrimef)/gq0(i,k,ntiw)) + else + gq0(i,k,nqrimef) = 1. + end if + end do end do - end if + end if - end subroutine GFS_suite_stateout_update_run + end subroutine GFS_suite_stateout_update_run - end module GFS_suite_stateout_update \ No newline at end of file +end module GFS_suite_stateout_update diff --git a/physics/GFS_suite_stateout_update.meta b/physics/GFS_suite_stateout_update.meta index 580482b71..8cbab9139 100644 --- a/physics/GFS_suite_stateout_update.meta +++ b/physics/GFS_suite_stateout_update.meta @@ -2,7 +2,7 @@ [ccpp-table-properties] name = GFS_suite_stateout_update type = scheme - dependencies = machine.F + dependencies = machine.F,module_ozphys.F90 ######################################################################## [ccpp-arg-table] @@ -37,6 +37,27 @@ type = real kind = kind_phys intent = in +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = in +[oz_phys_2015] + standard_name = flag_for_nrl_2015_ozone_scheme + long_name = flag for new (2015) ozone physics + units = flag + dimensions = () + type = logical + intent = in +[oz_phys_2006] + standard_name = flag_for_nrl_2006_ozone_scheme + long_name = flag for new (2006) ozone physics + units = flag + dimensions = () + type = logical + intent = in [tgrs] standard_name = air_temperature long_name = model layer mean temperature @@ -133,6 +154,14 @@ type = real kind = kind_phys intent = out +[oz0] + standard_name = ozone_concentration_of_new_state + long_name = ozone concentration updated by physics + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [ntiw] standard_name = index_of_cloud_ice_mixing_ratio_in_tracer_concentration_array long_name = tracer index for ice water @@ -169,6 +198,70 @@ type = real kind = kind_phys intent = in +[con_1ovg] + standard_name = one_divided_by_the_gravitational_acceleration + long_name = inverse of gravitational acceleration + units = s2 m-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[prsl] + standard_name = air_pressure + long_name = mid-layer pressure + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[ozpl] + standard_name = ozone_forcing + long_name = ozone forcing data + units = mixed + dimensions = (horizontal_loop_extent,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + type = real + kind = kind_phys + intent = in +[dp] + standard_name = air_pressure_difference_between_midlayers + long_name = difference between mid-layer pressures + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[do3_dt_prd] + standard_name = ozone_tendency_due_to_production_and_loss_rate + long_name = ozone tendency due to production and loss rate + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[do3_dt_ozmx] + standard_name = ozone_tendency_due_to_ozone_mixing_ratio + long_name = ozone tendency due to ozone mixing ratio + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[do3_dt_temp] + standard_name = ozone_tendency_due_to_temperature + long_name = ozone tendency due to temperature + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[do3_dt_ohoz] + standard_name = ozone_tendency_due_to_overhead_ozone_column + long_name = ozone tendency due to overhead ozone column + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/module_ozphys.F90 b/physics/module_ozphys.F90 index 966d27113..205a02b46 100644 --- a/physics/module_ozphys.F90 +++ b/physics/module_ozphys.F90 @@ -41,21 +41,22 @@ module module_ozphys integer :: k2oz !< Upper interpolation index in datac(dim=3), time dim real(kind_phys) :: facoz !< Parameter for ozone climotology contains - procedure, public :: load_forcing - procedure, public :: load_clim - procedure, public :: setup_forcing - procedure, public :: update_forcing - procedure, public :: update_clim - procedure, public :: oz_prog_2015 - procedure, public :: oz_prog_2006 - procedure, public :: oz_clim + procedure, public :: load_o3prog + procedure, public :: setup_o3prog + procedure, public :: update_o3prog + procedure, public :: run_o3prog_2015 + procedure, public :: run_o3prog_2006 + ! + procedure, public :: load_o3clim + procedure, public :: update_o3clim + procedure, public :: run_o3clim end type ty_ozphys contains ! ######################################################################################### ! Procedure (type-bound) for loading ozone forcing data. ! ######################################################################################### - function load_forcing(this, file, fileID) result (err_message) + function load_o3prog(this, file, fileID) result (err_message) class(ty_ozphys), intent(inout) :: this integer, intent(in) :: fileID character(len=*), intent(in) :: file @@ -97,12 +98,12 @@ function load_forcing(this, file, fileID) result (err_message) deallocate(tempin) close(fileID) - end function load_forcing + end function load_o3prog ! ######################################################################################### ! Procedure for setting up interpolation indices between data and model grid. ! ######################################################################################### - subroutine setup_forcing(this, lat, idx1, idx2, idxh) + subroutine setup_o3prog(this, lat, idx1, idx2, idxh) class(ty_ozphys), intent(in) :: this real(kind_phys), intent(in) :: lat(:) integer, intent(out) :: idx1(:), idx2(:) @@ -126,12 +127,12 @@ subroutine setup_forcing(this, lat, idx1, idx2, idxh) endif enddo - end subroutine setup_forcing + end subroutine setup_o3prog ! ######################################################################################### ! Procedure (type-bound) for updating ozone data. ! ######################################################################################### - subroutine update_forcing(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl) + subroutine update_o3prog(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl) class(ty_ozphys), intent(in) :: this integer, intent(in) :: idx1(:), idx2(:) real(kind_phys), intent(in) :: idxh(:) @@ -156,12 +157,12 @@ subroutine update_forcing(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl) enddo enddo - end subroutine update_forcing + end subroutine update_o3prog ! ######################################################################################### ! Procedure (type-bound) for NRL prognostic ozone (2015). ! ######################################################################################### - subroutine oz_prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, do3_dt_ozmx, & + subroutine run_o3prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, do3_dt_ozmx, & do3_dt_temp, do3_dt_ohoz) class(ty_ozphys), intent(in) :: this real(kind_phys),intent(in) :: & @@ -267,21 +268,20 @@ subroutine oz_prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, do3_ enddo return - end subroutine oz_prog_2015 + end subroutine run_o3prog_2015 ! ######################################################################################### ! Procedure (type-bound) for NRL prognostic ozone (2006). ! ######################################################################################### - subroutine oz_prog_2006(this) + subroutine run_o3prog_2006(this) class(ty_ozphys), intent(in) :: this return - end subroutine oz_prog_2006 + end subroutine run_o3prog_2006 ! ######################################################################################### ! Procedure (type-bound) for NRL updating climotological ozone. - ! Build this up from getozn. ! ######################################################################################### - subroutine oz_clim(this, lat, prslk, con_pi, oz) + subroutine run_o3clim(this, lat, prslk, con_pi, oz) class(ty_ozphys), intent(in) :: this real(kind_phys), intent(in) :: & con_pi ! Physics constant: Pi @@ -356,12 +356,12 @@ subroutine oz_clim(this, lat, prslk, con_pi, oz) enddo return - end subroutine oz_clim + end subroutine run_o3clim ! ######################################################################################### ! Procedure (type-bound) for loading ozone climo data. ! ######################################################################################### - function load_clim(this, file, fileID) result (err_message) + function load_o3clim(this, file, fileID) result (err_message) class(ty_ozphys), intent(inout) :: this integer, intent(in) :: fileID character(len=*), intent(in) :: file @@ -432,12 +432,12 @@ function load_clim(this, file, fileID) result (err_message) this%pkstr(iLev) = fpkapx(this%pstr(iLev)*100.0) enddo - end function load_clim + end function load_o3clim ! ######################################################################################### ! Procedure (type-bound) for updating ozone climotological data. ! ######################################################################################### - subroutine update_clim(this, imon, iday, ihour, loz1st) + subroutine update_o3clim(this, imon, iday, ihour, loz1st) class(ty_ozphys), intent(inout) :: this integer, intent(in) :: imon, iday, ihour logical, intent(in) :: loz1st @@ -471,6 +471,6 @@ subroutine update_clim(this, imon, iday, ihour, loz1st) this%facoz = float(id - midm) / float(midp - midm) - end subroutine update_clim + end subroutine update_o3clim end module module_ozphys From d0a4bfd63fae9f4e4a06cb5598049f1019aed945 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 15:50:51 -0600 Subject: [PATCH 48/58] Remove ozphysics modules. Now part of ty_ozphys --- physics/ozphys_2015.F90 | 167 --------------------------------------- physics/ozphys_2015.meta | 140 -------------------------------- 2 files changed, 307 deletions(-) delete mode 100644 physics/ozphys_2015.F90 delete mode 100644 physics/ozphys_2015.meta diff --git a/physics/ozphys_2015.F90 b/physics/ozphys_2015.F90 deleted file mode 100644 index 1478d0d6e..000000000 --- a/physics/ozphys_2015.F90 +++ /dev/null @@ -1,167 +0,0 @@ -! ########################################################################################### -!> \file ozphys_2015.F90 -!! -! ########################################################################################### -module ozphys_2015 - use machine, only: kind_phys, kind_dbl_prec, kind_sngl_prec - use module_ozphys, only: ty_ozphys - implicit none - public ozphys_2015_run -contains - -! ########################################################################################### -!>\defgroup GFS_ozphys_2015 GFS Ozone Photochemistry (2015) Module -!! This module contains the CCPP-compliant Ozone 2015 photochemistry scheme. -!> @{ -!> The operational GFS currently parameterizes ozone production and destruction based on -!! monthly mean coefficients ( \c ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77) provided by -!! Naval Research Laboratory through CHEM2D chemistry model -!! (McCormack et al. (2006) \cite mccormack_et_al_2006). -!! (https://doi.org/10.5194/acp-6-4943-2006) -!! -!> \section genal_ozphys_2015 GFS ozphys_2015_run General Algorithm -!> - This code assumes that both 2D fields are ordered from bottom to top. -!> - This code is specifically for NRL parameterization and climatological T and O3 are in -! location 5 and 6 of ozpl array -!!\author June 2015 - Shrinivas Moorthi -!!\modified May 2023 - Dustin Swales -! ########################################################################################### - -! ########################################################################################### -! SUBROUTINE ozphys_2015_run -! ########################################################################################### -!! \section arg_table_ozphys_2015_run Argument Table -!! \htmlinclude ozphys_2015_run.html -!! - subroutine ozphys_2015_run (oz_phys, ozphys, nCol, nLev, dt, oz, tin, prsl, ozpl, & - delp, con_1ovg, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - oz_phys ! Flag for ozone_physics_2015 scheme. - type(ty_ozphys),intent(in) :: & - ozphys - real(kind_phys),intent(in) :: & - con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) - integer, intent(in) :: & - nCol, & ! Horizontal dimension - nLev ! Number of vertical layers - real(kind_phys), intent(in) :: & - dt ! Physics timestep (seconds) - real(kind_phys), intent(in), dimension(:,:) :: & - prsl, & ! Air-pressure (Pa) - tin, & ! Temperature of new-state (K) - delp ! Difference between mid-layer pressures (Pa) - real(kind_phys), intent(in), dimension(:,:,:) :: & - ozpl ! Ozone forcing data - - ! Outputs (optional) - real(kind=kind_phys), intent(inout), dimension(:,:), pointer, optional :: & - do3_dt_prd, & ! Physics tendency: production and loss effect - do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect - do3_dt_temp, & ! Physics tendency: temperature effect - do3_dt_ohoz ! Physics tendency: overhead ozone effect - - ! Outputs - real(kind=kind_phys), intent(inout), dimension(:,:) :: & - oz ! Ozone concentration updated by physics - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Locals - integer :: k, kmax, kmin, l, i, j - logical, dimension(nCol) :: flg - real(kind_phys) :: pmax, pmin, tem, temp - real(kind_phys), dimension(nCol) :: wk1, wk2, wk3, ozib - real(kind_phys), dimension(nCol,ozphys%ncf) :: prod - real(kind_phys), dimension(nCol,nLev) :: ozi - real(kind_phys), dimension(nCol,nLev+1) :: colo3, coloz - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Sanity checks - if (.not.oz_phys) then - write (errmsg,'(*(a))') 'Logic error: oz_phys_2015 == .false.' - errflg = 1 - return - endif - - ! Temporaries - ozi = oz - - colo3(:,nLev+1) = 0.0 - coloz(:,nLev+1) = 0.0 - - do l=nLev,1,-1 - pmin = 1.0e10 - pmax = -1.0e10 - - do i=1,nCol - wk1(i) = log(prsl(i,l)) - pmin = min(wk1(i), pmin) - pmax = max(wk1(i), pmax) - prod(i,:) = 0.0 - enddo - kmax = 1 - kmin = 1 - do k=1,ozphys%nlev-1 - if (pmin < ozphys%po3(k)) kmax = k - if (pmax < ozphys%po3(k)) kmin = k - enddo - ! - do k=kmin,kmax - temp = 1.0 / (ozphys%po3(k) - ozphys%po3(k+1)) - do i=1,nCol - flg(i) = .false. - if (wk1(i) < ozphys%po3(k) .and. wk1(i) >= ozphys%po3(k+1)) then - flg(i) = .true. - wk2(i) = (wk1(i) - ozphys%po3(k+1)) * temp - wk3(i) = 1.0 - wk2(i) - endif - enddo - do j=1,ozphys%ncf - do i=1,nCol - if (flg(i)) then - prod(i,j) = wk2(i) * ozpl(i,k,j) + wk3(i) * ozpl(i,k+1,j) - endif - enddo - enddo - enddo - - do j=1,ozphys%ncf - do i=1,nCol - if (wk1(i) < ozphys%po3(ozphys%nlev)) then - prod(i,j) = ozpl(i,ozphys%nlev,j) - endif - if (wk1(i) >= ozphys%po3(1)) then - prod(i,j) = ozpl(i,1,j) - endif - enddo - enddo - do i=1,nCol - colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l)*con_1ovg - coloz(i,l) = coloz(i,l+1) + prod(i,6) * delp(i,l)*con_1ovg - prod(i,2) = min(prod(i,2), 0.0) - enddo - do i=1,nCol - ozib(i) = ozi(i,l) ! no filling - tem = prod(i,1) - prod(i,2) * prod(i,6) + prod(i,3) * (tin(i,l) - prod(i,5)) & - + prod(i,4) * (colo3(i,l)-coloz(i,l)) - oz(i,l) = (ozib(i) + tem*dt) / (1.0 - prod(i,2)*dt) - enddo - - ! Diagnostics (optional) - if (associated(do3_dt_prd)) do3_dt_prd(:,l) = (prod(:,1)-prod(:,2)*prod(:,6))*dt - if (associated(do3_dt_ozmx)) do3_dt_ozmx(:,l) = (oz(:,l) - ozib(:)) - if (associated(do3_dt_temp)) do3_dt_temp(:,l) = prod(:,3)*(tin(:,l)-prod(:,5))*dt - if (associated(do3_dt_ohoz)) do3_dt_ohoz(:,l) = prod(:,4) * (colo3(:,l)-coloz(:,l))*dt - enddo - - return - end subroutine ozphys_2015_run -!> @} -end module ozphys_2015 diff --git a/physics/ozphys_2015.meta b/physics/ozphys_2015.meta deleted file mode 100644 index ca2d56e4e..000000000 --- a/physics/ozphys_2015.meta +++ /dev/null @@ -1,140 +0,0 @@ -[ccpp-table-properties] - name = ozphys_2015 - type = scheme - dependencies = machine.F,module_ozphys.F90 - -######################################################################## -[ccpp-arg-table] - name = ozphys_2015_run - type = scheme -[oz_phys] - standard_name = flag_for_nrl_2015_ozone_scheme - long_name = flag for new (2015) ozone physics - units = flag - dimensions = () - type = logical - intent = in -[ozphys] - standard_name = dataset_for_ozone_physics - long_name = dataset for NRL ozone physics - units = mixed - dimensions = () - type = ty_ozphys - intent = in -[nCol] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical layers - units = count - dimensions = () - type = integer - intent = in -[dt] - standard_name = timestep_for_physics - long_name = physics time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[oz] - standard_name = ozone_concentration_of_new_state - long_name = ozone concentration updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[tin] - standard_name = air_temperature_of_new_state - long_name = updated air temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[prsl] - standard_name = air_pressure - long_name = mid-layer pressure - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[ozpl] - standard_name = ozone_forcing - long_name = ozone forcing data - units = mixed - dimensions = (horizontal_loop_extent,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) - type = real - kind = kind_phys - intent = in -[delp] - standard_name = air_pressure_difference_between_midlayers - long_name = difference between mid-layer pressures - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[con_1ovg] - standard_name = one_divided_by_the_gravitational_acceleration - long_name = inverse of gravitational acceleration - units = s2 m-1 - dimensions = () - type = real - kind = kind_phys - intent = in -[do3_dt_prd] - standard_name = ozone_tendency_due_to_production_and_loss_rate - long_name = ozone tendency due to production and loss rate - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[do3_dt_ozmx] - standard_name = ozone_tendency_due_to_ozone_mixing_ratio - long_name = ozone tendency due to ozone mixing ratio - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[do3_dt_temp] - standard_name = ozone_tendency_due_to_temperature - long_name = ozone tendency due to temperature - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[do3_dt_ohoz] - standard_name = ozone_tendency_due_to_overhead_ozone_column - long_name = ozone tendency due to overhead ozone column - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out From 385ef4e2802a838fd3099b17ee479ebaae1a6402 Mon Sep 17 00:00:00 2001 From: dustinswales Date: Wed, 27 Sep 2023 22:19:36 -0600 Subject: [PATCH 49/58] Some polishing. Merge 2006 ozone into module_ozphys --- physics/GFS_phys_time_vary.fv3.F90 | 69 ++++----- physics/GFS_suite_stateout_update.F90 | 3 +- physics/module_ozphys.F90 | 127 +++++++++++++++- physics/ozphys.f | 211 -------------------------- physics/ozphys.meta | 208 ------------------------- 5 files changed, 158 insertions(+), 460 deletions(-) delete mode 100644 physics/ozphys.f delete mode 100644 physics/ozphys.meta diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 70eeb81e1..cd1f8287a 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -802,38 +802,6 @@ subroutine GFS_phys_time_vary_timestep_init ( return end if - !> - Compute temporal interpolation indices for updating gas concentrations. - idat=0 - idat(1)=idate(4) - idat(2)=idate(2) - idat(3)=idate(3) - idat(5)=idate(1) - rinc=0. - rinc(2)=fhour - call w3kind(w3kindreal,w3kindint) - if(w3kindreal==4) then - rinc4=rinc - CALL w3movdat(rinc4,idat,jdat) - else - CALL w3movdat(rinc,idat,jdat) - endif - jdow = 0 - jdoy = 0 - jday = 0 - call w3doxdat(jdat,jdow,jdoy,jday) - rjday = jdoy + jdat(5) / 24. - if (rjday < ozphys%time(1)) rjday = rjday + 365. - - n2 = ozphys%ntime + 1 - do j=2,ozphys%ntime - if (rjday < ozphys%time(j)) then - n2 = j - exit - endif - enddo - n1 = n2 - 1 - if (n2 > ozphys%ntime) n2 = n2 - ozphys%ntime - !$OMP parallel num_threads(nthrds) default(none) & !$OMP shared(kdt,nsswr,lsswr,clstp,imfdeepcnv,cal_pre,random_clds) & !$OMP shared(fhswr,fhour,seed0,cnx,cny,nrcm,wrk,rannie,rndval) & @@ -841,8 +809,9 @@ subroutine GFS_phys_time_vary_timestep_init ( !$OMP shared(ozpl,ddy_o3,h2o_phys,jindx1_h,jindx2_h,h2opl,ddy_h,iaerclm,master) & !$OMP shared(levs,prsl,iccn,jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci) & !$OMP shared(ddx_ci,in_nm,ccn_nm,do_ugwp_v1,jindx1_tau,jindx2_tau,ddy_j1tau) & -!$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys) & -!$OMP private(iseed,iskip,i,j,k,rjday,n1,n2) +!$OMP shared(ddy_j2tau,tau_amf,iflip,ozphys,rjday,n1,n2,idat,jdat,rinc,rinc4) & +!$OMP shared(w3kindreal,w3kindint,jdow,jdoy,jday) & +!$OMP private(iseed,iskip,i,j,k) !$OMP sections @@ -892,6 +861,38 @@ subroutine GFS_phys_time_vary_timestep_init ( endif ! imfdeepcnv, cal_re, random_clds !$OMP section + !> - Compute temporal interpolation indices for updating gas concentrations. + idat=0 + idat(1)=idate(4) + idat(2)=idate(2) + idat(3)=idate(3) + idat(5)=idate(1) + rinc=0. + rinc(2)=fhour + call w3kind(w3kindreal,w3kindint) + if(w3kindreal==4) then + rinc4=rinc + CALL w3movdat(rinc4,idat,jdat) + else + CALL w3movdat(rinc,idat,jdat) + endif + jdow = 0 + jdoy = 0 + jday = 0 + call w3doxdat(jdat,jdow,jdoy,jday) + rjday = jdoy + jdat(5) / 24. + if (rjday < ozphys%time(1)) rjday = rjday + 365. + + n2 = ozphys%ntime + 1 + do j=2,ozphys%ntime + if (rjday < ozphys%time(j)) then + n2 = j + exit + endif + enddo + n1 = n2 - 1 + if (n2 > ozphys%ntime) n2 = n2 - ozphys%ntime + !> - Update ozone concentration. if (ntoz > 0) then call ozphys%update_o3prog(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) diff --git a/physics/GFS_suite_stateout_update.F90 b/physics/GFS_suite_stateout_update.F90 index 41f44e0de..e9e477fce 100644 --- a/physics/GFS_suite_stateout_update.F90 +++ b/physics/GFS_suite_stateout_update.F90 @@ -69,7 +69,8 @@ subroutine GFS_suite_stateout_update_run (im, levs, ntrac, dtp, tgrs, ugrs, vgrs do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz) endif if (oz_phys_2006) then - call ozphys%run_o3prog_2006() + call ozphys%run_o3prog_2006(con_1ovg, dtp, prsl, gt0, dp, ozpl, oz0, do3_dt_prd, & + do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz) endif ! If using Ferrier-Aligo microphysics, set bounds on the mass-weighted rime factor. diff --git a/physics/module_ozphys.F90 b/physics/module_ozphys.F90 index 205a02b46..d24585d4d 100644 --- a/physics/module_ozphys.F90 +++ b/physics/module_ozphys.F90 @@ -162,12 +162,12 @@ end subroutine update_o3prog ! ######################################################################################### ! Procedure (type-bound) for NRL prognostic ozone (2015). ! ######################################################################################### - subroutine run_o3prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, do3_dt_ozmx, & - do3_dt_temp, do3_dt_ohoz) + subroutine run_o3prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, & + do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz) class(ty_ozphys), intent(in) :: this - real(kind_phys),intent(in) :: & + real(kind_phys), intent(in) :: & con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) - real(kind_phys), intent(in) :: & + real(kind_phys), intent(in) :: & dt ! Model timestep (sec) real(kind_phys), intent(in), dimension(:,:) :: & p, & ! Model Pressure (Pa) @@ -253,7 +253,7 @@ subroutine run_o3prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, d prod(iCol,2) = min(prod(iCol,2), 0.0) enddo do iCol=1,nCol - ozib(iCol) = ozi(iCol,iLev) ! no filling + ozib(iCol) = ozi(iCol,iLev) tem = prod(iCol,1) - prod(iCol,2) * prod(iCol,6) & + prod(iCol,3) * (t(iCol,iLev) - prod(iCol,5)) & + prod(iCol,4) * (colo3(iCol,iLev)-coloz(iCol,iLev)) @@ -273,8 +273,123 @@ end subroutine run_o3prog_2015 ! ######################################################################################### ! Procedure (type-bound) for NRL prognostic ozone (2006). ! ######################################################################################### - subroutine run_o3prog_2006(this) + subroutine run_o3prog_2006(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, & + do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz) class(ty_ozphys), intent(in) :: this + real(kind_phys), intent(in) :: & + con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2) + real(kind_phys), intent(in) :: & + dt ! Model timestep (sec) + real(kind_phys), intent(in), dimension(:,:) :: & + p, & ! Model Pressure (Pa) + t, & ! Model temperature (K) + dp ! Model layer thickness (Pa) + real(kind_phys), intent(in), dimension(:,:,:) :: & + ozpl ! Ozone forcing data + real(kind_phys), intent(inout), dimension(:,:) :: & + oz ! Ozone concentration updated by physics + real(kind_phys), intent(inout), dimension(:,:), pointer, optional :: & + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect + + ! Locals + integer :: k, kmax, kmin, iLev, iCol, nCol, nLev, iCf + logical, dimension(size(p,1)) :: flg + real(kind_phys) :: pmax, pmin, tem, temp + real(kind_phys), dimension(size(p,1)) :: wk1, wk2, wk3, ozib + real(kind_phys), dimension(size(p,1),this%ncf) :: prod + real(kind_phys), dimension(size(p,1),size(p,2)) :: ozi + real(kind_phys), dimension(size(p,1),size(p,2)+1) :: colo3, coloz + + ! Dimensions + nCol = size(p,1) + nLev = size(p,2) + + ! Temporaries + ozi = oz + + !> - Calculate vertical integrated column ozone values. + if (this%ncf > 2) then + colo3(:,nLev+1) = 0.0 + do iLev=nLev,1,-1 + do iCol=1,nCol + colo3(iCol,iLev) = colo3(iCol,iLev+1) + ozi(iCol,iLev) * dp(iCol,iLev) * con_1ovg + enddo + enddo + endif + + !> - Apply vertically linear interpolation to the ozone coefficients. + do iLev=1,nLev + pmin = 1.0e10 + pmax = -1.0e10 + + do iCol=1,nCol + wk1(iCol) = log(p(iCol,iLev)) + pmin = min(wk1(iCol), pmin) + pmax = max(wk1(iCol), pmax) + prod(iCol,:) = 0._kind_phys + enddo + kmax = 1 + kmin = 1 + do k=1,this%nlev-1 + if (pmin < this%po3(k)) kmax = k + if (pmax < this%po3(k)) kmin = k + enddo + + do k=kmin,kmax + temp = 1.0 / (this%po3(k) - this%po3(k+1)) + do iCol=1,nCol + flg(iCol) = .false. + if (wk1(iCol) < this%po3(k) .and. wk1(iCol) >= this%po3(k+1)) then + flg(iCol) = .true. + wk2(iCol) = (wk1(iCol) - this%po3(k+1)) * temp + wk3(iCol) = 1.0 - wk2(iCol) + endif + enddo + do iCf=1,this%ncf + do iCol=1,nCol + if (flg(iCol)) then + prod(iCol,iCf) = wk2(iCol) * ozpl(iCol,k,iCf) + wk3(iCol) * ozpl(iCol,k+1,iCf) + endif + enddo + enddo + enddo + + do iCf=1,this%ncf + do iCol=1,nCol + if (wk1(iCol) < this%po3(this%nlev)) then + prod(iCol,iCf) = ozpl(iCol,this%nlev,iCf) + endif + if (wk1(iCol) >= this%po3(1)) then + prod(iCol,iCf) = ozpl(iCol,1,iCf) + endif + enddo + enddo + + if (this%ncf == 2) then + do iCol=1,nCol + ozib(iCol) = ozi(iCol,iLev) + oz(iCol,iLev) = (ozib(iCol) + prod(iCol,1)*dt) / (1.0 + prod(iCol,2)*dt) + enddo + endif + + if (this%ncf == 4) then + do iCol=1,nCol + ozib(iCol) = ozi(iCol,iLev) + tem = prod(iCol,1) + prod(iCol,3)*t(iCol,iLev) + prod(iCol,4)*colo3(iCol,iLev+1) + oz(iCol,iLev) = (ozib(iCol) + tem*dt) / (1.0 + prod(iCol,2)*dt) + enddo + endif + ! Diagnostics (optional) + if (associated(do3_dt_prd)) do3_dt_prd(:,iLev) = prod(:,1)*dt + if (associated(do3_dt_ozmx)) do3_dt_ozmx(:,iLev) = (oz(:,iLev) - ozib(:)) + if (associated(do3_dt_temp)) do3_dt_temp(:,iLev) = prod(:,3) * t(:,iLev) * dt + if (associated(do3_dt_ohoz)) do3_dt_ohoz(:,iLev) = prod(:,4) * colo3(:,iLev) * dt + + enddo + return end subroutine run_o3prog_2006 diff --git a/physics/ozphys.f b/physics/ozphys.f deleted file mode 100644 index 18a9ae46f..000000000 --- a/physics/ozphys.f +++ /dev/null @@ -1,211 +0,0 @@ -!> \file ozphys.f -!! This file is ozone sources and sinks (previous version). - - -!> This module contains the CCPP-compliant Ozone photochemistry scheme. - module ozphys - - contains - -! \brief Brief description of the subroutine -! -!> \section arg_table_ozphys_init Argument Table -!! \htmlinclude ozphys_init.html -!! - subroutine ozphys_init(oz_phys, errmsg, errflg) - - implicit none - logical, intent(in) :: oz_phys - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not.oz_phys) then - write (errmsg,'(*(a))') 'Logic error: oz_phys == .false.' - errflg = 1 - return - endif - - end subroutine ozphys_init - -!>\defgroup GFS_ozphys GFS ozphys Main -!! \brief The operational GFS currently parameterizes ozone production and -!! destruction based on monthly mean coefficients (\c global_o3prdlos.f77) provided by Naval -!! Research Laboratory through CHEM2D chemistry model -!! (McCormack et al. (2006) \cite mccormack_et_al_2006). -!! \section arg_table_ozphys_run Argument Table -!! \htmlinclude ozphys_run.html -!! -!> \section genal_ozphys GFS ozphys_run General Algorithm -!> @{ - subroutine ozphys_run ( & - & im, levs, ko3, dt, oz, tin, po3, & - & prsl, prdout, oz_coeff, delp, ldiag3d, & - & ntoz, dtend, dtidx, index_of_process_prod_loss, & - & index_of_process_ozmix, index_of_process_temp, & - & index_of_process_overhead_ozone, con_g, me, errmsg, errflg) -! -! this code assumes that both prsl and po3 are from bottom to top -! as are all other variables -! - use machine , only : kind_phys - implicit none -! - ! Interface variables - integer, intent(in) :: im, levs, ko3, oz_coeff, me - real(kind=kind_phys), intent(inout) :: oz(:,:) - real(kind=kind_phys), intent(inout) :: dtend(:,:,:) - integer, intent(in) :: dtidx(:,:), ntoz, & - & index_of_process_prod_loss, index_of_process_ozmix, & - & index_of_process_temp, index_of_process_overhead_ozone - real(kind=kind_phys), intent(in) :: & - & dt, po3(:), prdout(:,:,:), & - & prsl(:,:), tin(:,:), delp(:,:), & - & con_g - real :: gravi - logical, intent(in) :: ldiag3d - - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg -! - ! Local variables - integer k,kmax,kmin,l,i,j, idtend(4) - logical flg(im) - real(kind=kind_phys) pmax, pmin, tem, temp - real(kind=kind_phys) wk1(im), wk2(im), wk3(im), prod(im,oz_coeff), - & ozib(im), colo3(im,levs+1), ozi(im,levs) -! - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 -! -! save input oz in ozi - ozi = oz - gravi=1.0/con_g - - - if(ldiag3d) then - idtend(1) = dtidx(100+ntoz,index_of_process_prod_loss) ! was ozp1 - idtend(2) = dtidx(100+ntoz,index_of_process_ozmix) ! was ozp2 - idtend(3) = dtidx(100+ntoz,index_of_process_temp) ! was ozp3 - idtend(4) = dtidx(100+ntoz,index_of_process_overhead_ozone) ! was ozp4 - else - idtend=0 - endif - -! -!> - Calculate vertical integrated column ozone values. - if (oz_coeff > 2) then - colo3(:,levs+1) = 0.0 - do l=levs,1,-1 - do i=1,im - colo3(i,l) = colo3(i,l+1) + ozi(i,l) * delp(i,l) * gravi - enddo - enddo - endif -! -!> - Apply vertically linear interpolation to the ozone coefficients. - do l=1,levs - pmin = 1.0e10 - pmax = -1.0e10 -! - do i=1,im - wk1(i) = log(prsl(i,l)) - pmin = min(wk1(i), pmin) - pmax = max(wk1(i), pmax) - prod(i,:) = 0.0 - enddo - kmax = 1 - kmin = 1 - do k=1,ko3-1 - if (pmin < po3(k)) kmax = k - if (pmax < po3(k)) kmin = k - enddo -! - do k=kmin,kmax - temp = 1.0 / (po3(k) - po3(k+1)) - do i=1,im - flg(i) = .false. - if (wk1(i) < po3(k) .and. wk1(i) >= po3(k+1)) then - flg(i) = .true. - wk2(i) = (wk1(i) - po3(k+1)) * temp - wk3(i) = 1.0 - wk2(i) - endif - enddo - do j=1,oz_coeff - do i=1,im - if (flg(i)) then - prod(i,j) = wk2(i) * prdout(i,k,j) - & + wk3(i) * prdout(i,k+1,j) - endif - enddo - enddo - enddo -! - do j=1,oz_coeff - do i=1,im - if (wk1(i) < po3(ko3)) then - prod(i,j) = prdout(i,ko3,j) - endif - if (wk1(i) >= po3(1)) then - prod(i,j) = prdout(i,1,j) - endif - enddo - enddo - - if (oz_coeff == 2) then - do i=1,im - ozib(i) = ozi(i,l) ! no filling - oz(i,l) = (ozib(i) + prod(i,1)*dt) / (1.0 + prod(i,2)*dt) - enddo -! - if(idtend(1)>=1) then - dtend(:,l,idtend(1)) = dtend(:,l,idtend(1)) + ! was ozp1 - & prod(:,1)*dt - endif - if(idtend(2)>=1) then - dtend(:,l,idtend(2)) = dtend(:,l,idtend(2)) + ! was ozp2 - & (oz(:,l) - ozib(:)) - endif - endif -!> - Calculate the 4 terms of prognostic ozone change during time \a dt: -!! - ozp1(:,:) - Ozone production from production/loss ratio -!! - ozp2(:,:) - Ozone production from ozone mixing ratio -!! - ozp3(:,:) - Ozone production from temperature term at model layers -!! - ozp4(:,:) - Ozone production from column ozone term at model layers - if (oz_coeff == 4) then - do i=1,im - ozib(i) = ozi(i,l) ! no filling - tem = prod(i,1) + prod(i,3)*tin(i,l) - & + prod(i,4)*colo3(i,l+1) -! if (me .eq. 0) print *,'ozphys tem=',tem,' prod=',prod(i,:) -! &,' ozib=',ozib(i),' l=',l,' tin=',tin(i,l),'colo3=',colo3(i,l+1) - oz(i,l) = (ozib(i) + tem*dt) / (1.0 + prod(i,2)*dt) - enddo - if(idtend(1)>=1) then - dtend(:,l,idtend(1)) = dtend(:,l,idtend(1)) + ! was ozp1 - & prod(:,1)*dt - endif - if(idtend(2)>=1) then - dtend(:,l,idtend(2)) = dtend(:,l,idtend(2)) + ! was ozp2 - & (oz(:,l)-ozib(:)) - endif - if(idtend(3)>=1) then - dtend(:,l,idtend(3)) = dtend(:,l,idtend(3)) + ! was ozp3 - & prod(:,3)*tin(:,l)*dt - endif - if(idtend(4)>=1) then - dtend(:,l,idtend(4)) = dtend(:,l,idtend(4)) + ! was ozp4 - & prod(:,4)*colo3(:,l+1)*dt - endif - endif - enddo ! vertical loop -! - return - end subroutine ozphys_run -!> @} - - end module ozphys diff --git a/physics/ozphys.meta b/physics/ozphys.meta deleted file mode 100644 index 485e2a491..000000000 --- a/physics/ozphys.meta +++ /dev/null @@ -1,208 +0,0 @@ -[ccpp-table-properties] - name = ozphys - type = scheme - dependencies = machine.F - -######################################################################## -[ccpp-arg-table] - name = ozphys_init - type = scheme -[oz_phys] - standard_name = flag_for_nrl_2006_ozone_scheme - long_name = flag for old (2006) ozone physics - units = flag - dimensions = () - type = logical - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = ozphys_run - type = scheme -[im] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[levs] - standard_name = vertical_layer_dimension - long_name = number of vertical layers - units = count - dimensions = () - type = integer - intent = in -[ko3] - standard_name = vertical_dimension_of_ozone_forcing_data - long_name = number of vertical layers in ozone forcing data - units = count - dimensions = () - type = integer - intent = in -[dt] - standard_name = timestep_for_physics - long_name = physics time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[oz] - standard_name = ozone_concentration_of_new_state - long_name = ozone concentration updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[tin] - standard_name = air_temperature_of_new_state - long_name = updated air temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[po3] - standard_name = natural_log_of_ozone_forcing_data_pressure_levels - long_name = natural log of ozone forcing data pressure levels - units = 1 - dimensions = (vertical_dimension_of_ozone_forcing_data) - type = real - kind = kind_phys - intent = in -[prsl] - standard_name = air_pressure - long_name = mid-layer pressure - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[prdout] - standard_name = ozone_forcing - long_name = ozone forcing coefficients - units = mixed - dimensions = (horizontal_loop_extent,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_forcing_data) - type = real - kind = kind_phys - intent = in -[oz_coeff] - standard_name = number_of_coefficients_in_ozone_forcing_data - long_name = number of coefficients in ozone forcing data - units = index - dimensions = () - type = integer - intent = in -[delp] - standard_name = air_pressure_difference_between_midlayers - long_name = difference between mid-layer pressures - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[ldiag3d] - standard_name = flag_for_diagnostics_3D - long_name = flag for calculating 3-D diagnostic fields - units = flag - dimensions = () - type = logical - intent = in -[dtend] - standard_name = cumulative_change_of_state_variables - long_name = diagnostic tendencies for state variables - units = mixed - dimensions = (horizontal_loop_extent,vertical_layer_dimension,cumulative_change_of_state_variables_outer_index_max) - type = real - kind = kind_phys - active = (flag_for_diagnostics_3D) - intent = inout -[dtidx] - standard_name = cumulative_change_of_state_variables_outer_index - long_name = index of state-variable and process in last dimension of diagnostic tendencies array AKA cumulative_change_index - units = index - dimensions = (number_of_tracers_plus_one_hundred,number_of_cumulative_change_processes) - type = integer - intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in -[index_of_process_prod_loss] - standard_name = index_of_production_and_loss_process_in_cumulative_change_index - long_name = index of production and loss effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_ozmix] - standard_name = index_of_ozone_mixing_ratio_process_in_cumulative_change_index - long_name = index of ozone mixing ratio effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_temp] - standard_name = index_of_temperature_process_in_cumulative_change_index - long_name = index of temperature effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_overhead_ozone] - standard_name = index_of_overhead_process_in_cumulative_change_index - long_name = index of overhead ozone effect in photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[con_g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[me] - standard_name = mpi_rank - long_name = rank of the current MPI task - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out From 00d90608a08f13ac367f2c002b8ae18eea4e8f6b Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 28 Sep 2023 17:19:33 +0000 Subject: [PATCH 50/58] Added documentation --- physics/GFS_physics_post.F90 | 12 +++- physics/module_ozphys.F90 | 119 +++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/physics/GFS_physics_post.F90 b/physics/GFS_physics_post.F90 index d034c1999..e6a50cc3a 100644 --- a/physics/GFS_physics_post.F90 +++ b/physics/GFS_physics_post.F90 @@ -1,6 +1,11 @@ ! ########################################################################################### !> \file GFS_physics_post.F90 !! +!! This module contains GFS specific calculations (e.g. diagnostics) and suite specific +!! code (e.g Saving fields for subsequent physics timesteps). For interoperability across a +!! wide range of hosts, CCPP compliant schemes should avoid including such calculations. This +!! module/scheme is intended for such "host-specific" computations. +!! ! ########################################################################################### module GFS_physics_post use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec @@ -30,9 +35,10 @@ end subroutine GFS_physics_post_init !! \section arg_table_GFS_physics_post_run Argument Table !! \htmlinclude GFS_physics_post_run.html !! - subroutine GFS_physics_post_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, & - ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, dtend,& - errmsg, errflg) + subroutine GFS_physics_post_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, ip_temp, & + ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, dtend, errmsg, & + errflg) + ! Inputs integer, intent(in) :: & nCol, & ! Horizontal dimension diff --git a/physics/module_ozphys.F90 b/physics/module_ozphys.F90 index d24585d4d..f824736b1 100644 --- a/physics/module_ozphys.F90 +++ b/physics/module_ozphys.F90 @@ -2,6 +2,39 @@ !> \section arg_table_module_ozphys Argument table !! \htmlinclude module_ozphys.html !! +! +!> The operational GFS currently parameterizes ozone production and destruction based on +!! monthly mean coefficients (\c global_o3prdlos.f77) provided by Naval Research Laboratory +!! through CHEM2D chemistry model (McCormack et al. (2006) \cite mccormack_et_al_2006). +!! +!! There are two implementations of this parameterization within this module. +!! run_o3prog_2006 - Relies on either two/four mean monthly coefficients. This is explained +!! in (https://doi.org/10.5194/acp-6-4943-2006. See Eq.(4)). +!! run_o3prog_2015 - Relies on six mean monthly coefficients, specifically for NRL +!! parameterization and climatological T and O3 are in location 5 and 6 of +!! the coefficient array. +!! +!! Both of these rely on the scheme being setup correctly by invoking the load(), setup(), +!! and update() procedures prior to calling the run() procedure. +!! +!! load_o3prog() - Read in data and load into type ty_ozphys (called once from host) +!! setup_o3prog() - Create spatial interpolation indices (called once, after model grid is known) +!! update_o3prog() - Update ozone concentration in time (call in physics loop, before run()) +!! *CAVEAT* Since the radiation is often run at a lower temporal resolution +!! than the rest of the physics, update_o3prog() needs to be +!! called before the radiation, which is called before the physics. +!! For example, within the physics loop: +!! update_o3prog() -> radiation() -> run_o3prog() -> physics.... +!! +!! Additionally, there is the functionality to not use interactive ozone, instead reverting +!! to ozone climatology. In this case, analagous to when using prognostic ozone, there are +!! update() and run() procedures that need to be called before the radiation. +!! For example, within the physics loop: +!! update_o3clim() -> run_o3clim() -> radiation() -> physics... +!! +!!\author June 2015 - Shrinivas Moorthi +!!\modified Sep 2023 - Dustin Swales +!! ! ######################################################################################### module module_ozphys use machine, only : kind_phys @@ -14,7 +47,8 @@ module module_ozphys !> \section arg_table_ty_ozphys Argument Table !! \htmlinclude ty_ozphys.html !! -!! All data field are ordered from surface-to-toa (j=1=isfc) +!> Derived type containing data and procedures needed by ozone photochemistry parameterization +!! *Note* All data field are ordered from surface-to-toa. !! ! ######################################################################################### type ty_ozphys @@ -54,7 +88,7 @@ module module_ozphys contains ! ######################################################################################### - ! Procedure (type-bound) for loading ozone forcing data. + ! Procedure (type-bound) for loading data for prognostic ozone. ! ######################################################################################### function load_o3prog(this, file, fileID) result (err_message) class(ty_ozphys), intent(inout) :: this @@ -101,7 +135,9 @@ function load_o3prog(this, file, fileID) result (err_message) end function load_o3prog ! ######################################################################################### - ! Procedure for setting up interpolation indices between data and model grid. + ! Procedure (type-bound) for setting up interpolation indices between data-grid and + ! model-grid. + ! Called once during initialization ! ######################################################################################### subroutine setup_o3prog(this, lat, idx1, idx2, idxh) class(ty_ozphys), intent(in) :: this @@ -130,7 +166,7 @@ subroutine setup_o3prog(this, lat, idx1, idx2, idxh) end subroutine setup_o3prog ! ######################################################################################### - ! Procedure (type-bound) for updating ozone data. + ! Procedure (type-bound) for updating data used in prognostic ozone scheme. ! ######################################################################################### subroutine update_o3prog(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl) class(ty_ozphys), intent(in) :: this @@ -474,7 +510,7 @@ subroutine run_o3clim(this, lat, prslk, con_pi, oz) end subroutine run_o3clim ! ######################################################################################### - ! Procedure (type-bound) for loading ozone climo data. + ! Procedure (type-bound) for loading data for climotological ozone. ! ######################################################################################### function load_o3clim(this, file, fileID) result (err_message) class(ty_ozphys), intent(inout) :: this @@ -546,46 +582,47 @@ function load_o3clim(this, file, fileID) result (err_message) this%pstr(iLev) = pstr4(iLev) this%pkstr(iLev) = fpkapx(this%pstr(iLev)*100.0) enddo - + end function load_o3clim - ! ######################################################################################### - ! Procedure (type-bound) for updating ozone climotological data. - ! ######################################################################################### - subroutine update_o3clim(this, imon, iday, ihour, loz1st) - class(ty_ozphys), intent(inout) :: this - integer, intent(in) :: imon, iday, ihour - logical, intent(in) :: loz1st - - integer :: midmon=15, midm=15, midp=45, id - integer, parameter, dimension(13) :: mdays = (/31,28,31,30,31,30,31,31,30,31,30,31,30/) - logical :: change - - midmon = mdays(imon)/2 + 1 - change = loz1st .or. ( (iday==midmon) .and. (ihour==0) ) + ! ######################################################################################### + ! Procedure (type-bound) for updating temporal interpolation index when using climotological + ! ozone + ! ######################################################################################### + subroutine update_o3clim(this, imon, iday, ihour, loz1st) + class(ty_ozphys), intent(inout) :: this + integer, intent(in) :: imon, iday, ihour + logical, intent(in) :: loz1st + + integer :: midmon=15, midm=15, midp=45, id + integer, parameter, dimension(13) :: mdays = (/31,28,31,30,31,30,31,31,30,31,30,31,30/) + logical :: change + + midmon = mdays(imon)/2 + 1 + change = loz1st .or. ( (iday==midmon) .and. (ihour==0) ) - if ( change ) then - if ( iday < midmon ) then - this%k1oz = mod(imon+10, 12) + 1 - midm = mdays(this%k1oz)/2 + 1 - this%k2oz = imon - midp = mdays(this%k1oz) + midmon - else - this%k1oz = imon - midm = midmon - this%k2oz = mod(imon, 12) + 1 - midp = mdays(this%k2oz)/2 + 1 + mdays(this%k1oz) - endif - endif + if ( change ) then + if ( iday < midmon ) then + this%k1oz = mod(imon+10, 12) + 1 + midm = mdays(this%k1oz)/2 + 1 + this%k2oz = imon + midp = mdays(this%k1oz) + midmon + else + this%k1oz = imon + midm = midmon + this%k2oz = mod(imon, 12) + 1 + midp = mdays(this%k2oz)/2 + 1 + mdays(this%k1oz) + endif + endif - if (iday < midmon) then - id = iday + mdays(this%k1oz) - else - id = iday - endif + if (iday < midmon) then + id = iday + mdays(this%k1oz) + else + id = iday + endif - this%facoz = float(id - midm) / float(midp - midm) + this%facoz = float(id - midm) / float(midp - midm) - end subroutine update_o3clim + end subroutine update_o3clim -end module module_ozphys + end module module_ozphys From e08ecd648a3f984a79e1dfd042f66edfbfb54d62 Mon Sep 17 00:00:00 2001 From: Helin Wei Date: Fri, 6 Oct 2023 15:07:48 -0400 Subject: [PATCH 51/58] land surface updates for hr3 --- physics/module_sf_noahmplsm.F90 | 15 +++++++++------ physics/noahmpdrv.F90 | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/physics/module_sf_noahmplsm.F90 b/physics/module_sf_noahmplsm.F90 index 86853dabe..8ced8930f 100644 --- a/physics/module_sf_noahmplsm.F90 +++ b/physics/module_sf_noahmplsm.F90 @@ -2116,7 +2116,7 @@ subroutine energy (parameters,ice ,vegtyp ,ist ,nsnow ,nsoil , & !in ! thermal properties of soil, snow, lake, and frozen soil call thermoprop (parameters,nsoil ,nsnow ,isnow ,ist ,dzsnso , & !in - dt ,snowh ,snice ,snliq , & !in + dt ,snowh ,snice ,snliq , shdfac, & !in smc ,sh2o ,tg ,stc ,ur , & !in lat ,z0m ,zlvl ,vegtyp , & !in df ,hcpct ,snicev ,snliqv ,epore , & !out @@ -2463,7 +2463,7 @@ end subroutine energy !>\ingroup NoahMP_LSM subroutine thermoprop (parameters,nsoil ,nsnow ,isnow ,ist ,dzsnso , & !in - dt ,snowh ,snice ,snliq , & !in + dt ,snowh ,snice ,snliq , shdfac, & !in smc ,sh2o ,tg ,stc ,ur , & !in lat ,z0m ,zlvl ,vegtyp , & !in df ,hcpct ,snicev ,snliqv ,epore , & !out @@ -2480,6 +2480,7 @@ subroutine thermoprop (parameters,nsoil ,nsnow ,isnow ,ist ,dzsnso , real (kind=kind_phys) , intent(in) :: dt !< time step [s] real (kind=kind_phys), dimension(-nsnow+1: 0), intent(in) :: snice !< snow ice mass (kg/m2) real (kind=kind_phys), dimension(-nsnow+1: 0), intent(in) :: snliq !< snow liq mass (kg/m2) + real (kind=kind_phys) , intent(in) :: shdfac !< green vegetation fraction [0.0-1.0] real (kind=kind_phys), dimension(-nsnow+1:nsoil), intent(in) :: dzsnso !< thickness of snow/soil layers [m] real (kind=kind_phys), dimension( 1:nsoil), intent(in) :: smc !< soil moisture (ice + liq.) [m3/m3] real (kind=kind_phys), dimension( 1:nsoil), intent(in) :: sh2o !< liquid soil moisture [m3/m3] @@ -2539,6 +2540,7 @@ subroutine thermoprop (parameters,nsoil ,nsnow ,isnow ,ist ,dzsnso , ! not in use because of the separation of the canopy layer from the ground. ! but this may represent the effects of leaf litter (niu comments) ! df1 = df1 * exp (sbeta * shdfac) + df(1) = df(1) * exp (sbeta * shdfac) ! compute lake thermal properties ! (no consideration of turbulent mixing for this version) @@ -4888,7 +4890,7 @@ subroutine bare_flux (parameters,nsnow ,nsoil ,isnow ,dt ,sag , & end if endif ! 4 -! use sfc_diag to calculate t2mv and q2v for opt_sfc=1&3 +! use sfc_diag to calculate t2mb and q2b for opt_sfc=1&3 if(opt_diag ==3) then if(opt_sfc == 1 .or. opt_sfc == 3) then @@ -5823,7 +5825,8 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, elseif (opt_trs == chen09) then - z0m_out = exp(fveg * log(z0m) + (1.0 - fveg) * log(z0mg)) +! z0m_out = exp(fveg * log(z0m) + (1.0 - fveg) * log(z0mg)) +! z0m_out = fveg * z0m + (1.0 - fveg) * z0mg czil = 10.0 ** (- 0.4 * parameters%hvt) reyn = ustarx*z0m_out/viscosity ! Blumel99 eqn 36c @@ -5873,7 +5876,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, z0h_out = z0m_out - elseif (opt_trs == tessel) then + elseif (opt_trs == chen09 .or. opt_trs == tessel) then if (vegtyp <= 5) then z0h_out = z0m_out @@ -5881,7 +5884,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, z0h_out = z0m_out * 0.01 endif - elseif (opt_trs == blumel99 .or. opt_trs == chen09) then + elseif (opt_trs == blumel99) then reyn = ustarx*z0m_out/viscosity ! Blumel99 eqn 36c if (reyn > 2.0) then diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index 4500d51a8..c2c03d0de 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -450,7 +450,7 @@ subroutine noahmpdrv_run & integer :: iopt_pedo = 1 ! option for pedotransfer function integer :: iopt_crop = 0 ! option for crop model integer :: iopt_gla = 2 ! option for glacier treatment - integer :: iopt_z0m = 2 ! option for z0m treatment + integer :: iopt_z0m = 1 ! option for z0m treatment ! ! --- local inputs to noah-mp and glacier subroutines; listed in order in noah-mp call From 4f8004ab57b85d76884858849a5f4211f28d3084 Mon Sep 17 00:00:00 2001 From: Helin Wei Date: Fri, 6 Oct 2023 18:05:17 -0400 Subject: [PATCH 52/58] remove one printout from sfcsub.f and uncomment z0m composition in module_sf_noahmplsm.F90 --- physics/module_sf_noahmplsm.F90 | 2 +- physics/sfcsub.F | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/physics/module_sf_noahmplsm.F90 b/physics/module_sf_noahmplsm.F90 index 8ced8930f..6abd59f69 100644 --- a/physics/module_sf_noahmplsm.F90 +++ b/physics/module_sf_noahmplsm.F90 @@ -5826,7 +5826,7 @@ subroutine thermalz0(parameters, fveg, z0m, z0mg, zlvl, elseif (opt_trs == chen09) then ! z0m_out = exp(fveg * log(z0m) + (1.0 - fveg) * log(z0mg)) -! z0m_out = fveg * z0m + (1.0 - fveg) * z0mg + z0m_out = fveg * z0m + (1.0 - fveg) * z0mg czil = 10.0 ** (- 0.4 * parameters%hvt) reyn = ustarx*z0m_out/viscosity ! Blumel99 eqn 36c diff --git a/physics/sfcsub.F b/physics/sfcsub.F index 7be07b39c..494b8f7dc 100644 --- a/physics/sfcsub.F +++ b/physics/sfcsub.F @@ -7491,9 +7491,6 @@ subroutine clima(lugb,iy,im,id,ih,fh,len,lsoil,slmskl,slmskw, & endif call abort endif -! -! soil type - print *,'in FIXREAD fnsotc =',fnsotc ! if(fnsotc(1:8).ne.' ') then if ( index(fnsotc, "tileX.nc") == 0) then ! grib file From 1b2239714a949341409261ebbfb8a0bdf6a4f5da Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 12 Oct 2023 03:40:06 +0000 Subject: [PATCH 53/58] Some more cleanup --- physics/GFS_physics_post.F90 | 99 ++++++++++++++++++++++++++++++----- physics/GFS_physics_post.meta | 49 +++++++++++++++++ physics/phys_tend.F90 | 96 --------------------------------- physics/phys_tend.meta | 95 --------------------------------- 4 files changed, 134 insertions(+), 205 deletions(-) delete mode 100644 physics/phys_tend.F90 delete mode 100644 physics/phys_tend.meta diff --git a/physics/GFS_physics_post.F90 b/physics/GFS_physics_post.F90 index e6a50cc3a..def38cd1a 100644 --- a/physics/GFS_physics_post.F90 +++ b/physics/GFS_physics_post.F90 @@ -35,47 +35,62 @@ end subroutine GFS_physics_post_init !! \section arg_table_GFS_physics_post_run Argument Table !! \htmlinclude GFS_physics_post_run.html !! - subroutine GFS_physics_post_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, ip_temp, & - ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, dtend, errmsg, & - errflg) + subroutine GFS_physics_post_run(nCol, nLev, ntoz, ntracp100, nprocess, nprocess_summed, & + dtidx, is_photochem, ldiag3d, ip_physics, ip_photochem, & + ip_prod_loss, ip_ozmix, ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, & + do3_dt_temp, do3_dt_ohoz, dtend, errmsg, errflg) ! Inputs integer, intent(in) :: & nCol, & ! Horizontal dimension nLev, & ! Number of vertical layers ntoz, & ! Index for ozone mixing ratio + ntracp100, & ! Number of tracers plus 100 + nprocess, & ! Number of processes that cause changes in state variables + nprocess_summed,& ! Number of causes in dtidx per tracer summed for total physics tendency + ip_physics, & ! Index for process in diagnostic tendency output + ip_photochem, & ! ip_prod_loss, & ! Index for process in diagnostic tendency output ip_ozmix, & ! Index for process in diagnostic tendency output ip_temp, & ! Index for process in diagnostic tendency output ip_overhead_ozone ! Index for process in diagnostic tendency output integer, intent(in), dimension(:,:) :: & dtidx ! Bookkeeping indices for GFS diagnostic tendencies + logical, intent(in) :: & + ldiag3d ! Flag for 3d diagnostic fields + logical, intent(in), dimension(:) :: & + is_photochem ! Flags for photochemistry processes to sum ! Inputs (optional) real(kind=kind_phys), intent(in), dimension(:,:), pointer, optional :: & - do3_dt_prd, & ! Physics tendency: production and loss effect - do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect - do3_dt_temp, & ! Physics tendency: temperature effect - do3_dt_ohoz ! Physics tendency: overhead ozone effect + do3_dt_prd, & ! Physics tendency: production and loss effect + do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect + do3_dt_temp, & ! Physics tendency: temperature effect + do3_dt_ohoz ! Physics tendency: overhead ozone effect ! Outputs real(kind=kind_phys), intent(inout), dimension(:,:,:) :: & - dtend ! Diagnostic tendencies for state variables + dtend ! Diagnostic tendencies for state variables character(len=*), intent(out) :: & - errmsg ! CCPP error message + errmsg ! CCPP error message integer, intent(out) :: & - errflg ! CCPP error flag + errflg ! CCPP error flag ! Locals - integer :: idtend - + integer :: idtend, ichem, iphys, itrac + logical :: all_true(nprocess) + ! Initialize CCPP error handling variables errmsg = '' errflg = 0 + if(.not.ldiag3d) then + return + endif + ! ####################################################################################### ! - ! Ozone physics diagnostic + ! Ozone physics diagnostics ! ! ####################################################################################### idtend = dtidx(100+ntoz,ip_prod_loss) @@ -98,6 +113,62 @@ subroutine GFS_physics_post_run(nCol, nLev, ntoz, dtidx, ip_prod_loss, ip_ozmix, dtend(:,:,idtend) = dtend(:,:,idtend) + do3_dt_ohoz endif - end subroutine GFS_physics_post_run + ! ####################################################################################### + ! + ! Total (photochemical) tendencies. + ! + ! ####################################################################################### + itrac = ntoz+100 + ichem = dtidx(itrac, ip_photochem) + if(ichem >= 1) then + call sum_it(ichem, itrac, is_photochem) + endif + ! ####################################################################################### + ! + ! Total (physics) tendencies + ! + ! ####################################################################################### + all_true = .true. + do itrac = 2,ntracp100 + iphys = dtidx(itrac,ip_physics) + if(iphys >= 1) then + call sum_it(iphys, itrac, all_true) + endif + enddo + + contains + + subroutine sum_it(isum,itrac,sum_me) + integer, intent(in) :: isum ! third index of dtend of summary process + integer, intent(in) :: itrac ! tracer or state variable being summed + logical, intent(in) :: sum_me(nprocess) ! false = skip this process + logical :: first + integer :: idtend, iprocess + + first=.true. + do iprocess=1,nprocess + if(iprocess>nprocess_summed) then + exit ! Don't sum up the sums. + else if(.not.sum_me(iprocess)) then + cycle ! We were asked to skip this one. + endif + idtend = dtidx(itrac,iprocess) + if(idtend>=1) then + ! This tendency was calculated for this tracer, so + ! accumulate it into the total tendency. + if(first) then + dtend(:,:,isum) = dtend(:,:,idtend) + first=.false. + else + dtend(:,:,isum) = dtend(:,:,isum) + dtend(:,:,idtend) + endif + endif + enddo + if(first) then + ! No tendencies were calculated, so sum is 0: + dtend(:,:,isum) = 0 + endif + end subroutine sum_it + end subroutine GFS_physics_post_run end module GFS_physics_post diff --git a/physics/GFS_physics_post.meta b/physics/GFS_physics_post.meta index 8b5120b9e..649ef6491 100644 --- a/physics/GFS_physics_post.meta +++ b/physics/GFS_physics_post.meta @@ -63,6 +63,55 @@ dimensions = () type = integer intent = in +[ntracp100] + standard_name = number_of_tracers_plus_one_hundred + long_name = number of tracers plus one hundred + units = count + dimensions = () + type = integer + intent = in +[nprocess] + standard_name = number_of_cumulative_change_processes + long_name = number of processes that cause changes in state variables + units = count + dimensions = () + type = integer + intent = in +[nprocess_summed] + standard_name = number_of_physics_causes_of_tracer_changes + long_name = number of causes in dtidx per tracer summed for total physics tendency + units = count + dimensions = () + type = integer + intent = in +[ip_physics] + standard_name = index_of_all_physics_process_in_cumulative_change_index + long_name = index of all physics transport process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[ip_photochem] + standard_name = index_of_photochemistry_process_in_cumulative_change_index + long_name = index of photochemistry process in second dimension of array cumulative change index + units = index + dimensions = () + type = integer + intent = in +[is_photochem] + standard_name = flags_for_photochemistry_processes_to_sum + long_name = flags for photochemistry processes to sum as the total photochemistry process cumulative change + units = flag + dimensions = (number_of_cumulative_change_processes) + type = logical + intent = in +[ldiag3d] + standard_name = flag_for_diagnostics_3D + long_name = flag for 3d diagnostic fields + units = flag + dimensions = () + type = logical + intent = in [ip_prod_loss] standard_name = index_of_production_and_loss_process_in_cumulative_change_index long_name = index of production and loss effect in photochemistry process in second dimension of array cumulative change index diff --git a/physics/phys_tend.F90 b/physics/phys_tend.F90 deleted file mode 100644 index e63f44be5..000000000 --- a/physics/phys_tend.F90 +++ /dev/null @@ -1,96 +0,0 @@ -!>\file phys_tend.F90 -!! -module phys_tend - - use machine, only: kind_phys - - implicit none - - private - - public phys_tend_run - -contains - -!> \section arg_table_phys_tend_run Argument Table -!! \htmlinclude phys_tend_run.html -!! - subroutine phys_tend_run(ldiag3d, dtend, dtidx, ntracp100, & - index_of_process_physics, index_of_process_photochem, & - nprocess, nprocess_summed, is_photochem, ntoz, errmsg, errflg) - - ! Interface variables - logical, intent(in) :: ldiag3d, is_photochem(:) - real(kind=kind_phys), optional, intent(inout) :: dtend(:,:,:) - integer, intent(in) :: dtidx(:,:), index_of_process_physics, ntoz, & - ntracp100, nprocess, nprocess_summed, index_of_process_photochem - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - integer :: ichem, iphys, itrac - logical :: all_true(nprocess) - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if(.not.ldiag3d) then - return - endif - - all_true = .true. - - ! Total photochemical tendencies - itrac=ntoz+100 - ichem = dtidx(itrac,index_of_process_photochem) - if(ichem>=1) then - call sum_it(ichem,itrac,is_photochem) - endif - - - do itrac=2,ntracp100 - ! Total physics tendencies - iphys = dtidx(itrac,index_of_process_physics) - if(iphys>=1) then - call sum_it(iphys,itrac,all_true) - endif - enddo - - contains - - subroutine sum_it(isum,itrac,sum_me) - implicit none - integer, intent(in) :: isum ! third index of dtend of summary process - integer, intent(in) :: itrac ! tracer or state variable being summed - logical, intent(in) :: sum_me(nprocess) ! false = skip this process - logical :: first - integer :: idtend, iprocess - - first=.true. - do iprocess=1,nprocess - if(iprocess>nprocess_summed) then - exit ! Don't sum up the sums. - else if(.not.sum_me(iprocess)) then - cycle ! We were asked to skip this one. - endif - idtend = dtidx(itrac,iprocess) - if(idtend>=1) then - ! This tendency was calculated for this tracer, so - ! accumulate it into the total tendency. - if(first) then - dtend(:,:,isum) = dtend(:,:,idtend) - first=.false. - else - dtend(:,:,isum) = dtend(:,:,isum) + dtend(:,:,idtend) - endif - endif - enddo - if(first) then - ! No tendencies were calculated, so sum is 0: - dtend(:,:,isum) = 0 - endif - end subroutine sum_it - - end subroutine phys_tend_run - -end module phys_tend diff --git a/physics/phys_tend.meta b/physics/phys_tend.meta deleted file mode 100644 index 0f78af20b..000000000 --- a/physics/phys_tend.meta +++ /dev/null @@ -1,95 +0,0 @@ -[ccpp-table-properties] - name = phys_tend - type = scheme - dependencies = machine.F - -######################################################################## -[ccpp-arg-table] - name = phys_tend_run - type = scheme -[ldiag3d] - standard_name = flag_for_diagnostics_3D - long_name = flag for 3d diagnostic fields - units = flag - dimensions = () - type = logical - intent = in -[dtend] - standard_name = cumulative_change_of_state_variables - long_name = diagnostic tendencies for state variables - units = mixed - dimensions = (horizontal_loop_extent,vertical_layer_dimension,cumulative_change_of_state_variables_outer_index_max) - type = real - kind = kind_phys - intent = inout -[dtidx] - standard_name = cumulative_change_of_state_variables_outer_index - long_name = index of state-variable and process in last dimension of diagnostic tendencies array AKA cumulative_change_index - units = index - dimensions = (number_of_tracers_plus_one_hundred,number_of_cumulative_change_processes) - type = integer - intent = in -[ntracp100] - standard_name = number_of_tracers_plus_one_hundred - long_name = number of tracers plus one hundred - units = count - dimensions = () - type = integer - intent = in -[index_of_process_physics] - standard_name = index_of_all_physics_process_in_cumulative_change_index - long_name = index of all physics transport process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[index_of_process_photochem] - standard_name = index_of_photochemistry_process_in_cumulative_change_index - long_name = index of photochemistry process in second dimension of array cumulative change index - units = index - dimensions = () - type = integer - intent = in -[nprocess] - standard_name = number_of_cumulative_change_processes - long_name = number of processes that cause changes in state variables - units = count - dimensions = () - type = integer - intent = in -[nprocess_summed] - standard_name = number_of_physics_causes_of_tracer_changes - long_name = number of causes in dtidx per tracer summed for total physics tendency - units = count - dimensions = () - type = integer - intent = in -[is_photochem] - standard_name = flags_for_photochemistry_processes_to_sum - long_name = flags for photochemistry processes to sum as the total photochemistry process cumulative change - units = flag - dimensions = (number_of_cumulative_change_processes) - type = logical - intent = in -[ntoz] - standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array - long_name = tracer index for ozone mixing ratio - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out From 06bb2bcc9ea2fa5dd52d8f0aa8be2f41b65ab8c0 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 12 Oct 2023 15:17:00 +0000 Subject: [PATCH 54/58] Final cleanup --- physics/GFS_phys_time_vary.scm.F90 | 83 +++++++++++++++++++++++------ physics/GFS_phys_time_vary.scm.meta | 75 +++++++++++++++++++++++++- physics/GFS_physics_post.F90 | 24 ++------- physics/GFS_physics_post.meta | 20 ------- 4 files changed, 144 insertions(+), 58 deletions(-) diff --git a/physics/GFS_phys_time_vary.scm.F90 b/physics/GFS_phys_time_vary.scm.F90 index 97460ac98..075bfc039 100644 --- a/physics/GFS_phys_time_vary.scm.F90 +++ b/physics/GFS_phys_time_vary.scm.F90 @@ -2,15 +2,17 @@ !! Contains code related to GFS physics suite setup (physics part of time_vary_step) !>\defgroup mod_GFS_phys_time_vary GFS Physics Time Update -!! This module contains GFS physics time vary subroutines including, stratospheric water vapor, +!! This module contains GFS physics time vary subroutines including stratospheric water vapor, !! aerosol, IN&CCN and surface properties updates. !> @{ module GFS_phys_time_vary - use machine, only : kind_phys + use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec use mersenne_twister, only: random_setseed, random_number + use module_ozphys, only: ty_ozphys + use h2o_def, only : levh2o, h2o_coeff, h2o_lat, h2o_pres, h2o_time, h2oplin use h2ointerp, only : read_h2odata, setindxh2o, h2ointerpol @@ -58,8 +60,8 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !! @{ subroutine GFS_phys_time_vary_init ( & - me, master, h2o_phys, iaerclm, iccn, iflip, im, nx, ny, idate, xlat_d, xlon_d, & - jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & + me, master, ntoz, h2o_phys, iaerclm, iccn, iflip, im, nx, ny, idate, xlat_d, xlon_d, & + jindx1_o3, jindx2_o3, ddy_o3, ozphys, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, imap, jmap, & do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau, & @@ -76,14 +78,14 @@ subroutine GFS_phys_time_vary_init ( implicit none ! Interface variables - integer, intent(in) :: me, master, iccn, iflip, im, nx, ny + integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhour real(kind_phys), intent(in) :: xlat_d(:), xlon_d(:) - integer, intent(inout) :: jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(inout) :: ddy_h(:) + integer, intent(inout) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(inout) :: ddy_o3(:), ddy_h(:) real(kind_phys), intent(in) :: h2opl(:,:,:) integer, intent(inout) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(inout) :: ddy_aer(:), ddx_aer(:) @@ -101,6 +103,7 @@ subroutine GFS_phys_time_vary_init ( real(kind_phys), intent(in) :: min_seaice, fice(:) real(kind_phys), intent(in) :: landfrac(:) real(kind_phys), intent(inout) :: weasd(:) + type(ty_ozphys), intent(in) :: ozphys ! NoahMP - only allocated when NoahMP is used integer, intent(in) :: lsoil, lsnow_lsm_lbound, lsnow_lsm_ubound @@ -244,6 +247,11 @@ subroutine GFS_phys_time_vary_init ( !> - Initialize soil vegetation (needed for sncovr calculation further down) call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) +!> - Setup spatial interpolation indices for ozone physics. + if (ntoz > 0) then + call ozphys%setup_o3prog(xlat_d, jindx1_o3, jindx2_o3, ddy_o3) + endif + !> - Call setindxh2o() to initialize stratospheric water vapor data if (h2o_phys) then call setindxh2o (im, xlat_d, jindx1_h, jindx2_h, ddy_h) @@ -625,8 +633,8 @@ end subroutine GFS_phys_time_vary_init !! @{ subroutine GFS_phys_time_vary_timestep_init ( & me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, nsswr, fhswr, lsswr, fhour, & - imfdeepcnv, cal_pre, random_clds, h2o_phys, iaerclm, iccn, clstp, & - jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & + imfdeepcnv, cal_pre, random_clds, ozphys, ntoz, h2o_phys, iaerclm, iccn, clstp, & + jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, & imap, jmap, prsl, seed0, rann, do_ugwp_v1, jindx1_tau, jindx2_tau, ddy_j1tau, ddy_j2tau,& @@ -636,14 +644,14 @@ subroutine GFS_phys_time_vary_timestep_init ( ! Interface variables integer, intent(in) :: me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, & - nsswr, imfdeepcnv, iccn, iflip + nsswr, imfdeepcnv, iccn, ntoz, iflip integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhswr, fhour logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm real(kind_phys), intent(out) :: clstp - integer, intent(in) :: jindx1_h(:), jindx2_h(:) - real(kind_phys), intent(in) :: ddy_h(:) - real(kind_phys), intent(inout) :: h2opl(:,:,:) + integer, intent(in) :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:) + real(kind_phys), intent(in) :: ddy_o3(:), ddy_h(:) + real(kind_phys), intent(inout) :: ozpl(:,:,:), h2opl(:,:,:) integer, intent(in) :: jindx1_aer(:), jindx2_aer(:), iindx1_aer(:), iindx2_aer(:) real(kind_phys), intent(in) :: ddy_aer(:), ddx_aer(:) real(kind_phys), intent(inout) :: aer_nm(:,:,:) @@ -659,15 +667,19 @@ subroutine GFS_phys_time_vary_timestep_init ( integer, intent(in) :: jindx1_tau(:), jindx2_tau(:) real(kind_phys), intent(in) :: ddy_j1tau(:), ddy_j2tau(:) real(kind_phys), intent(inout) :: tau_amf(:) + type(ty_ozphys), intent(in) :: ozphys integer, intent(in) :: nthrds character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg ! Local variables - integer :: i, j, k, iseed, iskip, ix - real(kind=kind_phys) :: wrk(1) - real(kind=kind_phys) :: rannie(cny) - real(kind=kind_phys) :: rndval(cnx*cny*nrcm) + integer :: i, j, k, iseed, iskip, ix, idat(8), jdat(8), iday, j1, j2, nc, n1, n2, jdow, & + jdoy, jday, w3kindreal, w3kindint + real(kind_phys) :: wrk(1), tem, tx1, tx2, rjday + real(kind_phys) :: rannie(cny) + real(kind_phys) :: rndval(cnx*cny*nrcm) + real(kind_dbl_prec) :: rinc(5) + real(kind_sngl_prec) :: rinc4(5) ! Initialize CCPP error handling variables errmsg = '' @@ -721,6 +733,43 @@ subroutine GFS_phys_time_vary_timestep_init ( endif ! imfdeepcnv, cal_re, random_clds + !> - Compute temporal interpolation indices for updating gas concentrations. + idat=0 + idat(1)=idate(4) + idat(2)=idate(2) + idat(3)=idate(3) + idat(5)=idate(1) + rinc=0. + rinc(2)=fhour + call w3kind(w3kindreal,w3kindint) + if(w3kindreal==4) then + rinc4=rinc + CALL w3movdat(rinc4,idat,jdat) + else + CALL w3movdat(rinc,idat,jdat) + endif + jdow = 0 + jdoy = 0 + jday = 0 + call w3doxdat(jdat,jdow,jdoy,jday) + rjday = jdoy + jdat(5) / 24. + if (rjday < ozphys%time(1)) rjday = rjday + 365. + + n2 = ozphys%ntime + 1 + do j=2,ozphys%ntime + if (rjday < ozphys%time(j)) then + n2 = j + exit + endif + enddo + n1 = n2 - 1 + if (n2 > ozphys%ntime) n2 = n2 - ozphys%ntime + +!> - Update ozone concentration. + if (ntoz > 0) then + call ozphys%update_o3prog(jindx1_o3, jindx2_o3, ddy_o3, rjday, n1, n2, ozpl) + endif + !> - Call h2ointerpol() to make stratospheric water vapor data interpolation if (h2o_phys) then call h2ointerpol (me, im, idate, fhour, & diff --git a/physics/GFS_phys_time_vary.scm.meta b/physics/GFS_phys_time_vary.scm.meta index 21d1f2736..cf5ad15ca 100644 --- a/physics/GFS_phys_time_vary.scm.meta +++ b/physics/GFS_phys_time_vary.scm.meta @@ -2,7 +2,7 @@ name = GFS_phys_time_vary type = scheme dependencies = aerclm_def.F,aerinterp.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f - dependencies = namelist_soilveg.f,set_soilveg.f,cires_tauamf_data.F90,noahmp_tables.f90 + dependencies = namelist_soilveg.f,set_soilveg.f,module_ozphys.F90,cires_tauamf_data.F90,noahmp_tables.f90 ######################################################################## [ccpp-arg-table] @@ -23,6 +23,13 @@ dimensions = () type = integer intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -95,6 +102,28 @@ type = real kind = kind_phys intent = in +[jindx1_o3] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[jindx2_o3] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = inout +[ddy_o3] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor @@ -1019,6 +1048,13 @@ dimensions = () type = logical intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in [h2o_phys] standard_name = flag_for_stratospheric_water_vapor_physics long_name = flag for stratospheric water vapor physics @@ -1048,6 +1084,36 @@ type = real kind = kind_phys intent = out +[jindx1_o3] + standard_name = lower_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation low index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[jindx2_o3] + standard_name = upper_latitude_index_of_ozone_forcing_for_interpolation + long_name = interpolation high index for ozone + units = index + dimensions = (horizontal_dimension) + type = integer + intent = in +[ddy_o3] + standard_name = latitude_interpolation_weight_for_ozone_forcing + long_name = interpolation high index for ozone + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys + intent = in +[ozpl] + standard_name = ozone_forcing + long_name = ozone forcing data + units = mixed + dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + type = real + kind = kind_phys + intent = inout [jindx1_h] standard_name = lower_latitude_index_of_stratospheric_water_vapor_forcing_for_interpolation long_name = interpolation low index for stratospheric water vapor @@ -1279,6 +1345,13 @@ type = real kind = kind_phys intent = inout +[ozphys] + standard_name = dataset_for_ozone_physics + long_name = dataset for NRL ozone physics + units = mixed + dimensions = () + type = ty_ozphys + intent = in [nthrds] standard_name = number_of_openmp_threads long_name = number of OpenMP threads available for physics schemes diff --git a/physics/GFS_physics_post.F90 b/physics/GFS_physics_post.F90 index def38cd1a..f89b257a8 100644 --- a/physics/GFS_physics_post.F90 +++ b/physics/GFS_physics_post.F90 @@ -13,22 +13,6 @@ module GFS_physics_post public GFS_physics_post_init, GFS_physics_post_run contains -! ########################################################################################### -! SUBROUTINE GFS_physics_post_init -! ########################################################################################### -!! \section arg_table_GFS_physics_post_init Argument Table -!! \htmlinclude GFS_physics_post_init.html -!! - subroutine GFS_physics_post_init(errmsg, errflg) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - end subroutine GFS_physics_post_init - ! ########################################################################################### ! SUBROUTINE GFS_physics_post_run ! ########################################################################################### @@ -36,9 +20,9 @@ end subroutine GFS_physics_post_init !! \htmlinclude GFS_physics_post_run.html !! subroutine GFS_physics_post_run(nCol, nLev, ntoz, ntracp100, nprocess, nprocess_summed, & - dtidx, is_photochem, ldiag3d, ip_physics, ip_photochem, & - ip_prod_loss, ip_ozmix, ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, & - do3_dt_temp, do3_dt_ohoz, dtend, errmsg, errflg) + dtidx, is_photochem, ldiag3d, ip_physics, ip_photochem, ip_prod_loss, ip_ozmix, & + ip_temp, ip_overhead_ozone, do3_dt_prd, do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz, & + dtend, errmsg, errflg) ! Inputs integer, intent(in) :: & @@ -49,7 +33,7 @@ subroutine GFS_physics_post_run(nCol, nLev, ntoz, ntracp100, nprocess, nprocess_ nprocess, & ! Number of processes that cause changes in state variables nprocess_summed,& ! Number of causes in dtidx per tracer summed for total physics tendency ip_physics, & ! Index for process in diagnostic tendency output - ip_photochem, & ! + ip_photochem, & ! Index for process in diagnostic tendency output ip_prod_loss, & ! Index for process in diagnostic tendency output ip_ozmix, & ! Index for process in diagnostic tendency output ip_temp, & ! Index for process in diagnostic tendency output diff --git a/physics/GFS_physics_post.meta b/physics/GFS_physics_post.meta index 649ef6491..5701909fd 100644 --- a/physics/GFS_physics_post.meta +++ b/physics/GFS_physics_post.meta @@ -3,26 +3,6 @@ type = scheme dependencies = machine.F -######################################################################## -[ccpp-arg-table] - name = GFS_physics_post_init - type = scheme -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - ######################################################################## [ccpp-arg-table] name = GFS_physics_post_run From 89af3d8946ab25737628a016fe89356a261155ac Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 12 Oct 2023 15:45:58 +0000 Subject: [PATCH 55/58] Omission from previous commit --- physics/GFS_physics_post.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/GFS_physics_post.F90 b/physics/GFS_physics_post.F90 index f89b257a8..fe5409353 100644 --- a/physics/GFS_physics_post.F90 +++ b/physics/GFS_physics_post.F90 @@ -10,7 +10,7 @@ module GFS_physics_post use machine, only : kind_phys, kind_dbl_prec, kind_sngl_prec implicit none - public GFS_physics_post_init, GFS_physics_post_run + public GFS_physics_post_run contains ! ########################################################################################### From c6204e149fdbff013532cf991e9ad00b107d111b Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sun, 15 Oct 2023 08:15:23 -0400 Subject: [PATCH 56/58] add dlw,dsw inst to cpllnd block --- physics/GFS_surface_generic_post.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/physics/GFS_surface_generic_post.F90 b/physics/GFS_surface_generic_post.F90 index 9faebc8cf..7e8cfa753 100644 --- a/physics/GFS_surface_generic_post.F90 +++ b/physics/GFS_surface_generic_post.F90 @@ -130,6 +130,8 @@ subroutine GFS_surface_generic_post_run (im, cplflx, cplaqm, cplchm, cplwav, cpl if (cplflx .or. cpllnd) then do i=1,im + dlwsfci_cpl (i) = adjsfcdlw(i) + dswsfci_cpl (i) = adjsfcdsw(i) dlwsfc_cpl (i) = dlwsfc_cpl(i) + adjsfcdlw(i)*dtf dswsfc_cpl (i) = dswsfc_cpl(i) + adjsfcdsw(i)*dtf psurfi_cpl (i) = pgr(i) @@ -138,8 +140,6 @@ subroutine GFS_surface_generic_post_run (im, cplflx, cplaqm, cplchm, cplwav, cpl if (cplflx) then do i=1,im - dlwsfci_cpl (i) = adjsfcdlw(i) - dswsfci_cpl (i) = adjsfcdsw(i) dnirbmi_cpl (i) = adjnirbmd(i) dnirdfi_cpl (i) = adjnirdfd(i) dvisbmi_cpl (i) = adjvisbmd(i) @@ -242,7 +242,7 @@ subroutine GFS_surface_generic_post_run (im, cplflx, cplaqm, cplchm, cplwav, cpl tedir(i) = tedir(i) + edir(i) * dtf if (lsm == lsm_noahmp) then paha(i) = paha(i) + pah(i) * dtf - twa(i) = waxy(i) + twa(i) = waxy(i) endif enddo endif @@ -252,7 +252,7 @@ subroutine GFS_surface_generic_post_run (im, cplflx, cplaqm, cplchm, cplwav, cpl ! heat torage parameterization the kinematic sensible heat flux ! (hflx) as surface boundary forcing to the pbl scheme is ! reduced in a factor of hffac given as a function of surface roughness & -! green vegetation fraction (zvfun) +! green vegetation fraction (zvfun) ! do i=1,im hflxq(i) = hflx(i) From 2f417bb5f8c1e814ea5f3539615395d9ed096eca Mon Sep 17 00:00:00 2001 From: Helin Wei Date: Tue, 17 Oct 2023 12:32:30 -0400 Subject: [PATCH 57/58] refine surface 2m t/q diagnostic method --- physics/sfc_diag_post.F90 | 24 ++++++++++++++++++------ physics/sfc_diag_post.meta | 7 +++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/physics/sfc_diag_post.F90 b/physics/sfc_diag_post.F90 index c1a43f170..6945e48e9 100644 --- a/physics/sfc_diag_post.F90 +++ b/physics/sfc_diag_post.F90 @@ -14,16 +14,17 @@ module sfc_diag_post !! #endif subroutine sfc_diag_post_run (im, lsm, lsm_noahmp, opt_diag, dry, lssav, dtf, con_eps, con_epsm1, pgr,& - t2mmp,q2mp, t2m, q2m, u10m, v10m, tmpmin, tmpmax, spfhmin, spfhmax, & + vegtype,t2mmp,q2mp, t2m, q2m, u10m, v10m, tmpmin, tmpmax, spfhmin, spfhmax, & wind10mmax, u10mmax, v10mmax, dpt2m, errmsg, errflg) use machine, only: kind_phys, kind_dbl_prec implicit none - integer, intent(in) :: im, lsm, lsm_noahmp,opt_diag - logical, intent(in) :: lssav - real(kind=kind_phys), intent(in) :: dtf, con_eps, con_epsm1 + integer, intent(in) :: im, lsm, lsm_noahmp,opt_diag + integer, dimension(:), intent(in) :: vegtype ! vegetation type (integer index) + logical, intent(in) :: lssav + real(kind=kind_phys), intent(in) :: dtf, con_eps, con_epsm1 logical , dimension(:), intent(in) :: dry real(kind=kind_phys), dimension(:), intent(in) :: pgr, u10m, v10m real(kind=kind_phys), dimension(:), intent(inout) :: t2m, q2m, tmpmin, tmpmax, spfhmin, spfhmax @@ -41,12 +42,23 @@ subroutine sfc_diag_post_run (im, lsm, lsm_noahmp, opt_diag, dry, lssav, dtf, co errflg = 0 if (lsm == lsm_noahmp) then - if (opt_diag == 2 .or. opt_diag == 3)then +! over shrublands use opt_diag=2 + do i=1, im + if(dry(i)) then + if (vegtype(i) == 6 .or. vegtype(i) == 7 & + .or. vegtype(i) == 16) then + t2m(i) = t2mmp(i) + q2m(i) = q2mp(i) + endif + endif + enddo + + if (opt_diag == 2 .or. opt_diag == 3) then do i=1,im if(dry(i)) then t2m(i) = t2mmp(i) q2m(i) = q2mp(i) - endif + endif enddo endif endif diff --git a/physics/sfc_diag_post.meta b/physics/sfc_diag_post.meta index c50d3c4dc..17648753a 100644 --- a/physics/sfc_diag_post.meta +++ b/physics/sfc_diag_post.meta @@ -81,6 +81,13 @@ type = real kind = kind_phys intent = in +[vegtype] + standard_name = vegetation_type_classification + long_name = vegetation type at each grid cell + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent= in [t2mmp] standard_name = temperature_at_2m_from_noahmp long_name = 2 meter temperature from noahmp From 32cf7ba5484db1387e33c7f9d25de87079e9014c Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Fri, 27 Oct 2023 17:01:01 +0000 Subject: [PATCH 58/58] Reverted standard_name change --- physics/GFS_phys_time_vary.fv3.meta | 2 +- physics/GFS_phys_time_vary.scm.meta | 2 +- physics/GFS_suite_stateout_update.meta | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index ad543e146..968f33027 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -1205,7 +1205,7 @@ standard_name = ozone_forcing long_name = ozone forcing data units = mixed - dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_data) type = real kind = kind_phys intent = inout diff --git a/physics/GFS_phys_time_vary.scm.meta b/physics/GFS_phys_time_vary.scm.meta index cf5ad15ca..d72e27fd5 100644 --- a/physics/GFS_phys_time_vary.scm.meta +++ b/physics/GFS_phys_time_vary.scm.meta @@ -1110,7 +1110,7 @@ standard_name = ozone_forcing long_name = ozone forcing data units = mixed - dimensions = (horizontal_dimension,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + dimensions = (horizontal_dimension,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_data) type = real kind = kind_phys intent = inout diff --git a/physics/GFS_suite_stateout_update.meta b/physics/GFS_suite_stateout_update.meta index 8cbab9139..fae276d2f 100644 --- a/physics/GFS_suite_stateout_update.meta +++ b/physics/GFS_suite_stateout_update.meta @@ -218,7 +218,7 @@ standard_name = ozone_forcing long_name = ozone forcing data units = mixed - dimensions = (horizontal_loop_extent,number_of_levels_in_ozone_data,number_of_coefficients_in_ozone_data) + dimensions = (horizontal_loop_extent,vertical_dimension_of_ozone_forcing_data,number_of_coefficients_in_ozone_data) type = real kind = kind_phys intent = in