Skip to content

Commit 78e2017

Browse files
atmos_phys0_26_000: Move ndrop_bam, nucleate_ice, and other microp_aero interstitials to atmos_phys (#411)
Tag name (The PR title should also include the tag name): Originator(s): @jimmielin Description (include issue title and the keyword ['closes', 'fixes', 'resolves'] and issue number): - Moves `nucleate_ice.F90` portable code to atmospheric_physics. - Refactor and clean up `ndrop_bam.F90` to be portable and move to atmos_phys. - CCPPize interstitial schemes used in `microp_aero`: `compute_subgrid_vertical_velocity`, `scale_subgrid_vertical_velocity`, `dust_default_radii` List all namelist files that were added or changed: ``` A schemes/microp_aero/scale_subgrid_vertical_velocity_namelist.xml ``` List all files eliminated and why: N/A List all files added and what they do: ``` A schemes/microp_aero/nucleate_ice.F90 - portable nucleate_ice code A schemes/microp_aero/ndrop_bam.F90 - portable ndrop_bam code A schemes/microp_aero/compute_subgrid_vertical_velocity.F90 A schemes/microp_aero/compute_subgrid_vertical_velocity.meta A schemes/microp_aero/scale_subgrid_vertical_velocity.F90 A schemes/microp_aero/scale_subgrid_vertical_velocity.meta A schemes/microp_aero/dust_default_radii.F90 A schemes/microp_aero/dust_default_radii.meta - CCPPized interstitial schemes used in microp_aero M test/musica/test_musica_api.F90 M test/musica/tuvx/test_tuvx_load_species.F90 M to_be_ccppized/ccpp_const_utils.F90 - fix blocking MUSICA tests breaking due to upstream CCPP framework update ``` List all existing files that have been modified, and describe the changes: (Helpful git command: `git diff --name-status main...<your_branch_name>`) All new files. List all automated tests that failed, as well as an explanation for why they weren't fixed: Is this an answer-changing PR? If so, is it a new physics package, algorithm change, tuning change, etc? B4B in CAM New chemistry/physics code (microp_aero) If yes to the above question, describe how this code was validated with the new/modified features: CAM regression tests --------- Co-authored-by: Haipeng Lin <hplin@ucar.edu>
1 parent b98c7f5 commit 78e2017

12 files changed

Lines changed: 1986 additions & 18 deletions
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
! Compute raw subgrid-scale vertical velocity from TKE, KVH, or CLUBB WP2.
2+
module compute_subgrid_vertical_velocity
3+
4+
implicit none
5+
private
6+
7+
public :: compute_subgrid_vertical_velocity_tke_run
8+
public :: compute_subgrid_vertical_velocity_kvh_run
9+
public :: compute_subgrid_vertical_velocity_clubb_run
10+
11+
contains
12+
13+
!> \section arg_table_compute_subgrid_vertical_velocity_tke_run Argument Table
14+
!! \htmlinclude compute_subgrid_vertical_velocity_tke_run.html
15+
16+
! Note: despite the tke name, the "tke" used here is the CAM5 diag_TKE scheme TKE
17+
! and is not the TKE originating from CLUBB, and thus this scheme is not used for
18+
! CAM6+, it is used for CAM5 only.
19+
! For CAM6+ do not use TKE, derive from WP2_nadv - see the clubb variant. hplin 4/20/26
20+
pure subroutine compute_subgrid_vertical_velocity_tke_run( &
21+
ncol, pver, top_lev, &
22+
tke, &
23+
wsub, &
24+
errmsg, errflg)
25+
26+
use ccpp_kinds, only: kind_phys
27+
28+
! Input arguments
29+
integer, intent(in) :: ncol
30+
integer, intent(in) :: pver
31+
integer, intent(in) :: top_lev ! top vertical level for cloud physics
32+
33+
real(kind_phys), intent(in) :: tke(:, :) ! turbulent kinetic energy at interfaces [m2 s-2]
34+
35+
! Output arguments
36+
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]
37+
38+
character(len=*), intent(out) :: errmsg
39+
integer, intent(out) :: errflg
40+
41+
! Local variables
42+
integer :: i, k
43+
44+
errmsg = ''
45+
errflg = 0
46+
47+
wsub(:, :top_lev-1) = 0._kind_phys
48+
49+
! Assuming isotropic turbulent motion, the vertical velocity variance is
50+
! two thirds of the TKE. Cap the sub-grid vertical velocity at 10 m s-1.
51+
do k = top_lev, pver
52+
do i = 1, ncol
53+
wsub(i,k) = sqrt(0.5_kind_phys * (tke(i,k) + tke(i,k+1)) * (2._kind_phys / 3._kind_phys))
54+
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
55+
end do
56+
end do
57+
58+
end subroutine compute_subgrid_vertical_velocity_tke_run
59+
60+
!> \section arg_table_compute_subgrid_vertical_velocity_kvh_run Argument Table
61+
!! \htmlinclude compute_subgrid_vertical_velocity_kvh_run.html
62+
pure subroutine compute_subgrid_vertical_velocity_kvh_run( &
63+
ncol, pver, top_lev, &
64+
kvh, &
65+
wsub, &
66+
errmsg, errflg)
67+
68+
use ccpp_kinds, only: kind_phys
69+
70+
! Input arguments
71+
integer, intent(in) :: ncol
72+
integer, intent(in) :: pver
73+
integer, intent(in) :: top_lev ! top vertical level for cloud physics
74+
75+
real(kind_phys), intent(in) :: kvh(:, :) ! eddy diffusivity for heat at interfaces [m2 s-1]
76+
77+
! Output arguments
78+
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]
79+
80+
character(len=*), intent(out) :: errmsg
81+
integer, intent(out) :: errflg
82+
83+
! Local variables
84+
integer :: i, k
85+
86+
errmsg = ''
87+
errflg = 0
88+
89+
wsub(:, :top_lev-1) = 0._kind_phys
90+
91+
! Get sub-grid vertical velocity from diffusion coefficient.
92+
! Following equation 24 in Morrison et al. 2005, JAS, https://doi.org/10.1175/JAS3446.1
93+
! Assume mixing length of 30 m.
94+
! Use maximum sub-grid vertical vel of 10 m/s.
95+
do k = top_lev, pver
96+
do i = 1, ncol
97+
wsub(i,k) = (kvh(i,k) + kvh(i,k+1)) / 2._kind_phys / 30._kind_phys
98+
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
99+
end do
100+
end do
101+
102+
end subroutine compute_subgrid_vertical_velocity_kvh_run
103+
104+
!> \section arg_table_compute_subgrid_vertical_velocity_clubb_run Argument Table
105+
!! \htmlinclude compute_subgrid_vertical_velocity_clubb_run.html
106+
pure subroutine compute_subgrid_vertical_velocity_clubb_run( &
107+
ncol, pver, pverp, top_lev, &
108+
wp2, &
109+
wsub, &
110+
errmsg, errflg)
111+
112+
use ccpp_kinds, only: kind_phys
113+
114+
! Input arguments
115+
integer, intent(in) :: ncol
116+
integer, intent(in) :: pver
117+
integer, intent(in) :: pverp
118+
integer, intent(in) :: top_lev ! top vertical level for cloud physics
119+
120+
! wp2 is indexed on the full interface grid (1:pverp). CLUBB may compute it
121+
! on a shorter subgrid that only spans interfaces top_lev:pverp; it is the
122+
! caller's responsibility to expand it to the full grid before calling here.
123+
real(kind_phys), intent(in) :: wp2(:, :) ! CLUBB variance of vertical velocity at interfaces [m2 s-2]
124+
125+
! Output arguments
126+
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]
127+
128+
character(len=*), intent(out) :: errmsg
129+
integer, intent(out) :: errflg
130+
131+
! Local variables
132+
integer :: i, k
133+
real(kind_phys) :: tke(ncol, pver+1)
134+
135+
errmsg = ''
136+
errflg = 0
137+
138+
! Convert wp2 to TKE assuming isotropic turbulent motion: tke = (3/2) * wp2.
139+
! Only interfaces at and below top_lev are used by the cloud physics.
140+
tke(:ncol,top_lev:pverp) = (3._kind_phys/2._kind_phys)*wp2(:ncol,top_lev:pverp)
141+
tke(:ncol,1:top_lev-1) = 0._kind_phys
142+
143+
wsub(:, :top_lev-1) = 0._kind_phys
144+
145+
! Assuming isotropic turbulent motion, the vertical velocity variance is
146+
! two thirds of the TKE. Cap the sub-grid vertical velocity at 10 m s-1.
147+
do k = top_lev, pver
148+
do i = 1, ncol
149+
wsub(i,k) = sqrt(0.5_kind_phys * (tke(i,k) + tke(i,k+1)) * (2._kind_phys / 3._kind_phys))
150+
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
151+
end do
152+
end do
153+
154+
end subroutine compute_subgrid_vertical_velocity_clubb_run
155+
156+
end module compute_subgrid_vertical_velocity
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
[ccpp-table-properties]
2+
name = compute_subgrid_vertical_velocity_tke
3+
type = scheme
4+
5+
[ccpp-arg-table]
6+
name = compute_subgrid_vertical_velocity_tke_run
7+
type = scheme
8+
[ ncol ]
9+
standard_name = horizontal_loop_extent
10+
units = count
11+
type = integer
12+
dimensions = ()
13+
intent = in
14+
[ pver ]
15+
standard_name = vertical_layer_dimension
16+
units = count
17+
type = integer
18+
dimensions = ()
19+
intent = in
20+
[ top_lev ]
21+
standard_name = vertical_layer_index_of_cloud_fraction_top
22+
units = index
23+
type = integer
24+
dimensions = ()
25+
intent = in
26+
[ tke ]
27+
standard_name = specific_turbulent_kinetic_energy_at_interfaces
28+
units = m2 s-2
29+
type = real | kind = kind_phys
30+
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
31+
intent = in
32+
[ wsub ]
33+
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
34+
units = m s-1
35+
type = real | kind = kind_phys
36+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
37+
intent = out
38+
[ errmsg ]
39+
standard_name = ccpp_error_message
40+
units = none
41+
type = character | kind = len=*
42+
dimensions = ()
43+
intent = out
44+
[ errflg ]
45+
standard_name = ccpp_error_code
46+
units = 1
47+
type = integer
48+
dimensions = ()
49+
intent = out
50+
51+
[ccpp-table-properties]
52+
name = compute_subgrid_vertical_velocity_clubb
53+
type = scheme
54+
55+
[ccpp-arg-table]
56+
name = compute_subgrid_vertical_velocity_clubb_run
57+
type = scheme
58+
[ ncol ]
59+
standard_name = horizontal_loop_extent
60+
units = count
61+
type = integer
62+
dimensions = ()
63+
intent = in
64+
[ pver ]
65+
standard_name = vertical_layer_dimension
66+
units = count
67+
type = integer
68+
dimensions = ()
69+
intent = in
70+
[ pverp ]
71+
standard_name = vertical_interface_dimension
72+
units = count
73+
type = integer
74+
dimensions = ()
75+
intent = in
76+
[ top_lev ]
77+
standard_name = vertical_layer_index_of_cloud_fraction_top
78+
units = index
79+
type = integer
80+
dimensions = ()
81+
intent = in
82+
[ wp2 ]
83+
standard_name = advected_variance_of_vertical_velocity_at_interfaces
84+
units = m2 s-2
85+
type = real | kind = kind_phys
86+
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
87+
intent = in
88+
[ wsub ]
89+
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
90+
units = m s-1
91+
type = real | kind = kind_phys
92+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
93+
intent = out
94+
[ errmsg ]
95+
standard_name = ccpp_error_message
96+
units = none
97+
type = character | kind = len=*
98+
dimensions = ()
99+
intent = out
100+
[ errflg ]
101+
standard_name = ccpp_error_code
102+
units = 1
103+
type = integer
104+
dimensions = ()
105+
intent = out
106+
107+
[ccpp-table-properties]
108+
name = compute_subgrid_vertical_velocity_kvh
109+
type = scheme
110+
111+
[ccpp-arg-table]
112+
name = compute_subgrid_vertical_velocity_kvh_run
113+
type = scheme
114+
[ ncol ]
115+
standard_name = horizontal_loop_extent
116+
units = count
117+
type = integer
118+
dimensions = ()
119+
intent = in
120+
[ pver ]
121+
standard_name = vertical_layer_dimension
122+
units = count
123+
type = integer
124+
dimensions = ()
125+
intent = in
126+
[ top_lev ]
127+
standard_name = vertical_layer_index_of_cloud_fraction_top
128+
units = index
129+
type = integer
130+
dimensions = ()
131+
intent = in
132+
[ kvh ]
133+
standard_name = eddy_heat_diffusivity_at_interfaces
134+
units = m2 s-1
135+
type = real | kind = kind_phys
136+
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
137+
intent = in
138+
[ wsub ]
139+
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
140+
units = m s-1
141+
type = real | kind = kind_phys
142+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
143+
intent = out
144+
[ errmsg ]
145+
standard_name = ccpp_error_message
146+
units = none
147+
type = character | kind = len=*
148+
dimensions = ()
149+
intent = out
150+
[ errflg ]
151+
standard_name = ccpp_error_code
152+
units = 1
153+
type = integer
154+
dimensions = ()
155+
intent = out
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
! Set default dust radii for 4 size bins used in contact freezing.
2+
! For modal aerosols, bin 3 is overwritten later with wet diameter.
3+
module dust_default_radii
4+
5+
use ccpp_kinds, only: kind_phys
6+
7+
implicit none
8+
private
9+
10+
public :: dust_default_radii_timestep_init
11+
12+
real(kind_phys), parameter :: rn_dst1 = 0.258e-6_kind_phys
13+
real(kind_phys), parameter :: rn_dst2 = 0.717e-6_kind_phys
14+
real(kind_phys), parameter :: rn_dst3 = 1.576e-6_kind_phys
15+
real(kind_phys), parameter :: rn_dst4 = 3.026e-6_kind_phys
16+
17+
contains
18+
19+
!> \section arg_table_dust_default_radii_timestep_init Argument Table
20+
!! \htmlinclude dust_default_radii_timestep_init.html
21+
pure subroutine dust_default_radii_timestep_init(ncol, pver, ndust, rndst, errmsg, errflg)
22+
integer, intent(in) :: ncol
23+
integer, intent(in) :: pver
24+
integer, intent(in) :: ndust
25+
26+
real(kind_phys), intent(out) :: rndst(:,:,:)
27+
character(len=*), intent(out) :: errmsg
28+
integer, intent(out) :: errflg
29+
30+
errmsg = ''
31+
errflg = 0
32+
33+
rndst(:ncol, :pver, 1) = rn_dst1
34+
rndst(:ncol, :pver, 2) = rn_dst2
35+
rndst(:ncol, :pver, 3) = rn_dst3
36+
rndst(:ncol, :pver, 4) = rn_dst4
37+
38+
end subroutine dust_default_radii_timestep_init
39+
40+
end module dust_default_radii
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[ccpp-table-properties]
2+
name = dust_default_radii
3+
type = scheme
4+
5+
[ccpp-arg-table]
6+
name = dust_default_radii_timestep_init
7+
type = scheme
8+
[ ncol ]
9+
standard_name = horizontal_dimension
10+
units = count
11+
type = integer
12+
dimensions = ()
13+
intent = in
14+
[ pver ]
15+
standard_name = vertical_layer_dimension
16+
units = count
17+
type = integer
18+
dimensions = ()
19+
intent = in
20+
[ ndust ]
21+
standard_name = dust_size_bin_dimension
22+
units = count
23+
type = integer
24+
dimensions = ()
25+
intent = in
26+
[ rndst ]
27+
standard_name = dust_radii_by_size_bin
28+
units = m
29+
type = real | kind = kind_phys
30+
dimensions = (horizontal_dimension, vertical_layer_dimension, dust_size_bin_dimension)
31+
intent = out
32+
[ errmsg ]
33+
standard_name = ccpp_error_message
34+
units = none
35+
type = character | kind = len=*
36+
dimensions = ()
37+
intent = out
38+
[ errflg ]
39+
standard_name = ccpp_error_code
40+
units = 1
41+
type = integer
42+
dimensions = ()
43+
intent = out

0 commit comments

Comments
 (0)