Skip to content
Closed
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
44 changes: 29 additions & 15 deletions test/test_schemes/initialize_constituents.F90
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ subroutine initialize_constituents_register(constituents, errmsg, errcode)
integer :: num_variables
integer :: ierr
integer :: var_index
integer :: split_index
integer :: constituent_index
integer :: known_const_index
integer :: found_const_count
logical :: known_constituent
real(kind_phys) :: qmin_value
character(len=256) :: cnst_stdname
character(len=256) :: variable_name
character(len=512) :: alloc_err_msg
character(len=256), allocatable :: constituent_names(:)
character(len=256), allocatable :: const_diag_names(:)
character(len=65), parameter :: water_species_std_names(6) = &
(/'water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water ', &
'cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water', &
Expand Down Expand Up @@ -68,22 +68,14 @@ subroutine initialize_constituents_register(constituents, errmsg, errcode)
write(errmsg,*) 'Failed to allocate "constituent_names" in initialize_constituents_register: ', trim(alloc_err_msg)
return
end if
allocate(const_diag_names(num_variables), stat=ierr, errmsg=alloc_err_msg)
if (ierr /= 0) then
errcode = 1
write(errmsg,*) 'Failed to allocate "const_diag_names" in initialize_constituents_register: ', trim(alloc_err_msg)
return
end if

! Loop over all variables in the file and add each constituent to the
! dynamic constituent array
do var_index = 1, num_variables
ierr = pio_inq_varname(ncdata, var_index, variable_name)
known_constituent = .false.
split_index = index(variable_name, 'cnst_')
if (split_index > 0) then
if (index(variable_name, 'cnst_') > 0) then
constituent_index = constituent_index + 1
const_diag_names(constituent_index) = variable_name(split_index:)
! Replace with standard name if known, to avoid duplicates
if (found_const_count < size(water_species_std_names)) then
do known_const_index = 1, size(const_file_names)
Expand Down Expand Up @@ -117,7 +109,6 @@ subroutine initialize_constituents_register(constituents, errmsg, errcode)
vertical_dim = 'vertical_layer_dimension', &
min_value = 0.0_kind_phys, &
advected = .true., &
diag_name = const_diag_names(var_index), &
water_species = .true., &
mixing_ratio_type = 'wet', &
errcode = errcode, &
Expand All @@ -133,19 +124,42 @@ subroutine initialize_constituents_register(constituents, errmsg, errcode)
vertical_dim = 'vertical_layer_dimension', &
min_value = 0.0_kind_phys, &
advected = .true., &
diag_name = const_diag_names(var_index), &
mixing_ratio_type = 'wet', &
errcode = errcode, &
errmsg = errmsg)
else
! For chemistry species some special handling is necessary for qmin_value;
! this logic is replicated from chem_register in src/chemistry/mozart.
qmin_value = 0.0_kind_phys
cnst_stdname = trim(constituent_names(var_index))
! Special handling for specific chemical species
! Aerosol number density species
if (index(cnst_stdname, 'num_a') > 0) then
qmin_value = 1.e-5_kind_phys
else if (index(cnst_stdname, 'O3') > 0) then
qmin_value = 1.e-12_kind_phys
else if (index(cnst_stdname, 'CH4') > 0) then
qmin_value = 1.e-12_kind_phys
else if (index(cnst_stdname, 'N2O') > 0) then
qmin_value = 1.e-15_kind_phys
! CFCs
else if (index(cnst_stdname, 'CFC11') > 0 .or. &
index(cnst_stdname, 'CFC12') > 0 .or. &
index(cnst_stdname, 'cfc11') > 0 .or. &
index(cnst_stdname, 'cfc12') > 0) then
qmin_value = 1.e-20_kind_phys
end if
! Note: other chemistry species should be 1e-36 but we have no way
! of currently distinguishing between these and other non-chem
! constituents, so leaving as 0.0_kind_phys for now. (hplin, 11/20/25)

call constituents(var_index)%instantiate( &
std_name = constituent_names(var_index), &
long_name = constituent_names(var_index), &
units = 'kg kg-1', &
vertical_dim = 'vertical_layer_dimension', &
min_value = 0.0_kind_phys, &
min_value = qmin_value, &
advected = .true., &
diag_name = const_diag_names(var_index), &
errcode = errcode, &
errmsg = errmsg)
end if
Expand Down
44 changes: 44 additions & 0 deletions to_be_ccppized/ccpp_chem_utils.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
! Various utilities used in CAM-SIMA chemistry.
module ccpp_chem_utils

implicit none
private

public :: chem_constituent_qmin

contains

! Returns the minimum mixing ratio for a given constituent
! Used to set appropriate minimum value for various chemical species at register phase.
function chem_constituent_qmin(constituent_name) result(qmin)
use ccpp_kinds, only: kind_phys

use string_utils, only: to_lower

character(len=*), intent(in) :: constituent_name ! Name of the chemical constituent
real(kind_phys) :: qmin ! Minimum mixing ratio

character(len=len(constituent_name)) :: name_lower

! Convert to lowercase for case-insensitive comparison
name_lower = to_lower(constituent_name) ! impure

! Default minimum mixing ratio for chemistry species.
qmin = 1.e-36_kind_phys

if (index(name_lower, 'num_a') == 1) then
! Aerosol number density.
qmin = 1.e-5_kind_phys
else if (trim(name_lower) == 'o3') then
qmin = 1.e-12_kind_phys
else if (trim(name_lower) == 'ch4') then
qmin = 1.e-12_kind_phys
else if (trim(name_lower) == 'n2o') then
qmin = 1.e-15_kind_phys
else if (trim(name_lower) == 'cfc11' .or. trim(name_lower) == 'cfc12') then
qmin = 1.e-20_kind_phys
end if

end function chem_constituent_qmin

end module ccpp_chem_utils
Loading