diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 5f7f9a905..60e64e4c5 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -46,6 +46,7 @@
| theabro | Nathan Luke Abraham | NCAS & University of Cambridge | 2026-04-15 |
| ss421 | Steven Sandbach | Met Office | 2026-04-20 |
| MichaelWhitall | Michael Whitall | Met Office | 2026-04-22 |
+| DanCopsey | Dan Copsey | Met Office | 2026-05-14 |
| marcstring | Marc Stringer | NCAS, Reading University | 2026-05-06 |
| cameronbateman-mo | Cameron Bateman | Met Office | 2026-05-28 |
| davelee2804 | David Lee | Bureau of Meteorology, Australia | 2026-06-02 |
diff --git a/applications/lfric_atm/example/configuration.nml b/applications/lfric_atm/example/configuration.nml
index 7f330ba60..8033061cc 100644
--- a/applications/lfric_atm/example/configuration.nml
+++ b/applications/lfric_atm/example/configuration.nml
@@ -336,6 +336,7 @@ write_minmax_tseries=.false.,
/
&jules_hydrology
l_hydrology=.true.,
+l_inland=.false.,
l_var_rainfrac=.true.,
/
&jules_model_environment_lfric
diff --git a/applications/lfric_atm/metadata/field_def_diags.xml b/applications/lfric_atm/metadata/field_def_diags.xml
index 36f092c6d..cbe51e1b1 100644
--- a/applications/lfric_atm/metadata/field_def_diags.xml
+++ b/applications/lfric_atm/metadata/field_def_diags.xml
@@ -638,6 +638,7 @@
+
diff --git a/applications/lfric_atm/metadata/lfric_dictionary.xml b/applications/lfric_atm/metadata/lfric_dictionary.xml
index 3ab44ca0b..739df77f9 100644
--- a/applications/lfric_atm/metadata/lfric_dictionary.xml
+++ b/applications/lfric_atm/metadata/lfric_dictionary.xml
@@ -399,5 +399,6 @@
+
diff --git a/applications/lfric_coupled/example/configuration.nml b/applications/lfric_coupled/example/configuration.nml
index 0648d72ae..616aa93b3 100644
--- a/applications/lfric_coupled/example/configuration.nml
+++ b/applications/lfric_coupled/example/configuration.nml
@@ -168,6 +168,7 @@ write_minmax_tseries=.false.,
/
&jules_hydrology
l_hydrology=.true.,
+l_inland=.false.,
l_var_rainfrac=.false.
/
&jules_model_environment_lfric
diff --git a/dependencies.yaml b/dependencies.yaml
index 6e03afa85..51cb4bda9 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -22,8 +22,8 @@ casim:
ref: 2026.03.2
jules:
- source: git@github.com:MetOffice/jules.git
- ref: 3647a42962613d1f50d02d7660c86dece056f87c
+ source: git@github.com:DanCopsey/jules.git
+ ref: inland_flow
lfric_apps:
source:
diff --git a/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90 b/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90
index 6149953e4..92036846a 100644
--- a/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90
+++ b/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90
@@ -159,6 +159,13 @@ module coupler_update_prognostics_mod
'Ocean surface v from coupler', fld )
call depository%get_field('sea_v_current', fld_ptr1)
call invoke(setval_x(fld_ptr1, fld))
+ case ("lf_inland_flow")
+ call log_field_minmax( LOG_LEVEL_DEBUG, &
+ 'Inland basin flow from coupler', fld)
+ call depository%get_field('inland_basin_flow', fld_ptr1)
+ call invoke(setval_X( fld_ptr1, fld ))
+ fld_ptr1 => null()
+
case default
write(log_scratch_space, '(3A)' ) &
"PROBLEM coupler_update_prognostics variable ", &
diff --git a/interfaces/coupled_interface/source/coupler_mod.F90 b/interfaces/coupled_interface/source/coupler_mod.F90
index 6791d3a78..b75cdc651 100644
--- a/interfaces/coupled_interface/source/coupler_mod.F90
+++ b/interfaces/coupled_interface/source/coupler_mod.F90
@@ -296,6 +296,10 @@ subroutine create_coupling_fields( mesh, &
call add_cpl_field(depository, prognostic_fields, &
'lf_svnocean', vector_space, checkpoint_restart_flag)
+ ! From TRIP river model
+ call add_cpl_field(depository, prognostic_fields, &
+ 'lf_inland_flow', vector_space, checkpoint_restart_flag)
+
end subroutine create_coupling_fields
diff --git a/interfaces/jules_interface/build/extract.yaml b/interfaces/jules_interface/build/extract.yaml
index b57f5c3ff..75f0f1ef5 100644
--- a/interfaces/jules_interface/build/extract.yaml
+++ b/interfaces/jules_interface/build/extract.yaml
@@ -67,6 +67,7 @@ jules:
- src/control/shared/wtrac_extra_mod.F90
- src/initialisation/shared/calc_urban_aero_fields_mod.F90
- src/initialisation/shared/check_compatible_options_mod.F90
+ - src/initialisation/shared/check_compatible_options_rivers_mod.F90
- src/initialisation/shared/freeze_soil.F90
- src/initialisation/shared/wtrac_check_options_mod.F90
- src/science/deposition/deposition_check_species_mod.F90
diff --git a/interfaces/jules_interface/rose-meta/jules-lsm/versions.py b/interfaces/jules_interface/rose-meta/jules-lsm/versions.py
index 00aaf3d3e..7d7d2592f 100644
--- a/interfaces/jules_interface/rose-meta/jules-lsm/versions.py
+++ b/interfaces/jules_interface/rose-meta/jules-lsm/versions.py
@@ -18,7 +18,6 @@ def __repr__(self):
__str__ = __repr__
-
"""
Copy this template and complete to add your macro
class vnXX_txxx(MacroUpgrade):
@@ -391,3 +390,14 @@ def upgrade(self, config, meta_config=None):
)
return config, self.reports
+
+class vn31_t401(MacroUpgrade):
+ """Upgrade macro for ticket #401 by Dan Copsey."""
+
+ BEFORE_TAG = "vn3.1_t205"
+ AFTER_TAG = "vn3.1_t401"
+
+ def upgrade(self, config, meta_config=None):
+ # Add settings
+ self.add_setting(config, ["namelist:jules_hydrology", "l_inland"], ".false.")
+ return config, self.reports
diff --git a/interfaces/jules_interface/source/algorithm/init_soil_fields_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/init_soil_fields_alg_mod.x90
index c370e62b0..71bcb9201 100644
--- a/interfaces/jules_interface/source/algorithm/init_soil_fields_alg_mod.x90
+++ b/interfaces/jules_interface/source/algorithm/init_soil_fields_alg_mod.x90
@@ -69,6 +69,7 @@ contains
type( field_type ), pointer :: wetness_under_soil => null()
type( field_type ), pointer :: surface_runoff => null()
type( field_type ), pointer :: sub_surface_runoff => null()
+ type( field_type ), pointer :: inland_basin_flow => null()
call soil_fields%get_field('soil_albedo', soil_albedo)
call soil_fields%get_field('soil_moist_wilt', soil_moist_wilt)
@@ -95,6 +96,7 @@ contains
call soil_fields%get_field('wetness_under_soil', wetness_under_soil)
call soil_fields%get_field('surface_runoff', surface_runoff)
call soil_fields%get_field('sub_surface_runoff', sub_surface_runoff)
+ call soil_fields%get_field('inland_basin_flow',inland_basin_flow)
! Set soil ancillaries to fixed values for if no ancil is read
call invoke( setval_c(soil_albedo, 0.11_r_def), &
@@ -114,6 +116,7 @@ contains
setval_c(c_wet_frac, 1.0_r_def), &
setval_c(surface_runoff, 0.0_r_def), &
setval_c(sub_surface_runoff, 0.0_r_def), &
+ setval_c(inland_basin_flow, 0.0_r_def ), &
! Set soil prognostics when no values are provided by um2lfric
setval_c(soil_sat_frac, 1.0_r_def), &
setval_c(water_table, 1.0_r_def), &
diff --git a/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90
index 68241339a..c85bf2d92 100644
--- a/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90
+++ b/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90
@@ -91,6 +91,7 @@ contains
type( field_type ), pointer :: snowice_melt => null()
type( field_type ), pointer :: snowice_sublimation => null()
type( field_type ), pointer :: urbztm => null()
+ type( field_type ), pointer :: inland_basin_flow => null()
! Sea ice fields
type( field_type ), pointer :: sea_ice_thickness => null()
@@ -205,6 +206,7 @@ contains
call soil_fields%get_field('wetness_under_soil', wetness_under_soil)
call soil_fields%get_field('surface_runoff', surface_runoff)
call soil_fields%get_field('sub_surface_runoff', sub_surface_runoff)
+ call soil_fields%get_field('inland_basin_flow', inland_basin_flow)
! Snow fields
call snow_fields%get_field('tile_snow_mass', tile_snow_mass)
@@ -247,6 +249,7 @@ contains
mean_topog_index, a_sat_frac, c_sat_frac, &
a_wet_frac, c_wet_frac, tile_temperature, &
net_prim_prod, snowice_sublimation, surf_heat_flux, &
+ inland_basin_flow, &
canopy_evap, water_extraction, &
thermal_cond_wet_soil, urbztm, &
soil_temperature, soil_moisture, &
@@ -298,6 +301,9 @@ contains
sea_ice_pensolar, melt_pond_fraction, &
melt_pond_depth)
+ ! Output extra coupling diagnostics
+ call inland_basin_flow%write_field('soil__inland_basin_flow')
+
end if
end subroutine jules_extra_alg
diff --git a/interfaces/jules_interface/source/kernel/jules_extra_kernel_mod.F90 b/interfaces/jules_interface/source/kernel/jules_extra_kernel_mod.F90
index 14885cc8b..171092e90 100644
--- a/interfaces/jules_interface/source/kernel/jules_extra_kernel_mod.F90
+++ b/interfaces/jules_interface/source/kernel/jules_extra_kernel_mod.F90
@@ -32,7 +32,7 @@ module jules_extra_kernel_mod
!>
type, public, extends(kernel_type) :: jules_extra_kernel_type
private
- type(arg_type) :: meta_args(58) = (/ &
+ type(arg_type) :: meta_args(59) = (/ &
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! ls_rain
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! conv_rain
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! ls_snow
@@ -62,6 +62,7 @@ module jules_extra_kernel_mod
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! net_prim_prod
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_2), & ! snowice_sublimation
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_2), & ! surf_heat_flux
+ arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! inland_basin_flow
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_2), & ! canopy_evap
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_4), & ! water_extraction
arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! thermal_cond_wet_soil
@@ -137,6 +138,7 @@ module jules_extra_kernel_mod
!> @param[in] net_prim_prod Net Primary Productivity (kg m-2 s-1)
!> @param[in] snowice_sublimation Sublimation of snow and ice (kg m-2 s-1)
!> @param[in] surf_heat_flux Surface heat flux (W m-2)
+ !> @param[in] inland_basin_flow Inland flow of water from rivers to soil (kg m-2 s-1)
!> @param[in] canopy_evap Canopy evaporation from land tiles (kg m-2 s-1)
!> @param[in] water_extraction Extraction of water from each soil layer (kg m-2 s-1)
!> @param[in] thermal_cond_wet_soil Thermal conductivity of soil (W m-1 K-1)
@@ -212,6 +214,7 @@ subroutine jules_extra_code( &
net_prim_prod, &
snowice_sublimation, &
surf_heat_flux, &
+ inland_basin_flow, &
canopy_evap, &
water_extraction, &
thermal_cond_wet_soil, &
@@ -421,6 +424,7 @@ subroutine jules_extra_code( &
real(kind=r_def), intent(in) :: net_prim_prod(undf_2d)
real(kind=r_def), intent(in) :: thermal_cond_wet_soil(undf_2d)
real(kind=r_def), intent(in) :: urbztm(undf_2d)
+ real(kind=r_def), intent(in) :: inland_basin_flow(undf_2d)
real(kind=r_def), intent(inout) :: canopy_water(undf_tile)
real(kind=r_def), intent(inout) :: tile_snow_mass(undf_tile)
@@ -902,6 +906,7 @@ subroutine jules_extra_code( &
allocate(fsat_soilt(land_pts, nsoilt))
allocate(zw_soilt(land_pts, nsoilt))
allocate(sthzw_soilt(land_pts, nsoilt))
+ allocate(inlandout_atm_gb(land_pts))
do l = 1, land_pts
! Soil saturated fraction
fsat_soilt(l,1) = real(soil_sat_frac(map_2d(1,ainfo%land_index(l))), r_um)
@@ -909,6 +914,8 @@ subroutine jules_extra_code( &
zw_soilt(l,1) = real(water_table(map_2d(1,ainfo%land_index(l))), r_um)
! Soil wetness below soil column
sthzw_soilt(l,1) = real(wetness_under_soil(map_2d(1,ainfo%land_index(l))), r_um)
+ ! Inland basin flow
+ inlandout_atm_gb(l) = real(inland_basin_flow(map_2d(1,ainfo%land_index(l))), r_um)
end do
!----------------------------------------------------------------------------
@@ -929,7 +936,6 @@ subroutine jules_extra_code( &
allocate(dhf_surf_minus_soil(land_pts))
allocate(tot_surf_runoff(land_pts))
allocate(tot_sub_runoff(land_pts))
- allocate(inlandout_atm_gb(land_pts))
call surf_couple_extra( &
!Driving data and associated INTENT(IN)
@@ -1049,8 +1055,10 @@ subroutine jules_extra_code( &
! Wetness below soil column
wetness_under_soil(map_2d(1,ainfo%land_index(l))) = real(sthzw_soilt(l,1), r_def)
! River runoffs
- surface_runoff(map_2d(1,ainfo%land_index(l))) = real(fluxes%surf_roff_gb(l), r_def)
- sub_surface_runoff(map_2d(1,ainfo%land_index(l))) = real(fluxes%sub_surf_roff_gb(l), r_def)
+ surface_runoff(map_2d(1,ainfo%land_index(l))) = real(fluxes%surf_roff_gb(l), r_def) * &
+ flandg(ainfo%land_index(l), 1)
+ sub_surface_runoff(map_2d(1,ainfo%land_index(l))) = real(fluxes%sub_surf_roff_gb(l), r_def) * &
+ flandg(ainfo%land_index(l), 1)
end do
if (.not. associated(soil_moisture_content, empty_real_data) ) then
diff --git a/interfaces/jules_interface/source/support/jules_physics_init_mod.f90 b/interfaces/jules_interface/source/support/jules_physics_init_mod.f90
index 9736bfddd..fbb90ca54 100644
--- a/interfaces/jules_interface/source/support/jules_physics_init_mod.f90
+++ b/interfaces/jules_interface/source/support/jules_physics_init_mod.f90
@@ -108,7 +108,7 @@ subroutine jules_physics_init(config)
use c_z0h_z0m, only: c_z0h_z0m_print, c_z0h_z0m_check, z0h_z0m
use jules_hydrology_mod, only: check_jules_hydrology, &
print_nlist_jules_hydrology, l_hydrology, l_top, l_var_rainfrac, &
- nfita, ti_max, ti_wetl, zw_max
+ nfita, ti_max, ti_wetl, zw_max, l_inland
use jules_irrig_mod, only: l_irrig_dmd
use jules_radiation_mod, only: i_sea_alb_method, &
l_embedded_snow, l_mask_snow_orog, &
@@ -197,6 +197,7 @@ subroutine jules_physics_init(config)
! JULES hydrology settings - contained in module jules_hydrology
! ----------------------------------------------------------------
l_hydrology = config%jules_hydrology%l_hydrology()
+ l_inland = config%jules_hydrology%l_inland()
l_top = .true.
l_var_rainfrac = config%jules_hydrology%l_var_rainfrac()
nfita = 30
diff --git a/rose-stem/app/lfric_coupled_rivers/rose-app.conf b/rose-stem/app/lfric_coupled_rivers/rose-app.conf
index 35e9afab0..1f49936e0 100644
--- a/rose-stem/app/lfric_coupled_rivers/rose-app.conf
+++ b/rose-stem/app/lfric_coupled_rivers/rose-app.conf
@@ -1,4 +1,4 @@
-meta=jules-standalone/vn7.9_t1392
+meta=jules-standalone/vn8.1_t34
[command]
default=rose-run jules.exe
@@ -67,6 +67,7 @@ y_dim_name='latitude'
[namelist:jules_land_frac]
file='$RIV_NUMBER_ANCILLARY/river_mask_fracarea_ancil.nc'
+l_use_land_fraction=.false.
land_frac_name='lsmask'
[namelist:jules_latlon]
@@ -128,7 +129,6 @@ prnt_writers=1
!!cland=0.2
!!criver=0.62
i_river_vn=3
-!!l_inland=.false.
!!l_riv_overbank=.false.
l_rivers=.true.
!!lake_water_conserve_method=1
diff --git a/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt
index 879448cab..fd63bdf5f 100644
--- a/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt
+++ b/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt
@@ -1,9 +1,9 @@
-Inner product checksum rho = 411B5409D804A878
-Inner product checksum theta = 42735B1D0D01AE5C
-Inner product checksum u = 456F4385CD1ACE02
-Inner product checksum mr1 = 4036846D52D0A856
-Inner product checksum mr2 = 3F3FA19DE10519BC
-Inner product checksum mr3 = 3F00ED1994A93DC6
-Inner product checksum mr4 = 3F36893E43F07BCC
+Inner product checksum rho = 411B540A96B37E4F
+Inner product checksum theta = 42735B1DC4620029
+Inner product checksum u = 456F4479A8EB9CF2
+Inner product checksum mr1 = 4036851FACCD4D6A
+Inner product checksum mr2 = 3F3FA5B17FDDA974
+Inner product checksum mr3 = 3F00D65E266F8C62
+Inner product checksum mr4 = 3F368FE5FDCA5515
Inner product checksum mr5 = 0
Inner product checksum mr6 = 0
diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90
index 6e6545f72..e53228520 100644
--- a/science/gungho/source/driver/create_physics_prognostics_mod.F90
+++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90
@@ -941,6 +941,7 @@ subroutine process_physics_prognostics(processor)
empty = (.not. l_urban2t) ))
call processor%apply(make_spec('urbemisc', main%surface, W3, twod=.true., &
empty = (.not. l_urban2t)))
+
! 2D fields, need checkpointing for urban-2-tile schemes
call processor%apply(make_spec('urbwrr', main%surface, twod=.true., &
ckp=l_urban2t, empty = (.not. l_urban2t) ))
@@ -1039,6 +1040,8 @@ subroutine process_physics_prognostics(processor)
call processor%apply(make_spec('soil_moist_avail', main%soil, W3, twod=.true.))
call processor%apply(make_spec('thermal_cond_wet_soil', main%soil, W3, &
twod=.true.))
+ call processor%apply(make_spec('inland_basin_flow', main%soil, W3, &
+ twod=.true.))
!========================================================================
! Fields owned by the snow scheme
diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90
index b2a7c7a15..d8b152969 100644
--- a/science/gungho/source/driver/gungho_model_mod.F90
+++ b/science/gungho/source/driver/gungho_model_mod.F90
@@ -794,9 +794,9 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
! Set up collections to hold 2d coupling fields
call modeldb%fields%add_empty_field_collection("cpl_snd_2d" , &
- table_len = 30)
+ table_len = 1)
call modeldb%fields%add_empty_field_collection("cpl_rcv_2d" , &
- table_len = 30)
+ table_len = 1)
cpl_snd_2d => modeldb%fields%get_field_collection("cpl_snd_2d")
cpl_rcv_2d => modeldb%fields%get_field_collection("cpl_rcv_2d")