From d61764c8a4f7acb65db0bc2c54d874a1dab69594 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Thu, 4 Mar 2021 11:56:26 -0700 Subject: [PATCH] Make convert_dry_rho an input argument, fix a bug in the non-aerosol-aware version (nc not allocated) --- physics/module_mp_thompson.F90 | 11 +++--- physics/mp_thompson.F90 | 62 ++++++++++++++++++++++++++++------ physics/mp_thompson.meta | 16 +++++++++ 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/physics/module_mp_thompson.F90 b/physics/module_mp_thompson.F90 index 09bb5c939..25466f412 100644 --- a/physics/module_mp_thompson.F90 +++ b/physics/module_mp_thompson.F90 @@ -423,9 +423,7 @@ MODULE module_mp_thompson !..If SIONlib isn't used, write Thompson tables with master MPI task !.. after computing them in thompson_init -#ifndef SION LOGICAL:: thompson_table_writer -#endif !+---+ !+---+-----------------------------------------------------------------+ @@ -767,7 +765,7 @@ SUBROUTINE thompson_init(mpicomm, mpirank, mpiroot, & precomputed_tables = .false. if (mpirank==mpiroot) write(0,*) "An error occurred reading Thompson tables from disk, recalculate" end if -#else +#endif ! Standard tables are only written by master MPI task; ! (physics init cannot be called by multiple threads, ! hence no need to test for a specific thread number) @@ -776,7 +774,6 @@ SUBROUTINE thompson_init(mpicomm, mpirank, mpiroot, & else thompson_table_writer = .false. end if -#endif precomputed_tables_1: if (.not.precomputed_tables) then @@ -3847,7 +3844,7 @@ subroutine qr_acr_qg #ifndef SION if (thompson_table_writer) write_thompson_tables = .true. #endif - write(0,*) "ThompMP: computing qr_acr_qg" + if (thompson_table_writer) write(0,*) "ThompMP: computing qr_acr_qg" do n2 = 1, nbr ! vr(n2) = av_r*Dr(n2)**bv_r * DEXP(-fv_r*Dr(n2)) vr(n2) = -0.1021 + 4.932E3*Dr(n2) - 0.9551E6*Dr(n2)*Dr(n2) & @@ -4029,7 +4026,7 @@ subroutine qr_acr_qs #ifndef SION if (thompson_table_writer) write_thompson_tables = .true. #endif - write(0,*) "ThompMP: computing qr_acr_qs" + if (thompson_table_writer) write(0,*) "ThompMP: computing qr_acr_qs" do n2 = 1, nbr ! vr(n2) = av_r*Dr(n2)**bv_r * DEXP(-fv_r*Dr(n2)) vr(n2) = -0.1021 + 4.932E3*Dr(n2) - 0.9551E6*Dr(n2)*Dr(n2) & @@ -4284,7 +4281,7 @@ subroutine freezeH2O(threads) #ifndef SION if (thompson_table_writer) write_thompson_tables = .true. #endif - write(0,*) "ThompMP: computing freezeH2O" + if (thompson_table_writer) write(0,*) "ThompMP: computing freezeH2O" orho_w = 1./rho_w diff --git a/physics/mp_thompson.F90 b/physics/mp_thompson.F90 index fbfbe72a9..252944b77 100644 --- a/physics/mp_thompson.F90 +++ b/physics/mp_thompson.F90 @@ -21,7 +21,6 @@ module mp_thompson private logical :: is_initialized = .False. - logical :: convert_dry_rho = .False. contains @@ -31,6 +30,7 @@ module mp_thompson !! subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & imp_physics, imp_physics_thompson, & + convert_dry_rho, & spechum, qc, qr, qi, qs, qg, ni, nr, & is_aerosol_aware, nc, nwfa2d, nifa2d, & nwfa, nifa, tgrs, prsl, phil, area, & @@ -48,6 +48,7 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & integer, intent(in ) :: imp_physics integer, intent(in ) :: imp_physics_thompson ! Hydrometeors + logical, intent(in ) :: convert_dry_rho real(kind_phys), intent(inout) :: spechum(:,:) real(kind_phys), intent(inout) :: qc(:,:) real(kind_phys), intent(inout) :: qr(:,:) @@ -83,10 +84,11 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & integer, intent( out) :: errflg ! - real(kind_phys) :: qv(1:ncol,1:nlev) ! kg kg-1 (water vapor mixing ratio) - real(kind_phys) :: hgt(1:ncol,1:nlev) ! m - real(kind_phys) :: rho(1:ncol,1:nlev) ! kg m-3 - real(kind_phys) :: orho(1:ncol,1:nlev) ! m3 kg-1 + real(kind_phys) :: qv(1:ncol,1:nlev) ! kg kg-1 (water vapor mixing ratio) + real(kind_phys) :: hgt(1:ncol,1:nlev) ! m + real(kind_phys) :: rho(1:ncol,1:nlev) ! kg m-3 + real(kind_phys) :: orho(1:ncol,1:nlev) ! m3 kg-1 + real(kind_phys) :: nc_local(1:ncol,1:nlev) ! needed because nc is only allocated if is_aerosol_aware is true ! real (kind=kind_phys) :: h_01, airmass, niIN3, niCCN3 integer :: i, k @@ -134,9 +136,28 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & where(qs<0) qs = 0.0 where(qg<0) qg = 0.0 - ! Convert specific humidity to water vapor mixing ratio + !> - Convert specific humidity to water vapor mixing ratio. + !> - Also, hydrometeor variables are mass or number mixing ratio + !> - either kg of species per kg of dry air, or per kg of (dry + vapor). + qv = spechum/(1.0_kind_phys-spechum) + if (convert_dry_rho) then + qc = qc/(1.0_kind_phys-spechum) + qr = qr/(1.0_kind_phys-spechum) + qi = qi/(1.0_kind_phys-spechum) + qs = qs/(1.0_kind_phys-spechum) + qg = qg/(1.0_kind_phys-spechum) + + ni = ni/(1.0_kind_phys-spechum) + nr = nr/(1.0_kind_phys-spechum) + if (is_aerosol_aware) then + nc = nc/(1.0_kind_phys-spechum) + nwfa = nwfa/(1.0_kind_phys-spechum) + nifa = nifa/(1.0_kind_phys-spechum) + end if + end if + ! Density of moist air in kg m-3 and inverse density of air rho = 0.622*prsl/(con_rd*tgrs*(qv+0.622)) orho = 1.0/rho @@ -229,17 +250,20 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & ! Ensure we have 1st guess cloud droplet number where mass non-zero but no number. where(qc .LE. 0.0) nc=0.0 where(qc .GT. 0 .and. nc .LE. 0.0) nc = make_DropletNumber(qc*rho, nwfa*rho) * orho - where(qc .EQ. 0.0 .and. nc .GT. 0.0) nc=0.0 + where(qc .EQ. 0.0 .and. nc .GT. 0.0) nc = 0.0 ! Ensure non-negative aerosol number concentrations. where(nwfa .LE. 0.0) nwfa = 1.1E6 where(nifa .LE. 0.0) nifa = naIN1*0.01 + ! Copy to local array for calculating cloud effective radii below + nc_local = nc + else ! Constant droplet concentration for single moment cloud water as in ! module_mp_thompson.F90, only needed for effective radii calculation - nc = Nt_c/rho + nc_local = Nt_c/rho end if @@ -247,8 +271,8 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & if (present(re_cloud) .and. present(re_ice) .and. present(re_snow)) then ! Effective radii [m] are now intent(out), bounds applied in calc_effectRad do i = 1, ncol - call calc_effectRad (tgrs(i,:), prsl(i,:), qv(i,:), qc(i,:), & - nc(i,:), qi(i,:), ni(i,:), qs(i,:), & + call calc_effectRad (tgrs(i,:), prsl(i,:), qv(i,:), qc(i,:), & + nc_local(i,:), qi(i,:), ni(i,:), qs(i,:), & re_cloud(i,:), re_ice(i,:), re_snow(i,:), 1, nlev) do k = 1, nlev re_cloud(i,k) = MAX(re_qc_min, MIN(re_cloud(i,k), re_qc_max)) @@ -271,6 +295,22 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, restart, & return end if + if (convert_dry_rho) then + !qc = qc/(1.0_kind_phys+qv) + !qr = qr/(1.0_kind_phys+qv) + !qi = qi/(1.0_kind_phys+qv) + !qs = qs/(1.0_kind_phys+qv) + !qg = qg/(1.0_kind_phys+qv) + + ni = ni/(1.0_kind_phys+qv) + nr = nr/(1.0_kind_phys+qv) + if (is_aerosol_aware) then + nc = nc/(1.0_kind_phys+qv) + nwfa = nwfa/(1.0_kind_phys+qv) + nifa = nifa/(1.0_kind_phys+qv) + end if + end if + is_initialized = .true. end subroutine mp_thompson_init @@ -283,6 +323,7 @@ end subroutine mp_thompson_init !>\section gen_thompson_hrrr Thompson MP General Algorithm !>@{ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & + convert_dry_rho, & spechum, qc, qr, qi, qs, qg, ni, nr, & is_aerosol_aware, nc, nwfa, nifa, & nwfa2d, nifa2d, & @@ -303,6 +344,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & real(kind_phys), intent(in ) :: con_g real(kind_phys), intent(in ) :: con_rd ! Hydrometeors + logical, intent(in ) :: convert_dry_rho real(kind_phys), intent(inout) :: spechum(1:ncol,1:nlev) real(kind_phys), intent(inout) :: qc(1:ncol,1:nlev) real(kind_phys), intent(inout) :: qr(1:ncol,1:nlev) diff --git a/physics/mp_thompson.meta b/physics/mp_thompson.meta index 4cfee6afc..ed54f8d02 100644 --- a/physics/mp_thompson.meta +++ b/physics/mp_thompson.meta @@ -65,6 +65,14 @@ type = integer intent = in optional = F +[convert_dry_rho] + standard_name = flag_for_converting_hydrometeors_from_moist_to_dry_air + long_name = flag for converting hydrometeors from moist to dry air + units = flag + dimensions = () + type = logical + intent = in + optional = F [spechum] standard_name = water_vapor_specific_humidity long_name = water vapor specific humidity @@ -341,6 +349,14 @@ kind = kind_phys intent = in optional = F +[convert_dry_rho] + standard_name = flag_for_converting_hydrometeors_from_moist_to_dry_air + long_name = flag for converting hydrometeors from moist to dry air + units = flag + dimensions = () + type = logical + intent = in + optional = F [spechum] standard_name = water_vapor_specific_humidity_updated_by_physics long_name = water vapor specific humidity