From c013064a0c1853b5be35ee3554483198acc39b8f Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:37:01 +0100 Subject: [PATCH 01/16] This could let radaer have a different i_mode_setup to ukca --- .../ukca_config_specification_mod.F90 | 1 + .../top_level/ukca_radaer_lfric_init_mod.F90 | 203 ++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 diff --git a/src/control/core/interface/ukca_config_specification_mod.F90 b/src/control/core/interface/ukca_config_specification_mod.F90 index a32b743..16e80b3 100644 --- a/src/control/core/interface/ukca_config_specification_mod.F90 +++ b/src/control/core/interface/ukca_config_specification_mod.F90 @@ -655,6 +655,7 @@ MODULE ukca_config_specification_mod TYPE(glomap_variables_type), SAVE, TARGET :: glomap_variables TYPE(glomap_variables_type), SAVE, TARGET :: glomap_variables_climatology +TYPE(glomap_variables_type), SAVE, TARGET :: glomap_variables_radaer ! --------------------------------------------------------------------------- ! -- Templates for parent callback procedures to be used in UKCA -- diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 new file mode 100644 index 0000000..a869952 --- /dev/null +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -0,0 +1,203 @@ +! ----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +! ----------------------------------------------------------------------------- +! +! Purpose: An interface routine to initialise radaer setting with lfric parent +! +! Procedure: +! 1) CALL the relevant mode setup subroutine from ukca_mode_setup +! +! This file belongs in section: UKCA +! +MODULE ukca_radaer_lfric_init_mod + +IMPLICIT NONE + +CHARACTER(LEN=*),PARAMETER,PRIVATE :: ModuleName = 'UKCA_RADAER_LFRIC_INIT_MOD' + +CONTAINS + +SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & + i_tune_bc_in, & + l_dust_mp_ageing ) + +USE ereport_mod, ONLY: & + ereport + +USE errormessagelength_mod, ONLY: & + errormessagelength + +USE parkind1, ONLY: & + jpim, & + jprb + +USE ukca_config_specification_mod, ONLY: & + i_suss_4mode, & + i_sussbcoc_5mode, & + i_sussbcoc_4mode, & + i_sussbcocso_5mode, & + i_sussbcocso_4mode, & + i_du_2mode, & + i_sussbcocdu_7mode, & + i_sussbcocntnh_5mode_7cpt, & + i_solinsol_6mode, & + i_sussbcocduntnh_8mode_8cpt, & + i_sussbcocdump_8mode + glomap_variables_radaer + +USE ukca_mode_setup, ONLY: & + ukca_mode_suss_4mode, & + ukca_mode_sussbcoc_5mode, & + ukca_mode_sussbcoc_4mode, & + ukca_mode_sussbcocso_5mode, & + ukca_mode_sussbcocso_4mode, & + ukca_mode_duonly_2mode, & + ukca_mode_sussbcocdu_7mode, & + ukca_mode_sussbcocntnh_5mode_7cpt, & + ukca_mode_solinsol_6mode, & + ukca_mode_sussbcocduntnh_8mode_8cpt, & + ukca_mode_sussbcocdump_8mode, & + glomap_variables_type + + +USE umPrintMgr, ONLY: & + umPrint, & + umMessage + +USE yomhook, ONLY: & + lhook, & + dr_hook + +IMPLICIT NONE + +! Arguments + +INTEGER, INTENT(IN) :: i_mode_setup_in +INTEGER, INTENT(IN) :: i_tune_bc_in +LOGICAL, INTENT(IN) :: l_dust_mp_ageing + +! Local variables + +! We are calling this module because radaer is on. Forced true +LOGICAL, PARAMETER :: l_radaer_in = .true. + +! Force existing temporary logicals to always be true from LFRic +LOGICAL, PARAMETER :: l_fix_nacl_density_in = .true. +LOGICAL, PARAMETER :: l_fix_ukca_hygroscopicities_in = .true. + +INTEGER :: errcode ! error code +CHARACTER(LEN=errormessagelength) :: cmessage ! error message + +INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0 +INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1 +REAL(KIND=jprb) :: zhook_handle +CHARACTER(LEN=*), PARAMETER :: RoutineName='UKCA_RADAER_LFRIC_INIT' + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_in, zhook_handle) + +SELECT CASE(i_mode_setup_in) +CASE (i_suss_4mode) ! 1 + CALL ukca_mode_suss_4mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing) + +CASE (i_sussbcoc_5mode) ! 2 + CALL ukca_mode_sussbcoc_5mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing) + +CASE (i_sussbcoc_4mode) ! 3 + CALL ukca_mode_sussbcoc_4mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocso_5mode) ! 4 + CALL ukca_mode_sussbcocso_5mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocso_4mode) ! 5 + CALL ukca_mode_sussbcocso_4mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_du_2mode) ! 6 + CALL ukca_mode_duonly_2mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocdu_7mode) ! 8 + CALL ukca_mode_sussbcocdu_7mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocntnh_5mode_7cpt) ! 10 + CALL ukca_mode_sussbcocntnh_5mode_7cpt( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_solinsol_6mode) ! 11 + CALL ukca_mode_solinsol_6mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocduntnh_8mode_8cpt) ! 12 + CALL ukca_mode_sussbcocduntnh_8mode_8cpt( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE (i_sussbcocdump_8mode) ! 13 + CALL ukca_mode_sussbcocdump_8mode( glomap_variables_radaer, & + l_radaer_in, & + i_tune_bc_in, & + l_fix_nacl_density_in, & + l_fix_ukca_hygroscopicities_in, & + l_dust_mp_ageing ) + +CASE DEFAULT + cmessage='i_mode_setup_in has unrecognised value' + WRITE(umMessage,'(A,I0)') cmessage, i_mode_setup_in + CALL umPrint(umMessage,src=RoutineName) + errcode = 1 + CALL ereport(RoutineName,errcode,cmessage) +END SELECT + + + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) + +END SUBROUTINE ukca_radaer_lfric_init + +END MODULE ukca_radaer_lfric_init_mod From b55e95d02bf39ad39067d510d971dccbf5d2bea0 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:30:31 +0100 Subject: [PATCH 02/16] pipework to populate ukca_radaer structure --- .../top_level/ukca_radaer_lfric_init_mod.F90 | 28 +- .../radaer/ukca_radaer_lfric_settings_mod.F90 | 267 ++++++++++++++++++ 2 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 src/science/radaer/ukca_radaer_lfric_settings_mod.F90 diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index a869952..733bab2 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -9,19 +9,29 @@ ! Procedure: ! 1) CALL the relevant mode setup subroutine from ukca_mode_setup ! +! 2) CALL +! ! This file belongs in section: UKCA ! MODULE ukca_radaer_lfric_init_mod IMPLICIT NONE +! Default private +PRIVATE + +PUBLIC :: ukca_radaer_lfric_init + +PUBLIC :: n_ukca_mode , n_ukca_cpnt + CHARACTER(LEN=*),PARAMETER,PRIVATE :: ModuleName = 'UKCA_RADAER_LFRIC_INIT_MOD' CONTAINS SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & i_tune_bc_in, & - l_dust_mp_ageing ) + l_dust_mp_ageing, & + l_ukca_radaer_sustrat ) USE ereport_mod, ONLY: & ereport @@ -61,6 +71,11 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & ukca_mode_sussbcocdump_8mode, & glomap_variables_type +USE ukca_radaer_lfric_settings_mod, ONLY: & + ukca_radaer_lfric_settings + +USE ukca_radaer_saved_mod, ONLY: & + ukca_radaer USE umPrintMgr, ONLY: & umPrint, & @@ -80,6 +95,10 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & ! Local variables +! These are used in radaer_kernel_mod +INTEGER, SAVE :: n_ukca_mode = 0 +INTEGER, SAVE :: n_ukca_cpnt = 0 + ! We are calling this module because radaer is on. Forced true LOGICAL, PARAMETER :: l_radaer_in = .true. @@ -194,7 +213,12 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & CALL ereport(RoutineName,errcode,cmessage) END SELECT - +! Now call ukca_radaer_lfric_settings +CALL ukca_radaer_lfric_settings ( l_ukca_radaer_sustrat, & + glomap_variables_radaer, & + ukca_radaer, & + n_ukca_mode, & + n_ukca_cpnt ) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 new file mode 100644 index 0000000..08f333b --- /dev/null +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -0,0 +1,267 @@ +! ----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +! ----------------------------------------------------------------------------- +! +! Purpose: This could allow RADAER to have different GLOMAP settings +! to UKCA (e.g. with option dust_and_clim) +! +! Procedure: +! 1) +! +! This file belongs in section: UKCA +! +MODULE ukca_radaer_lfric_settings_mod + +IMPLICIT NONE + +CHARACTER(LEN=*),PARAMETER,PRIVATE :: ModuleName = & + 'UKCA_RADAER_LFRIC_SETTINGS_MOD' + +CONTAINS + +SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & + glomap_variables_radaer, & + ukca_radaer, & + n_loc_mode, & + n_loc_cpnt ) + +USE errormessagelength_mod, ONLY: & + errormessagelength + +USE ukca_mode_setup, ONLY: & + glomap_variables_type, & + nmodes, & + mode_names, & + ncp_max, & + mode_sup_insol, & + ip_ukca_mode_nucleation, & + ip_ukca_mode_aitken, & + ip_ukca_mode_accum, & + ip_ukca_mode_coarse, & + ip_ukca_mode_supercoarse, & + cp_su, & + cp_bc, & + cp_oc, & + cp_cl, & + cp_du, & + cp_so, & + cp_no3, & + cp_nh4, & + cp_nn, & + cp_mp + +USE ukca_radaer_struct_mod, ONLY: & + ukca_radaer_struct + +USE parkind1, ONLY: & + jpim, & + jprb + +USE yomhook, ONLY: & + lhook, & + dr_hook + +IMPLICIT NONE + +! Arguments +! ========= + +! Switch: Use sulphuric acid optical properties in the stratosphere, +! instead of ammonium sulphate. +LOGICAL, INTENT(IN) :: l_ukca_radaer_sustrat + +TYPE(glomap_variables_type), INTENT(IN OUT) :: glomap_variables_radaer +TYPE (ukca_radaer_struct), INTENT(IN OUT) :: ukca_radaer + +! Counters for number of modes and components +INTEGER, INTENT(IN OUT) :: n_loc_mode +INTEGER, INTENT(IN OUT) :: n_loc_cpnt + +! Local variables +! =============== + +LOGICAL, POINTER :: component(:,:) +CHARACTER(LEN=7), POINTER :: component_names(:) +REAL, POINTER :: ddplim0(:) +REAL, POINTER :: ddplim1(:) +LOGICAL, POINTER :: mode(:) +INTEGER, POINTER :: modesol(:) +INTEGER, POINTER :: ncp +REAL, POINTER :: rhocomp(:) +REAL, POINTER :: sigmag(:) + +! Loop counters +INTEGER :: i, j + +! In-loop mode type +INTEGER :: this_type + +! Local counters for number of modes and components +INTEGER :: n_loc_mode +INTEGER :: n_loc_cpnt + +! Error message +INTEGER :: ierr +CHARACTER (LEN=errormessagelength) :: cmessage + +INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0 +INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1 +REAL(KIND=jprb) :: zhook_handle +CHARACTER(LEN=*), PARAMETER :: RoutineName='UKCA_RADAER_LFRIC_INIT' + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_in, zhook_handle) + +! Caution - pointers to TYPE glomap_variables% +! have been included here to make the code easier to read +! take care when making changes involving pointers +component => glomap_variables_radaer%component +component_names => glomap_variables_radaer%component_names +ddplim0 => glomap_variables_radaer%ddplim0 +ddplim1 => glomap_variables_radaer%ddplim1 +mode => glomap_variables_radaer%mode +modesol => glomap_variables_radaer%modesol +ncp => glomap_variables_radaer%ncp +rhocomp => glomap_variables_radaer%rhocomp +sigmag => glomap_variables_radaer%sigmag + +! Allocate elements that depend on ncp or nmodes +CALL allocate_radaer_struct(ukca_radaer, glomap_variables_radaer) + +! Loop over all modes and components per mode, +! and only retain included modes and components. +ukca_radaer%idx_cpnt_mode(:,:)=-1 +DO i = 1, nmodes + IF (mode(i)) THEN + + this_name = mode_names(i) + + ! Get the mode type. Since there is no direct information, + ! it is obtained from the mode names. + + SELECT CASE (this_name(1:3)) + + CASE ('Nuc') + this_type = ip_ukca_mode_nucleation + + CASE ('Ait') + this_type = ip_ukca_mode_aitken + + CASE ('Acc') + this_type = ip_ukca_mode_accum + + CASE ('Cor') + this_type = ip_ukca_mode_coarse + + CASE ('Sup') + this_type = ip_ukca_mode_supercoarse + + CASE DEFAULT + ierr = 1 + cmessage = 'Unexpected mode name.' // this_name + CALL ereport(RoutineName,errcode,cmessage) + + END SELECT + + ! Interaction of nucleation modes with radiation is neglected. + IF (this_type /= ip_ukca_mode_nucleation) THEN + + n_loc_mode = n_loc_mode + 1 + ukca_radaer%i_mode_type(n_loc_mode) = this_type + ukca_radaer%l_soluble(n_loc_mode) = modesol(i) == 1 + ukca_radaer%d0low(n_loc_mode) = ddplim0(i) + ukca_radaer%d0up(n_loc_mode) = ddplim1(i) + ukca_radaer%sigma(n_loc_mode) = sigmag(i) + ukca_radaer%n_cpnt_in_mode(n_loc_mode) = 0 + + ! Loop on components within that mode. + DO j = 1, ncp + IF (component(i, j)) THEN + + n_loc_cpnt = n_loc_cpnt + 1 + + ! Update the number of components in that mode and + ! retain the array index of the current component. + + ukca_radaer%n_cpnt_in_mode(n_loc_mode) = & + ukca_radaer%n_cpnt_in_mode(n_loc_mode) + 1 + + ukca_radaer%i_cpnt_index(ukca_radaer%n_cpnt_in_mode(n_loc_mode), & + n_loc_mode) = n_loc_cpnt + + ukca_radaer%idx_cpnt_mode(i,j) = n_loc_cpnt + + ukca_radaer%density(n_loc_cpnt) = rhocomp(j) + + ukca_radaer%i_mode(n_loc_cpnt) = n_loc_mode + + ! Get the component type. Since there is no direct + ! information, it is obtained from the component + ! names. + + SELECT CASE ( component_names(j) ) + + CASE ('h2so4 ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_su + + CASE ('bcarbon') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_bc + + CASE ('ocarbon') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_oc + + CASE ('nacl ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_cl + + CASE ('dust ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_du + + CASE ('sec_org') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_so + + CASE ('no3 ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_no3 + + CASE ('nano3 ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_nn + + CASE ('nh4 ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_nh4 + + CASE ('mp ') + ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_mp + + CASE DEFAULT + ierr = 2 + cmessage = 'Unexpected component name: ' // component_names(j) + CALL ereport(RoutineName,errcode,cmessage) + + END SELECT + + END IF + END DO ! j + + END IF + END IF +END DO ! i + +ukca_radaer%n_mode = n_loc_mode +ukca_radaer%n_cpnt = n_loc_cpnt +ukca_radaer%l_sustrat = l_ukca_radaer_sustrat + +! Ensure that the coarse narrow LUTs are used for the coarse insoluble mode +! if the super-coarse insoluble mode is selected +ukca_radaer%l_cornarrow_ins = mode(mode_sup_insol) + +IF (ukca_radaer%n_mode == 0 .OR. ukca_radaer%n_cpnt == 0) THEN + ierr = 3 + cmessage = 'Setup includes no UKCA aerosols.' + CALL ereport(RoutineName,errcode,cmessage) +END IF + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) + +END SUBROUTINE ukca_radaer_lfric_settings + +END MODULE ukca_radaer_lfric_settings_mod From b8840ee0b72da811f1eeb876eaf7629a06397c3b Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:21:09 +0100 Subject: [PATCH 03/16] Needed more UM repository functionality --- .../top_level/ukca_radaer_lfric_init_mod.F90 | 6 +- .../radaer/ukca_radaer_lfric_saved_mod.F90 | 24 ++ .../radaer/ukca_radaer_lfric_settings_mod.F90 | 72 +++--- .../radaer/ukca_radaer_lfric_struct_mod.F90 | 223 ++++++++++++++++++ 4 files changed, 287 insertions(+), 38 deletions(-) create mode 100644 src/science/radaer/ukca_radaer_lfric_saved_mod.F90 create mode 100644 src/science/radaer/ukca_radaer_lfric_struct_mod.F90 diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index 733bab2..dcab78f 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -74,8 +74,8 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & USE ukca_radaer_lfric_settings_mod, ONLY: & ukca_radaer_lfric_settings -USE ukca_radaer_saved_mod, ONLY: & - ukca_radaer +USE ukca_radaer_lfric_saved_mod, ONLY: & + ukca_radaer_lfric USE umPrintMgr, ONLY: & umPrint, & @@ -216,7 +216,7 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & ! Now call ukca_radaer_lfric_settings CALL ukca_radaer_lfric_settings ( l_ukca_radaer_sustrat, & glomap_variables_radaer, & - ukca_radaer, & + ukca_radaer_lfric, & n_ukca_mode, & n_ukca_cpnt ) diff --git a/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 b/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 new file mode 100644 index 0000000..66e465b --- /dev/null +++ b/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 @@ -0,0 +1,24 @@ +! *****************************COPYRIGHT******************************* +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +! *****************************COPYRIGHT******************************* +! +! Purpose: +! To save structure ukca_radaer_lfric +! +! --------------------------------------------------------------------- + +MODULE ukca_radaer_lfric_saved_mod + +USE ukca_radaer_lfric_struct_mod, ONLY: & + ukca_radaer_lfric_struct + +IMPLICIT NONE + +CHARACTER(LEN=*), PARAMETER, PRIVATE :: ModuleName='UKCA_RADAER_LFRIC_SAVED_MOD' + +! Structure for UKCA/radiation interaction +TYPE (ukca_radaer_lfric_struct), SAVE :: ukca_radaer_lfric + +END MODULE ukca_radaer_lfric_saved_mod diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 index 08f333b..7b01cd0 100644 --- a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -23,7 +23,7 @@ MODULE ukca_radaer_lfric_settings_mod SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & glomap_variables_radaer, & - ukca_radaer, & + ukca_radaer_lfric, & n_loc_mode, & n_loc_cpnt ) @@ -52,8 +52,9 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & cp_nn, & cp_mp -USE ukca_radaer_struct_mod, ONLY: & - ukca_radaer_struct +USE ukca_radaer_lfric_struct_mod, ONLY: & + ukca_radaer_lfric_struct, & + allocate_radaer_lfric_struct USE parkind1, ONLY: & jpim, & @@ -72,8 +73,8 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! instead of ammonium sulphate. LOGICAL, INTENT(IN) :: l_ukca_radaer_sustrat -TYPE(glomap_variables_type), INTENT(IN OUT) :: glomap_variables_radaer -TYPE (ukca_radaer_struct), INTENT(IN OUT) :: ukca_radaer +TYPE(glomap_variables_type), INTENT(IN OUT) :: glomap_variables_radaer +TYPE (ukca_radaer_lfric_struct), INTENT(IN OUT) :: ukca_radaer_lfric ! Counters for number of modes and components INTEGER, INTENT(IN OUT) :: n_loc_mode @@ -127,11 +128,11 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & sigmag => glomap_variables_radaer%sigmag ! Allocate elements that depend on ncp or nmodes -CALL allocate_radaer_struct(ukca_radaer, glomap_variables_radaer) +CALL allocate_radaer_lfric_struct(ukca_radaer_lfric, glomap_variables_radaer) ! Loop over all modes and components per mode, ! and only retain included modes and components. -ukca_radaer%idx_cpnt_mode(:,:)=-1 +ukca_radaer_lfric%idx_cpnt_mode(:,:)=-1 DO i = 1, nmodes IF (mode(i)) THEN @@ -168,12 +169,12 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & IF (this_type /= ip_ukca_mode_nucleation) THEN n_loc_mode = n_loc_mode + 1 - ukca_radaer%i_mode_type(n_loc_mode) = this_type - ukca_radaer%l_soluble(n_loc_mode) = modesol(i) == 1 - ukca_radaer%d0low(n_loc_mode) = ddplim0(i) - ukca_radaer%d0up(n_loc_mode) = ddplim1(i) - ukca_radaer%sigma(n_loc_mode) = sigmag(i) - ukca_radaer%n_cpnt_in_mode(n_loc_mode) = 0 + ukca_radaer_lfric%i_mode_type(n_loc_mode) = this_type + ukca_radaer_lfric%l_soluble(n_loc_mode) = modesol(i) == 1 + ukca_radaer_lfric%d0low(n_loc_mode) = ddplim0(i) + ukca_radaer_lfric%d0up(n_loc_mode) = ddplim1(i) + ukca_radaer_lfric%sigma(n_loc_mode) = sigmag(i) + ukca_radaer_lfric%n_cpnt_in_mode(n_loc_mode) = 0 ! Loop on components within that mode. DO j = 1, ncp @@ -184,17 +185,18 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! Update the number of components in that mode and ! retain the array index of the current component. - ukca_radaer%n_cpnt_in_mode(n_loc_mode) = & - ukca_radaer%n_cpnt_in_mode(n_loc_mode) + 1 + ukca_radaer_lfric%n_cpnt_in_mode(n_loc_mode) = & + ukca_radaer_lfric%n_cpnt_in_mode(n_loc_mode) + 1 - ukca_radaer%i_cpnt_index(ukca_radaer%n_cpnt_in_mode(n_loc_mode), & - n_loc_mode) = n_loc_cpnt + ukca_radaer_lfric%i_cpnt_index( & + ukca_radaer_lfric%n_cpnt_in_mode(n_loc_mode),n_loc_mode) = & + n_loc_cpnt - ukca_radaer%idx_cpnt_mode(i,j) = n_loc_cpnt + ukca_radaer_lfric%idx_cpnt_mode(i,j) = n_loc_cpnt - ukca_radaer%density(n_loc_cpnt) = rhocomp(j) + ukca_radaer_lfric%density(n_loc_cpnt) = rhocomp(j) - ukca_radaer%i_mode(n_loc_cpnt) = n_loc_mode + ukca_radaer_lfric%i_mode(n_loc_cpnt) = n_loc_mode ! Get the component type. Since there is no direct ! information, it is obtained from the component @@ -203,34 +205,34 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & SELECT CASE ( component_names(j) ) CASE ('h2so4 ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_su + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_su CASE ('bcarbon') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_bc + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_bc CASE ('ocarbon') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_oc + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_oc CASE ('nacl ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_cl + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_cl CASE ('dust ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_du + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_du CASE ('sec_org') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_so + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_so CASE ('no3 ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_no3 + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_no3 CASE ('nano3 ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_nn + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_nn CASE ('nh4 ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_nh4 + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_nh4 CASE ('mp ') - ukca_radaer%i_cpnt_type(n_loc_cpnt) = cp_mp + ukca_radaer_lfric%i_cpnt_type(n_loc_cpnt) = cp_mp CASE DEFAULT ierr = 2 @@ -246,15 +248,15 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & END IF END DO ! i -ukca_radaer%n_mode = n_loc_mode -ukca_radaer%n_cpnt = n_loc_cpnt -ukca_radaer%l_sustrat = l_ukca_radaer_sustrat +ukca_radaer_lfric%n_mode = n_loc_mode +ukca_radaer_lfric%n_cpnt = n_loc_cpnt +ukca_radaer_lfric%l_sustrat = l_ukca_radaer_sustrat ! Ensure that the coarse narrow LUTs are used for the coarse insoluble mode ! if the super-coarse insoluble mode is selected -ukca_radaer%l_cornarrow_ins = mode(mode_sup_insol) +ukca_radaer_lfric%l_cornarrow_ins = mode(mode_sup_insol) -IF (ukca_radaer%n_mode == 0 .OR. ukca_radaer%n_cpnt == 0) THEN +IF (ukca_radaer_lfric%n_mode == 0 .OR. ukca_radaer_lfric%n_cpnt == 0) THEN ierr = 3 cmessage = 'Setup includes no UKCA aerosols.' CALL ereport(RoutineName,errcode,cmessage) diff --git a/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 b/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 new file mode 100644 index 0000000..b8af00b --- /dev/null +++ b/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 @@ -0,0 +1,223 @@ +! *****************************COPYRIGHT******************************* +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +! *****************************COPYRIGHT******************************* +! +! Purpose: +! Defines maximum dimensions +! Defines type ukca_radaer_lfric_struct, the structure used by UKCA_RADAER +! +! Code Owner: Please refer to the UM file CodeOwners.txt +! This file belongs in section: UKCA +! +! Contained subroutines: +! allocate_radaer_lfric_struct +! +! Code description: +! Language: FORTRAN 90 +! This code is written to UMDP3 programming standards. +! +! --------------------------------------------------------------------- + +MODULE ukca_radaer_lfric_struct_mod + +IMPLICIT NONE + +CHARACTER(LEN=*),PARAMETER,PRIVATE :: ModuleName='UKCA_RADAER_LFRIC_STRUCT_MOD' + +INTEGER, SAVE :: npd_ukca_cpnt ! nmodes*ncp + +INTEGER, SAVE :: ncp_max_x_nmodes ! nmodes * ncp_max + +! Thresholds on the modal mass-mixing ratio and modal number +! concentrations above which aerosol optical properties are to be +! computed. Placed here as used by multiple subroutines. +REAL, PARAMETER :: threshold_mmr = 1.0e-12 ! kg/kg +! Corresponds to burden of 0.01 mg/m2 if mmr=1.e-12 everywhere. + +REAL, PARAMETER :: threshold_vol = 1.0e-25 ! m3/m3 +! Corresponds to particle diameter < 10nm + +REAL, PARAMETER :: threshold_nbr = 1.0e+00 ! m-3 +! A single coarse-mode particle with d=10um per would give +! a mixing ratio of ~1.e-12kg/kg in the lower troposphere + +! Main structure holding all the variables needed for +! interacting UKCA aerosols with radiation. + +TYPE :: ukca_radaer_lfric_struct + + ! Information about UKCA aerosol modes + ! ==================================== + + ! Actual number of modes, with a default value for + ! minimising array dimensions. + INTEGER :: n_mode = 1 + + ! Type of mode (i.e. nucleation, Aitken, accum, or coarse) + INTEGER, ALLOCATABLE :: i_mode_type(:) + + ! Solubility of mode (soluble if true) + LOGICAL, ALLOCATABLE :: l_soluble(:) + + ! Lower and upper limits on the geometric mean diameter (m) + ! in each mode + REAL, ALLOCATABLE :: d0low(:) + REAL, ALLOCATABLE :: d0up(:) + + ! Geometric standard deviation in this mode + REAL, ALLOCATABLE :: sigma(:) + + ! Number of components in each mode and index of each + ! component in array ukca_cpnt_info + INTEGER, ALLOCATABLE :: n_cpnt_in_mode(:) + INTEGER, ALLOCATABLE :: i_cpnt_index(:,:) + + ! Modal diameter of the dry aerosol (m) + REAL, ALLOCATABLE :: dry_diam(:, :, :, :) + + ! Modal diameter of the wet aerosol (m) + REAL, ALLOCATABLE :: wet_diam(:, :, :, :) + + ! Modal densities (kg/m3) + REAL, ALLOCATABLE :: modal_rho(:, :, :, :) + + ! Modal volumes (including water for soluble modes) + REAL, ALLOCATABLE :: modal_vol(:, :, :, :) + + ! Fractional volume of water in each mode + REAL, ALLOCATABLE :: modal_wtv(:, :, :, :) + + ! Modal number concentrations + REAL, ALLOCATABLE :: modal_nbr(:, :, :, :) + + ! Information about UKCA aerosol components + ! ========================================= + + ! Actual number of components, with a default value for + ! minimising array dimensions. + INTEGER :: n_cpnt = 1 + + ! Size of ncp_max + INTEGER :: ncp_max + + ! Size of ncp + INTEGER :: ncp + + ! Size of nmodes + INTEGER :: nmodes + + ! Size of ncp_max_x_nmodes + INTEGER :: ncp_max_x_nmodes + + ! Type of component (e.g. sulphate) + INTEGER, ALLOCATABLE :: i_cpnt_type(:) + + ! Mass density of each component (kg/m3) + REAL, ALLOCATABLE :: density(:) + + ! Array index of the mode this component belongs to + INTEGER, ALLOCATABLE :: i_mode(:) + + ! Array index for translating component and mode + ! to ukca_radaer index + INTEGER, ALLOCATABLE :: idx_cpnt_mode(:,:) + + ! Component mass-mixing ratio (kg/kg) + REAL, ALLOCATABLE :: mix_ratio(:, :, :, :) + + ! Component volumes + REAL, ALLOCATABLE :: comp_vol(:, :, :, :) + + ! Switch: if true, use sulphuric acid optical properties in the + ! stratosphere, instead of ammonium sulphate (if false). + ! Has the same default as run_ukca:l_ukca_radaer_sustrat or + ! run_glomap_aeroclim:l_glomap_clim_radaer_sustrat + ! from which is it assigned. + LOGICAL :: l_sustrat = .FALSE. + + ! Switch: if true, nitrate scheme is on and sodium nitrate + ! refractive indices are included in the pcalc file + LOGICAL :: l_nitrate = .FALSE. + + ! Switch: if true, use the narrow coarse mode LUTs for the + ! coarse insoluble mode. This is the case if the super coarse + ! insoluble mode is used + LOGICAL :: l_cornarrow_ins = .FALSE. + +END TYPE ukca_radaer_lfric_struct + +PUBLIC :: allocate_radaer_lfric_struct + +CONTAINS + +! ############################################################################# + +SUBROUTINE allocate_radaer_lfric_struct(ukca_radaer, glomap_variables) + +! To allocate arrays in the structure ukca_radaer using the number of modes +! and number of components configured in the GLOMAP setup routine. + +USE ukca_mode_setup, ONLY: nmodes, ncp_max, cp_no3, glomap_variables_type +USE parkind1, ONLY: jprb, jpim +USE yomhook, ONLY: lhook, dr_hook +IMPLICIT NONE + +TYPE(ukca_radaer_lfric_struct), INTENT(IN OUT) :: ukca_radaer +TYPE(glomap_variables_type), INTENT(IN) :: glomap_variables + +INTEGER :: ncp + +INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0 +INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1 +REAL(KIND=jprb) :: zhook_handle + +CHARACTER(LEN=*), PARAMETER :: RoutineName='ALLOCATE_RADAER_LFRIC_STRUCT' + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) + + +ncp = glomap_variables%ncp +npd_ukca_cpnt = ncp * nmodes +ncp_max_x_nmodes = ncp_max * nmodes + +ukca_radaer%ncp = ncp +ukca_radaer%ncp_max = ncp_max +ukca_radaer%nmodes = nmodes +ukca_radaer%ncp_max_x_nmodes = ncp_max_x_nmodes + +! Amend the indices of H2SO4 and water for sodium nitrate inclusion +IF (ncp >= cp_no3) THEN + IF (ANY(glomap_variables%component (:,cp_no3))) THEN + ukca_radaer%l_nitrate = .TRUE. + END IF +END IF + +IF (.NOT. ALLOCATED(ukca_radaer%i_mode_type)) & + ALLOCATE(ukca_radaer%i_mode_type(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%l_soluble)) & + ALLOCATE(ukca_radaer%l_soluble(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%d0low)) & + ALLOCATE(ukca_radaer%d0low(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%d0up)) & + ALLOCATE(ukca_radaer%d0up(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%sigma)) & + ALLOCATE(ukca_radaer%sigma(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%n_cpnt_in_mode)) & + ALLOCATE(ukca_radaer%n_cpnt_in_mode(nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%i_cpnt_index)) & + ALLOCATE(ukca_radaer%i_cpnt_index(ncp_max,nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%i_cpnt_type)) & + ALLOCATE(ukca_radaer%i_cpnt_type(ncp_max_x_nmodes)) +IF (.NOT. ALLOCATED(ukca_radaer%density)) & + ALLOCATE(ukca_radaer%density(npd_ukca_cpnt)) +IF (.NOT. ALLOCATED(ukca_radaer%i_mode)) & + ALLOCATE(ukca_radaer%i_mode(npd_ukca_cpnt)) +IF (.NOT. ALLOCATED(ukca_radaer%idx_cpnt_mode)) & + ALLOCATE(ukca_radaer%idx_cpnt_mode(nmodes,ncp_max)) + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) +END SUBROUTINE allocate_radaer_lfric_struct + +END MODULE ukca_radaer_lfric_struct_mod From 1054a3884bf2984aebec164f120848f200dbc7fa Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Wed, 12 Aug 2026 15:30:59 +0100 Subject: [PATCH 04/16] Fixing build errors --- .../radaer/ukca_radaer_lfric_settings_mod.F90 | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 index 7b01cd0..a7efb98 100644 --- a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -8,7 +8,9 @@ ! to UKCA (e.g. with option dust_and_clim) ! ! Procedure: -! 1) +! 1) Allocate structure ukca_radaer_lfric +! 2) Obtain number of modes and components for specific GLOMAP setting +! 3) Populate structure ukca_radaer_lfric ! ! This file belongs in section: UKCA ! @@ -73,8 +75,8 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! instead of ammonium sulphate. LOGICAL, INTENT(IN) :: l_ukca_radaer_sustrat -TYPE(glomap_variables_type), INTENT(IN OUT) :: glomap_variables_radaer -TYPE (ukca_radaer_lfric_struct), INTENT(IN OUT) :: ukca_radaer_lfric +TYPE(glomap_variables_type), TARGET, INTENT(IN OUT) :: glomap_variables_radaer +TYPE (ukca_radaer_lfric_struct), INTENT(IN OUT) :: ukca_radaer_lfric ! Counters for number of modes and components INTEGER, INTENT(IN OUT) :: n_loc_mode @@ -96,13 +98,12 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! Loop counters INTEGER :: i, j +! In-loop copy of mode names +CHARACTER(LEN=7) :: this_name + ! In-loop mode type INTEGER :: this_type -! Local counters for number of modes and components -INTEGER :: n_loc_mode -INTEGER :: n_loc_cpnt - ! Error message INTEGER :: ierr CHARACTER (LEN=errormessagelength) :: cmessage @@ -128,12 +129,13 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & sigmag => glomap_variables_radaer%sigmag ! Allocate elements that depend on ncp or nmodes -CALL allocate_radaer_lfric_struct(ukca_radaer_lfric, glomap_variables_radaer) +CALL allocate_radaer_lfric_struct( ukca_radaer_lfric, glomap_variables_radaer ) ! Loop over all modes and components per mode, ! and only retain included modes and components. ukca_radaer_lfric%idx_cpnt_mode(:,:)=-1 DO i = 1, nmodes + IF (mode(i)) THEN this_name = mode_names(i) @@ -141,7 +143,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! Get the mode type. Since there is no direct information, ! it is obtained from the mode names. - SELECT CASE (this_name(1:3)) + SELECT CASE ( this_name(1:3) ) CASE ('Nuc') this_type = ip_ukca_mode_nucleation @@ -161,14 +163,16 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & CASE DEFAULT ierr = 1 cmessage = 'Unexpected mode name.' // this_name - CALL ereport(RoutineName,errcode,cmessage) + CALL ereport(RoutineName,ierr,cmessage) END SELECT ! Interaction of nucleation modes with radiation is neglected. - IF (this_type /= ip_ukca_mode_nucleation) THEN + IF ( this_type /= ip_ukca_mode_nucleation ) THEN + ! Increase mode counter by one n_loc_mode = n_loc_mode + 1 + ukca_radaer_lfric%i_mode_type(n_loc_mode) = this_type ukca_radaer_lfric%l_soluble(n_loc_mode) = modesol(i) == 1 ukca_radaer_lfric%d0low(n_loc_mode) = ddplim0(i) @@ -178,8 +182,9 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & ! Loop on components within that mode. DO j = 1, ncp - IF (component(i, j)) THEN + IF ( component(i, j) ) THEN + ! Increase component counter by one n_loc_cpnt = n_loc_cpnt + 1 ! Update the number of components in that mode and @@ -237,7 +242,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & CASE DEFAULT ierr = 2 cmessage = 'Unexpected component name: ' // component_names(j) - CALL ereport(RoutineName,errcode,cmessage) + CALL ereport(RoutineName,ierr,cmessage) END SELECT @@ -245,6 +250,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & END DO ! j END IF + END IF END DO ! i @@ -259,7 +265,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & IF (ukca_radaer_lfric%n_mode == 0 .OR. ukca_radaer_lfric%n_cpnt == 0) THEN ierr = 3 cmessage = 'Setup includes no UKCA aerosols.' - CALL ereport(RoutineName,errcode,cmessage) + CALL ereport(RoutineName,ierr,cmessage) END IF IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) From 7e840664fdce6a1fadc18b8e94b884ef4b1f1f3a Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:24:37 +0100 Subject: [PATCH 05/16] More build errors --- .../core/top_level/ukca_radaer_lfric_init_mod.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index dcab78f..0402339 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -22,7 +22,8 @@ MODULE ukca_radaer_lfric_init_mod PUBLIC :: ukca_radaer_lfric_init -PUBLIC :: n_ukca_mode , n_ukca_cpnt +INTEGER, PUBLIC, SAVE :: n_ukca_mode +INTEGER, PUBLIC, SAVE :: n_ukca_cpnt CHARACTER(LEN=*),PARAMETER,PRIVATE :: ModuleName = 'UKCA_RADAER_LFRIC_INIT_MOD' @@ -54,7 +55,7 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & i_sussbcocntnh_5mode_7cpt, & i_solinsol_6mode, & i_sussbcocduntnh_8mode_8cpt, & - i_sussbcocdump_8mode + i_sussbcocdump_8mode, & glomap_variables_radaer USE ukca_mode_setup, ONLY: & @@ -92,13 +93,10 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & INTEGER, INTENT(IN) :: i_mode_setup_in INTEGER, INTENT(IN) :: i_tune_bc_in LOGICAL, INTENT(IN) :: l_dust_mp_ageing +LOGICAL, INTENT(IN) :: l_ukca_radaer_sustrat ! Local variables -! These are used in radaer_kernel_mod -INTEGER, SAVE :: n_ukca_mode = 0 -INTEGER, SAVE :: n_ukca_cpnt = 0 - ! We are calling this module because radaer is on. Forced true LOGICAL, PARAMETER :: l_radaer_in = .true. @@ -213,6 +211,10 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & CALL ereport(RoutineName,errcode,cmessage) END SELECT +! Initialise these to zero +n_ukca_mode = 0 +n_ukca_cpnt = 0 + ! Now call ukca_radaer_lfric_settings CALL ukca_radaer_lfric_settings ( l_ukca_radaer_sustrat, & glomap_variables_radaer, & From d8284556e68c7469c889e37f10c40ee3ad8162ba Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:49:27 +0100 Subject: [PATCH 06/16] didnt declare ereport --- src/science/radaer/ukca_radaer_lfric_settings_mod.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 index a7efb98..093f7a7 100644 --- a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -29,6 +29,9 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & n_loc_mode, & n_loc_cpnt ) +USE ereport_mod, ONLY: & + ereport + USE errormessagelength_mod, ONLY: & errormessagelength From 7eca4d87ee5b22ccfed9038fd14c0f1cc0375e8d Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Fri, 14 Aug 2026 15:53:22 +0100 Subject: [PATCH 07/16] Needed by LFRic_apps --- src/science/core/aerosols/glomap/ukca_mode_setup.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/science/core/aerosols/glomap/ukca_mode_setup.F90 b/src/science/core/aerosols/glomap/ukca_mode_setup.F90 index c64ecae..20e311d 100644 --- a/src/science/core/aerosols/glomap/ukca_mode_setup.F90 +++ b/src/science/core/aerosols/glomap/ukca_mode_setup.F90 @@ -102,6 +102,7 @@ MODULE ukca_mode_setup INTEGER, PARAMETER :: ip_ukca_mode_coarse = 3 INTEGER, PARAMETER :: ip_ukca_mode_supercoarse = 4 +INTEGER, PARAMETER :: i_ukca_tune_bc_off = 0 ! No BC density tuning INTEGER, PARAMETER :: i_ukca_bc_tuned = 1 ! BC density tuned INTEGER, PARAMETER :: i_ukca_bc_mg_mix = 2 ! BC density tuned, plus ! Maxwell-Garnet mixing method From 5fed92bf3f8832d5275cff076b48d8e0af1509e1 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:50:04 +0100 Subject: [PATCH 08/16] Allocatable lists used by radaer kernel --- .../radaer/ukca_radaer_lfric_list_mod.F90 | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/science/radaer/ukca_radaer_lfric_list_mod.F90 diff --git a/src/science/radaer/ukca_radaer_lfric_list_mod.F90 b/src/science/radaer/ukca_radaer_lfric_list_mod.F90 new file mode 100644 index 0000000..32d59a3 --- /dev/null +++ b/src/science/radaer/ukca_radaer_lfric_list_mod.F90 @@ -0,0 +1,291 @@ +! *****************************COPYRIGHT******************************* +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +! *****************************COPYRIGHT******************************* +! +! Purpose: +! Allocatable lists used in radaer kernel are set here +! +! --------------------------------------------------------------------- + +MODULE ukca_radaer_lfric_list_mod + +IMPLICIT NONE +PRIVATE + +! Maximum number of characters allowed for names in list +INTEGER, PARAMETER, PUBLIC :: max_fldname_len = 40 + +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: pvol_comp_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: comp_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: mode_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: rhopar_mode_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: dry_diam_mode_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: modal_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: ait_sol_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: acc_sol_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: cor_sol_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: ait_ins_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: acc_ins_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: cor_ins_volume_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: modal_wtv_names(:) +CHARACTER(LEN=max_fldname_len),PUBLIC,ALLOCATABLE,SAVE:: wet_diam_mode_names(:) + +CHARACTER(LEN=*), PARAMETER, PRIVATE :: ModuleName='UKCA_RADAER_LFRIC_LIST_MOD' + +PUBLIC :: ukca_radaer_lfric_list + +CONTAINS + +SUBROUTINE ukca_radaer_lfric_list( i_mode_setup_in ) + +USE ereport_mod, ONLY: & + ereport + +USE errormessagelength_mod, ONLY: & + errormessagelength + +USE parkind1, ONLY: & + jpim, & + jprb + +USE ukca_config_specification_mod, ONLY: & + i_du_2mode, & + i_sussbcocdu_7mode + +USE umPrintMgr, ONLY: & + umPrint, & + umMessage + +USE yomhook, ONLY: & + lhook, & + dr_hook + +IMPLICIT NONE + +! Arguments + +INTEGER, INTENT(IN) :: i_mode_setup_in + +! Local variables + +INTEGER :: errcode ! error code +CHARACTER(LEN=errormessagelength) :: cmessage ! error message + +INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0 +INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1 +REAL(KIND=jprb) :: zhook_handle +CHARACTER(LEN=*), PARAMETER :: RoutineName='UKCA_RADAER_LFRIC_LIST' + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_in, zhook_handle) + +SELECT CASE(i_mode_setup_in) +CASE (i_du_2mode) + + IF (.NOT. ALLOCATED(pvol_comp_names)) ALLOCATE(pvol_comp_names(2)) + IF (.NOT. ALLOCATED(comp_names)) ALLOCATE(comp_names(2)) + IF (.NOT. ALLOCATED(mode_names)) ALLOCATE(mode_names(6)) + IF (.NOT. ALLOCATED(rhopar_mode_names)) ALLOCATE(rhopar_mode_names(6)) + IF (.NOT. ALLOCATED(dry_diam_mode_names)) ALLOCATE(dry_diam_mode_names(6)) + IF (.NOT. ALLOCATED(modal_volume_names)) ALLOCATE(modal_volume_names(5)) + IF (.NOT. ALLOCATED(ait_sol_volume_names)) ALLOCATE(ait_sol_volume_names(1)) + IF (.NOT. ALLOCATED(acc_sol_volume_names)) ALLOCATE(acc_sol_volume_names(1)) + IF (.NOT. ALLOCATED(cor_sol_volume_names)) ALLOCATE(cor_sol_volume_names(1)) + IF (.NOT. ALLOCATED(ait_ins_volume_names)) ALLOCATE(ait_ins_volume_names(1)) + IF (.NOT. ALLOCATED(acc_ins_volume_names)) ALLOCATE(acc_ins_volume_names(1)) + IF (.NOT. ALLOCATED(cor_ins_volume_names)) ALLOCATE(cor_ins_volume_names(1)) + IF (.NOT. ALLOCATED(modal_wtv_names)) ALLOCATE(modal_wtv_names(6)) + IF (.NOT. ALLOCATED(wet_diam_mode_names)) ALLOCATE(wet_diam_mode_names(6)) + + pvol_comp_names = [ 'fldname_pvol_du_acc_ins' , & + 'fldname_pvol_du_cor_ins' ] + + comp_names = [ 'fldname_acc_ins_du' , & + 'fldname_cor_ins_du' ] + + mode_names = [ 'fldname_n_ait_sol' , & + 'fldname_n_acc_sol' , & + 'fldname_n_cor_sol' , & + 'fldname_n_ait_ins' , & + 'fldname_n_acc_ins' , & + 'fldname_n_cor_ins' ] + + rhopar_mode_names = [ 'fldname_rhopar_ait_sol' , & + 'fldname_rhopar_acc_sol' , & + 'fldname_rhopar_cor_sol' , & + 'fldname_rhopar_ait_ins' , & + 'fldname_rhopar_acc_ins' , & + 'fldname_rhopar_cor_ins' ] + + dry_diam_mode_names = [ 'fldname_drydp_ait_sol' , & + 'fldname_drydp_acc_sol' , & + 'fldname_drydp_cor_sol' , & + 'fldname_drydp_ait_ins' , & + 'fldname_drydp_acc_ins' , & + 'fldname_drydp_cor_ins' ] + + modal_volume_names = [ 'fldname_mod_vol_ait_sol' , & + 'fldname_mod_vol_acc_sol' , & + 'fldname_mod_vol_cor_sol' , & + 'fldname_mod_vol_acc_ins' , & + 'fldname_mod_vol_cor_ins' ] + + ait_sol_volume_names = [ 'pvol_wat_ait_sol' ] + + acc_sol_volume_names = [ 'pvol_wat_acc_sol' ] + + cor_sol_volume_names = [ 'pvol_wat_cor_sol' ] + + ait_ins_volume_names = [ 'null' ] + + acc_ins_volume_names = [ 'pvol_du_acc_ins' ] + + cor_ins_volume_names = [ 'pvol_du_cor_ins' ] + + modal_wtv_names = [ 'fldname_pvol_wat_ait_sol' , & + 'fldname_pvol_wat_acc_sol' , & + 'fldname_pvol_wat_cor_sol' , & + 'fldname_pvol_wat_ait_ins' , & + 'fldname_pvol_wat_acc_ins' , & + 'fldname_pvol_wat_cor_ins' ] + + wet_diam_mode_names = [ 'fldname_wetdp_ait_sol' , & + 'fldname_wetdp_acc_sol' , & + 'fldname_wetdp_cor_sol' , & + 'fldname_wetdp_ait_ins' , & + 'fldname_wetdp_acc_ins' , & + 'fldname_wetdp_cor_ins' ] + +CASE (i_sussbcocdu_7mode) + + IF (.NOT. ALLOCATED(pvol_comp_names)) ALLOCATE(pvol_comp_names(17)) + IF (.NOT. ALLOCATED(comp_names)) ALLOCATE(comp_names(17)) + IF (.NOT. ALLOCATED(mode_names)) ALLOCATE(mode_names(6)) + IF (.NOT. ALLOCATED(rhopar_mode_names)) ALLOCATE(rhopar_mode_names(6)) + IF (.NOT. ALLOCATED(dry_diam_mode_names)) ALLOCATE(dry_diam_mode_names(6)) + IF (.NOT. ALLOCATED(modal_volume_names)) ALLOCATE(modal_volume_names(6)) + IF (.NOT. ALLOCATED(ait_sol_volume_names)) ALLOCATE(ait_sol_volume_names(4)) + IF (.NOT. ALLOCATED(acc_sol_volume_names)) ALLOCATE(acc_sol_volume_names(5)) + IF (.NOT. ALLOCATED(cor_sol_volume_names)) ALLOCATE(cor_sol_volume_names(5)) + IF (.NOT. ALLOCATED(ait_ins_volume_names)) ALLOCATE(ait_ins_volume_names(2)) + IF (.NOT. ALLOCATED(acc_ins_volume_names)) ALLOCATE(acc_ins_volume_names(1)) + IF (.NOT. ALLOCATED(cor_ins_volume_names)) ALLOCATE(cor_ins_volume_names(1)) + IF (.NOT. ALLOCATED(modal_wtv_names)) ALLOCATE(modal_wtv_names(6)) + IF (.NOT. ALLOCATED(wet_diam_mode_names)) ALLOCATE(wet_diam_mode_names(6)) + + pvol_comp_names = [ 'fldname_pvol_su_ait_sol' , & + 'fldname_pvol_bc_ait_sol' , & + 'fldname_pvol_om_ait_sol' , & + 'fldname_pvol_su_acc_sol' , & + 'fldname_pvol_bc_acc_sol' , & + 'fldname_pvol_om_acc_sol' , & + 'fldname_pvol_ss_acc_sol' , & + 'fldname_pvol_du_acc_sol' , & + 'fldname_pvol_su_cor_sol' , & + 'fldname_pvol_bc_cor_sol' , & + 'fldname_pvol_om_cor_sol' , & + 'fldname_pvol_ss_cor_sol' , & + 'fldname_pvol_du_cor_sol' , & + 'fldname_pvol_bc_ait_ins' , & + 'fldname_pvol_om_ait_ins' , & + 'fldname_pvol_du_acc_ins' , & + 'fldname_pvol_du_cor_ins' ] + + comp_names = [ 'fldname_ait_sol_su' , & + 'fldname_ait_sol_bc' , & + 'fldname_ait_sol_om' , & + 'fldname_acc_sol_su' , & + 'fldname_acc_sol_bc' , & + 'fldname_acc_sol_om' , & + 'fldname_acc_sol_ss' , & + 'fldname_acc_sol_du' , & + 'fldname_cor_sol_su' , & + 'fldname_cor_sol_bc' , & + 'fldname_cor_sol_om' , & + 'fldname_cor_sol_ss' , & + 'fldname_cor_sol_du' , & + 'fldname_ait_ins_bc' , & + 'fldname_ait_ins_om' , & + 'fldname_acc_ins_du' , & + 'fldname_cor_ins_du' ] + + mode_names = [ 'fldname_n_ait_sol' , & + 'fldname_n_acc_sol' , & + 'fldname_n_cor_sol' , & + 'fldname_n_ait_ins' , & + 'fldname_n_acc_ins' , & + 'fldname_n_cor_ins' ] + + rhopar_mode_names = [ 'fldname_rhopar_ait_sol' , & + 'fldname_rhopar_acc_sol' , & + 'fldname_rhopar_cor_sol' , & + 'fldname_rhopar_ait_ins' , & + 'fldname_rhopar_acc_ins' , & + 'fldname_rhopar_cor_ins' ] + + dry_diam_mode_names = [ 'fldname_drydp_ait_sol' , & + 'fldname_drydp_acc_sol' , & + 'fldname_drydp_cor_sol' , & + 'fldname_drydp_ait_ins' , & + 'fldname_drydp_acc_ins' , & + 'fldname_drydp_cor_ins' ] + + modal_volume_names = [ 'fldname_mod_vol_ait_sol' , & + 'fldname_mod_vol_acc_sol' , & + 'fldname_mod_vol_cor_sol' , & + 'fldname_mod_vol_ait_ins' , & + 'fldname_mod_vol_acc_ins' , & + 'fldname_mod_vol_cor_ins' ] + + ait_sol_volume_names = [ 'pvol_wat_ait_sol' , & + 'pvol_su_ait_sol ' , & + 'pvol_bc_ait_sol ' , & + 'pvol_om_ait_sol ' ] + + acc_sol_volume_names = [ 'pvol_wat_acc_sol' , & + 'pvol_su_acc_sol ' , & + 'pvol_bc_acc_sol ' , & + 'pvol_om_acc_sol ' , & + 'pvol_ss_acc_sol ' ] + + cor_sol_volume_names = [ 'pvol_wat_cor_sol' , & + 'pvol_su_cor_sol ' , & + 'pvol_bc_cor_sol ' , & + 'pvol_om_cor_sol ' , & + 'pvol_ss_cor_sol ' ] + + ait_ins_volume_names = [ 'pvol_bc_ait_ins' , & + 'pvol_om_ait_ins' ] + + acc_ins_volume_names = [ 'pvol_du_acc_ins' ] + + cor_ins_volume_names = [ 'pvol_du_cor_ins' ] + + modal_wtv_names = [ 'fldname_pvol_wat_ait_sol' , & + 'fldname_pvol_wat_acc_sol' , & + 'fldname_pvol_wat_cor_sol' , & + 'fldname_pvol_wat_ait_ins' , & + 'fldname_pvol_wat_acc_ins' , & + 'fldname_pvol_wat_cor_ins' ] + + wet_diam_mode_names = [ 'fldname_wetdp_ait_sol' , & + 'fldname_wetdp_acc_sol' , & + 'fldname_wetdp_cor_sol' , & + 'fldname_wetdp_ait_ins' , & + 'fldname_wetdp_acc_ins' , & + 'fldname_wetdp_cor_ins' ] + +CASE DEFAULT + cmessage='i_mode_setup_in has unrecognised value' + WRITE(umMessage,'(A,I0)') cmessage, i_mode_setup_in + CALL umPrint(umMessage,src=RoutineName) + errcode = 1 + CALL ereport(RoutineName,errcode,cmessage) +END SELECT + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) + +END SUBROUTINE ukca_radaer_lfric_list + +END MODULE ukca_radaer_lfric_list_mod From 8e0f14c241cc5a0ccc95690bab94ca2234e4e0eb Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Mon, 24 Aug 2026 17:10:01 +0100 Subject: [PATCH 09/16] call new ukca module --- .../core/top_level/ukca_radaer_lfric_init_mod.F90 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index 0402339..d5469cb 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -72,12 +72,15 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & ukca_mode_sussbcocdump_8mode, & glomap_variables_type -USE ukca_radaer_lfric_settings_mod, ONLY: & - ukca_radaer_lfric_settings +USE ukca_radaer_lfric_list_mod, ONLY: & + ukca_radaer_lfric_list USE ukca_radaer_lfric_saved_mod, ONLY: & ukca_radaer_lfric +USE ukca_radaer_lfric_settings_mod, ONLY: & + ukca_radaer_lfric_settings + USE umPrintMgr, ONLY: & umPrint, & umMessage @@ -222,6 +225,9 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & n_ukca_mode, & n_ukca_cpnt ) +! Allocate lists used in radaer kernel based on i_mode_setup_in +CALL ukca_radaer_lfric_list( i_mode_setup_in ) + IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_out, zhook_handle) END SUBROUTINE ukca_radaer_lfric_init From d98da23b7bcb6913d2fc0f1b0b7ba30120d428a3 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 11:40:43 +0100 Subject: [PATCH 10/16] Replace hard coded settings with calculated values --- .../top_level/ukca_radaer_lfric_api_mod.F90 | 68 +++++-------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 index f8bee6b..73cb662 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 @@ -90,6 +90,8 @@ SUBROUTINE ukca_radaer_lfric_interface( & aod_ukca_all_modes, & aaod_ukca_all_modes ) +USE ukca_config_specification_mod, ONLY: glomap_variables_radaer + USE ukca_mode_setup, ONLY: mode_ait_sol, mode_acc_sol, & mode_cor_sol, mode_ait_insol, & mode_acc_insol, mode_cor_insol, & @@ -196,33 +198,33 @@ SUBROUTINE ukca_radaer_lfric_interface( & ! Modal mass-mixing ratios REAL, INTENT(IN OUT) :: ukca_mode_mix_ratio( npd_profile, npd_layer, & - n_radaer_mode ) + n_radaer_mode ) ! Band-averaged modal optical properties REAL, INTENT(IN OUT) :: aer_lw_absorption( npd_profile, npd_layer, & - n_radaer_mode, n_lw_band ) + n_radaer_mode, n_lw_band ) REAL, INTENT(IN OUT) :: aer_sw_absorption( npd_profile, npd_layer, & - n_radaer_mode, n_sw_band ) + n_radaer_mode, n_sw_band ) REAL, INTENT(IN OUT) :: aer_lw_scattering( npd_profile, npd_layer, & - n_radaer_mode, n_lw_band ) + n_radaer_mode, n_lw_band ) REAL, INTENT(IN OUT) :: aer_sw_scattering( npd_profile, npd_layer, & - n_radaer_mode, n_sw_band ) + n_radaer_mode, n_sw_band ) REAL, INTENT(IN OUT) :: aer_lw_asymmetry( npd_profile, npd_layer, & - n_radaer_mode, n_lw_band ) + n_radaer_mode, n_lw_band ) REAL, INTENT(IN OUT) :: aer_sw_asymmetry( npd_profile, npd_layer, & - n_radaer_mode, n_sw_band ) + n_radaer_mode, n_sw_band ) ! Aerosol Optical Depth diagnostics REAL, INTENT(IN OUT) :: aod_ukca_all_modes( npd_profile, npd_ukca_aod_wavel, & - n_ukca_mode ) + n_ukca_mode ) REAL, INTENT(IN OUT) :: aaod_ukca_all_modes(npd_profile, npd_ukca_aod_wavel, & - n_ukca_mode ) + n_ukca_mode ) ! Local variables @@ -243,8 +245,8 @@ SUBROUTINE ukca_radaer_lfric_interface( & LOGICAL, PARAMETER :: l_sustrat = .TRUE. ! Make this a namelist option later ! l_sustrat=.true. for ga9 -LOGICAL, PARAMETER :: l_cornarrow_ins = .FALSE. ! Make this a namelist option later +LOGICAL, PARAMETER :: l_cornarrow_ins = .FALSE. ! ----------------------------------------------------------------- @@ -259,14 +261,11 @@ SUBROUTINE ukca_radaer_lfric_interface( & LOGICAL, PARAMETER :: soluble_wanted = .TRUE. LOGICAL, PARAMETER :: soluble_unwanted = .FALSE. +! Local pointers to glomap_variables_radaer INTEGER :: i_cpnt_index( ncp_max, nmodes ) - INTEGER :: i_mode_type( nmodes ) - INTEGER :: n_cpnt_in_mode( nmodes ) - LOGICAL :: l_soluble( nmodes ) - INTEGER :: i_cpnt_type( ncp_max_x_nmodes ) ! ----------------------------------------------------------------- @@ -280,42 +279,11 @@ SUBROUTINE ukca_radaer_lfric_interface( & !----------------------------------------------------------------------- - -! Note that these hard coded values are calculated in UM module -! ukca_radaer_init-ukca.F90 -! Arrays with modes start on 2nd mode ( Aitkin Solvent ) -! Radaer expects data to be structured in this way. - -! No nucleation mode -l_soluble(1:nmodes) = [.TRUE., .TRUE., .TRUE., .FALSE., & - .FALSE.,.FALSE.,.FALSE.,.FALSE.] - -! No nucleation mode -n_cpnt_in_mode(1:nmodes) = [ 3, 5, 5, 2, 1, 1, -1, -1 ] - -! No nucleation mode -i_mode_type(1:nmodes) = [ 1, 2, 3, 1, 2, 3, -1, -1 ] - -! No nucleation mode -i_cpnt_index(cp_su, 1:nmodes)=[ 1, 4, 9, 14, 16, 17, -1, -1 ] -i_cpnt_index(cp_bc, 1:nmodes)=[ 2, 5, 10, 15, -1, -1, -1, -1 ] -i_cpnt_index(cp_oc, 1:nmodes)=[ 3, 6, 11, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_cl, 1:nmodes)=[ -1, 7, 12, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_du, 1:nmodes)=[ -1, 8, 13, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_so, 1:nmodes)=[ -1, -1, -1, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_no3,1:nmodes)=[ -1, -1, -1, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_nn, 1:nmodes)=[ -1, -1, -1, -1, -1, -1, -1, -1 ] -i_cpnt_index(cp_nh4,1:nmodes)=[ -1, -1, -1, -1, -1, -1, -1, -1 ] - -i_cpnt_type(1:ncp_max_x_nmodes) = & - [ 1, 2, 3, 1, 2, 3, 4, 5, 1, & - 2, 3, 4, 5, 2, 3, 5, 5, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1, & - -1, -1, -1, -1, -1, -1, -1, -1, -1 ] +i_cpnt_index => glomap_variables_radaer%i_cpnt_index +i_cpnt_type => glomap_variables_radaer%i_cpnt_type +i_mode_type => glomap_variables_radaer%i_mode_type +n_cpnt_in_mode => glomap_variables_radaer%n_cpnt_in_mode +l_soluble => glomap_variables_radaer%l_soluble !---------------------------------------------------------------------- From fae90334619cedd7fdbf26337ab8ceb5998fb831 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 11:48:16 +0100 Subject: [PATCH 11/16] tidy --- src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index d5469cb..7b74790 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -9,10 +9,12 @@ ! Procedure: ! 1) CALL the relevant mode setup subroutine from ukca_mode_setup ! -! 2) CALL +! 2) CALL ukca_radaer_lfric_settings to obtain runtime values ! -! This file belongs in section: UKCA +! 3) CALL ukca_radaer_lfric_list to allocate lists for radaer kernel ! +! This file belongs in section: UKCA + MODULE ukca_radaer_lfric_init_mod IMPLICIT NONE From 3d281a4923eef26d2c841e401b2e2c09211f1d2b Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 12:01:53 +0100 Subject: [PATCH 12/16] l_sustrat is a namelist option now --- .../core/top_level/ukca_radaer_lfric_api_mod.F90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 index 73cb662..f5b9a9e 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 @@ -55,6 +55,8 @@ SUBROUTINE ukca_radaer_lfric_interface( & ukca_modal_wtv, & ! Logical to describe orientation l_inverted, & + ! Logical to account for optical properties of sulphate in atmosphere + l_sustrat, & ! Control option for prescribed single scattering albedo array i_ukca_radaer_prescribe_ssa, & ! Model level of the tropopause (input) @@ -160,6 +162,9 @@ SUBROUTINE ukca_radaer_lfric_interface( & ! Logical to describe orientation LOGICAL, INTENT(IN) :: l_inverted +! Logical to account for optical properties of sulphate in atmosphere +LOGICAL, INTENT(IN) :: l_sustrat + ! When > 0, use a prescribed single scattering albedo field INTEGER, INTENT(IN) :: i_ukca_radaer_prescribe_ssa @@ -241,9 +246,8 @@ SUBROUTINE ukca_radaer_lfric_interface( & ! ----------------------------------------------------------------- -LOGICAL, PARAMETER :: l_nitrate = .FALSE. ! Make this a namelist option later -LOGICAL, PARAMETER :: l_sustrat = .TRUE. ! Make this a namelist option later - ! l_sustrat=.true. for ga9 +! Make this a namelist option later +LOGICAL, PARAMETER :: l_nitrate = .FALSE. ! Make this a namelist option later LOGICAL, PARAMETER :: l_cornarrow_ins = .FALSE. From d30ba8e4fea0508d2c6186ecc9d783ab2c967693 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:22:42 +0100 Subject: [PATCH 13/16] pointers were looking in wrong structure --- .../top_level/ukca_radaer_lfric_api_mod.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 index f5b9a9e..8562305 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 @@ -92,8 +92,6 @@ SUBROUTINE ukca_radaer_lfric_interface( & aod_ukca_all_modes, & aaod_ukca_all_modes ) -USE ukca_config_specification_mod, ONLY: glomap_variables_radaer - USE ukca_mode_setup, ONLY: mode_ait_sol, mode_acc_sol, & mode_cor_sol, mode_ait_insol, & mode_acc_insol, mode_cor_insol, & @@ -110,6 +108,8 @@ SUBROUTINE ukca_radaer_lfric_interface( & USE ukca_radaer_compute_aod_mod, ONLY: ukca_radaer_compute_aod +USE ukca_radaer_lfric_saved_mod, ONLY: ukca_radaer_lfric + USE ukca_radaer_prepare_mod, ONLY: ukca_radaer_prepare USE parkind1, ONLY: jpim, jprb @@ -265,12 +265,12 @@ SUBROUTINE ukca_radaer_lfric_interface( & LOGICAL, PARAMETER :: soluble_wanted = .TRUE. LOGICAL, PARAMETER :: soluble_unwanted = .FALSE. -! Local pointers to glomap_variables_radaer +! Local pointers to ukca_radaer_lfric INTEGER :: i_cpnt_index( ncp_max, nmodes ) INTEGER :: i_mode_type( nmodes ) INTEGER :: n_cpnt_in_mode( nmodes ) LOGICAL :: l_soluble( nmodes ) -INTEGER :: i_cpnt_type( ncp_max_x_nmodes ) +INTEGER :: i_cpnt_type( ncp_max_x_nmodes ) ! ----------------------------------------------------------------- @@ -283,11 +283,11 @@ SUBROUTINE ukca_radaer_lfric_interface( & !----------------------------------------------------------------------- -i_cpnt_index => glomap_variables_radaer%i_cpnt_index -i_cpnt_type => glomap_variables_radaer%i_cpnt_type -i_mode_type => glomap_variables_radaer%i_mode_type -n_cpnt_in_mode => glomap_variables_radaer%n_cpnt_in_mode -l_soluble => glomap_variables_radaer%l_soluble +i_cpnt_index => ukca_radaer_lfric%i_cpnt_index +i_cpnt_type => ukca_radaer_lfric%i_cpnt_type +i_mode_type => ukca_radaer_lfric%i_mode_type +n_cpnt_in_mode => ukca_radaer_lfric%n_cpnt_in_mode +l_soluble => ukca_radaer_lfric%l_soluble !---------------------------------------------------------------------- From ff8947f1c11176e1e20d629b6c4a2c860eaea2c9 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 14:39:07 +0100 Subject: [PATCH 14/16] Dont need pointers here --- .../top_level/ukca_radaer_lfric_api_mod.F90 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 index 8562305..0133ded 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_api_mod.F90 @@ -99,6 +99,7 @@ SUBROUTINE ukca_radaer_lfric_interface( & ip_ukca_mode_accum, & ip_ukca_mode_coarse, & i_ukca_bc_tuned, & + i_ukca_tune_bc_off, & cp_su, cp_bc, cp_oc, & cp_cl, cp_du, cp_so, & cp_no3, cp_nn, cp_nh4, & @@ -256,7 +257,7 @@ SUBROUTINE ukca_radaer_lfric_interface( & ! Maxwell-Garnett mixing approach logical control switches INTEGER, PARAMETER :: i_ukca_tune_bc = i_ukca_bc_tuned -INTEGER, PARAMETER :: i_glomap_clim_tune_bc = 0 ! No tuning +INTEGER, PARAMETER :: i_glomap_clim_tune_bc = i_ukca_tune_bc_off ! Spectral information INTEGER, PARAMETER :: ip_infra_red = 2 @@ -265,12 +266,12 @@ SUBROUTINE ukca_radaer_lfric_interface( & LOGICAL, PARAMETER :: soluble_wanted = .TRUE. LOGICAL, PARAMETER :: soluble_unwanted = .FALSE. -! Local pointers to ukca_radaer_lfric +! Local copies from ukca_radaer_lfric INTEGER :: i_cpnt_index( ncp_max, nmodes ) +INTEGER :: i_cpnt_type( ncp_max_x_nmodes ) INTEGER :: i_mode_type( nmodes ) INTEGER :: n_cpnt_in_mode( nmodes ) LOGICAL :: l_soluble( nmodes ) -INTEGER :: i_cpnt_type( ncp_max_x_nmodes ) ! ----------------------------------------------------------------- @@ -283,11 +284,12 @@ SUBROUTINE ukca_radaer_lfric_interface( & !----------------------------------------------------------------------- -i_cpnt_index => ukca_radaer_lfric%i_cpnt_index -i_cpnt_type => ukca_radaer_lfric%i_cpnt_type -i_mode_type => ukca_radaer_lfric%i_mode_type -n_cpnt_in_mode => ukca_radaer_lfric%n_cpnt_in_mode -l_soluble => ukca_radaer_lfric%l_soluble +! Local copies to make the code easier to read +i_cpnt_index = ukca_radaer_lfric%i_cpnt_index +i_cpnt_type = ukca_radaer_lfric%i_cpnt_type +i_mode_type = ukca_radaer_lfric%i_mode_type +n_cpnt_in_mode = ukca_radaer_lfric%n_cpnt_in_mode +l_soluble = ukca_radaer_lfric%l_soluble !---------------------------------------------------------------------- From 558a140eae9d526ef0fd80849f754820806d5335 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:13:00 +0100 Subject: [PATCH 15/16] Applied code styling --- src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 | 6 +++--- src/science/radaer/ukca_radaer_lfric_settings_mod.F90 | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 index 7b74790..aedb034 100644 --- a/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 +++ b/src/control/core/top_level/ukca_radaer_lfric_init_mod.F90 @@ -103,11 +103,11 @@ SUBROUTINE ukca_radaer_lfric_init( i_mode_setup_in, & ! Local variables ! We are calling this module because radaer is on. Forced true -LOGICAL, PARAMETER :: l_radaer_in = .true. +LOGICAL, PARAMETER :: l_radaer_in = .TRUE. ! Force existing temporary logicals to always be true from LFRic -LOGICAL, PARAMETER :: l_fix_nacl_density_in = .true. -LOGICAL, PARAMETER :: l_fix_ukca_hygroscopicities_in = .true. +LOGICAL, PARAMETER :: l_fix_nacl_density_in = .TRUE. +LOGICAL, PARAMETER :: l_fix_ukca_hygroscopicities_in = .TRUE. INTEGER :: errcode ! error code CHARACTER(LEN=errormessagelength) :: cmessage ! error message diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 index 093f7a7..d043219 100644 --- a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -140,7 +140,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & DO i = 1, nmodes IF (mode(i)) THEN - + this_name = mode_names(i) ! Get the mode type. Since there is no direct information, @@ -248,7 +248,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & CALL ereport(RoutineName,ierr,cmessage) END SELECT - + END IF END DO ! j From a1ab8e671965d97df660a0d3dd948120d5226d32 Mon Sep 17 00:00:00 2001 From: Alan J Hewitt <40797340+alanjhewitt@users.noreply.github.com> Date: Thu, 27 Aug 2026 15:11:54 +0100 Subject: [PATCH 16/16] Scitech - Mohit suggested changes --- src/control/core/interface/ukca_api_mod.F90 | 5 +++++ src/science/radaer/ukca_radaer_lfric_list_mod.F90 | 8 ++++---- src/science/radaer/ukca_radaer_lfric_saved_mod.F90 | 8 ++++---- src/science/radaer/ukca_radaer_lfric_settings_mod.F90 | 2 +- src/science/radaer/ukca_radaer_lfric_struct_mod.F90 | 8 ++++---- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/control/core/interface/ukca_api_mod.F90 b/src/control/core/interface/ukca_api_mod.F90 index 9c54fa2..f012868 100644 --- a/src/control/core/interface/ukca_api_mod.F90 +++ b/src/control/core/interface/ukca_api_mod.F90 @@ -53,6 +53,8 @@ MODULE ukca_api_mod ukca_chem_strat => i_ukca_chem_strat, & ukca_chem_offline => i_ukca_chem_offline, & ukca_chem_cristrat => i_ukca_chem_cristrat, & + ukca_i_sussbcocdu_7mode => i_sussbcocdu_7mode, & + ukca_i_du_2mode => i_du_2mode, & ukca_age_reset_by_level => i_age_reset_by_level, & ukca_age_reset_by_height => i_age_reset_by_height, & ukca_strat_lbc_off => i_strat_lbc_off, & @@ -168,6 +170,9 @@ MODULE ukca_api_mod ukca_zhg_urban => zhg_urban, & ukca_zhg_ned_leaf => zhg_ned_leaf, & ukca_zhg_brd_leaf => zhg_brd_leaf +USE ukca_mode_setup, ONLY: & + ukca_i_ukca_bc_tuned => i_ukca_bc_tuned, & + ukca_i_ukca_tune_bc_off => i_ukca_tune_bc_off IMPLICIT NONE diff --git a/src/science/radaer/ukca_radaer_lfric_list_mod.F90 b/src/science/radaer/ukca_radaer_lfric_list_mod.F90 index 32d59a3..b32b526 100644 --- a/src/science/radaer/ukca_radaer_lfric_list_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_list_mod.F90 @@ -1,8 +1,8 @@ -! *****************************COPYRIGHT******************************* +! ----------------------------------------------------------------------------- ! (C) Crown copyright Met Office. All rights reserved. -! For further details please refer to the file COPYRIGHT.txt -! which you should have received as part of this distribution. -! *****************************COPYRIGHT******************************* +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +! ----------------------------------------------------------------------------- ! ! Purpose: ! Allocatable lists used in radaer kernel are set here diff --git a/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 b/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 index 66e465b..3a07901 100644 --- a/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_saved_mod.F90 @@ -1,8 +1,8 @@ -! *****************************COPYRIGHT******************************* +! ----------------------------------------------------------------------------- ! (C) Crown copyright Met Office. All rights reserved. -! For further details please refer to the file COPYRIGHT.txt -! which you should have received as part of this distribution. -! *****************************COPYRIGHT******************************* +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +! ----------------------------------------------------------------------------- ! ! Purpose: ! To save structure ukca_radaer_lfric diff --git a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 index d043219..3e82af3 100644 --- a/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_settings_mod.F90 @@ -114,7 +114,7 @@ SUBROUTINE ukca_radaer_lfric_settings( l_ukca_radaer_sustrat, & INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0 INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1 REAL(KIND=jprb) :: zhook_handle -CHARACTER(LEN=*), PARAMETER :: RoutineName='UKCA_RADAER_LFRIC_INIT' +CHARACTER(LEN=*), PARAMETER :: RoutineName='UKCA_RADAER_LFRIC_SETTINGS' IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName, zhook_in, zhook_handle) diff --git a/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 b/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 index b8af00b..bf1840e 100644 --- a/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 +++ b/src/science/radaer/ukca_radaer_lfric_struct_mod.F90 @@ -1,8 +1,8 @@ -! *****************************COPYRIGHT******************************* +! ----------------------------------------------------------------------------- ! (C) Crown copyright Met Office. All rights reserved. -! For further details please refer to the file COPYRIGHT.txt -! which you should have received as part of this distribution. -! *****************************COPYRIGHT******************************* +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +! ----------------------------------------------------------------------------- ! ! Purpose: ! Defines maximum dimensions