Skip to content

Commit 35d419d

Browse files
authored
Merge pull request #1548 from fvitt/aqueous_chemistry_fixes
cam6_4_172: Aqueous chemistry fixes
2 parents 64c9fd7 + 9b1bee2 commit 35d419d

4 files changed

Lines changed: 168 additions & 23 deletions

File tree

doc/ChangeLog

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,93 @@
11
===============================================================
22

3+
Tag name: cam6_4_172
4+
Originator(s): fvitt
5+
Date: 14 May 2026
6+
One-line Summary: Aqueous chemistry bug fixes
7+
Github PR URL: https://github.com/ESCOMP/CAM/pull/1548
8+
9+
Purpose of changes (include the issue number and title text for each relevant GitHub issue):
10+
11+
Issue #1544
12+
Fix the following aqueous chemistry bugs:
13+
- 5th mode is not included in the updates when MAM5 is used
14+
- Failure to update NH3 when CARMA is used
15+
16+
Describe any changes made to build system: N/A
17+
18+
Describe any changes made to the namelist: N/A
19+
20+
List any changes to the defaults for the boundary datasets: N/A
21+
22+
Describe any substantial timing or memory changes: N/A
23+
24+
Code reviewed by: cacraigucar tilmes
25+
26+
List all files eliminated:
27+
28+
List all files added and what they do:
29+
30+
List all existing files that have been modified, and describe the changes:
31+
M src/chemistry/carma_aero/carma_aero_gasaerexch.F90
32+
- initialize diagnostic varible to zero
33+
34+
M src/chemistry/carma_aero/sox_cldaero_mod.F90
35+
- include NH3 gas loss
36+
- enforce lower limits
37+
38+
M src/chemistry/modal_aero/sox_cldaero_mod.F90
39+
- include the 5th sulfate mode
40+
41+
If there were any failures reported from running test_driver.sh on any test
42+
platform, and checkin with these failures has been OK'd by the gatekeeper,
43+
then copy the lines from the td.*.status files for the failed tests to the
44+
appropriate machine below. All failed tests must be justified.
45+
46+
derecho/intel/aux_cam:
47+
DIFF ERP_Ld3.ne16pg3_ne16pg3_mg17.FHISTC_WAt1ma.derecho_intel.cam-reduced_hist1d
48+
DIFF ERP_Ld3.ne30pg3_ne30pg3_mt232.FHISTC_MTt4s.derecho_intel.cam-outfrq1d_aoa
49+
DIFF ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s
50+
DIFF ERP_Ln9.ne30pg3_ne30pg3_mg17.FCnudged.derecho_intel.cam-outfrq9s
51+
DIFF ERP_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WAma.derecho_intel.cam-outfrq9s
52+
DIFF ERS_Ln9.f09_f09_mg17.FX2000.derecho_intel.cam-outfrq9s
53+
DIFF ERS_Ln9.f19_f19_mg17.FXSD.derecho_intel.cam-outfrq9s
54+
DIFF ERS_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s_ctem
55+
DIFF SMS_C2_D_Ln9.ne16pg3_ne16pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s
56+
DIFF SMS_D_Ln9.f09_f09_mg17.FCts2nudged.derecho_intel.cam-outfrq9s_leapday
57+
DIFF SMS_D_Ln9.f09_f09_mg17.FCvbsxHIST.derecho_intel.cam-outfrq9s
58+
DIFF SMS_D_Ln9.f19_f19_mg17.FCARMA2000climo.derecho_intel.cam-outfrq9s
59+
DIFF SMS_D_Ln9.f19_f19_mg17.FCHIST_SLH.derecho_intel.cam-outfrq9s
60+
DIFF SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s
61+
DIFF SMS_D_Ln9.f19_f19_mg17.QPC2000climo.derecho_intel.cam-outfrq3s_usecase
62+
DIFF SMS_D_Ln9.ne30pg3_ne30pg3_mt232.1850C_CAM70%MT%CT4S2_CLM60%SP_CICE%PRES_DOCN%DOM_MOSART_SGLC_SWAV_SESP.derecho_intel.cam-outfrq9s
63+
DIFF SMS_D_Ln9_P1280x1.ne30pg3_ne30pg3_mt232.FHISTC_MTt1s.derecho_intel.cam-outfrq9s_Leung_dust
64+
DIFF SMS_D_Ln9_P1536x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s
65+
DIFF SMS_Ld1.f09_f09_mg17.FW2000climo.derecho_intel.cam-outfrq1d
66+
DIFF SMS_Ld1.ne30pg3_ne30pg3_mg17.FC2010climo.derecho_intel.cam-outfrq1d
67+
DIFF SMS_Lh12.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq3h
68+
DIFF SMS_Ln9.f09_f09_mg17.FW1850.derecho_intel.cam-reduced_hist3s
69+
DIFF SMS_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s_rrtmgp
70+
- expected differences due to bug fixes for MAM5 and CARMA
71+
72+
derecho/nvhpc/aux_cam: PASS
73+
74+
izumi/nag/aux_cam:
75+
FAIL ERC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-outfrq3s_subcol COMPARE_base_rest
76+
- pre-existing failure -- see https://github.com/ESCOMP/CAM/issues/1514
77+
78+
DIFF ERC_D_Ln9.f10_f10_mg37.QPWmaC6.izumi_nag.cam-outfrq3s
79+
- expected differences due to bug fix for MAM5
80+
81+
izumi/gnu/aux_cam:
82+
DIFF SMS_D_Ln9.f10_f10_mg37.FWmaHIST.izumi_gnu.cam-outfrq9s_mee_fluxes
83+
- expected differences due to bug fix for MAM5
84+
85+
Summarize any changes to answers:
86+
larger than roundoff for MAM5 and CARMA configurations
87+
88+
===============================================================
89+
===============================================================
90+
391
Tag name: cam6_4_171
492
Originator(s): fvitt
593
Date: 1 May 2026

src/chemistry/carma_aero/carma_aero_gasaerexch.F90

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ subroutine carma_aero_gasaerexch_sub( state, &
507507
num_bin, t, pmid, &
508508
wetr_n, uptkrate )
509509

510+
! initialize to zero before summing
511+
uptkrate_all(:,:) = 0._r8
512+
510513
do m = 1, nbins
511514

512515
write(fieldname,'("NUMDENS_bin",I2.2)') m

src/chemistry/carma_aero/sox_cldaero_mod.F90

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ subroutine sox_cldaero_update( &
230230
dso4dt_aqrxn, dso4dt_hprxn, &
231231
dso4dt_gasuptk, dmsadt_gasuptk_toso4, &
232232
dqdt_aq, dqdt_wr, dqdt
233+
real(r8) :: delnh3
233234

234235
real(r8) :: fwetrem, uptkrate
235236

@@ -295,6 +296,10 @@ subroutine sox_cldaero_update( &
295296

296297
delso4_o3rxn = xso4(i,k) - xso4_init(i,k)
297298

299+
if (id_nh3>0) then
300+
delnh3 = nh3g(i,k) - xnh3(i,k)
301+
endif
302+
298303
! the factors are proportional to the activated particle MR for each
299304
! bin, which is the MR of cloud drops "associated with" the mode
300305
! thus we are assuming the cloud drop size is independent of the
@@ -384,7 +389,6 @@ subroutine sox_cldaero_update( &
384389
dqdt_aq = -dso4dt_aqrxn*cldfrc(i,k)
385390
dqdt = dqdt_aq + dqdt_wr
386391
qin(i,k,id_so2) = qin(i,k,id_so2) + dqdt * dtime
387-
qin(i,k,id_so2) = MAX( qin(i,k,id_so2), small_value )
388392

389393
! h2o2 -- the first order loss rate for h2o2 is frh2o2_c*clwlrat(i,k)
390394
! fwetrem = max( 0.0_r8, (1.0_r8-exp(-min(100._r8,dtime*frh2o2_c*clwlrat(i,k)))) )
@@ -394,7 +398,13 @@ subroutine sox_cldaero_update( &
394398
dqdt_aq = -dso4dt_hprxn*cldfrc(i,k)
395399
dqdt = dqdt_aq + dqdt_wr
396400
qin(i,k,id_h2o2) = qin(i,k,id_h2o2) + dqdt * dtime
397-
qin(i,k,id_h2o2) = MAX( qin(i,k,id_h2o2), small_value )
401+
402+
! NH3
403+
if (id_nh3>0) then
404+
dqdt_aq = delnh3/dtime*cldfrc(i,k)
405+
dqdt = dqdt_aq
406+
qin(i,k,id_nh3) = qin(i,k,id_nh3) + dqdt * dtime
407+
endif
398408

399409
! for SO4 from H2O2/O3 budgets
400410
dqdt_aqhprxn(i,k) = dso4dt_hprxn*cldfrc(i,k)
@@ -408,31 +418,52 @@ subroutine sox_cldaero_update( &
408418
!==============================================================
409419
! ... Update the mixing ratios
410420
!==============================================================
421+
do k = 1,pver
422+
423+
do n = 1, nbins
424+
do l = 1, nspec(n)
425+
mm = bin_idx(n, l)
426+
call rad_aer_get_bin_props_by_idx(0, n, l,spectype=spectype)
427+
if (trim(spectype) == 'sulfate') then
428+
qcw(:,k,mm) = max(qcw(:,k,mm), small_value )
429+
end if
430+
end do
431+
end do
432+
433+
qin(:ncol,k,id_so2) = max( qin(:ncol,k,id_so2), small_value )
434+
qin(:ncol,k,id_h2o2) = max( qin(:ncol,k,id_h2o2), small_value )
435+
qin(:ncol,k,id_h2so4) = max( qin(:ncol,k,id_h2so4), small_value )
436+
if ( id_nh3 > 0 ) qin(:ncol,k,id_nh3) = max( qin(:ncol,k,id_nh3), small_value )
437+
438+
end do
411439

412440
! diagnostics
413441

414442
specmw_so4_amode = 96.0_r8
415-
do n = 1, nbins
416-
! while looking through all species, only dqdt_aqso4 from sulfates is gt zero
417-
do l = 1, nspec(n)
418-
mm = bin_idx(n, l)
419-
aqso4(:,n)=0._r8
420-
do k=1,pver
421-
do i=1,ncol
422-
aqso4(i,n)=aqso4(i,n)+dqdt_aqso4(i,k,mm)*specmw_so4_amode/mbar(i,k) &
423-
*pdel(i,k)/gravit ! kg/m2/s
424-
enddo
425-
enddo
426-
427-
aqh2so4(:,n)=0._r8
428-
do k=1,pver
429-
do i=1,ncol
430-
aqh2so4(i,n)=aqh2so4(i,n)+dqdt_aqh2so4(i,k,mm)*specmw_so4_amode/mbar(i,k) &
431-
*pdel(i,k)/gravit ! kg/m2/s
432-
enddo
433-
enddo
434-
end do
435-
end do
443+
do n = 1, nbins
444+
! while looking through all species, only dqdt_aqso4 from sulfates is gt zero
445+
do l = 1, nspec(n)
446+
call rad_aer_get_bin_props_by_idx(0, n, l,spectype=spectype)
447+
if (trim(spectype) == 'sulfate') then
448+
mm = bin_idx(n, l)
449+
aqso4(:,n)=0._r8
450+
do k=1,pver
451+
do i=1,ncol
452+
aqso4(i,n)=aqso4(i,n)+dqdt_aqso4(i,k,mm)*specmw_so4_amode/mbar(i,k) &
453+
*pdel(i,k)/gravit ! kg/m2/s
454+
enddo
455+
enddo
456+
457+
aqh2so4(:,n)=0._r8
458+
do k=1,pver
459+
do i=1,ncol
460+
aqh2so4(i,n)=aqh2so4(i,n)+dqdt_aqh2so4(i,k,mm)*specmw_so4_amode/mbar(i,k) &
461+
*pdel(i,k)/gravit ! kg/m2/s
462+
enddo
463+
enddo
464+
end if
465+
end do
466+
end do
436467

437468
aqso4_h2o2(:) = 0._r8
438469
do k=1,pver

src/chemistry/modal_aero/sox_cldaero_mod.F90

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@ function sox_cldaero_create_obj(cldfrc, qcw, lwc, cfact, ncol, loffset) result(
7777
integer :: i,k
7878

7979
logical :: mode7
80+
logical :: mode5
8081

8182
mode7 = ntot_amode == 7
83+
mode5 = ntot_amode == 5
8284

8385
conc_obj => cldaero_allocate()
8486

@@ -127,6 +129,27 @@ function sox_cldaero_create_obj(cldfrc, qcw, lwc, cfact, ncol, loffset) result(
127129
+ qcw(:ncol,:,id_nh4_4a) &
128130
+ qcw(:ncol,:,id_nh4_5a) &
129131
+ qcw(:ncol,:,id_nh4_6a)
132+
else if (mode5) then
133+
#if ( defined MODAL_AERO_5MODE )
134+
id_so4_1a = lptr_so4_cw_amode(1) - loffset
135+
id_so4_2a = lptr_so4_cw_amode(2) - loffset
136+
id_so4_3a = lptr_so4_cw_amode(3) - loffset
137+
id_so4_5a = lptr_so4_cw_amode(5) - loffset
138+
#endif
139+
conc_obj%so4c(:ncol,:) &
140+
= qcw(:,:,id_so4_1a) &
141+
+ qcw(:,:,id_so4_2a) &
142+
+ qcw(:,:,id_so4_3a) &
143+
+ qcw(:,:,id_so4_5a)
144+
145+
! for 3-mode, so4 is assumed to be nh4hso4
146+
! the partial neutralization of so4 is handled by using a
147+
! -1 charge (instead of -2) in the electro-neutrality equation
148+
conc_obj%nh4c(:ncol,:) = 0._r8
149+
150+
! with 3-mode, assume so4 is nh4hso4, and so half-neutralized
151+
conc_obj%so4_fact = 1._r8
152+
130153
else
131154
id_so4_1a = lptr_so4_cw_amode(1) - loffset
132155
id_so4_2a = lptr_so4_cw_amode(2) - loffset

0 commit comments

Comments
 (0)