Skip to content
7 changes: 0 additions & 7 deletions bld/configure
Original file line number Diff line number Diff line change
Expand Up @@ -989,13 +989,6 @@ if ($rad_pkg eq 'camrt') {
" with aerosol package $chem_pkg\n";
}
}
elsif ($rad_pkg =~ m/rrtmg/) {

# RRTMGP not currently working with CARMA
if ($rad_pkg eq 'rrtmgp' and $carma_pkg ne 'none') {
die "configure ERROR: The CARMA microphysics package does not currently work with RRTMGP\n";
}
}

$cfg_ref->set('rad', $rad_pkg);

Expand Down
19 changes: 19 additions & 0 deletions cime_config/testdefs/testlist_cam.xml
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,16 @@
</options>
</test>

<test compset="QPC7" grid="ne3pg3_ne3pg3_mt232" name="SMS_D_Ln9" testmods="cam/carma_test_tracers">
<machines>
<machine name="izumi" compiler="nag" category="aux_cam"/>
</machines>
<options>
<option name="comment" >CAM7, CARMA test tracers</option>
<option name="wallclock">00:30:00</option>
</options>
</test>

<test compset="FCARMA2000climo" grid="f19_f19_mg17" name="SMS_D_Ln9" testmods="cam/outfrq9s" supported="false">
<machines>
<machine name="derecho" compiler="intel" category="aux_cam"/>
Expand All @@ -334,6 +344,15 @@
<option name="comment">CARMA trop_strat model test</option>
</options>
</test>
<test compset="FWmaCARMAHIST" grid="f19_f19_mg17" name="SMS_D_Ln9" testmods="cam/outfrq9s" supported="false">
<machines>
<machine name="derecho" compiler="intel" category="carma"/>
</machines>
<options>
<option name="wallclock">00:40:00</option>
<option name="comment">CARMA WACCM trop_strat model test</option>
</options>
</test>

<test compset="FHIST_C5" grid="f10_f10_mt232" name="TMC_D_Ln9" testmods="cam/mc_ttrac">
<machines>
Expand Down
78 changes: 78 additions & 0 deletions doc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,83 @@
===============================================================

Tag name: cam6_4_169
Originator(s): fvitt
Date: 28 Apr 2026
One-line Summary: Enable CARMA with cam7 physics and RRTMGP radiation
Github PR URL: https://github.com/ESCOMP/CAM/pull/1508

Purpose of changes (include the issue number and title text for each relevant GitHub issue):

- Enables the use of CARMA with RRTMGP / cam7 physics -- issue #1430
- Improve performance of CARMA

Describe any changes made to build system: N/A

Describe any changes made to the namelist: N/A

List any changes to the defaults for the boundary datasets: N/A

Describe any substantial timing or memory changes: N/A

Code reviewed by: peverwhee

List all files eliminated: N/A

List all files added and what they do: N/A

List all existing files that have been modified, and describe the changes:

M bld/configure
- allow both carma and rrtmgp in same configuration

M cime_config/testdefs/testlist_cam.xml
- add QPC7 with carma_test_tracers aux_cam test
- add FCARMAHIST carma test

M src/chemistry/aerosol/aero_convproc.F90
M src/chemistry/aerosol/aerosol_properties_mod.F90
M src/chemistry/aerosol/aerosol_state_mod.F90
M src/chemistry/aerosol/bulk_aerosol_properties_mod.F90
M src/chemistry/aerosol/carma_aerosol_properties_mod.F90
M src/chemistry/aerosol/modal_aerosol_properties_mod.F90
M src/physics/cam/ndrop.F90
- improve efficiency by getting aerosol concentrations (number and volumn)
for all columns and levels at once

M src/physics/cam/physpkg.F90
M src/physics/cam7/physpkg.F90
- register carma after rrtmgp

M src/physics/carma/cam/carma_intr.F90
- allow the option to create optics files when rrtmgp is used

M src/physics/rrtmgp/radiation.F90
- initialize at registration time

If there were any failures reported from running test_driver.sh on any test
platform, and checkin with these failures has been OK'd by the gatekeeper,
then copy the lines from the td.*.status files for the failed tests to the
appropriate machine below. All failed tests must be justified.

derecho/intel/aux_cam: All PASS

derecho/nvhpc/aux_cam: All PASS

izumi/nag/aux_cam:

FAIL ERC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-outfrq3s_subcol COMPARE_base_rest
- pre-existing failure -- see https://github.com/ESCOMP/CAM/issues/1514

DIFF SMS_D_Ln9.ne3pg3_ne3pg3_mt232.QPC7.izumi_nag.cam-carma_test_tracers
-new test

izumi/gnu/aux_cam: All PASS

Summarize any changes to answers: bit-for-bit

===============================================================
===============================================================

Tag name: cam6_4_168
Originator(s): jimmielin, cacraig, sjsprecious
Date: April 24, 2026
Expand Down
20 changes: 10 additions & 10 deletions src/chemistry/aerosol/aero_convproc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1711,8 +1711,8 @@ subroutine activate_convproc( aero_props, &
character(len=32) :: spec_type

real(r8) :: tmpa, tmpb, tmpc ! working variable
real(r8) :: naerosol_a(1) ! number conc (1/m3)
real(r8) :: vaerosol_a(1) ! volume conc (m3/m3)
real(r8) :: naerosol_a(1,1) ! number conc (1/m3)
real(r8) :: vaerosol_a(1,1) ! volume conc (m3/m3)

!-----------------------------------------------------------------------

Expand Down Expand Up @@ -1779,12 +1779,12 @@ subroutine activate_convproc( aero_props, &
tmpa = tmpa + max( conent(2,mm), 0.0_r8 )
naerosol(m) = tmpa * rhoair

naerosol_a(1) = naerosol(m)
vaerosol_a(1) = vaerosol(m)
naerosol_a(1,1) = naerosol(m)
vaerosol_a(1,1) = vaerosol(m)

call aero_props%apply_number_limits( naerosol_a, vaerosol_a, 1, 1, m )

naerosol(m) = naerosol_a(1)
naerosol(m) = naerosol_a(1,1)
end do

! call Razzak-Ghan activation routine with single updraft
Expand Down Expand Up @@ -1918,8 +1918,8 @@ subroutine activate_convproc_method2( aero_props, &
character(len=32) :: spec_type

real(r8) :: tmpa, tmpb, tmpc ! working variable
real(r8) :: naerosol_a(1) ! number conc (1/m3)
real(r8) :: vaerosol_a(1) ! volume conc (m3/m3)
real(r8) :: naerosol_a(1,1) ! number conc (1/m3)
real(r8) :: vaerosol_a(1,1) ! volume conc (m3/m3)

!-----------------------------------------------------------------------

Expand Down Expand Up @@ -1999,12 +1999,12 @@ subroutine activate_convproc_method2( aero_props, &
tmpa = tmpa + max( conu(2,mm), 0.0_r8 )
naerosol(m) = tmpa * rhoair

naerosol_a(1) = naerosol(m)
vaerosol_a(1) = vaerosol(m)
naerosol_a(1,1) = naerosol(m)
vaerosol_a(1,1) = vaerosol(m)

call aero_props%apply_number_limits( naerosol_a, vaerosol_a, 1, 1, m )

naerosol(m) = naerosol_a(1)
naerosol(m) = naerosol_a(1,1)

end do

Expand Down
10 changes: 5 additions & 5 deletions src/chemistry/aerosol/aerosol_properties_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ end function aero_icenuc_updates_mmr
!------------------------------------------------------------------------------
! apply max / min to number concentration
!------------------------------------------------------------------------------
subroutine aero_apply_num_limits( self, naerosol, vaerosol, istart, istop, m )
subroutine aero_apply_num_limits( self, naerosol, vaerosol, ncol, nlev, m )
import :: aerosol_properties, r8
class(aerosol_properties), intent(in) :: self
real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3)
integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols)
integer, intent(in) :: istop ! stop column index
real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3)
integer, intent(in) :: ncol ! number of columns
integer, intent(in) :: nlev ! number of vert levels
integer, intent(in) :: m ! mode or bin index

end subroutine aero_apply_num_limits
Expand Down
71 changes: 25 additions & 46 deletions src/chemistry/aerosol/aerosol_state_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ end subroutine set_list_idx
!------------------------------------------------------------------------------
! returns aerosol number, volume concentrations, and bulk hygroscopicity
!------------------------------------------------------------------------------
subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, &
subroutine loadaer( self, aero_props, ncol, nlev, m, cs, phase, &
naerosol, vaerosol, hygro, errnum, errstr, pom_hygro)

use aerosol_properties_mod, only: aerosol_properties
Expand All @@ -312,17 +312,15 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, &
class(aerosol_state), intent(in) :: self
class(aerosol_properties), intent(in) :: aero_props

integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols)
integer, intent(in) :: istop ! stop column index
integer, intent(in) :: k ! level index
integer, intent(in) :: ncol, nlev
integer, intent(in) :: m ! mode or bin index
real(r8), intent(in) :: cs(:,:) ! air density (kg/m3)
integer, intent(in) :: phase ! phase of aerosol: 1 for interstitial, 2 for cloud-borne, 3 for sum

! output arguments
real(r8), intent(out) :: naerosol(:) ! number conc (1/m3)
real(r8), intent(out) :: vaerosol(:) ! volume conc (m3/m3)
real(r8), intent(out) :: hygro(:) ! bulk hygroscopicity of mode
real(r8), intent(out) :: naerosol(:,:) ! number conc (1/m3)
real(r8), intent(out) :: vaerosol(:,:) ! volume conc (m3/m3)
real(r8), intent(out) :: hygro(:,:) ! bulk hygroscopicity of mode

integer , intent(out) :: errnum
character(len=*), intent(out) :: errstr
Expand All @@ -335,15 +333,13 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, &
real(r8) :: specdens, spechygro
character(len=aero_name_len) :: spectype

real(r8) :: vol(istart:istop) ! aerosol volume mixing ratio
integer :: i, l
real(r8) :: vol(ncol,nlev) ! aerosol volume mixing ratio
integer :: l
!-------------------------------------------------------------------------------
errnum = 0

do i = istart, istop
vaerosol(i) = 0._r8
hygro(i) = 0._r8
end do
vaerosol(:,:) = 0._r8
hygro(:,:) = 0._r8

do l = 1, aero_props%nspecies(m)

Expand All @@ -357,59 +353,42 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, &
endif

if (phase == 3) then
do i = istart, istop
vol(i) = max(raer(i,k) + qqcw(i,k), 0._r8)/specdens
end do
vol(:ncol,:) = max(raer(:ncol,:) + qqcw(:ncol,:), 0._r8)/specdens
else if (phase == 2) then
do i = istart, istop
vol(i) = max(qqcw(i,k), 0._r8)/specdens
end do
vol(:ncol,:) = max(qqcw(:ncol,:), 0._r8)/specdens
else if (phase == 1) then
do i = istart, istop
vol(i) = max(raer(i,k), 0._r8)/specdens
end do
vol(:ncol,:) = max(raer(:ncol,:), 0._r8)/specdens
else
errnum = -1
write(errstr,*)'phase = ',phase,' in aerosol_state::loadaer not recognized'
return
end if

do i = istart, istop
vaerosol(i) = vaerosol(i) + vol(i)
hygro(i) = hygro(i) + vol(i)*spechygro
end do

vaerosol(:ncol,:) = vaerosol(:ncol,:) + vol(:ncol,:)
hygro(:ncol,:) = hygro(:ncol,:) + vol(:ncol,:)*spechygro
end do

do i = istart, istop
if (vaerosol(i) > 1.0e-30_r8) then
hygro(i) = hygro(i)/(vaerosol(i))
vaerosol(i) = vaerosol(i)*cs(i,k)
else
hygro(i) = 0.0_r8
vaerosol(i) = 0.0_r8
end if
end do
where(vaerosol(:ncol,:) > 1.0e-30_r8)
hygro(:ncol,:) = hygro(:ncol,:)/(vaerosol(:ncol,:))
vaerosol(:ncol,:) = vaerosol(:ncol,:)*cs(:ncol,:)
elsewhere
hygro(:ncol,:) = 0._r8
vaerosol(:ncol,:) = 0._r8
end where

! aerosol number mixing ratios (#/kg)
call self%get_ambient_num(m, raer)
call self%get_cldbrne_num(m, qqcw)
if (phase == 3) then
do i = istart, istop
naerosol(i) = (raer(i,k) + qqcw(i,k))*cs(i,k) ! #/kg -> #/m3
end do
naerosol(:ncol,:) = (raer(:ncol,:) + qqcw(:ncol,:))*cs(:ncol,:) ! #/kg -> #/m3
else if (phase == 2) then
do i = istart, istop
naerosol(i) = qqcw(i,k)*cs(i,k)
end do
naerosol(:ncol,:) = qqcw(:ncol,:)*cs(:ncol,:)
else
do i = istart, istop
naerosol(i) = raer(i,k)*cs(i,k)
end do
naerosol(:ncol,:) = raer(:ncol,:)*cs(:ncol,:)
end if

! adjust number
call aero_props%apply_number_limits( naerosol, vaerosol, istart, istop, m )
call aero_props%apply_number_limits( naerosol, vaerosol, ncol, nlev, m )

end subroutine loadaer

Expand Down
10 changes: 5 additions & 5 deletions src/chemistry/aerosol/bulk_aerosol_properties_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,12 @@ end function icenuc_updates_mmr
!------------------------------------------------------------------------------
! apply max / min to number concentration
!------------------------------------------------------------------------------
subroutine apply_number_limits( self, naerosol, vaerosol, istart, istop, m )
subroutine apply_number_limits( self, naerosol, vaerosol, ncol, nlev, m )
class(bulk_aerosol_properties), intent(in) :: self
real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3)
integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols)
integer, intent(in) :: istop ! stop column index
real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3)
integer, intent(in) :: ncol ! number of columns
integer, intent(in) :: nlev ! number of vert levels
integer, intent(in) :: m ! mode or bin index

call endrun('ERROR: bulk_aerosol_properties_mod%apply_number_limits not yet implemented')
Expand Down
10 changes: 5 additions & 5 deletions src/chemistry/aerosol/carma_aerosol_properties_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -488,12 +488,12 @@ end function icenuc_updates_mmr
!------------------------------------------------------------------------------
! apply max / min to number concentration
!------------------------------------------------------------------------------
subroutine apply_number_limits( self, naerosol, vaerosol, istart, istop, m )
subroutine apply_number_limits( self, naerosol, vaerosol, ncol, nlev, m )
class(carma_aerosol_properties), intent(in) :: self
real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3)
integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols)
integer, intent(in) :: istop ! stop column index
real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3)
real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3)
integer, intent(in) :: ncol ! number of columns
integer, intent(in) :: nlev ! number of vert levels
integer, intent(in) :: m ! mode or bin index

end subroutine apply_number_limits
Expand Down
Loading
Loading