From 074e498b6ea1a5e11113cd4da5dfb9b50321d90b Mon Sep 17 00:00:00 2001 From: Noah Smith Date: Fri, 13 Mar 2026 10:06:52 +0000 Subject: [PATCH 1/9] Added geothermal heat flux hflux_geo parameter to jules_soil --- .../jules-standalone/HEAD/rose-meta.conf | 8 +++++ src/control/shared/jules_soil_mod.F90 | 33 ++++++++++++++----- src/science/soil/bedrock_jls_mod.F90 | 21 ++++++------ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/rose-meta/jules-standalone/HEAD/rose-meta.conf b/rose-meta/jules-standalone/HEAD/rose-meta.conf index df0ae55d..8b6d5823 100644 --- a/rose-meta/jules-standalone/HEAD/rose-meta.conf +++ b/rose-meta/jules-standalone/HEAD/rose-meta.conf @@ -5386,6 +5386,14 @@ sort-key=Panel-E06c type=real url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::hcondeep +[namelist:jules_soil=hflux_geo] +compulsory=false +description=Geothermal heat flux (W/m2) +range=-0.052:15.6 # For continents, areal average 0.067 (F.LUCAZEAU, 2019) +sort-key=Panel-E06e +type=real +url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::hcondeep + [namelist:jules_soil=l_bedrock] compulsory=true description=Include bedrock below soil column with thermal diffusion; does not include hydrology diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index 711b8cd2..ada1c56b 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -129,12 +129,14 @@ MODULE jules_soil_mod REAL(KIND=real_jlslsm) :: & hcapdeep = rmdi, & - ! Heat capacity of bedrock + ! Heat capacity of bedrock (J/K/m3) hcondeep = rmdi, & - ! Thermal conductivity of bedrock - dzdeep = rmdi - ! Thickness of bedrock layers - + ! Thermal conductivity of bedrock (W/m/K) + dzdeep = rmdi, & + ! Thickness of bedrock layers (m) + hflux_geo = 0.0 + ! Geothermal heat flux (W/m2) + ! 0.067 +- 0.031 is areal average for continents (F.Lucazeau, 2019) !----------------------------------------------------------------------------- ! Variable length arrays that can be set using the namelist @@ -172,7 +174,7 @@ MODULE jules_soil_mod l_holdwater, l_tile_soil, & ! Parameters cs_min, zsmc, zst, confrac, ns_deep, hcapdeep, hcondeep, & - dzdeep, dzsoil_io, dzsoil_elev + dzdeep, dzsoil_io, dzsoil_elev, hflux_geo @@ -292,21 +294,28 @@ SUBROUTINE check_jules_soil() CALL ereport(RoutineName, errorstatus, 'dzdeep not found') ELSE IF ( dzdeep < 0.01 ) THEN CALL ereport(RoutineName, errorstatus, & - 'layer thickness for bedrock (dzdeep) must be > 0.01') + 'layer thickness for bedrock (dzdeep) must be > 0.01 m') END IF IF ( ABS( hcondeep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'hcondeep not found') ELSE IF ( hcondeep < 0.4 .OR. hcondeep > 12.0 ) THEN CALL ereport(RoutineName, errorstatus, & - 'hcondeep must lie in the range 0.4 to 12.0') + 'hcondeep must lie in the range 0.4 to 12.0 W/m/K') END IF IF ( ABS( hcapdeep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'hcapdeep not found') ELSE IF (hcapdeep < 100000.0 .OR. hcapdeep > 8000000.0 ) THEN CALL ereport(RoutineName, errorstatus, & - 'hcapdeep must lie in the range 100000 to 8000000') + 'hcapdeep must lie in the range 100000 to 8000000 J/K/m3') + END IF + + ! As 0.0 default value, not compulsory to set. + ! For continents, areal average 0.067 (F.LUCAZEAU, 2019) + IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN: + CALL ereport(RoutineName, errorstatus, & + 'hflux_geo must lie in the range -0.052 to 15.6 W/m2') END IF END IF ! end if l_bedrock @@ -372,6 +381,9 @@ SUBROUTINE print_nlist_jules_soil() WRITE(lineBuffer, *) ' dzdeep = ', dzdeep CALL jules_print('jules_soil', lineBuffer) +WRITE(lineBuffer, *) ' hflux_geo = ', hflux_geo +CALL jules_print('jules_soil', lineBuffer) + WRITE(lineBuffer, *) ' dzsoil_io = ', dzsoil_io CALL jules_print('jules_soil', lineBuffer) @@ -433,6 +445,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) REAL(KIND=real_jlslsm) :: hcapdeep REAL(KIND=real_jlslsm) :: hcondeep REAL(KIND=real_jlslsm) :: dzdeep + REAL(KIND=real_jlslsm) :: hflux_geo REAL(KIND=real_jlslsm) ::dzsoil_io(sm_levels_max) REAL(KIND=real_jlslsm) ::dzsoil_elev LOGICAL :: l_vg_soil @@ -467,6 +480,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) my_nml % confrac = confrac my_nml % hcapdeep = hcapdeep my_nml % hcondeep = hcondeep + my_nml % hflux_geo = hflux_geo my_nml % dzdeep = dzdeep my_nml % dzsoil_io = dzsoil_io my_nml % dzsoil_elev = dzsoil_elev @@ -493,6 +507,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) hcapdeep = my_nml % hcapdeep hcondeep = my_nml % hcondeep dzdeep = my_nml % dzdeep + hflux_geo = my_nml % hflux_geo dzsoil_io = my_nml % dzsoil_io dzsoil_elev = my_nml % dzsoil_elev l_vg_soil = my_nml % l_vg_soil diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 7cbbf924..41f59d3f 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -9,7 +9,7 @@ MODULE bedrock_mod SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & tsoil,hcsoil,tsoil_deep_gb,hflux_in) -USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep +USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep, hflux_geo USE conversions_mod, ONLY: zerodegc USE parkind1, ONLY: jprb, jpim @@ -24,28 +24,28 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !----------------------------------------------------------------------------- INTEGER, INTENT(IN) :: & npnts, & - ! number of land points + ! Number of land points soil_pts - ! number of soil points + ! Number of soil points REAL(KIND=real_jlslsm), INTENT(IN) :: & dzsoil, & - ! thickness of base soil layer (m). + ! Thickness of base soil layer (m). timestep - ! model timestep (s). + ! Model timestep (s). !----------------------------------------------------------------------------- ! Array arguments with INTENT(IN): !----------------------------------------------------------------------------- INTEGER, INTENT(IN) :: & soil_index(npnts) - ! index of soil points + ! Index of soil points REAL(KIND=real_jlslsm), INTENT(IN) :: & tsoil(npnts), & - ! soil temp at base of column (Celsius) + ! Soil temp at base of column (Celsius) hcsoil(npnts) - ! heat conductivity of base soil layer + ! Heat conductivity of base soil layer !----------------------------------------------------------------------------- ! Arguments with INTENT(IN OUT): @@ -112,8 +112,9 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !--------------------------------------------------------------------------- IF (ns_deep > 1) THEN ! bottom: - dtsd(i,ns_deep) = hcondeep * timestep * (tsoil_deep_gb(i,ns_deep-1) - & - tsoil_deep_gb(i,ns_deep)) / (hcapdeep * dzdeep**2) + dtsd(i,ns_deep) = timestep * ( hcondeep * (tsoil_deep_gb(i,ns_deep-1) - & + tsoil_deep_gb(i,ns_deep)) / dzdeep + hflux_geo ) / & + (hcapdeep * dzdeep) ! top: dtsd(i,1) = timestep * ( hcondeep * (tsoil_deep_gb(i,2) - & tsoil_deep_gb(i,1)) / dzdeep + hflux_in(i) ) / & From 3f2c30ce7e1b751a7caf3b378b45b5ffc62cf533 Mon Sep 17 00:00:00 2001 From: Noah Smith Date: Mon, 16 Mar 2026 10:11:58 +0000 Subject: [PATCH 2/9] Correct typo. --- src/control/shared/jules_soil_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index ada1c56b..12c77eb4 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -313,7 +313,7 @@ SUBROUTINE check_jules_soil() ! As 0.0 default value, not compulsory to set. ! For continents, areal average 0.067 (F.LUCAZEAU, 2019) - IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN: + IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN CALL ereport(RoutineName, errorstatus, & 'hflux_geo must lie in the range -0.052 to 15.6 W/m2') END IF From 8cca34b84262133a3fbe8836d178bc3f7b87e148 Mon Sep 17 00:00:00 2001 From: Noah Smith Date: Wed, 18 Mar 2026 14:26:01 +0000 Subject: [PATCH 3/9] Added numerical correction to bedrock T calc --- src/control/shared/jules_soil_mod.F90 | 6 +++++- src/control/shared/p_s_parms.F90 | 20 ++++++++++++++++--- src/control/shared/surf_couple_extra_mod.F90 | 2 +- .../allocate_river_arrays_mod.F90 | 2 +- .../shared/allocate_jules_arrays.F90 | 2 +- src/science/soil/bedrock_jls_mod.F90 | 20 ++++++++++++++----- src/science/soil/hydrol_jls_mod.F90 | 10 ++++++---- src/science/soil/soil_htc_jls_mod.F90 | 8 +++++--- 8 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index 12c77eb4..abb866af 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -6,7 +6,8 @@ MODULE jules_soil_mod -USE max_dimensions, ONLY: sm_levels_max +USE max_dimensions, ONLY: sm_levels_max +USE ancil_info, ONLY: nsoilt USE missing_data_mod, ONLY: rmdi, imdi @@ -288,6 +289,9 @@ SUBROUTINE check_jules_soil() ELSE IF ( ns_deep < 1 ) THEN CALL ereport(RoutineName, errorstatus, & 'Bedrock must have at least one layer') + ELSE IF ( nsoilt > 1 ) THEN + CALL ereport(RoutineName, errorstatus, & + 'Bedrock not yet compatible with soil tiling') END IF IF ( ABS( dzdeep - rmdi ) < EPSILON(1.0) ) THEN diff --git a/src/control/shared/p_s_parms.F90 b/src/control/shared/p_s_parms.F90 index e5e032d9..05567893 100644 --- a/src/control/shared/p_s_parms.F90 +++ b/src/control/shared/p_s_parms.F90 @@ -96,6 +96,9 @@ MODULE p_s_parms ! thaw depth calculation based on unfrozen water content fraction. REAL(KIND=real_jlslsm), ALLOCATABLE :: soil_ph_soilt(:,:,:) ! Soil pH, defined on soil layers. + REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_soilt(:,:,:) + ! Accumulated correction in deep soil (bedrock) temperature (K). + END TYPE !================================ @@ -127,6 +130,7 @@ MODULE p_s_parms REAL(KIND=real_jlslsm), POINTER :: sthf_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: sthu_min_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: soil_ph_soilt(:,:,:) + REAL(KIND=real_jlslsm), POINTER :: dtsd_acc_soilt(:,:,:) END TYPE CHARACTER(LEN=*), PARAMETER, PRIVATE :: ModuleName='P_S_PARMS' @@ -136,7 +140,7 @@ MODULE p_s_parms SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data) + psparms_data,l_bedrock,ns_deep) !No USE statements other than Dr Hook USE parkind1, ONLY: jprb, jpim @@ -146,11 +150,11 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & !Arguments INTEGER, INTENT(IN) :: land_pts,t_i_length,t_j_length, & - nsoilt,sm_levels,dim_cslayer,nsurft,npft + nsoilt,sm_levels,dim_cslayer,nsurft,npft,ns_deep INTEGER, INTENT(IN) :: soil_bgc_model,soil_model_ecosse -LOGICAL, INTENT(IN) :: l_use_pft_psi +LOGICAL, INTENT(IN) :: l_use_pft_psi, l_bedrock TYPE(psparms_data_type), INTENT(IN OUT) :: psparms_data @@ -234,6 +238,13 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & ALLOCATE(psparms_data%v_open_pft(1,1,1)) END IF +IF ( l_bedrock ) THEN + ALLOCATE(psparms_data%dtsd_acc_soilt(land_pts,nsoilt,ns_deep)) + psparms_data%dtsd_acc_soilt(:,:,:) = 0.0 +ELSE + ALLOCATE(psparms_data%dtsd_acc_soilt(1,1,1)) +END IF + IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN END SUBROUTINE psparms_alloc @@ -286,6 +297,7 @@ SUBROUTINE psparms_dealloc(psparms_data) DEALLOCATE(psparms_data%soil_ph_soilt) DEALLOCATE(psparms_data%v_close_pft) DEALLOCATE(psparms_data%v_open_pft) +DEALLOCATE(psparms_data%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -345,6 +357,7 @@ SUBROUTINE psparms_assoc(psparms,psparms_data) psparms%soil_ph_soilt => psparms_data%soil_ph_soilt psparms%v_close_pft => psparms_data%v_close_pft psparms%v_open_pft => psparms_data%v_open_pft +psparms%dtsd_acc_soilt => psparms_data%dtsd_acc_soilt IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -400,6 +413,7 @@ SUBROUTINE psparms_nullify(psparms) NULLIFY(psparms%soil_ph_soilt) NULLIFY(psparms%v_close_pft) NULLIFY(psparms%v_open_pft) +NULLIFY(psparms%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN diff --git a/src/control/shared/surf_couple_extra_mod.F90 b/src/control/shared/surf_couple_extra_mod.F90 index ca35dc00..9b924e30 100644 --- a/src/control/shared/surf_couple_extra_mod.F90 +++ b/src/control/shared/surf_couple_extra_mod.F90 @@ -792,7 +792,7 @@ SUBROUTINE surf_couple_extra( & toppdm%qbase_soilt, qbase_l_soilt, toppdm%qbase_zw_soilt, & toppdm%fch4_wetl_soilt, toppdm%fch4_wetl_cs_soilt, & toppdm%fch4_wetl_npp_soilt, toppdm%fch4_wetl_resps_soilt, & - trif_vars%n_leach_soilt) + trif_vars%n_leach_soilt, psparms%dtsd_acc_soilt) DEALLOCATE(ls_graup_wtrac) diff --git a/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 b/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 index 8c9bdf65..821175cf 100644 --- a/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 +++ b/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 @@ -146,7 +146,7 @@ SUBROUTINE allocate_river_arrays(psparms_data,ainfo_data, progs_data, & CALL psparms_alloc(temp_size, t_i_length, t_j_length, & nsoilt, sm_levels, dim_cslayer, nsurft, npft, & soil_bgc_model, soil_model_ecosse, l_use_pft_psi, & - psparms_data) + psparms_data, l_bedrock, ns_deep) CALL ancil_info_alloc(temp_size, t_i_length, t_j_length, & nice, nsoilt, ntype, & diff --git a/src/initialisation/shared/allocate_jules_arrays.F90 b/src/initialisation/shared/allocate_jules_arrays.F90 index 2712494b..0d632744 100644 --- a/src/initialisation/shared/allocate_jules_arrays.F90 +++ b/src/initialisation/shared/allocate_jules_arrays.F90 @@ -238,7 +238,7 @@ SUBROUTINE allocate_jules_arrays(crop_vars_data,psparms_data,top_pdm_data, & CALL psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data) + psparms_data,l_bedrock,ns_deep) CALL top_pdm_alloc(land_pts,nsoilt, top_pdm_data) diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 41f59d3f..289fffd3 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -7,7 +7,7 @@ MODULE bedrock_mod CONTAINS SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & - tsoil,hcsoil,tsoil_deep_gb,hflux_in) + tsoil,hcsoil,tsoil_deep_gb,hflux_in,dtsd_acc) USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep, hflux_geo USE conversions_mod, ONLY: zerodegc @@ -50,8 +50,11 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !----------------------------------------------------------------------------- ! Arguments with INTENT(IN OUT): !----------------------------------------------------------------------------- -REAL(KIND=real_jlslsm), INTENT(IN OUT) :: tsoil_deep_gb(npnts,ns_deep) +REAL(KIND=real_jlslsm), INTENT(IN OUT) :: & + tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). + dtsd_acc(npnts,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- ! Arguments with INTENT(OUT): @@ -71,9 +74,12 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & dztop, & ! interpolated layer thickness for heat transfer between base of soil ! and top of bedrock. - tsoil_k + tsoil_k, & ! temperature of base soil layer in Kelvin - + tsoil_deep_0, & + ! Previous value of deep soil temperature (K). + dtsh_applied + ! Change in value of deep soil temperature in this timestep (K). !----------------------------------------------------------------------------- ! Local array variables. !----------------------------------------------------------------------------- @@ -135,8 +141,12 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & ! Update the layer temperatures !--------------------------------------------------------------------------- DO n = 1,ns_deep - tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n) + dtsd(i,n),0.0) + tsoil_deep_0 = tsoil_deep_gb(i,n) + tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n)+dtsd(i,n)+dtsd_acc(i,n), 0.0) tsoil_deep_gb(i,n) = MIN(tsoil_deep_gb(i,n),10000.0) + ! Calculate cumulative numerical correction (avoids rounding error) + dtsh_applied = tsoil_deep_gb(i,n) - tsoil_deep_0 + dtsd_acc(i,n) = dtsd(i,n) + dtsd_acc(i,n) - dtsh_applied END DO END DO diff --git a/src/science/soil/hydrol_jls_mod.F90 b/src/science/soil/hydrol_jls_mod.F90 index 25ce61d4..22f03014 100644 --- a/src/science/soil/hydrol_jls_mod.F90 +++ b/src/science/soil/hydrol_jls_mod.F90 @@ -58,7 +58,7 @@ SUBROUTINE hydrol ( & qbase_l_soilt, qbase_zw_soilt, & fch4_wetl_soilt, fch4_wetl_cs_soilt, & fch4_wetl_npp_soilt, fch4_wetl_resps_soilt, & - n_leach_soilt) + n_leach_soilt, dtsd_acc_soilt) !Use in relevant subroutines USE ancil_info, ONLY: dim_cslayer, nsoilt @@ -316,9 +316,11 @@ SUBROUTINE hydrol ( & ! Soil moisture content of each layer (kg/m2). sthf_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & ! Frozen soil moisture content of each layer as a fraction of saturation. - sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls) + sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & ! Unfrozen soil moisture content of each layer as a fraction of ! saturation. + dtsd_acc_soilt(land_pts,nsoilt,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). ! TOPMODEL variables. @@ -1126,7 +1128,7 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & surf_ht_flux_ld, smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb ) + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:) ) ELSE ! Surface and soil tiles map directly on to each other. DO m = 1, nsoilt @@ -1139,7 +1141,7 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & snow_soil_htf(:,n), smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb ) + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:) ) END DO END IF diff --git a/src/science/soil/soil_htc_jls_mod.F90 b/src/science/soil/soil_htc_jls_mod.F90 index 343bd941..eac725ac 100644 --- a/src/science/soil/soil_htc_jls_mod.F90 +++ b/src/science/soil/soil_htc_jls_mod.F90 @@ -21,7 +21,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & non_lake_frac, hcap, hcon, & sathh, smcl, snowdepth, & surf_ht_flux, v_sat, w_flux, & - sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb ) + sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb, dtsd_acc ) !Use in relevant subroutines USE bedrock_mod, ONLY: bedrock @@ -113,8 +113,10 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & ! Unfrozen soil wetness over irrigation tsoil(npnts,nshyd), & ! Sub-surface temperatures (K). - tsoil_deep_gb(npnts,ns_deep) + tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). + dtsd_acc(npnts,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- ! Local parameters. @@ -366,7 +368,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & v_sat(:,nshyd), hc(:,nshyd)) CALL bedrock (npnts, soil_pts, dz(nshyd), timestep, soil_index, & - tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base) + tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base, dtsd_acc) ELSE hflux_base(:) = 0.0 END IF From 55e9d30126a3685c20b18089fe12292ef589715d Mon Sep 17 00:00:00 2001 From: eleanorgb <38913404+eleanorgb@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:09:37 +0100 Subject: [PATCH 4/9] addingo some information to the documentation --- doc/source/namelists/jules_soil.nml.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/source/namelists/jules_soil.nml.rst b/doc/source/namelists/jules_soil.nml.rst index 28734f9d..db5dacc4 100644 --- a/doc/source/namelists/jules_soil.nml.rst +++ b/doc/source/namelists/jules_soil.nml.rst @@ -113,7 +113,7 @@ This file sets the soil options and parameters. It contains one namelist called Switch for using a thermal bedrock column beneath the soil column. The bedrock has no hydrological processes - diffusion of heat is the only process represented. - Properties of the bedrock can be set using :nml:mem:`ns_deep`, :nml:mem:`hcapdeep`, :nml:mem:`hcondeep` and :nml:mem:`dzdeep`. + Properties of the bedrock can be set using :nml:mem:`ns_deep`, :nml:mem:`hcapdeep`, :nml:mem:`hcondeep`, :nml:mem:`dzdeep` and :nml:mem:`hflux_geo`:. TRUE An additional bedrock column is used below the soil column. @@ -147,7 +147,7 @@ This file sets the soil options and parameters. It contains one namelist called .. nml:member:: hcondeep :type: real - :default: 8.6 + :default: 3.0 The heat conductivity of the bedrock (W m\ :sup:`-2` K\ :sup:`-1` ). @@ -159,6 +159,13 @@ This file sets the soil options and parameters. It contains one namelist called The thickness of the bedrock layers (m). + .. nml:member:: hflux_geo + + :type: real + :default: 0.067 + + The geothermal heat flux (W m\ :sup:`-2` ). + .. nml:member:: cs_min From 008370fa13d14126aba78074e0498ea2dee27e95 Mon Sep 17 00:00:00 2001 From: Carolina Duran Rojas Date: Thu, 25 Jun 2026 14:38:46 +0100 Subject: [PATCH 5/9] Testing [Issue #76] --- dependencies.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/dependencies.yaml b/dependencies.yaml index 516b6922..60f6583f 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -24,3 +24,4 @@ jules: SimSys_Scripts: source: git@github.com:MetOffice/SimSys_Scripts.git ref: 2026.03.1 + From c1721d1a045f5208248e505a765eda5cd14e9897 Mon Sep 17 00:00:00 2001 From: eleanorgb <38913404+eleanorgb@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:52:05 +0100 Subject: [PATCH 6/9] adding new geotehrmal bedrock --- src/control/shared/jules_soil_mod.F90 | 37 +++++++++++++---- src/control/shared/p_s_parms.F90 | 20 +++++++-- src/control/shared/surf_couple_extra_mod.F90 | 2 +- .../shared/allocate_jules_arrays.F90 | 2 +- src/science/soil/bedrock_jls_mod.F90 | 41 ++++++++++++------- src/science/soil/hydrol_jls_mod.F90 | 12 ++++-- src/science/soil/soil_htc_jls_mod.F90 | 8 ++-- 7 files changed, 86 insertions(+), 36 deletions(-) diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index 92d646a0..1cd0026f 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -7,6 +7,7 @@ MODULE jules_soil_mod USE max_dimensions, ONLY: sm_levels_max +USE ancil_info, ONLY: nsoilt USE missing_data_mod, ONLY: rmdi, imdi @@ -129,12 +130,14 @@ MODULE jules_soil_mod REAL(KIND=real_jlslsm) :: & hcapdeep = rmdi, & - ! Heat capacity of bedrock + ! Heat capacity of bedrock (J/K/m3) hcondeep = rmdi, & - ! Thermal conductivity of bedrock - dzdeep = rmdi - ! Thickness of bedrock layers - + ! Thermal conductivity of bedrock (W/m/K) + dzdeep = rmdi, & + ! Thickness of bedrock layers (m) + hflux_geo = 0.0 + ! Geothermal heat flux (W/m2) + ! 0.067 +- 0.031 is areal average for continents (F.Lucazeau, 2019) !----------------------------------------------------------------------------- ! Variable length arrays that can be set using the namelist @@ -172,7 +175,7 @@ MODULE jules_soil_mod l_holdwater, l_tile_soil, & ! Parameters cs_min, zsmc, zst, confrac, ns_deep, hcapdeep, hcondeep, & - dzdeep, dzsoil_io, dzsoil_elev + dzdeep, dzsoil_io, dzsoil_elev, hflux_geo @@ -286,27 +289,37 @@ SUBROUTINE check_jules_soil() ELSE IF ( ns_deep < 1 ) THEN CALL ereport(RoutineName, errorstatus, & 'Bedrock must have at least one layer') + ELSE IF ( nsoilt > 1 ) THEN + CALL ereport(RoutineName, errorstatus, & + 'Bedrock not yet compatible with soil tiling') END IF IF ( ABS( dzdeep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'dzdeep not found') ELSE IF ( dzdeep < 0.01 ) THEN CALL ereport(RoutineName, errorstatus, & - 'layer thickness for bedrock (dzdeep) must be > 0.01') + 'layer thickness for bedrock (dzdeep) must be > 0.01 m') END IF IF ( ABS( hcondeep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'hcondeep not found') ELSE IF ( hcondeep < 0.4 .OR. hcondeep > 12.0 ) THEN CALL ereport(RoutineName, errorstatus, & - 'hcondeep must lie in the range 0.4 to 12.0') + 'hcondeep must lie in the range 0.4 to 12.0 W/m/K') END IF IF ( ABS( hcapdeep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'hcapdeep not found') ELSE IF (hcapdeep < 100000.0 .OR. hcapdeep > 8000000.0 ) THEN CALL ereport(RoutineName, errorstatus, & - 'hcapdeep must lie in the range 100000 to 8000000') + 'hcapdeep must lie in the range 100000 to 8000000 J/K/m3') + END IF + + ! As 0.0 default value, not compulsory to set. + ! For continents, areal average 0.067 (F.LUCAZEAU, 2019) + IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN + CALL ereport(RoutineName, errorstatus, & + 'hflux_geo must lie in the range -0.052 to 15.6 W/m2') END IF END IF ! end if l_bedrock @@ -372,6 +385,9 @@ SUBROUTINE print_nlist_jules_soil() WRITE(lineBuffer, *) ' dzdeep = ', dzdeep CALL jules_print('jules_soil', lineBuffer) +WRITE(lineBuffer, *) ' hflux_geo = ', hflux_geo +CALL jules_print('jules_soil', lineBuffer) + WRITE(lineBuffer, *) ' dzsoil_io = ', dzsoil_io(1:sm_levels) CALL jules_print('jules_soil', lineBuffer) @@ -433,6 +449,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) REAL(KIND=real_jlslsm) :: hcapdeep REAL(KIND=real_jlslsm) :: hcondeep REAL(KIND=real_jlslsm) :: dzdeep + REAL(KIND=real_jlslsm) :: hflux_geo REAL(KIND=real_jlslsm) ::dzsoil_io(sm_levels_max) REAL(KIND=real_jlslsm) ::dzsoil_elev LOGICAL :: l_vg_soil @@ -467,6 +484,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) my_nml % confrac = confrac my_nml % hcapdeep = hcapdeep my_nml % hcondeep = hcondeep + my_nml % hflux_geo = hflux_geo my_nml % dzdeep = dzdeep my_nml % dzsoil_io = dzsoil_io my_nml % dzsoil_elev = dzsoil_elev @@ -493,6 +511,7 @@ SUBROUTINE read_nml_jules_soil (unitnumber) hcapdeep = my_nml % hcapdeep hcondeep = my_nml % hcondeep dzdeep = my_nml % dzdeep + hflux_geo = my_nml % hflux_geo dzsoil_io = my_nml % dzsoil_io dzsoil_elev = my_nml % dzsoil_elev l_vg_soil = my_nml % l_vg_soil diff --git a/src/control/shared/p_s_parms.F90 b/src/control/shared/p_s_parms.F90 index e5e032d9..05567893 100644 --- a/src/control/shared/p_s_parms.F90 +++ b/src/control/shared/p_s_parms.F90 @@ -96,6 +96,9 @@ MODULE p_s_parms ! thaw depth calculation based on unfrozen water content fraction. REAL(KIND=real_jlslsm), ALLOCATABLE :: soil_ph_soilt(:,:,:) ! Soil pH, defined on soil layers. + REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_soilt(:,:,:) + ! Accumulated correction in deep soil (bedrock) temperature (K). + END TYPE !================================ @@ -127,6 +130,7 @@ MODULE p_s_parms REAL(KIND=real_jlslsm), POINTER :: sthf_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: sthu_min_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: soil_ph_soilt(:,:,:) + REAL(KIND=real_jlslsm), POINTER :: dtsd_acc_soilt(:,:,:) END TYPE CHARACTER(LEN=*), PARAMETER, PRIVATE :: ModuleName='P_S_PARMS' @@ -136,7 +140,7 @@ MODULE p_s_parms SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data) + psparms_data,l_bedrock,ns_deep) !No USE statements other than Dr Hook USE parkind1, ONLY: jprb, jpim @@ -146,11 +150,11 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & !Arguments INTEGER, INTENT(IN) :: land_pts,t_i_length,t_j_length, & - nsoilt,sm_levels,dim_cslayer,nsurft,npft + nsoilt,sm_levels,dim_cslayer,nsurft,npft,ns_deep INTEGER, INTENT(IN) :: soil_bgc_model,soil_model_ecosse -LOGICAL, INTENT(IN) :: l_use_pft_psi +LOGICAL, INTENT(IN) :: l_use_pft_psi, l_bedrock TYPE(psparms_data_type), INTENT(IN OUT) :: psparms_data @@ -234,6 +238,13 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & ALLOCATE(psparms_data%v_open_pft(1,1,1)) END IF +IF ( l_bedrock ) THEN + ALLOCATE(psparms_data%dtsd_acc_soilt(land_pts,nsoilt,ns_deep)) + psparms_data%dtsd_acc_soilt(:,:,:) = 0.0 +ELSE + ALLOCATE(psparms_data%dtsd_acc_soilt(1,1,1)) +END IF + IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN END SUBROUTINE psparms_alloc @@ -286,6 +297,7 @@ SUBROUTINE psparms_dealloc(psparms_data) DEALLOCATE(psparms_data%soil_ph_soilt) DEALLOCATE(psparms_data%v_close_pft) DEALLOCATE(psparms_data%v_open_pft) +DEALLOCATE(psparms_data%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -345,6 +357,7 @@ SUBROUTINE psparms_assoc(psparms,psparms_data) psparms%soil_ph_soilt => psparms_data%soil_ph_soilt psparms%v_close_pft => psparms_data%v_close_pft psparms%v_open_pft => psparms_data%v_open_pft +psparms%dtsd_acc_soilt => psparms_data%dtsd_acc_soilt IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -400,6 +413,7 @@ SUBROUTINE psparms_nullify(psparms) NULLIFY(psparms%soil_ph_soilt) NULLIFY(psparms%v_close_pft) NULLIFY(psparms%v_open_pft) +NULLIFY(psparms%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN diff --git a/src/control/shared/surf_couple_extra_mod.F90 b/src/control/shared/surf_couple_extra_mod.F90 index 4b52d3c1..593f66fc 100644 --- a/src/control/shared/surf_couple_extra_mod.F90 +++ b/src/control/shared/surf_couple_extra_mod.F90 @@ -793,7 +793,7 @@ SUBROUTINE surf_couple_extra( & toppdm%qbase_soilt, qbase_l_soilt, toppdm%qbase_zw_soilt, & toppdm%fch4_wetl_soilt, toppdm%fch4_wetl_cs_soilt, & toppdm%fch4_wetl_npp_soilt, toppdm%fch4_wetl_resps_soilt, & - trif_vars%n_leach_soilt) + trif_vars%n_leach_soilt, psparms%dtsd_acc_soilt) DEALLOCATE(ls_graup_wtrac) diff --git a/src/initialisation/shared/allocate_jules_arrays.F90 b/src/initialisation/shared/allocate_jules_arrays.F90 index 533ff2f7..fab6f3d6 100644 --- a/src/initialisation/shared/allocate_jules_arrays.F90 +++ b/src/initialisation/shared/allocate_jules_arrays.F90 @@ -238,7 +238,7 @@ SUBROUTINE allocate_jules_arrays(crop_vars_data,psparms_data,top_pdm_data, & CALL psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data) + psparms_data,l_bedrock,ns_deep) CALL top_pdm_alloc(land_pts,nsoilt, top_pdm_data) diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 7cbbf924..289fffd3 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -7,9 +7,9 @@ MODULE bedrock_mod CONTAINS SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & - tsoil,hcsoil,tsoil_deep_gb,hflux_in) + tsoil,hcsoil,tsoil_deep_gb,hflux_in,dtsd_acc) -USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep +USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep, hflux_geo USE conversions_mod, ONLY: zerodegc USE parkind1, ONLY: jprb, jpim @@ -24,34 +24,37 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !----------------------------------------------------------------------------- INTEGER, INTENT(IN) :: & npnts, & - ! number of land points + ! Number of land points soil_pts - ! number of soil points + ! Number of soil points REAL(KIND=real_jlslsm), INTENT(IN) :: & dzsoil, & - ! thickness of base soil layer (m). + ! Thickness of base soil layer (m). timestep - ! model timestep (s). + ! Model timestep (s). !----------------------------------------------------------------------------- ! Array arguments with INTENT(IN): !----------------------------------------------------------------------------- INTEGER, INTENT(IN) :: & soil_index(npnts) - ! index of soil points + ! Index of soil points REAL(KIND=real_jlslsm), INTENT(IN) :: & tsoil(npnts), & - ! soil temp at base of column (Celsius) + ! Soil temp at base of column (Celsius) hcsoil(npnts) - ! heat conductivity of base soil layer + ! Heat conductivity of base soil layer !----------------------------------------------------------------------------- ! Arguments with INTENT(IN OUT): !----------------------------------------------------------------------------- -REAL(KIND=real_jlslsm), INTENT(IN OUT) :: tsoil_deep_gb(npnts,ns_deep) +REAL(KIND=real_jlslsm), INTENT(IN OUT) :: & + tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). + dtsd_acc(npnts,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- ! Arguments with INTENT(OUT): @@ -71,9 +74,12 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & dztop, & ! interpolated layer thickness for heat transfer between base of soil ! and top of bedrock. - tsoil_k + tsoil_k, & ! temperature of base soil layer in Kelvin - + tsoil_deep_0, & + ! Previous value of deep soil temperature (K). + dtsh_applied + ! Change in value of deep soil temperature in this timestep (K). !----------------------------------------------------------------------------- ! Local array variables. !----------------------------------------------------------------------------- @@ -112,8 +118,9 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !--------------------------------------------------------------------------- IF (ns_deep > 1) THEN ! bottom: - dtsd(i,ns_deep) = hcondeep * timestep * (tsoil_deep_gb(i,ns_deep-1) - & - tsoil_deep_gb(i,ns_deep)) / (hcapdeep * dzdeep**2) + dtsd(i,ns_deep) = timestep * ( hcondeep * (tsoil_deep_gb(i,ns_deep-1) - & + tsoil_deep_gb(i,ns_deep)) / dzdeep + hflux_geo ) / & + (hcapdeep * dzdeep) ! top: dtsd(i,1) = timestep * ( hcondeep * (tsoil_deep_gb(i,2) - & tsoil_deep_gb(i,1)) / dzdeep + hflux_in(i) ) / & @@ -134,8 +141,12 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & ! Update the layer temperatures !--------------------------------------------------------------------------- DO n = 1,ns_deep - tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n) + dtsd(i,n),0.0) + tsoil_deep_0 = tsoil_deep_gb(i,n) + tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n)+dtsd(i,n)+dtsd_acc(i,n), 0.0) tsoil_deep_gb(i,n) = MIN(tsoil_deep_gb(i,n),10000.0) + ! Calculate cumulative numerical correction (avoids rounding error) + dtsh_applied = tsoil_deep_gb(i,n) - tsoil_deep_0 + dtsd_acc(i,n) = dtsd(i,n) + dtsd_acc(i,n) - dtsh_applied END DO END DO diff --git a/src/science/soil/hydrol_jls_mod.F90 b/src/science/soil/hydrol_jls_mod.F90 index d86095c2..5bf769dd 100644 --- a/src/science/soil/hydrol_jls_mod.F90 +++ b/src/science/soil/hydrol_jls_mod.F90 @@ -58,7 +58,7 @@ SUBROUTINE hydrol ( & qbase_l_soilt, qbase_zw_soilt, & fch4_wetl_soilt, fch4_wetl_cs_soilt, & fch4_wetl_npp_soilt, fch4_wetl_resps_soilt, & - n_leach_soilt) + n_leach_soilt, dtsd_acc_soilt) !Use in relevant subroutines USE ancil_info, ONLY: dim_cslayer, nsoilt @@ -316,9 +316,11 @@ SUBROUTINE hydrol ( & ! Soil moisture content of each layer (kg/m2). sthf_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & ! Frozen soil moisture content of each layer as a fraction of saturation. - sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls) + sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & ! Unfrozen soil moisture content of each layer as a fraction of ! saturation. + dtsd_acc_soilt(land_pts,nsoilt,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). ! TOPMODEL variables. @@ -1126,7 +1128,8 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & surf_ht_flux_ld, smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb, dim_cs1, resp_s_soilt ) + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:), & + dim_cs1, resp_s_soilt ) ELSE ! Surface and soil tiles map directly on to each other. DO m = 1, nsoilt @@ -1139,7 +1142,8 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & snow_soil_htf(:,n), smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb, dim_cs1, resp_s_soilt ) + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:), & + dim_cs1, resp_s_soilt ) END DO END IF diff --git a/src/science/soil/soil_htc_jls_mod.F90 b/src/science/soil/soil_htc_jls_mod.F90 index 475e1175..9bcab7fe 100644 --- a/src/science/soil/soil_htc_jls_mod.F90 +++ b/src/science/soil/soil_htc_jls_mod.F90 @@ -21,7 +21,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & non_lake_frac, hcap, hcon, & sathh, smcl, snowdepth, & surf_ht_flux, v_sat, w_flux, & - sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb, & + sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb, dtsd_acc, & dim_cs1, resp_s_soilt ) !Use in relevant subroutines @@ -120,8 +120,10 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & ! Unfrozen soil wetness over irrigation tsoil(npnts,nshyd), & ! Sub-surface temperatures (K). - tsoil_deep_gb(npnts,ns_deep) + tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). + dtsd_acc(npnts,ns_deep) + ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- ! Local parameters. @@ -373,7 +375,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & v_sat(:,nshyd), hc(:,nshyd)) CALL bedrock (npnts, soil_pts, dz(nshyd), timestep, soil_index, & - tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base) + tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base, dtsd_acc) ELSE hflux_base(:) = 0.0 END IF From 0e73857a02945662ce018f05a8bdd545d18f1e65 Mon Sep 17 00:00:00 2001 From: eleanorgb <38913404+eleanorgb@users.noreply.github.com> Date: Thu, 27 Aug 2026 15:39:53 +0100 Subject: [PATCH 7/9] refactoring bedrock --- .../jules-standalone/HEAD/rose-meta.conf | 1 + rose-meta/jules-standalone/versions.py | 8 +++++--- src/control/shared/jules_soil_mod.F90 | 6 ++---- src/control/shared/p_s_parms.F90 | 20 +++---------------- src/control/shared/prognostics.F90 | 9 +++++++++ src/control/shared/surf_couple_extra_mod.F90 | 3 ++- .../allocate_river_arrays_mod.F90 | 2 +- .../shared/allocate_jules_arrays.F90 | 2 +- .../standalone/grid/init_dim_sizes_mod.F90 | 6 ++++-- src/science/soil/bedrock_jls_mod.F90 | 17 ++++++++-------- src/science/soil/hydrol_jls_mod.F90 | 14 ++++++------- src/science/soil/soil_htc_jls_mod.F90 | 6 +++--- 12 files changed, 47 insertions(+), 47 deletions(-) diff --git a/rose-meta/jules-standalone/HEAD/rose-meta.conf b/rose-meta/jules-standalone/HEAD/rose-meta.conf index 0fe72288..c3183197 100644 --- a/rose-meta/jules-standalone/HEAD/rose-meta.conf +++ b/rose-meta/jules-standalone/HEAD/rose-meta.conf @@ -4723,6 +4723,7 @@ trigger=namelist:jules_soil=ns_deep: .true.; = namelist:jules_soil=hcapdeep: .true.; = namelist:jules_soil=hcondeep: .true.; = namelist:jules_soil=dzdeep: .true.; + = namelist:jules_soil=hflux_geo: .true.; type=logical url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::l_bedrock diff --git a/rose-meta/jules-standalone/versions.py b/rose-meta/jules-standalone/versions.py index 1d4c41a9..22ac800a 100644 --- a/rose-meta/jules-standalone/versions.py +++ b/rose-meta/jules-standalone/versions.py @@ -45,15 +45,17 @@ from .version81_82 import * -class vnYY_txxxx(MacroUpgrade): +class vn82_t76(MacroUpgrade): """Upgrade macro from JULES by Author""" - BEFORE_TAG = "vnY.Y" - AFTER_TAG = "vnY.Y_txxxx" + BEFORE_TAG = "vn8.2" + AFTER_TAG = "vn8.2_t76" def upgrade(self, config, meta_config=None): """Upgrade a JULES runtime app configuration.""" # Add settings + self.add_setting(config, ["namelist:jules_soil", "hflux_geo"], "0.067") + return config, self.reports diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index 59f7f8dd..5fdc7844 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -135,9 +135,8 @@ MODULE jules_soil_mod ! Thermal conductivity of bedrock (W/m/K) dzdeep = rmdi, & ! Thickness of bedrock layers (m) - hflux_geo = 0.0 + hflux_geo = rmdi ! Geothermal heat flux (W/m2) - ! 0.067 +- 0.031 is areal average for continents (F.Lucazeau, 2019) !----------------------------------------------------------------------------- ! Variable length arrays that can be set using the namelist @@ -214,7 +213,6 @@ SUBROUTINE check_jules_soil() ! Check that sm_levels has been set IF ( sm_levels < 1 ) THEN - errorstatus = 101 CALL ereport("check_jules_soil", errorstatus, & "sm_levels must be between 1 and sm_levels_max") END IF @@ -283,7 +281,7 @@ SUBROUTINE check_jules_soil() END IF IF ( l_bedrock ) THEN - ! Check ns_deep, dzdeep, hcondeep. hcapdeep are set and valid + ! Check ns_deep, dzdeep, hcondeep. hcapdeep, hflux_geo are set and valid IF ( ABS( ns_deep - rmdi ) < EPSILON(1.0) ) THEN CALL ereport(RoutineName, errorstatus, 'ns_deep not found') ELSE IF ( ns_deep < 1 ) THEN diff --git a/src/control/shared/p_s_parms.F90 b/src/control/shared/p_s_parms.F90 index 05567893..e5e032d9 100644 --- a/src/control/shared/p_s_parms.F90 +++ b/src/control/shared/p_s_parms.F90 @@ -96,9 +96,6 @@ MODULE p_s_parms ! thaw depth calculation based on unfrozen water content fraction. REAL(KIND=real_jlslsm), ALLOCATABLE :: soil_ph_soilt(:,:,:) ! Soil pH, defined on soil layers. - REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_soilt(:,:,:) - ! Accumulated correction in deep soil (bedrock) temperature (K). - END TYPE !================================ @@ -130,7 +127,6 @@ MODULE p_s_parms REAL(KIND=real_jlslsm), POINTER :: sthf_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: sthu_min_soilt(:,:,:) REAL(KIND=real_jlslsm), POINTER :: soil_ph_soilt(:,:,:) - REAL(KIND=real_jlslsm), POINTER :: dtsd_acc_soilt(:,:,:) END TYPE CHARACTER(LEN=*), PARAMETER, PRIVATE :: ModuleName='P_S_PARMS' @@ -140,7 +136,7 @@ MODULE p_s_parms SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data,l_bedrock,ns_deep) + psparms_data) !No USE statements other than Dr Hook USE parkind1, ONLY: jprb, jpim @@ -150,11 +146,11 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & !Arguments INTEGER, INTENT(IN) :: land_pts,t_i_length,t_j_length, & - nsoilt,sm_levels,dim_cslayer,nsurft,npft,ns_deep + nsoilt,sm_levels,dim_cslayer,nsurft,npft INTEGER, INTENT(IN) :: soil_bgc_model,soil_model_ecosse -LOGICAL, INTENT(IN) :: l_use_pft_psi, l_bedrock +LOGICAL, INTENT(IN) :: l_use_pft_psi TYPE(psparms_data_type), INTENT(IN OUT) :: psparms_data @@ -238,13 +234,6 @@ SUBROUTINE psparms_alloc(land_pts,t_i_length,t_j_length, & ALLOCATE(psparms_data%v_open_pft(1,1,1)) END IF -IF ( l_bedrock ) THEN - ALLOCATE(psparms_data%dtsd_acc_soilt(land_pts,nsoilt,ns_deep)) - psparms_data%dtsd_acc_soilt(:,:,:) = 0.0 -ELSE - ALLOCATE(psparms_data%dtsd_acc_soilt(1,1,1)) -END IF - IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN END SUBROUTINE psparms_alloc @@ -297,7 +286,6 @@ SUBROUTINE psparms_dealloc(psparms_data) DEALLOCATE(psparms_data%soil_ph_soilt) DEALLOCATE(psparms_data%v_close_pft) DEALLOCATE(psparms_data%v_open_pft) -DEALLOCATE(psparms_data%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -357,7 +345,6 @@ SUBROUTINE psparms_assoc(psparms,psparms_data) psparms%soil_ph_soilt => psparms_data%soil_ph_soilt psparms%v_close_pft => psparms_data%v_close_pft psparms%v_open_pft => psparms_data%v_open_pft -psparms%dtsd_acc_soilt => psparms_data%dtsd_acc_soilt IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -413,7 +400,6 @@ SUBROUTINE psparms_nullify(psparms) NULLIFY(psparms%soil_ph_soilt) NULLIFY(psparms%v_close_pft) NULLIFY(psparms%v_open_pft) -NULLIFY(psparms%dtsd_acc_soilt) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN diff --git a/src/control/shared/prognostics.F90 b/src/control/shared/prognostics.F90 index c00ed914..c18147df 100644 --- a/src/control/shared/prognostics.F90 +++ b/src/control/shared/prognostics.F90 @@ -48,6 +48,8 @@ MODULE prognostics REAL(KIND=real_jlslsm), ALLOCATABLE :: tsoil_deep_gb(:,:) ! Deep soil temperatures (K) + REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_gb(:,:) + ! Accumulated correction in deep soil (bedrock) temperature (K). REAL(KIND=real_jlslsm), ALLOCATABLE :: sice_surft(:,:,:) ! Snow layer ice mass on tiles (kg/m2) REAL(KIND=real_jlslsm), ALLOCATABLE :: sliq_surft(:,:,:) @@ -201,6 +203,7 @@ MODULE prognostics INTEGER, POINTER :: years_since_harvest(:,:) REAL(KIND=real_jlslsm), POINTER :: tsoil_deep_gb(:,:) + REAL(KIND=real_jlslsm), POINTER :: dtsd_acc_gb(:,:) REAL(KIND=real_jlslsm), POINTER :: sice_surft(:,:,:) REAL(KIND=real_jlslsm), POINTER :: sliq_surft(:,:,:) REAL(KIND=real_jlslsm), POINTER :: snowdepth_surft(:,:) @@ -410,8 +413,11 @@ SUBROUTINE prognostics_alloc(land_pts, t_i_length, t_j_length, & IF ( l_bedrock ) THEN ALLOCATE(progs_data%tsoil_deep_gb(land_pts,ns_deep)) progs_data%tsoil_deep_gb(:,:) = 0.0 + ALLOCATE(progs_data%dtsd_acc_gb(land_pts,ns_deep)) + progs_data%dtsd_acc_gb(:,:) = 0.0 ELSE ALLOCATE(progs_data%tsoil_deep_gb(1,1)) + ALLOCATE(progs_data%dtsd_acc_gb(1,1)) END IF ! Prognostics for microbial methane scheme @@ -566,6 +572,7 @@ SUBROUTINE prognostics_dealloc(progs_data) END IF DEALLOCATE(progs_data%tsoil_deep_gb) +DEALLOCATE(progs_data%dtsd_acc_gb) IF ( ALLOCATED(progs_data%t_home_gb) ) THEN DEALLOCATE(progs_data%t_home_gb) @@ -662,6 +669,7 @@ SUBROUTINE prognostics_assoc(progs,progs_data) progs%frac_biocrop_prev_gb => progs_data%frac_biocrop_prev_gb progs%triffid_co2_gb => progs_data%triffid_co2_gb progs%tsoil_deep_gb => progs_data%tsoil_deep_gb +progs%dtsd_acc_gb => progs_data%dtsd_acc_gb progs%lai_pft => progs_data%lai_pft progs%canht_pft => progs_data%canht_pft progs%smcl_soilt => progs_data%smcl_soilt @@ -752,6 +760,7 @@ SUBROUTINE prognostics_nullify(progs) NULLIFY(progs%frac_biocrop_prev_gb) NULLIFY(progs%triffid_co2_gb) NULLIFY(progs%tsoil_deep_gb) +NULLIFY(progs%dtsd_acc_gb) NULLIFY(progs%lai_pft) NULLIFY(progs%canht_pft) NULLIFY(progs%smcl_soilt) diff --git a/src/control/shared/surf_couple_extra_mod.F90 b/src/control/shared/surf_couple_extra_mod.F90 index 593f66fc..284b8ceb 100644 --- a/src/control/shared/surf_couple_extra_mod.F90 +++ b/src/control/shared/surf_couple_extra_mod.F90 @@ -778,6 +778,7 @@ SUBROUTINE surf_couple_extra( & progs%canopy_surft, wtrac_jls%canopy_surft, & progs%smcl_soilt, psparms%sthf_soilt, & psparms%sthu_soilt, crop_vars%sthu_irr_soilt, progs%tsoil_deep_gb, & + progs%dtsd_acc_gb, & progs%t_soil_soilt, progs%t_soil_soilt_acc, progs%tsurf_elev_surft, & wtrac_jls%smcl_soilt, wtrac_jls%sthf_soilt, wtrac_jls%sthu_soilt, & fsat_soilt, fwetl_soilt, sthzw_soilt, zw_soilt, wtrac_jls%sthzw_soilt, & @@ -793,7 +794,7 @@ SUBROUTINE surf_couple_extra( & toppdm%qbase_soilt, qbase_l_soilt, toppdm%qbase_zw_soilt, & toppdm%fch4_wetl_soilt, toppdm%fch4_wetl_cs_soilt, & toppdm%fch4_wetl_npp_soilt, toppdm%fch4_wetl_resps_soilt, & - trif_vars%n_leach_soilt, psparms%dtsd_acc_soilt) + trif_vars%n_leach_soilt) DEALLOCATE(ls_graup_wtrac) diff --git a/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 b/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 index 821175cf..8c9bdf65 100644 --- a/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 +++ b/src/initialisation/rivers-standalone/allocate_river_arrays_mod.F90 @@ -146,7 +146,7 @@ SUBROUTINE allocate_river_arrays(psparms_data,ainfo_data, progs_data, & CALL psparms_alloc(temp_size, t_i_length, t_j_length, & nsoilt, sm_levels, dim_cslayer, nsurft, npft, & soil_bgc_model, soil_model_ecosse, l_use_pft_psi, & - psparms_data, l_bedrock, ns_deep) + psparms_data) CALL ancil_info_alloc(temp_size, t_i_length, t_j_length, & nice, nsoilt, ntype, & diff --git a/src/initialisation/shared/allocate_jules_arrays.F90 b/src/initialisation/shared/allocate_jules_arrays.F90 index fab6f3d6..533ff2f7 100644 --- a/src/initialisation/shared/allocate_jules_arrays.F90 +++ b/src/initialisation/shared/allocate_jules_arrays.F90 @@ -238,7 +238,7 @@ SUBROUTINE allocate_jules_arrays(crop_vars_data,psparms_data,top_pdm_data, & CALL psparms_alloc(land_pts,t_i_length,t_j_length, & nsoilt,sm_levels,dim_cslayer,nsurft,npft, & soil_bgc_model,soil_model_ecosse,l_use_pft_psi, & - psparms_data,l_bedrock,ns_deep) + psparms_data) CALL top_pdm_alloc(land_pts,nsoilt, top_pdm_data) diff --git a/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 b/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 index 68ed1b28..d95f4486 100644 --- a/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 +++ b/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 @@ -36,7 +36,7 @@ SUBROUTINE init_dim_sizes() USE jules_sea_seaice_mod, ONLY: nice, nice_use -USE jules_soil_mod, ONLY: sm_levels, ns_deep, l_tile_soil +USE jules_soil_mod, ONLY: sm_levels, ns_deep, l_tile_soil, l_bedrock USE model_interface_mod, ONLY: bl_level_dim_size, bedrock_dim_size, & pft_dim_size, quantile_dim_size, & @@ -145,7 +145,9 @@ SUBROUTINE init_dim_sizes() END IF ch4layer_dim_size = dim_ch4layer dep_species_dim_size = ndry_dep_species -bedrock_dim_size = ns_deep +IF ( l_bedrock ) THEN + bedrock_dim_size = ns_deep +END IF nmasst_dim_size = nmasst RETURN diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 289fffd3..445f7824 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -7,7 +7,7 @@ MODULE bedrock_mod CONTAINS SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & - tsoil,hcsoil,tsoil_deep_gb,hflux_in,dtsd_acc) + tsoil,hcsoil,tsoil_deep_gb,hflux_in,dtsd_acc_gb) USE jules_soil_mod, ONLY: ns_deep, hcapdeep, hcondeep, dzdeep, hflux_geo USE conversions_mod, ONLY: zerodegc @@ -53,7 +53,7 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & REAL(KIND=real_jlslsm), INTENT(IN OUT) :: & tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). - dtsd_acc(npnts,ns_deep) + dtsd_acc_gb(npnts,ns_deep) ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- @@ -76,7 +76,7 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & ! and top of bedrock. tsoil_k, & ! temperature of base soil layer in Kelvin - tsoil_deep_0, & + tsoil_deep_prev, & ! Previous value of deep soil temperature (K). dtsh_applied ! Change in value of deep soil temperature in this timestep (K). @@ -141,12 +141,13 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & ! Update the layer temperatures !--------------------------------------------------------------------------- DO n = 1,ns_deep - tsoil_deep_0 = tsoil_deep_gb(i,n) - tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n)+dtsd(i,n)+dtsd_acc(i,n), 0.0) - tsoil_deep_gb(i,n) = MIN(tsoil_deep_gb(i,n),10000.0) + tsoil_deep_prev = tsoil_deep_gb(i,n) + tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n) + dtsd(i,n) + & + dtsd_acc_gb(i,n), 0.0) + tsoil_deep_gb(i,n) = MIN(tsoil_deep_gb(i,n), 1000.0) ! Calculate cumulative numerical correction (avoids rounding error) - dtsh_applied = tsoil_deep_gb(i,n) - tsoil_deep_0 - dtsd_acc(i,n) = dtsd(i,n) + dtsd_acc(i,n) - dtsh_applied + dtsh_applied = tsoil_deep_gb(i,n) - tsoil_deep_prev + dtsd_acc_gb(i,n) = dtsd(i,n) + dtsd_acc_gb(i,n) - dtsh_applied END DO END DO diff --git a/src/science/soil/hydrol_jls_mod.F90 b/src/science/soil/hydrol_jls_mod.F90 index 5bf769dd..c40e717a 100644 --- a/src/science/soil/hydrol_jls_mod.F90 +++ b/src/science/soil/hydrol_jls_mod.F90 @@ -42,7 +42,7 @@ SUBROUTINE hydrol ( & fexp_soilt, ti_mean_soilt, & npp_soilt, inlandout_atm_gb, inlandout_atm_gb_wtrac, & canopy_surft, canopy_surft_wtrac, smcl_soilt, sthf_soilt, & - sthu_soilt, sthu_irr_soilt, tsoil_deep_gb, & + sthu_soilt, sthu_irr_soilt, tsoil_deep_gb, dtsd_acc_gb, & t_soil_soilt, t_soil_soilt_acc, tsurf_elev_surft, & smcl_soilt_wtrac, sthf_soilt_wtrac, sthu_soilt_wtrac, & fsat_soilt, fwetl_soilt, sthzw_soilt, zw_soilt, sthzw_soilt_wtrac, & @@ -58,7 +58,7 @@ SUBROUTINE hydrol ( & qbase_l_soilt, qbase_zw_soilt, & fch4_wetl_soilt, fch4_wetl_cs_soilt, & fch4_wetl_npp_soilt, fch4_wetl_resps_soilt, & - n_leach_soilt, dtsd_acc_soilt) + n_leach_soilt) !Use in relevant subroutines USE ancil_info, ONLY: dim_cslayer, nsoilt @@ -305,6 +305,8 @@ SUBROUTINE hydrol ( & ! Unfrozen soil wetness over irrigation. tsoil_deep_gb(land_pts,ns_deep), & ! Deep soil temperature (K). + dtsd_acc_gb(land_pts,ns_deep), & + ! Accumulated correction in deep soil (bedrock) temperature (K). t_soil_soilt(land_pts,nsoilt,sm_levels), & ! Sub-surface temperatures (K). t_soil_soilt_acc(land_pts,nsoilt,sm_levels), & @@ -316,11 +318,9 @@ SUBROUTINE hydrol ( & ! Soil moisture content of each layer (kg/m2). sthf_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & ! Frozen soil moisture content of each layer as a fraction of saturation. - sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls), & + sthu_soilt_wtrac(land_pts,nsoilt,sm_levels,n_wtrac_jls) ! Unfrozen soil moisture content of each layer as a fraction of ! saturation. - dtsd_acc_soilt(land_pts,nsoilt,ns_deep) - ! Accumulated correction in deep soil (bedrock) temperature (K). ! TOPMODEL variables. @@ -1128,7 +1128,7 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & surf_ht_flux_ld, smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:), & + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_gb, & dim_cs1, resp_s_soilt ) ELSE ! Surface and soil tiles map directly on to each other. @@ -1142,7 +1142,7 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & snow_soil_htf(:,n), smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_soilt(:,m,:), & + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_gb, & dim_cs1, resp_s_soilt ) END DO END IF diff --git a/src/science/soil/soil_htc_jls_mod.F90 b/src/science/soil/soil_htc_jls_mod.F90 index 9bcab7fe..bf7d0217 100644 --- a/src/science/soil/soil_htc_jls_mod.F90 +++ b/src/science/soil/soil_htc_jls_mod.F90 @@ -21,7 +21,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & non_lake_frac, hcap, hcon, & sathh, smcl, snowdepth, & surf_ht_flux, v_sat, w_flux, & - sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb, dtsd_acc, & + sthf, sthu, sthu_irr, tsoil, tsoil_deep_gb, dtsd_acc_gb, & dim_cs1, resp_s_soilt ) !Use in relevant subroutines @@ -122,7 +122,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & ! Sub-surface temperatures (K). tsoil_deep_gb(npnts,ns_deep), & ! Deep soil temperature (K). - dtsd_acc(npnts,ns_deep) + dtsd_acc_gb(npnts,ns_deep) ! Accumulated correction in deep soil (bedrock) temperature (K). !----------------------------------------------------------------------------- @@ -375,7 +375,7 @@ SUBROUTINE soil_htc ( npnts, nshyd, nsurft, soil_pts, timestep, soil_index, & v_sat(:,nshyd), hc(:,nshyd)) CALL bedrock (npnts, soil_pts, dz(nshyd), timestep, soil_index, & - tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base, dtsd_acc) + tsl(:,nshyd), hc(:,nshyd), tsoil_deep_gb, hflux_base, dtsd_acc_gb) ELSE hflux_base(:) = 0.0 END IF From e55b48fe2c12a6eaac792d851f147dd286c1378f Mon Sep 17 00:00:00 2001 From: eleanorgb <38913404+eleanorgb@users.noreply.github.com> Date: Fri, 28 Aug 2026 08:51:34 +0100 Subject: [PATCH 8/9] changes in response to copliot revoew --- doc/source/namelists/jules_soil.nml.rst | 4 ++-- rose-meta/jules-standalone/HEAD/rose-meta.conf | 10 +++++----- rose-meta/jules-standalone/versions.py | 2 +- src/control/shared/jules_soil_mod.F90 | 9 +++++---- src/control/shared/prognostics.F90 | 4 ++-- .../standalone/grid/init_dim_sizes_mod.F90 | 6 ++---- src/initialisation/standalone/init_soil.F90 | 10 +++++++++- src/science/soil/bedrock_jls_mod.F90 | 10 +++++----- 8 files changed, 31 insertions(+), 24 deletions(-) diff --git a/doc/source/namelists/jules_soil.nml.rst b/doc/source/namelists/jules_soil.nml.rst index db5dacc4..4748b140 100644 --- a/doc/source/namelists/jules_soil.nml.rst +++ b/doc/source/namelists/jules_soil.nml.rst @@ -113,7 +113,7 @@ This file sets the soil options and parameters. It contains one namelist called Switch for using a thermal bedrock column beneath the soil column. The bedrock has no hydrological processes - diffusion of heat is the only process represented. - Properties of the bedrock can be set using :nml:mem:`ns_deep`, :nml:mem:`hcapdeep`, :nml:mem:`hcondeep`, :nml:mem:`dzdeep` and :nml:mem:`hflux_geo`:. + Properties of the bedrock can be set using :nml:mem:`ns_deep`, :nml:mem:`hcapdeep`, :nml:mem:`hcondeep`, :nml:mem:`dzdeep` and :nml:mem:`hflux_geo`. TRUE An additional bedrock column is used below the soil column. @@ -149,7 +149,7 @@ This file sets the soil options and parameters. It contains one namelist called :type: real :default: 3.0 - The heat conductivity of the bedrock (W m\ :sup:`-2` K\ :sup:`-1` ). + The heat conductivity of the bedrock (W m\ :sup:`-1` K\ :sup:`-1` ). .. nml:member:: dzdeep diff --git a/rose-meta/jules-standalone/HEAD/rose-meta.conf b/rose-meta/jules-standalone/HEAD/rose-meta.conf index c3183197..16bbdd1f 100644 --- a/rose-meta/jules-standalone/HEAD/rose-meta.conf +++ b/rose-meta/jules-standalone/HEAD/rose-meta.conf @@ -4700,23 +4700,23 @@ url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES [namelist:jules_soil=hcondeep] compulsory=true -description=Thermal conductivity of bedrock (W m-2 K-1) +description=Thermal conductivity of bedrock (W m-1 K-1) range=0.4:12.0 sort-key=Panel-E06c type=real url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::hcondeep [namelist:jules_soil=hflux_geo] -compulsory=false +compulsory=true description=Geothermal heat flux (W/m2) -range=-0.052:15.6 # For continents, areal average 0.067 (F.LUCAZEAU, 2019) +range=-0.052:15.6 sort-key=Panel-E06e type=real -url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::hcondeep +url=https://metoffice.github.io/jules/latest/namelists/jules_soil.nml.html#JULES_SOIL::hflux_geo [namelist:jules_soil=l_bedrock] compulsory=true -description=Include bedrock below soil column with thermal diffusion; does not include hydrology +description=Include bedrock below soil column with thermal diffusion - does not include hydrology =NOT AVAILABLE TO UM sort-key=Panel-E06 trigger=namelist:jules_soil=ns_deep: .true.; diff --git a/rose-meta/jules-standalone/versions.py b/rose-meta/jules-standalone/versions.py index 22ac800a..395bb3b4 100644 --- a/rose-meta/jules-standalone/versions.py +++ b/rose-meta/jules-standalone/versions.py @@ -57,5 +57,5 @@ def upgrade(self, config, meta_config=None): # Add settings self.add_setting(config, ["namelist:jules_soil", "hflux_geo"], "0.067") - + self.change_setting_value(config, ["namelist:jules_soil", "hcondeep"], "3.0") return config, self.reports diff --git a/src/control/shared/jules_soil_mod.F90 b/src/control/shared/jules_soil_mod.F90 index 5fdc7844..6ee75d99 100644 --- a/src/control/shared/jules_soil_mod.F90 +++ b/src/control/shared/jules_soil_mod.F90 @@ -282,8 +282,8 @@ SUBROUTINE check_jules_soil() IF ( l_bedrock ) THEN ! Check ns_deep, dzdeep, hcondeep. hcapdeep, hflux_geo are set and valid - IF ( ABS( ns_deep - rmdi ) < EPSILON(1.0) ) THEN - CALL ereport(RoutineName, errorstatus, 'ns_deep not found') + IF ( ns_deep == imdi ) THEN + CALL ereport(RoutineName, errorstatus, 'ns_deep not specified') ELSE IF ( ns_deep < 1 ) THEN CALL ereport(RoutineName, errorstatus, & 'Bedrock must have at least one layer') @@ -313,9 +313,10 @@ SUBROUTINE check_jules_soil() 'hcapdeep must lie in the range 100000 to 8000000 J/K/m3') END IF - ! As 0.0 default value, not compulsory to set. ! For continents, areal average 0.067 (F.LUCAZEAU, 2019) - IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN + IF ( ABS( hflux_geo - rmdi ) < EPSILON(1.0) ) THEN + CALL ereport(RoutineName, errorstatus, 'hflux_geo not found') + ELSE IF (hflux_geo < -0.052 .OR. hflux_geo > 15.6 ) THEN CALL ereport(RoutineName, errorstatus, & 'hflux_geo must lie in the range -0.052 to 15.6 W/m2') END IF diff --git a/src/control/shared/prognostics.F90 b/src/control/shared/prognostics.F90 index c18147df..ccae7750 100644 --- a/src/control/shared/prognostics.F90 +++ b/src/control/shared/prognostics.F90 @@ -412,13 +412,13 @@ SUBROUTINE prognostics_alloc(land_pts, t_i_length, t_j_length, & ! Only allocate the bedrock tsoil_deep_gb if bedrock is being used IF ( l_bedrock ) THEN ALLOCATE(progs_data%tsoil_deep_gb(land_pts,ns_deep)) - progs_data%tsoil_deep_gb(:,:) = 0.0 ALLOCATE(progs_data%dtsd_acc_gb(land_pts,ns_deep)) - progs_data%dtsd_acc_gb(:,:) = 0.0 ELSE ALLOCATE(progs_data%tsoil_deep_gb(1,1)) ALLOCATE(progs_data%dtsd_acc_gb(1,1)) END IF +progs_data%dtsd_acc_gb(:,:) = 0.0 +progs_data%tsoil_deep_gb(:,:) = 0.0 ! Prognostics for microbial methane scheme ALLOCATE(progs_data%substr_ch4(land_pts,dim_ch4layer)) diff --git a/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 b/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 index d95f4486..68ed1b28 100644 --- a/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 +++ b/src/initialisation/standalone/grid/init_dim_sizes_mod.F90 @@ -36,7 +36,7 @@ SUBROUTINE init_dim_sizes() USE jules_sea_seaice_mod, ONLY: nice, nice_use -USE jules_soil_mod, ONLY: sm_levels, ns_deep, l_tile_soil, l_bedrock +USE jules_soil_mod, ONLY: sm_levels, ns_deep, l_tile_soil USE model_interface_mod, ONLY: bl_level_dim_size, bedrock_dim_size, & pft_dim_size, quantile_dim_size, & @@ -145,9 +145,7 @@ SUBROUTINE init_dim_sizes() END IF ch4layer_dim_size = dim_ch4layer dep_species_dim_size = ndry_dep_species -IF ( l_bedrock ) THEN - bedrock_dim_size = ns_deep -END IF +bedrock_dim_size = ns_deep nmasst_dim_size = nmasst RETURN diff --git a/src/initialisation/standalone/init_soil.F90 b/src/initialisation/standalone/init_soil.F90 index 0ddf8cb7..ed702fd1 100644 --- a/src/initialisation/standalone/init_soil.F90 +++ b/src/initialisation/standalone/init_soil.F90 @@ -111,9 +111,15 @@ SUBROUTINE init_soil(nml_dir) "soilHc_method = 3 - Chadburn et al. (2015)") END IF -IF ( l_bedrock ) & +IF ( l_bedrock ) THEN & CALL log_info("init_soil", "Bedrock will be included at base of soil") + IF ( ns_deep == 1) THEN + CALL log_warn("init_soil", "Bedrock will be modelled as a single layer") + CALL log_warn("init_soil", "There is no geothermal heat flux applied") + END IF +END IF + IF ( l_tile_soil ) THEN CALL log_info("init_soil", & "l_tile_soil = T. Soil tiling is switched on: nsoilt = nsurft") @@ -129,6 +135,8 @@ SUBROUTINE init_soil(nml_dir) "l_tile_soil = F. Soil tiling is switched off: nsoilt = 1") END IF + + RETURN END SUBROUTINE init_soil diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 445f7824..6d087ed5 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -45,7 +45,7 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & tsoil(npnts), & ! Soil temp at base of column (Celsius) hcsoil(npnts) - ! Heat conductivity of base soil layer + ! Heat conductivity of base soil layer (W/m/K) !----------------------------------------------------------------------------- ! Arguments with INTENT(IN OUT): @@ -61,7 +61,7 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !----------------------------------------------------------------------------- REAL(KIND=real_jlslsm), INTENT(OUT) :: & hflux_in(npnts) - ! heat flux from base of soil column into bedrock layers + ! heat flux from base of soil column into bedrock layers (W/m2) !----------------------------------------------------------------------------- ! Local scalar variables. @@ -70,13 +70,13 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & REAL(KIND=real_jlslsm) :: & hctop, & - ! interpolated heat conductivity where bedrock joins soil + ! interpolated heat conductivity where bedrock joins soil (W/m/K) dztop, & ! interpolated layer thickness for heat transfer between base of soil - ! and top of bedrock. + ! and top of bedrock (m). tsoil_k, & ! temperature of base soil layer in Kelvin - tsoil_deep_prev, & + tsoil_deep_prev, & ! Previous value of deep soil temperature (K). dtsh_applied ! Change in value of deep soil temperature in this timestep (K). From b51ef2402573515a66d2fafa334cbcd74d902e65 Mon Sep 17 00:00:00 2001 From: eleanorgb <38913404+eleanorgb@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:57:17 +0100 Subject: [PATCH 9/9] minor syntax changes --- CONTRIBUTORS.md | 1 + src/control/shared/prognostics.F90 | 4 ++-- src/initialisation/standalone/init_soil.F90 | 8 +++----- src/science/soil/bedrock_jls_mod.F90 | 2 +- src/science/soil/hydrol_jls_mod.F90 | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index db1cc110..5c9e382f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -5,3 +5,4 @@ | yaswant | Yaswant Pradhan | Met Office | 2026-06-30 | | doucla | Douglas Clark | UKCEH | 2026-07-03 | | james-bruten-mo | James Bruten | Met Office | 2026-07-09 | +| eleanorgb | Eleanor Burke | Met Office | 2026-08-24 | diff --git a/src/control/shared/prognostics.F90 b/src/control/shared/prognostics.F90 index ccae7750..cc71a945 100644 --- a/src/control/shared/prognostics.F90 +++ b/src/control/shared/prognostics.F90 @@ -48,8 +48,8 @@ MODULE prognostics REAL(KIND=real_jlslsm), ALLOCATABLE :: tsoil_deep_gb(:,:) ! Deep soil temperatures (K) - REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_gb(:,:) - ! Accumulated correction in deep soil (bedrock) temperature (K). + REAL(KIND=real_jlslsm), ALLOCATABLE :: dtsd_acc_gb(:,:) + ! Accumulated correction in deep soil (bedrock) temperature (K). REAL(KIND=real_jlslsm), ALLOCATABLE :: sice_surft(:,:,:) ! Snow layer ice mass on tiles (kg/m2) REAL(KIND=real_jlslsm), ALLOCATABLE :: sliq_surft(:,:,:) diff --git a/src/initialisation/standalone/init_soil.F90 b/src/initialisation/standalone/init_soil.F90 index ed702fd1..4c5d3403 100644 --- a/src/initialisation/standalone/init_soil.F90 +++ b/src/initialisation/standalone/init_soil.F90 @@ -29,11 +29,11 @@ SUBROUTINE init_soil(nml_dir) USE jules_soil_mod, ONLY: jules_soil, sm_levels, dzsoil, dzsoil_elev, & l_vg_soil, l_soil_sat_down, soilhc_method, & l_bedrock, l_tile_soil, l_broadcast_ancils, & - check_jules_soil + check_jules_soil, ns_deep USE jules_surface_mod, ONLY: l_elev_land_ice -USE logging_mod, ONLY: log_info, log_fatal +USE logging_mod, ONLY: log_info, log_fatal, log_warn USE errormessagelength_mod, ONLY: errormessagelength @@ -111,7 +111,7 @@ SUBROUTINE init_soil(nml_dir) "soilHc_method = 3 - Chadburn et al. (2015)") END IF -IF ( l_bedrock ) THEN & +IF ( l_bedrock ) THEN CALL log_info("init_soil", "Bedrock will be included at base of soil") IF ( ns_deep == 1) THEN @@ -135,8 +135,6 @@ SUBROUTINE init_soil(nml_dir) "l_tile_soil = F. Soil tiling is switched off: nsoilt = 1") END IF - - RETURN END SUBROUTINE init_soil diff --git a/src/science/soil/bedrock_jls_mod.F90 b/src/science/soil/bedrock_jls_mod.F90 index 6d087ed5..358532d8 100644 --- a/src/science/soil/bedrock_jls_mod.F90 +++ b/src/science/soil/bedrock_jls_mod.F90 @@ -142,7 +142,7 @@ SUBROUTINE bedrock (npnts,soil_pts,dzsoil,timestep,soil_index, & !--------------------------------------------------------------------------- DO n = 1,ns_deep tsoil_deep_prev = tsoil_deep_gb(i,n) - tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n) + dtsd(i,n) + & + tsoil_deep_gb(i,n) = MAX(tsoil_deep_gb(i,n) + dtsd(i,n) + & dtsd_acc_gb(i,n), 0.0) tsoil_deep_gb(i,n) = MIN(tsoil_deep_gb(i,n), 1000.0) ! Calculate cumulative numerical correction (avoids rounding error) diff --git a/src/science/soil/hydrol_jls_mod.F90 b/src/science/soil/hydrol_jls_mod.F90 index c40e717a..362b633c 100644 --- a/src/science/soil/hydrol_jls_mod.F90 +++ b/src/science/soil/hydrol_jls_mod.F90 @@ -1128,7 +1128,7 @@ SUBROUTINE hydrol ( & sathh_soilt(:,m,:), smcl_soilt(:,m,:), snowdepth_surft, & surf_ht_flux_ld, smvcst_soilt(:,m,:), w_flux_soilt(:,m,:), & sthf_soilt(:,m,:), sthu_soilt(:,m,:), sthu_irr_soilt(:,m,:), & - t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_gb, & + t_soil_soilt(:,m,:), tsoil_deep_gb, dtsd_acc_gb, & dim_cs1, resp_s_soilt ) ELSE ! Surface and soil tiles map directly on to each other.