Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions schemes/microp_aero/compute_subgrid_vertical_velocity.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
! Compute raw subgrid-scale vertical velocity from TKE, KVH, or CLUBB WP2.
module compute_subgrid_vertical_velocity

use ccpp_kinds, only: kind_phys

implicit none
private

public :: compute_subgrid_vertical_velocity_tke_run
public :: compute_subgrid_vertical_velocity_kvh_run
public :: compute_subgrid_vertical_velocity_clubb_run

contains

!> \section arg_table_compute_subgrid_vertical_velocity_tke_run Argument Table
!! \htmlinclude compute_subgrid_vertical_velocity_tke_run.html

! Note: despite the tke name, the "tke" used here is the CAM5 diag_TKE scheme TKE
! and is not the TKE originating from CLUBB, and thus this scheme is not used for
! CAM6+, it is used for CAM5 only.
! For CAM6+ do not use TKE, derive from WP2_nadv - see the clubb variant. hplin 4/20/26
subroutine compute_subgrid_vertical_velocity_tke_run( &
ncol, pver, top_lev, &
tke, &
wsub, &
errmsg, errflg)

! Input arguments
integer, intent(in) :: ncol
integer, intent(in) :: pver
integer, intent(in) :: top_lev ! top vertical level for cloud physics

real(kind_phys), intent(in) :: tke(:, :) ! turbulent kinetic energy at interfaces [m2 s-2]

! Output arguments
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]

character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
integer :: i, k

errmsg = ''
errflg = 0

wsub(:, :top_lev-1) = 0._kind_phys

do k = top_lev, pver
do i = 1, ncol
wsub(i,k) = sqrt(0.5_kind_phys * (tke(i,k) + tke(i,k+1)) * (2._kind_phys / 3._kind_phys))
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
end do
end do

end subroutine compute_subgrid_vertical_velocity_tke_run

!> \section arg_table_compute_subgrid_vertical_velocity_kvh_run Argument Table
!! \htmlinclude compute_subgrid_vertical_velocity_kvh_run.html
subroutine compute_subgrid_vertical_velocity_kvh_run( &
ncol, pver, top_lev, &
kvh, &
wsub, &
errmsg, errflg)

! Input arguments
integer, intent(in) :: ncol
integer, intent(in) :: pver
integer, intent(in) :: top_lev ! top vertical level for cloud physics

real(kind_phys), intent(in) :: kvh(:, :) ! eddy diffusivity for heat at interfaces [m2 s-1]

! Output arguments
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]

character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
integer :: i, k

errmsg = ''
errflg = 0

wsub(:, :top_lev-1) = 0._kind_phys

! Get sub-grid vertical velocity from diffusion coefficient.
! Following Morrison et al. 2005, JAS.
! Assume mixing length of 30 m.
! Use maximum sub-grid vertical vel of 10 m/s.
do k = top_lev, pver
do i = 1, ncol
wsub(i,k) = (kvh(i,k) + kvh(i,k+1)) / 2._kind_phys / 30._kind_phys
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
end do
end do

end subroutine compute_subgrid_vertical_velocity_kvh_run

!> \section arg_table_compute_subgrid_vertical_velocity_clubb_run Argument Table
!! \htmlinclude compute_subgrid_vertical_velocity_clubb_run.html
subroutine compute_subgrid_vertical_velocity_clubb_run( &
ncol, pver, pverp, top_lev, &
wp2, &
wsub, &
errmsg, errflg)

! Input arguments
integer, intent(in) :: ncol
integer, intent(in) :: pver
integer, intent(in) :: pverp
integer, intent(in) :: top_lev ! top vertical level for cloud physics

real(kind_phys), intent(in) :: wp2(:, :) ! CLUBB variance of vertical velocity at interfaces [m2 s-2]

! Output arguments
real(kind_phys), intent(out) :: wsub(:, :) ! subgrid vertical velocity [m s-1]

character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
integer :: i, k
real(kind_phys) :: tke(ncol, pver+1)

errmsg = ''
errflg = 0

! Convert wp2 to TKE: tke = (3/2) * wp2 from [pver+1, top_lev]
! This matches CAM microp_aero.F90 CLUBB_SGS branch exactly.
tke(:ncol,top_lev:pverp) = (3._kind_phys/2._kind_phys)*wp2(:ncol,1:pverp-top_lev+1)
tke(:ncol,1:top_lev-1) = 0._kind_phys

wsub(:, :top_lev-1) = 0._kind_phys

do k = top_lev, pver
do i = 1, ncol
wsub(i,k) = sqrt(0.5_kind_phys * (tke(i,k) + tke(i,k+1)) * (2._kind_phys / 3._kind_phys))
wsub(i,k) = min(wsub(i,k), 10._kind_phys)
end do
end do

end subroutine compute_subgrid_vertical_velocity_clubb_run

end module compute_subgrid_vertical_velocity
155 changes: 155 additions & 0 deletions schemes/microp_aero/compute_subgrid_vertical_velocity.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
[ccpp-table-properties]
name = compute_subgrid_vertical_velocity_tke
type = scheme

[ccpp-arg-table]
name = compute_subgrid_vertical_velocity_tke_run
type = scheme
[ ncol ]
standard_name = horizontal_loop_extent
units = count
type = integer
dimensions = ()
intent = in
[ pver ]
standard_name = vertical_layer_dimension
units = count
type = integer
dimensions = ()
intent = in
[ top_lev ]
standard_name = vertical_layer_index_of_cloud_fraction_top
units = index
type = integer
dimensions = ()
intent = in
[ tke ]
standard_name = specific_turbulent_kinetic_energy_at_interfaces
units = m2 s-2
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
intent = in
[ wsub ]
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
units = m s-1
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=*
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out

[ccpp-table-properties]
name = compute_subgrid_vertical_velocity_clubb
type = scheme

[ccpp-arg-table]
name = compute_subgrid_vertical_velocity_clubb_run
type = scheme
[ ncol ]
standard_name = horizontal_loop_extent
units = count
type = integer
dimensions = ()
intent = in
[ pver ]
standard_name = vertical_layer_dimension
units = count
type = integer
dimensions = ()
intent = in
[ pverp ]
standard_name = vertical_interface_dimension
units = count
type = integer
dimensions = ()
intent = in
[ top_lev ]
standard_name = vertical_layer_index_of_cloud_fraction_top
units = index
type = integer
dimensions = ()
intent = in
[ wp2 ]
standard_name = advected_variance_of_vertical_velocity_at_interfaces
units = m2 s-2
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
intent = in
[ wsub ]
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
units = m s-1
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=*
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out

[ccpp-table-properties]
name = compute_subgrid_vertical_velocity_kvh
type = scheme

[ccpp-arg-table]
name = compute_subgrid_vertical_velocity_kvh_run
type = scheme
[ ncol ]
standard_name = horizontal_loop_extent
units = count
type = integer
dimensions = ()
intent = in
[ pver ]
standard_name = vertical_layer_dimension
units = count
type = integer
dimensions = ()
intent = in
[ top_lev ]
standard_name = vertical_layer_index_of_cloud_fraction_top
units = index
type = integer
dimensions = ()
intent = in
[ kvh ]
standard_name = eddy_heat_diffusivity_at_interfaces
units = m2 s-1
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_interface_dimension)
intent = in
[ wsub ]
standard_name = subgrid_scale_vertical_velocity_for_droplet_nucleation
units = m s-1
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=*
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out
40 changes: 40 additions & 0 deletions schemes/microp_aero/dust_default_radii.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
! Set default dust radii for 4 size bins used in contact freezing.
! For modal aerosols, bin 3 is overwritten later with wet diameter.
module dust_default_radii

use ccpp_kinds, only: kind_phys

implicit none
private

public :: dust_default_radii_timestep_init

real(kind_phys), parameter :: rn_dst1 = 0.258e-6_kind_phys
real(kind_phys), parameter :: rn_dst2 = 0.717e-6_kind_phys
real(kind_phys), parameter :: rn_dst3 = 1.576e-6_kind_phys
real(kind_phys), parameter :: rn_dst4 = 3.026e-6_kind_phys

contains

!> \section arg_table_dust_default_radii_timestep_init Argument Table
!! \htmlinclude dust_default_radii_timestep_init.html
subroutine dust_default_radii_timestep_init(ncol, pver, ndust, rndst, errmsg, errflg)
integer, intent(in) :: ncol
integer, intent(in) :: pver
integer, intent(in) :: ndust

real(kind_phys), intent(out) :: rndst(:,:,:)
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg

errmsg = ''
errflg = 0

rndst(:ncol, :pver, 1) = rn_dst1
rndst(:ncol, :pver, 2) = rn_dst2
rndst(:ncol, :pver, 3) = rn_dst3
rndst(:ncol, :pver, 4) = rn_dst4

end subroutine dust_default_radii_timestep_init

end module dust_default_radii
43 changes: 43 additions & 0 deletions schemes/microp_aero/dust_default_radii.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[ccpp-table-properties]
name = dust_default_radii
type = scheme

[ccpp-arg-table]
name = dust_default_radii_timestep_init
type = scheme
[ ncol ]
standard_name = horizontal_dimension
units = count
type = integer
dimensions = ()
intent = in
[ pver ]
standard_name = vertical_layer_dimension
units = count
type = integer
dimensions = ()
intent = in
[ ndust ]
standard_name = dust_size_bin_dimension
units = count
type = integer
dimensions = ()
intent = in
[ rndst ]
standard_name = dust_radii_by_size_bin
units = m
type = real | kind = kind_phys
dimensions = (horizontal_dimension, vertical_layer_dimension, dust_size_bin_dimension)
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=*
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out
Loading
Loading