Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
| james-bruten-mo | James Bruten | Met Office | 2025-12-09 |
| andrewcoughtrie | Andrew Coughtrie | Met Office | 2026-02-10 |
| jennyhickson | Jenny Hickson | Met Office | 2026-03-02 |
| theabro | Nathan Luke Abraham | NCAS & University of Cambridge | 2026-03-19 |
29 changes: 29 additions & 0 deletions src/control/core/diagnostics/asad_flux_dat.F90
Original file line number Diff line number Diff line change
Expand Up @@ -8766,6 +8766,20 @@ MODULE asad_flux_dat
[' ',' ',' ',' ']) &
]

! Add extra het chem fluxes for both troposphere and stratosphere
! Reactions are used in both StratTrop and CRI-Strat2
! Note that B85 is a biomolecular reaction but is aping a heterogeneous one
TYPE(asad_flux_defn), PARAMETER, PUBLIC :: &
het_chem_n2o5_h2o(2) = [ &
! B85 N2O5+H2O
asad_flux_defn('RXN',50993,'B',.FALSE.,0,4, &
['N2O5 ','H2O '], &
['HONO2 ','HONO2 ',' ',' ']), &
! PSC N2O5-H2O H04
asad_flux_defn('RXN',50994,'H',.FALSE.,0,4, &
['N2O5 ','H2O '], &
['HONO2 ','HONO2 ',' ',' ']) &
]


PUBLIC :: asad_load_default_fluxes
Expand Down Expand Up @@ -8853,6 +8867,7 @@ SUBROUTINE asad_load_default_fluxes
TYPE(asad_flux_defn), ALLOCATABLE, SAVE :: aa_ch4_budget_loss(:)
TYPE(asad_flux_defn), ALLOCATABLE, SAVE :: aa_ch4_drydep(:)
TYPE(asad_flux_defn), ALLOCATABLE, SAVE :: aa_ch4_ste(:)
TYPE(asad_flux_defn), ALLOCATABLE, SAVE :: aa_het_chem_n2o5_h2o(:)

INTEGER :: p1 ! start position in asad_chemical_fluxes array
INTEGER :: p2 ! end position in asad_chemical_fluxes array
Expand Down Expand Up @@ -9025,6 +9040,9 @@ SUBROUTINE asad_load_default_fluxes
ALLOCATE(aa_ch4_ste(SIZE(asad_ch4_ste)))
aa_ch4_ste = asad_ch4_ste
END IF
! aa_het_chem_n2o5_h2o
ALLOCATE(aa_het_chem_n2o5_h2o(SIZE(het_chem_n2o5_h2o)))
aa_het_chem_n2o5_h2o = het_chem_n2o5_h2o

ELSE IF (ukca_config%l_ukca_cristrat) THEN
! Select the asad diagnostics appropriate for CRI-Strat chemistry and
Expand Down Expand Up @@ -9233,6 +9251,9 @@ SUBROUTINE asad_load_default_fluxes
ALLOCATE(aa_oxidN_wetdep(SIZE(cri_oxidN_wetdep)))
aa_oxidN_wetdep = cri_oxidN_wetdep
END IF
! aa_het_chem_n2o5_h2o
ALLOCATE(aa_het_chem_n2o5_h2o(SIZE(het_chem_n2o5_h2o)))
aa_het_chem_n2o5_h2o = het_chem_n2o5_h2o


ELSE IF (ukca_config%l_ukca_offline .OR. ukca_config%l_ukca_offline_be) THEN
Expand Down Expand Up @@ -9306,6 +9327,8 @@ SUBROUTINE asad_load_default_fluxes
n_chemical_fluxes = n_chemical_fluxes + SIZE(aa_ch4_drydep)
IF (ALLOCATED(aa_ch4_ste)) &
n_chemical_fluxes = n_chemical_fluxes + SIZE(aa_ch4_ste)
IF (ALLOCATED(aa_het_chem_n2o5_h2o)) &
n_chemical_fluxes = n_chemical_fluxes + SIZE(aa_het_chem_n2o5_h2o)

ALLOCATE(asad_chemical_fluxes(n_chemical_fluxes))

Expand Down Expand Up @@ -9449,6 +9472,11 @@ SUBROUTINE asad_load_default_fluxes
asad_chemical_fluxes(p1:p2) = aa_ch4_ste(:)
p1 = p2 + 1
END IF
IF (ALLOCATED(aa_het_chem_n2o5_h2o)) THEN
p2 = p1 + SIZE(aa_het_chem_n2o5_h2o) - 1
asad_chemical_fluxes(p1:p2) = aa_het_chem_n2o5_h2o(:)
p1 = p2 + 1
END IF

IF (p2 /= n_chemical_fluxes) THEN
cmessage = ' n_chemical_fluxes and p2 are different'
Expand Down Expand Up @@ -9502,6 +9530,7 @@ SUBROUTINE asad_load_default_fluxes
END IF

! Deallocate the generic arrays
IF (ALLOCATED(aa_het_chem_n2o5_h2o)) DEALLOCATE(aa_het_chem_n2o5_h2o)
IF (ALLOCATED(aa_ch4_ste)) DEALLOCATE(aa_ch4_ste)
IF (ALLOCATED(aa_ch4_drydep)) DEALLOCATE(aa_ch4_drydep)
IF (ALLOCATED(aa_ch4_budget_loss)) DEALLOCATE(aa_ch4_budget_loss)
Expand Down
6 changes: 6 additions & 0 deletions src/control/core/interface/ukca_config_specification_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ MODULE ukca_config_specification_mod
! B-E Offline Oxidants scheme
LOGICAL :: l_fix_ukca_h2so4_ystore ! True to fix storage of H2SO4 in ASAD
! N-R schemes for updating in GLOMAP
LOGICAL :: l_fix_ukca_n2o5_h2o ! True to filter N2O5+H2O to strat and trop only

! Settings for managing photolysis environmental driver
! requirements on behalf of external UKCA Photolysis code
Expand Down Expand Up @@ -949,6 +950,7 @@ SUBROUTINE init_ukca_configuration()
ukca_config%l_fix_drydep_so2_water = .FALSE.
ukca_config%l_fix_ukca_offox_h2o_fac = .FALSE.
ukca_config%l_fix_ukca_h2so4_ystore = .FALSE.
ukca_config%l_fix_ukca_n2o5_h2o = .FALSE.

! -- Settings for managing Photolysis driver requirements
ukca_config%i_photol_scheme = imdi
Expand Down Expand Up @@ -1179,6 +1181,7 @@ SUBROUTINE ukca_get_config( &
l_fix_drydep_so2_water, &
l_fix_ukca_offox_h2o_fac, &
l_fix_ukca_h2so4_ystore, &
l_fix_ukca_n2o5_h2o, &
l_ukca_chem, l_ukca_trop, l_ukca_aerchem, l_ukca_raq, l_ukca_raqaero, &
l_ukca_offline_be, l_ukca_tropisop, l_ukca_strattrop, l_ukca_strat, &
l_ukca_offline, l_ukca_cristrat, l_ukca_stratcfc, l_ukca_achem, &
Expand Down Expand Up @@ -1395,6 +1398,7 @@ SUBROUTINE ukca_get_config( &
LOGICAL, OPTIONAL, INTENT(OUT) :: l_fix_drydep_so2_water
LOGICAL, OPTIONAL, INTENT(OUT) :: l_fix_ukca_offox_h2o_fac
LOGICAL, OPTIONAL, INTENT(OUT) :: l_fix_ukca_h2so4_ystore
LOGICAL, OPTIONAL, INTENT(OUT) :: l_fix_ukca_n2o5_h2o
LOGICAL, OPTIONAL, INTENT(OUT) :: l_ukca_chem
LOGICAL, OPTIONAL, INTENT(OUT) :: l_ukca_trop
LOGICAL, OPTIONAL, INTENT(OUT) :: l_ukca_aerchem
Expand Down Expand Up @@ -1685,6 +1689,8 @@ SUBROUTINE ukca_get_config( &
l_fix_ukca_offox_h2o_fac = ukca_config%l_fix_ukca_offox_h2o_fac
IF (PRESENT(l_fix_ukca_h2so4_ystore)) &
l_fix_ukca_h2so4_ystore = ukca_config%l_fix_ukca_h2so4_ystore
IF (PRESENT(l_fix_ukca_n2o5_h2o)) &
l_fix_ukca_n2o5_h2o = ukca_config%l_fix_ukca_n2o5_h2o

! -- UKCA internal configuration variables
IF (PRESENT(l_ukca_chem)) l_ukca_chem = ukca_config%l_ukca_chem
Expand Down
9 changes: 9 additions & 0 deletions src/control/core/top_level/ukca_setup_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ SUBROUTINE ukca_setup(error_code, &
l_fix_ukca_h2dd_x, &
l_fix_ukca_offox_h2o_fac, &
l_fix_ukca_h2so4_ystore, &
l_fix_ukca_n2o5_h2o, &
l_mode_bhn_on, &
l_mode_bln_on, &
l_ddepaer, &
Expand Down Expand Up @@ -540,6 +541,7 @@ SUBROUTINE ukca_setup(error_code, &
LOGICAL, OPTIONAL, INTENT(IN) :: l_fix_ukca_h2dd_x
LOGICAL, OPTIONAL, INTENT(IN) :: l_fix_ukca_offox_h2o_fac
LOGICAL, OPTIONAL, INTENT(IN) :: l_fix_ukca_h2so4_ystore
LOGICAL, OPTIONAL, INTENT(IN) :: l_fix_ukca_n2o5_h2o
LOGICAL, OPTIONAL, INTENT(IN) :: l_mode_bhn_on
LOGICAL, OPTIONAL, INTENT(IN) :: l_mode_bln_on
LOGICAL, OPTIONAL, INTENT(IN) :: l_ddepaer
Expand Down Expand Up @@ -1232,6 +1234,13 @@ SUBROUTINE ukca_setup(error_code, &
ukca_config%l_fix_ukca_h2so4_ystore = l_fix_ukca_h2so4_ystore
END IF

IF (ukca_config%i_ukca_chem == i_ukca_chem_strattrop .OR. &
ukca_config%i_ukca_chem == i_ukca_chem_cristrat) THEN
ukca_config%l_fix_ukca_n2o5_h2o = .TRUE.
IF (PRESENT(l_fix_ukca_n2o5_h2o)) &
ukca_config%l_fix_ukca_n2o5_h2o = l_fix_ukca_n2o5_h2o
END IF

! Settings for managing photolysis environmental driver
! requirements on behalf of external UKCA Photolysis code

Expand Down
30 changes: 29 additions & 1 deletion src/science/core/chemistry/asad/asad_bimol.F90
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ MODULE asad_bimol_mod

CONTAINS

SUBROUTINE asad_bimol( n_points )
SUBROUTINE asad_bimol( n_points, stratflag_opt )

USE asad_mod, ONLY: t, t300, specf, spb, ab, rk, tnd, p, &
wp, f, peps, nbrkx, jpspb, jpcspf, jpbk
Expand All @@ -91,6 +91,8 @@ SUBROUTINE asad_bimol( n_points )
IMPLICIT NONE

INTEGER, INTENT(IN) :: n_points
! optional argument used for masking off the stratosphere
LOGICAL, INTENT(IN), OPTIONAL :: stratflag_opt(n_points)

! Local variables

Expand All @@ -112,6 +114,7 @@ SUBROUTINE asad_bimol( n_points )
INTEGER, SAVE :: ics2oh = 0
INTEGER, SAVE :: ih2o = 0
INTEGER, SAVE :: iho2no = 0
INTEGER, SAVE :: in2o5_h2o = 0
INTEGER :: jtr
INTEGER :: j
INTEGER :: jr
Expand Down Expand Up @@ -145,6 +148,10 @@ SUBROUTINE asad_bimol( n_points )
REAL :: tmp1(1:n_points)
REAL :: inv_t(1:n_points)

! logical array for masking-off the stratosphere
! default to False unless changed by stratflag_opt
LOGICAL :: stratflag(n_points)

! ErrorStatus
INTEGER :: errcode=0 ! Error flag (0 = OK)
CHARACTER(LEN=errormessagelength) :: cmessage ! Error return message
Expand All @@ -167,6 +174,12 @@ SUBROUTINE asad_bimol( n_points )
ratioa2b(:) = 0.0
ratiob2total(:) = 0.0

! set stratflag from optional argument - only True in the stratosphere
stratflag(:) = .FALSE.
IF (PRESENT(stratflag_opt)) THEN
stratflag = stratflag_opt
END IF

! 1. Calculate bimolecular rate coefficients
! --------- ----------- ---- ------------

Expand Down Expand Up @@ -255,6 +268,14 @@ SUBROUTINE asad_bimol( n_points )
iho2no = asad_findreaction( r1, r2, prods, 1, spb, nbrkx, &
jpbk+1, jpspb )

! Find B85: N2O5 + H2O -> HONO2 + HONO2.
r1 = 'N2O5 '
r2 = 'H2O '
prods(1) = 'HONO2 '
prods(2) = 'HONO2 '
in2o5_h2o = asad_findreaction( r1, r2, prods, 2, spb, nbrkx, &
jpbk+1, jpspb )


IF (ukca_config%l_ukca_chem_aero) THEN
r1 = 'DMS '
Expand Down Expand Up @@ -408,6 +429,13 @@ SUBROUTINE asad_bimol( n_points )
8.53e-4*(1e-2*p(1:n_points))-1.73)/100.0
END IF

! Keep B85 (N2O5 + H2O) in the troposphere only when fix is enabled.
IF (ukca_config%l_fix_ukca_n2o5_h2o .AND. in2o5_h2o > 0) THEN
WHERE (stratflag(1:n_points))
rk(1:n_points,in2o5_h2o) = 0.0
END WHERE
END IF

! SO3 + H2O: 2nd H2O molecule dealt with here by multiplying rate by [H2O]
IF ( ih2o /= 0 .AND. iso3h2o /= 0 ) THEN
! water is an advected tracer
Expand Down
2 changes: 1 addition & 1 deletion src/science/core/chemistry/asad/asad_cdrive.F90
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ SUBROUTINE asad_cdrive(ftr, pp, pt, pq, co2_1d, cld_f, cld_l, &
! 4. Calculate reaction rate coefficients
! --------- -------- ---- ------------

CALL asad_bimol (n_points)
CALL asad_bimol (n_points, stratflag)
CALL asad_trimol(n_points)

! Calculate aqueous-phase SO2 oxdn. and tropospheric heterogeneous rates
Expand Down
28 changes: 25 additions & 3 deletions src/science/core/chemistry/ukca_hetero_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,18 @@ SUBROUTINE ukca_hetero(n_points, have_nat, stratflag)
rk(:,n_hocl_hcl) = hk(:,3)
END IF

! Optionally filter N2O5+H2O by stratflag to prevent double-counting.
IF (n_n2o5_h2o > 0) THEN
! 4. N2O5 + H2O -> 2 HNO3
rk(:,n_n2o5_h2o) = hk(:,4)
IF (ukca_config%l_fix_ukca_n2o5_h2o) THEN
WHERE (stratflag)
rk(:,n_n2o5_h2o) = hk(:,4)
ELSE WHERE
rk(:,n_n2o5_h2o) = 0.0
END WHERE
ELSE
rk(:,n_n2o5_h2o) = hk(:,4)
END IF
END IF

IF (n_n2o5_hcl > 0) THEN
Expand Down Expand Up @@ -659,14 +668,27 @@ SUBROUTINE ukca_hetero(n_points, have_nat, stratflag)

WHERE ( zh2o > peps )
rk(:,n_clono2_h2o) = kpsc(:,2) / zh2o
rk(:,n_n2o5_h2o) = kpsc(:,4) / zh2o
rk(:,n_brono2_h2o) = kpsc(:,8) / zh2o
ELSE WHERE
rk(:,n_clono2_h2o) = 0.0
rk(:,n_n2o5_h2o) = 0.0
rk(:,n_brono2_h2o) = 0.0
END WHERE

! Optionally filter N2O5+H2O by stratflag to prevent double-counting.
IF (ukca_config%l_fix_ukca_n2o5_h2o) THEN
WHERE ( zh2o > peps .AND. stratflag )
rk(:,n_n2o5_h2o) = kpsc(:,4) / zh2o
ELSE WHERE
rk(:,n_n2o5_h2o) = 0.0
END WHERE
ELSE
WHERE ( zh2o > peps )
rk(:,n_n2o5_h2o) = kpsc(:,4) / zh2o
ELSE WHERE
rk(:,n_n2o5_h2o) = 0.0
END WHERE
END IF

WHERE ( zhbr > peps )
rk(:,n_hobr_hbr) = kpsc(:,9) / zhbr
rk(:,n_hocl_hbr) = kpsc(:,10) / zhbr
Expand Down
Loading