Skip to content

Commit 7b530d7

Browse files
authored
Merge branch 'whannah/eam/zm-bridge-00' (PR #7473)
This is the first step of bringing ZM into eamxx by adding the basic infrastructure needed for bridging from C++ to fortran. Currently this only includes a single, simple unit test to the ZM routine for finding the maximum moist static energy for launching a parcel.
2 parents dfb364d + 1e8d606 commit 7b530d7

30 files changed

+2024
-101
lines changed

components/eam/src/physics/cam/zm_aero.F90

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,72 +7,10 @@ module zm_aero
77
use ppgrid, only: pcols, pver, pverp
88
use cam_abortutils, only: endrun
99
use cam_logfile, only: iulog
10+
use zm_aero_type, only: zm_aero_t
1011

11-
public :: zm_aero_t ! structure to hold aerosol state information for ZM microphysics
1212
public :: zm_aero_init ! aerosol stype initialization
1313

14-
!===================================================================================================
15-
16-
! generic 2D pointer type for zm_aero_t
17-
type, public :: ptr2d
18-
real(r8), pointer :: val(:,:)
19-
end type ptr2d
20-
21-
! structure to hold aerosol state information for ZM microphysics
22-
type :: zm_aero_t
23-
24-
! Aerosol treatment
25-
character(len=5) :: scheme ! either 'bulk' or 'modal'
26-
27-
! Bulk aerosols
28-
integer :: nbulk = 0 ! number of bulk aerosols affecting climate
29-
integer :: idxsul = -1 ! index in aerosol list for sulfate
30-
integer :: idxdst1 = -1 ! index in aerosol list for dust1
31-
integer :: idxdst2 = -1 ! index in aerosol list for dust2
32-
integer :: idxdst3 = -1 ! index in aerosol list for dust3
33-
integer :: idxdst4 = -1 ! index in aerosol list for dust4
34-
integer :: idxbcphi = -1 ! index in aerosol list for Soot (BCPHI)
35-
36-
real(r8), allocatable :: num_to_mass_aer(:) ! conversion of mmr to number conc for bulk aerosols
37-
type(ptr2d), allocatable :: mmr_bulk(:) ! array of pointers to bulk aerosol mmr
38-
real(r8), allocatable :: mmrg_bulk(:,:,:) ! gathered bulk aerosol mmr
39-
40-
! Modal aerosols
41-
integer :: nmodes = 0 ! number of modes
42-
integer, allocatable :: nspec(:) ! number of species in each mode
43-
type(ptr2d), allocatable :: num_a(:) ! number mixing ratio of modes (interstitial phase)
44-
type(ptr2d), allocatable :: mmr_a(:,:) ! species mmr in each mode (interstitial phase)
45-
real(r8), allocatable :: numg_a(:,:,:) ! gathered number mixing ratio of modes (interstitial phase)
46-
real(r8), allocatable :: mmrg_a(:,:,:,:) ! gathered species mmr in each mode (interstitial phase)
47-
real(r8), allocatable :: voltonumblo(:) ! volume to number conversion (lower bound) for each mode
48-
real(r8), allocatable :: voltonumbhi(:) ! volume to number conversion (upper bound) for each mode
49-
real(r8), allocatable :: specdens(:,:) ! density of modal species
50-
real(r8), allocatable :: spechygro(:,:) ! hygroscopicity of modal species
51-
52-
integer :: mode_accum_idx = -1 ! index of accumulation mode
53-
integer :: mode_aitken_idx = -1 ! index of aitken mode
54-
integer :: mode_coarse_idx = -1 ! index of coarse mode
55-
integer :: coarse_dust_idx = -1 ! index of dust in coarse mode
56-
integer :: coarse_nacl_idx = -1 ! index of nacl in coarse mode
57-
58-
integer :: coarse_so4_idx = -1 ! index of so4 in coarse mode
59-
#if (defined MODAL_AERO_4MODE_MOM || defined MODAL_AERO_5MODE)
60-
integer :: coarse_mom_idx = -1 ! index of mom in coarse mode
61-
#endif
62-
63-
#if (defined RAIN_EVAP_TO_COARSE_AERO)
64-
integer :: coarse_bc_idx = -1 ! index of bc in coarse mode
65-
integer :: coarse_pom_idx = -1 ! index of pom in coarse mode
66-
integer :: coarse_soa_idx = -1 ! index of soa in coarse mode
67-
#endif
68-
69-
type(ptr2d), allocatable :: dgnum(:) ! mode dry radius
70-
real(r8), allocatable :: dgnumg(:,:,:) ! gathered mode dry radius
71-
72-
real(r8) :: sigmag_aitken
73-
74-
end type zm_aero_t
75-
7614
!===================================================================================================
7715
contains
7816
!===================================================================================================
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
module zm_aero_type
2+
!----------------------------------------------------------------------------
3+
! Purpose: aerosol derived type for ZM microphysics
4+
! Original Author: Xialiang Song and Guang Zhang, June 2010
5+
!----------------------------------------------------------------------------
6+
#ifdef SCREAM_CONFIG_IS_CMAKE
7+
use zm_eamxx_bridge_params, only: r8
8+
#else
9+
use shr_kind_mod, only: r8=>shr_kind_r8
10+
#endif
11+
12+
public :: zm_aero_t ! structure to hold aerosol state information for ZM microphysics
13+
14+
!===================================================================================================
15+
16+
! generic 2D pointer type for zm_aero_t
17+
type, public :: ptr2d
18+
real(r8), pointer :: val(:,:)
19+
end type ptr2d
20+
21+
! structure to hold aerosol state information for ZM microphysics
22+
type :: zm_aero_t
23+
24+
! Aerosol treatment
25+
character(len=5) :: scheme ! either 'bulk' or 'modal'
26+
27+
! Bulk aerosols
28+
integer :: nbulk = 0 ! number of bulk aerosols affecting climate
29+
integer :: idxsul = -1 ! index in aerosol list for sulfate
30+
integer :: idxdst1 = -1 ! index in aerosol list for dust1
31+
integer :: idxdst2 = -1 ! index in aerosol list for dust2
32+
integer :: idxdst3 = -1 ! index in aerosol list for dust3
33+
integer :: idxdst4 = -1 ! index in aerosol list for dust4
34+
integer :: idxbcphi = -1 ! index in aerosol list for Soot (BCPHI)
35+
36+
real(r8), allocatable :: num_to_mass_aer(:) ! conversion of mmr to number conc for bulk aerosols
37+
type(ptr2d), allocatable :: mmr_bulk(:) ! array of pointers to bulk aerosol mmr
38+
real(r8), allocatable :: mmrg_bulk(:,:,:) ! gathered bulk aerosol mmr
39+
40+
! Modal aerosols
41+
integer :: nmodes = 0 ! number of modes
42+
integer, allocatable :: nspec(:) ! number of species in each mode
43+
type(ptr2d), allocatable :: num_a(:) ! number mixing ratio of modes (interstitial phase)
44+
type(ptr2d), allocatable :: mmr_a(:,:) ! species mmr in each mode (interstitial phase)
45+
real(r8), allocatable :: numg_a(:,:,:) ! gathered number mixing ratio of modes (interstitial phase)
46+
real(r8), allocatable :: mmrg_a(:,:,:,:) ! gathered species mmr in each mode (interstitial phase)
47+
real(r8), allocatable :: voltonumblo(:) ! volume to number conversion (lower bound) for each mode
48+
real(r8), allocatable :: voltonumbhi(:) ! volume to number conversion (upper bound) for each mode
49+
real(r8), allocatable :: specdens(:,:) ! density of modal species
50+
real(r8), allocatable :: spechygro(:,:) ! hygroscopicity of modal species
51+
52+
integer :: mode_accum_idx = -1 ! index of accumulation mode
53+
integer :: mode_aitken_idx = -1 ! index of aitken mode
54+
integer :: mode_coarse_idx = -1 ! index of coarse mode
55+
integer :: coarse_dust_idx = -1 ! index of dust in coarse mode
56+
integer :: coarse_nacl_idx = -1 ! index of nacl in coarse mode
57+
58+
integer :: coarse_so4_idx = -1 ! index of so4 in coarse mode
59+
#if (defined MODAL_AERO_4MODE_MOM || defined MODAL_AERO_5MODE)
60+
integer :: coarse_mom_idx = -1 ! index of mom in coarse mode
61+
#endif
62+
63+
#if (defined RAIN_EVAP_TO_COARSE_AERO)
64+
integer :: coarse_bc_idx = -1 ! index of bc in coarse mode
65+
integer :: coarse_pom_idx = -1 ! index of pom in coarse mode
66+
integer :: coarse_soa_idx = -1 ! index of soa in coarse mode
67+
#endif
68+
69+
type(ptr2d), allocatable :: dgnum(:) ! mode dry radius
70+
real(r8), allocatable :: dgnumg(:,:,:) ! gathered mode dry radius
71+
72+
real(r8) :: sigmag_aitken
73+
74+
end type zm_aero_t
75+
76+
!===================================================================================================
77+
78+
end module zm_aero_type

components/eam/src/physics/cam/zm_conv.F90

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
21
module zm_conv
32
!----------------------------------------------------------------------------
43
! Purpose: primary methods for the Zhang-McFarlane convection scheme
54
!----------------------------------------------------------------------------
65
! Contributors: Rich Neale, Byron Boville, Xiaoliang song
76
!----------------------------------------------------------------------------
7+
#ifdef SCREAM_CONFIG_IS_CMAKE
8+
use zm_eamxx_bridge_params, only: r8, pcols, pver, pverp
9+
use zm_eamxx_bridge_methods,only: cldfrc_fice
10+
#else
811
use shr_kind_mod, only: r8 => shr_kind_r8
9-
use spmd_utils, only: masterproc
1012
use ppgrid, only: pcols, pver, pverp
1113
use cloud_fraction, only: cldfrc_fice
12-
use cam_abortutils, only: endrun
13-
use cam_logfile, only: iulog
14+
use zm_microphysics, only: zm_mphy
15+
#endif
1416
use zm_conv_cape, only: compute_dilute_cape
1517
use zm_conv_types, only: zm_const_t, zm_param_t
1618
use zm_conv_util, only: qsat_hpa ! remove after moving cldprp to new module
17-
use zm_aero, only: zm_aero_t
18-
use zm_microphysics, only: zm_mphy
19+
use zm_aero_type, only: zm_aero_t
1920
use zm_microphysics_state, only: zm_microp_st, zm_microp_st_alloc, zm_microp_st_dealloc, zm_microp_st_ini, zm_microp_st_gb
2021
!----------------------------------------------------------------------------
2122
implicit none
@@ -32,9 +33,8 @@ module zm_conv
3233
type(zm_param_t), public :: zm_param ! derived type to hold ZM tunable parameters
3334
!----------------------------------------------------------------------------
3435
! private variables
35-
real(r8), parameter :: capelmt = 70._r8 ! threshold value of cape for deep convection
36+
real(r8), parameter :: capelmt = 70._r8 ! threshold value for cape for deep convection
3637
real(r8), parameter :: trigdcapelmt = 0._r8 ! threshold value of dcape for deep convection
37-
3838
!===================================================================================================
3939
contains
4040
!===================================================================================================
@@ -43,7 +43,7 @@ subroutine zm_convi(limcnv_in, no_deep_pbl_in)
4343
!----------------------------------------------------------------------------
4444
! Purpose: initialize quantities for ZM convection scheme
4545
!----------------------------------------------------------------------------
46-
use zm_conv_types, only: zm_const_set_to_global
46+
use zm_conv_types, only: zm_const_set_to_global, zm_param_print
4747
!----------------------------------------------------------------------------
4848
! Arguments
4949
integer, intent(in) :: limcnv_in ! top interface level limit for convection
@@ -60,14 +60,17 @@ subroutine zm_convi(limcnv_in, no_deep_pbl_in)
6060
! set zm_const using global values
6161
call zm_const_set_to_global(zm_const)
6262

63+
! print parameter values to the log file
64+
call zm_param_print(zm_param)
65+
6366
!----------------------------------------------------------------------------
6467
return
6568

6669
end subroutine zm_convi
6770

6871
!===================================================================================================
6972

70-
subroutine zm_convr(lchnk ,ncol , &
73+
subroutine zm_convr(lchnk ,ncol ,is_first_step, &
7174
t ,qh ,prec ,jctop ,jcbot , &
7275
pblh ,zm ,geos ,zi ,qtnd , &
7376
heat ,pap ,paph ,dpp ,omega , &
@@ -98,7 +101,6 @@ subroutine zm_convr(lchnk ,ncol , &
98101
! and will make use of the standard CAM nomenclature
99102
!
100103
!-----------------------------------------------------------------------
101-
use time_manager, only: is_first_step
102104
!
103105
! ************************ index of variables **********************
104106
!
@@ -198,6 +200,7 @@ subroutine zm_convr(lchnk ,ncol , &
198200
!
199201
integer, intent(in) :: lchnk ! chunk identifier
200202
integer, intent(in) :: ncol ! number of atmospheric columns
203+
logical, intent(in) :: is_first_step ! flag to control DCAPE calculations
201204

202205
real(r8), intent(in) :: t(pcols,pver) ! grid slice of temperature at mid-layer.
203206
real(r8), intent(in) :: qh(pcols,pver) ! grid slice of specific humidity.
@@ -565,7 +568,7 @@ subroutine zm_convr(lchnk ,ncol , &
565568
if (zm_param%trig_dcape) dcapemx(:ncol) = maxi(:ncol)
566569

567570
! Calculate dcape trigger condition
568-
if ( .not.is_first_step() .and. zm_param%trig_dcape ) then
571+
if ( .not.is_first_step .and. zm_param%trig_dcape ) then
569572
iclosure = .false.
570573
call compute_dilute_cape( pcols, ncol, pver, pverp, &
571574
zm_param%num_cin, msg, &
@@ -585,13 +588,13 @@ subroutine zm_convr(lchnk ,ncol , &
585588
!
586589
capelmt_wk = capelmt ! capelmt_wk default to capelmt for default trigger
587590

588-
if ( zm_param%trig_dcape .and. (.not.is_first_step()) ) capelmt_wk = 0.0_r8
591+
if ( zm_param%trig_dcape .and. (.not.is_first_step) ) capelmt_wk = 0.0_r8
589592

590593
lengath = 0
591594
do i=1,ncol
592595
if (zm_param%trig_dcape) then
593596
! DCAPE-ULL
594-
if (is_first_step()) then
597+
if (is_first_step) then
595598
!Will this cause restart to be non-BFB
596599
if (cape(i) > capelmt) then
597600
lengath = lengath + 1
@@ -1163,10 +1166,11 @@ subroutine zm_conv_evap(ncol,lchnk, &
11631166
! in the Zhang-MacFarlane parameterization.
11641167
! Evaporate some of the precip directly into the environment using a Sundqvist type algorithm
11651168
!-----------------------------------------------------------------------
1166-
1169+
#ifdef SCREAM_CONFIG_IS_CMAKE
1170+
use zm_eamxx_bridge_wv_saturation, only: qsat
1171+
#else
11671172
use wv_saturation, only: qsat
1168-
use phys_grid, only: get_rlat_all_p
1169-
1173+
#endif
11701174
!------------------------------Arguments--------------------------------
11711175
integer,intent(in) :: ncol, lchnk ! number of columns and chunk index
11721176
real(r8),intent(in), dimension(pcols,pver) :: t ! temperature (K)
@@ -2161,6 +2165,7 @@ subroutine cldprp(lchnk , zm_const, &
21612165
end do
21622166
end do
21632167

2168+
#ifndef SCREAM_CONFIG_IS_CMAKE
21642169
call zm_mphy(su, qu, mu, du, eu, loc_microp_st%cmel, loc_microp_st%cmei, zf, p, &
21652170
t, q, eps0, jb, jt, jlcl, msg, il2g, zm_const%grav, zm_const%cpair, zm_const%rdair, aero, gamhat, &
21662171
loc_microp_st%qliq, loc_microp_st%qice, loc_microp_st%qnl, loc_microp_st%qni, &
@@ -2183,7 +2188,7 @@ subroutine cldprp(lchnk , zm_const, &
21832188
loc_microp_st%acciln ,loc_microp_st%fallrm ,loc_microp_st%fallsm ,loc_microp_st%fallgm , &
21842189
loc_microp_st%fallrn ,loc_microp_st%fallsn ,loc_microp_st%fallgn ,loc_microp_st%fhmrm , &
21852190
dsfm, dsfn, zm_param%auto_fac, zm_param%accr_fac, zm_param%micro_dcs)
2186-
2191+
#endif
21872192

21882193
do k = pver,msg + 2,-1
21892194
do i = 1,il2g

components/eam/src/physics/cam/zm_conv_cape.F90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ module zm_conv_cape
22
!----------------------------------------------------------------------------
33
! Purpose: CAPE calculation methods for ZM deep convection scheme
44
!----------------------------------------------------------------------------
5+
#ifdef SCREAM_CONFIG_IS_CMAKE
6+
use zm_eamxx_bridge_params, only: r8
7+
#else
58
use shr_kind_mod, only: r8=>shr_kind_r8
9+
#endif
610
use cam_abortutils, only: endrun
711
use zm_conv_util, only: entropy, ientropy, qsat_hPa
812
use zm_conv_types, only: zm_const_t, zm_param_t
@@ -12,6 +16,9 @@ module zm_conv_cape
1216

1317
public :: compute_dilute_cape ! calculate convective available potential energy (CAPE) with dilute parcel ascent
1418

19+
! Only public for testing
20+
public :: find_mse_max ! find level of max moist static energy for parcel initialization
21+
1522
real(r8), parameter :: lcl_pressure_threshold = 600._r8 ! if LCL pressure is lower => no convection and cape is zero
1623
real(r8), parameter :: ull_upper_launch_pressure = 600._r8 ! upper search limit for unrestricted launch level (ULL)
1724
real(r8), parameter :: pergro_rhd_threshold = -1.e-4_r8 ! MSE difference threshold for perturbation growth test

components/eam/src/physics/cam/zm_conv_intr.F90

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module zm_conv_intr
2020
use ndrop_bam, only: ndrop_bam_init
2121
use zm_conv, only: zm_conv_evap, zm_convr
2222
use zm_transport, only: zm_transport_tracer, zm_transport_momentum
23-
use zm_aero, only: zm_aero_t
23+
use zm_aero_type, only: zm_aero_t
2424
use zm_microphysics_state, only: zm_microp_st
2525

2626
implicit none
@@ -468,6 +468,7 @@ subroutine zm_conv_tend(pblh, mcon, cme, tpert, dlftot, pflx, zdu, &
468468
integer :: ncol ! number of atmospheric columns
469469
integer :: itim_old ! for physics buffer fields
470470
logical :: lq(pcnst) ! flags for ptend initialization
471+
logical :: is_first_step_loc
471472

472473
real(r8), dimension(pcols,pver) :: ftem ! Temporary workspace for outfld variables
473474
real(r8), dimension(pcols,pver) :: ntprprd ! evap outfld: net precip production in layer
@@ -629,9 +630,12 @@ subroutine zm_conv_tend(pblh, mcon, cme, tpert, dlftot, pflx, zdu, &
629630
end if
630631
end if
631632

633+
is_first_step_loc = is_first_step()
634+
632635
! Call the primary Zhang-McFarlane convection parameterization
633636
call t_startf ('zm_convr')
634-
call zm_convr( lchnk, ncol, state%t, state%q(:,:,1), prec, jctop, jcbot, &
637+
call zm_convr( lchnk, ncol, is_first_step_loc, &
638+
state%t, state%q(:,:,1), prec, jctop, jcbot, &
635639
pblh, state%zm, state%phis, state%zi, ptend_loc%q(:,:,1), &
636640
ptend_loc%s, state%pmid, state%pint, state%pdel, state%omega, &
637641
0.5*ztodt, mcon, cme, cape, tpert, dlf, pflx, zdu, rprd, mu, md, du, eu, ed, &

0 commit comments

Comments
 (0)