From 6f67d3394b6e4fccd0392da446db79dc8f82d992 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 26 Jun 2026 11:50:00 +0100
Subject: [PATCH 01/53] add additional extrusion
---
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 14 ++
.../lfric2lfric_infrastructure_mod.X90 | 156 +++++++++++++-----
2 files changed, 129 insertions(+), 41 deletions(-)
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index dbe84fe41f..fbf7104840 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -290,3 +290,17 @@ help=The mesh can be used to perform a LFRic forecast (Dynamics),
ns=namelist/lfric2lfric/configuration
value-titles=Dynamics, Source, Destination
values='dynamics', 'source', 'destination'
+
+[namelist:extrusion]
+duplicate=true
+!instance_key_member=mesh_type
+
+[namelist:extrusion=mesh_type]
+compulsory=true
+description=The purpose of the mesh
+!enumeration=true
+help=Is this vertical extrusion associated with the source or
+ =destination grids?
+ns=namelist/lfric2lfric/configuration
+value-titles=Source, Destination
+values='source', 'destination'
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 83f7f6c1f8..2a5c73acf4 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -114,6 +114,9 @@ module lfric2lfric_infrastructure_mod
character(len=*), public, parameter :: source_collection_name = "source_fields"
character(len=*), public, parameter :: target_collection_name = "target_fields"
+ integer(kind=i_def), public, parameter :: dst = 1 ! destination mesh, destination extrusion
+ integer(kind=i_def), public, parameter :: src = 2 ! source mesh, source extrusion
+
contains
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -155,18 +158,21 @@ contains
type(mesh_type), pointer :: orography_twod_mesh
type(mesh_type), pointer :: orography_mesh
- class(extrusion_type), allocatable :: extrusion
+ class(extrusion_type), allocatable :: extrusion_src
+ class(extrusion_type), allocatable :: extrusion_dst
type(uniform_extrusion_type), allocatable :: extrusion_2d
! Pointers for namelists
type(namelist_type), pointer :: planet_nml
- type(namelist_type), pointer :: extrusion_nml
+ type(namelist_type), pointer :: src_extrusion_nml
+ type(namelist_type), pointer :: dst_extrusion_nml
type(namelist_type), pointer :: lfric2lfric_nml
type(namelist_type), pointer :: files_nml
type(namelist_type), pointer :: finite_element_nml
! Namelist parameters
character(len=str_def) :: mesh_names(2)
+ character(len=str_def), allocatable :: mesh_names_dst_ext(2)
character(len=str_def), allocatable :: twod_names(:)
character(len=str_def) :: start_dump_filename
character(len=str_def) :: source_file_lbc
@@ -181,16 +187,16 @@ contains
integer(kind=i_def) :: element_order_h
integer(kind=i_def) :: element_order_v
- integer(kind=i_def) :: extrusion_method
- integer(kind=i_def) :: number_of_layers
- real(kind=r_def) :: domain_height
+ integer(kind=i_def) :: src_extrusion_method
+ integer(kind=i_def) :: dst_extrusion_method
+ integer(kind=i_def) :: src_number_of_layers
+ integer(kind=i_def) :: dst_number_of_layers
+ real(kind=r_def) :: src_domain_height
+ real(kind=r_def) :: dst_domain_height
integer(kind=i_def) :: i
integer(kind=i_def), parameter :: one_layer = 1_i_def
- integer(kind=i_def), parameter :: dst = 1
- integer(kind=i_def), parameter :: src = 2
-
type(coupling_type), pointer :: coupling_ptr
type(field_collection_type), pointer :: cpl_snd_2d
type(field_collection_type), pointer :: cpl_rcv_2d
@@ -217,15 +223,21 @@ contains
! Extract namelist variables
! -------------------------------
planet_nml => modeldb%configuration%get_namelist('planet')
- extrusion_nml => modeldb%configuration%get_namelist('extrusion')
+ src_extrusion_nml => modeldb%configuration%get_namelist('extrusion', &
+ 'source')
+ dst_extrusion_nml => modeldb%configuration%get_namelist('extrusion', &
+ 'destination')
lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric')
files_nml => modeldb%configuration%get_namelist('files')
finite_element_nml => modeldb%configuration%get_namelist('finite_element')
call planet_nml%get_value( 'scaled_radius', scaled_radius )
- call extrusion_nml%get_value( 'method', extrusion_method )
- call extrusion_nml%get_value( 'number_of_layers', number_of_layers )
- call extrusion_nml%get_value( 'domain_height', domain_height )
+ call src_extrusion_nml%get_value( 'method', src_extrusion_method )
+ call src_extrusion_nml%get_value( 'number_of_layers', src_number_of_layers )
+ call src_extrusion_nml%get_value( 'domain_height', src_domain_height )
+ call dst_extrusion_nml%get_value( 'method', dst_extrusion_method )
+ call dst_extrusion_nml%get_value( 'number_of_layers', dst_number_of_layers )
+ call dst_extrusion_nml%get_value( 'domain_height', dst_domain_height )
! Check lfric2lfric configuration settings are allowed
call lfric2lfric_check_configuration( lfric2lfric_nml )
@@ -259,57 +271,109 @@ contains
log_level_error)
end select
- select case (extrusion_method)
+ select case (src_extrusion_method)
case (method_uniform, method_quadratic, method_geometric)
- allocate( extrusion, source=create_extrusion( &
- extrusion_method, domain_height, &
- domain_bottom, number_of_layers, &
- prime_extrusion ) )
+ allocate( src_extrusion, source=create_extrusion( &
+ src_extrusion_method, src_domain_height, &
+ domain_bottom, src_number_of_layers, &
+ prime_extrusion ) )
case (method_dcmip)
- allocate( extrusion, source=dcmip_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=dcmip_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L38_29t_9s_40km)
- allocate( extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L85_50t_35s_85km)
- allocate( extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L70_50t_20s_80km)
- allocate( extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L70_61t_9s_40km)
- allocate( extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L120_99t_21s_40km)
- allocate( extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case (method_um_L140_122t_18s_40km)
- allocate( extrusion, source=um_L140_122t_18s_40km_extrusion_type(&
- domain_bottom, domain_height, &
- number_of_layers, prime_extrusion ) )
+ allocate( src_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
+ domain_bottom, src_domain_height, &
+ src_number_of_layers, prime_extrusion ) )
case default
write( log_scratch_space, '(A)' ) &
"lfric2lfric_infrastructure_mod" // &
- ': Unrecognised extrusion method: ' // &
- trim(key_from_method( extrusion_method ))
+ ': Unrecognised source extrusion method: ' // &
+ trim(key_from_method( src_extrusion_method ))
call log_event( log_scratch_space, log_level_error )
end select
+ select case (dst_extrusion_method)
+ case (method_uniform, method_quadratic, method_geometric)
+ allocate( dst_extrusion, source=create_extrusion( &
+ dst_extrusion_method, dst_domain_height, &
+ domain_bottom, dst_number_of_layers, &
+ prime_extrusion ) )
+
+ case (method_dcmip)
+ allocate( dst_extrusion, source=dcmip_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L38_29t_9s_40km)
+ allocate( dst_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L85_50t_35s_85km)
+ allocate( dst_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L70_50t_20s_80km)
+ allocate( dst_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L70_61t_9s_40km)
+ allocate( dst_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L120_99t_21s_40km)
+ allocate( dst_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L140_122t_18s_40km)
+ allocate( dst_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case default
+ write( log_scratch_space, '(A)' ) &
+ "lfric2lfric_infrastructure_mod" // &
+ ': Unrecognised destination extrusion method: ' // &
+ trim(key_from_method( dst_extrusion_method ))
+ call log_event( log_scratch_space, log_level_error )
+
+ end select
+
+
extrusion_2d = uniform_extrusion_type( domain_bottom, &
domain_bottom, &
one_layer, twod )
@@ -321,8 +385,18 @@ contains
call init_mesh( modeldb%configuration, &
modeldb%mpi%get_comm_rank(), &
modeldb%mpi%get_comm_size(), &
- mesh_names, extrusion, &
+ mesh_names, &
+ src_extrusion, &
stencil_depth, regrid_method )
+
+ ! If dst extrusion is different to src extrusion
+ allocate( mesh_names_dst_ext, source=mesh_names )
+ do i=1, size(mesh_names)
+ mesh_names_dst_ext(i) = trim(mesh_names(i))//'_dst_ext'
+ end do
+ call create_mesh( mesh_names, &
+ dst_extrusion, &
+ alt_name=mesh_names_dst_ext )
allocate( twod_names, source=mesh_names )
do i=1, size(twod_names)
From 9b047e309cfe4ec342dc50cbdbf80d96677455fa Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 26 Jun 2026 14:17:02 +0100
Subject: [PATCH 02/53] change_of_extrusion logical
---
.../lfric2lfric_infrastructure_mod.X90 | 131 ++++++++++--------
1 file changed, 71 insertions(+), 60 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 2a5c73acf4..ee2260bf65 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -158,8 +158,8 @@ contains
type(mesh_type), pointer :: orography_twod_mesh
type(mesh_type), pointer :: orography_mesh
- class(extrusion_type), allocatable :: extrusion_src
- class(extrusion_type), allocatable :: extrusion_dst
+ class(extrusion_type), allocatable :: src_extrusion
+ class(extrusion_type), allocatable :: dst_extrusion
type(uniform_extrusion_type), allocatable :: extrusion_2d
! Pointers for namelists
@@ -204,6 +204,7 @@ contains
type(coupler_exchange_2d_type) :: coupler_exchange_2d
integer(kind=i_def) :: ierror
logical(kind=l_def) :: is_running
+ logical(kind=l_def) :: extrusion_change
!------------------------
! XIOS contexts
@@ -239,6 +240,11 @@ contains
call dst_extrusion_nml%get_value( 'number_of_layers', dst_number_of_layers )
call dst_extrusion_nml%get_value( 'domain_height', dst_domain_height )
+ extrusion_change=.false.
+ if ( src_extrusion_method \= dst_extrusion_method ) then extrusion_change=.true.
+ if ( src_number_of_layers \= dst_number_of_layers ) then extrusion_change=.true.
+ if ( src_domain_height \= dst_domain_height ) then extrusion_change=.true.
+
! Check lfric2lfric configuration settings are allowed
call lfric2lfric_check_configuration( lfric2lfric_nml )
@@ -322,57 +328,60 @@ contains
end select
- select case (dst_extrusion_method)
- case (method_uniform, method_quadratic, method_geometric)
- allocate( dst_extrusion, source=create_extrusion( &
- dst_extrusion_method, dst_domain_height, &
- domain_bottom, dst_number_of_layers, &
- prime_extrusion ) )
-
- case (method_dcmip)
- allocate( dst_extrusion, source=dcmip_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L38_29t_9s_40km)
- allocate( dst_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L85_50t_35s_85km)
- allocate( dst_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_50t_20s_80km)
- allocate( dst_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_61t_9s_40km)
- allocate( dst_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L120_99t_21s_40km)
- allocate( dst_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L140_122t_18s_40km)
- allocate( dst_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case default
- write( log_scratch_space, '(A)' ) &
- "lfric2lfric_infrastructure_mod" // &
- ': Unrecognised destination extrusion method: ' // &
- trim(key_from_method( dst_extrusion_method ))
- call log_event( log_scratch_space, log_level_error )
-
- end select
+ if (extrusion_change) then
+
+ select case (dst_extrusion_method)
+ case (method_uniform, method_quadratic, method_geometric)
+ allocate( dst_extrusion, source=create_extrusion( &
+ dst_extrusion_method, dst_domain_height, &
+ domain_bottom, dst_number_of_layers, &
+ prime_extrusion ) )
+
+ case (method_dcmip)
+ allocate( dst_extrusion, source=dcmip_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L38_29t_9s_40km)
+ allocate( dst_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L85_50t_35s_85km)
+ allocate( dst_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L70_50t_20s_80km)
+ allocate( dst_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L70_61t_9s_40km)
+ allocate( dst_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L120_99t_21s_40km)
+ allocate( dst_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case (method_um_L140_122t_18s_40km)
+ allocate( dst_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
+ domain_bottom, dst_domain_height, &
+ dst_number_of_layers, prime_extrusion ) )
+
+ case default
+ write( log_scratch_space, '(A)' ) &
+ "lfric2lfric_infrastructure_mod" // &
+ ': Unrecognised destination extrusion method: ' // &
+ trim(key_from_method( dst_extrusion_method ))
+ call log_event( log_scratch_space, log_level_error )
+
+ end select
+ end if
extrusion_2d = uniform_extrusion_type( domain_bottom, &
domain_bottom, &
@@ -390,14 +399,16 @@ contains
stencil_depth, regrid_method )
! If dst extrusion is different to src extrusion
- allocate( mesh_names_dst_ext, source=mesh_names )
- do i=1, size(mesh_names)
- mesh_names_dst_ext(i) = trim(mesh_names(i))//'_dst_ext'
- end do
- call create_mesh( mesh_names, &
- dst_extrusion, &
- alt_name=mesh_names_dst_ext )
-
+ if (extrusion_change) then
+ allocate( mesh_names_dst_ext, source=mesh_names )
+ do i=1, size(mesh_names)
+ mesh_names_dst_ext(i) = trim(mesh_names(i))//'_dst_ext'
+ end do
+ call create_mesh( mesh_names, &
+ dst_extrusion, &
+ alt_name=mesh_names_dst_ext )
+ end if
+
allocate( twod_names, source=mesh_names )
do i=1, size(twod_names)
twod_names(i) = trim(twod_names(i))//'_2d'
From 479df9341cc1cb25d9e8c02b9fecdf462d87b811 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 29 Jun 2026 09:02:25 +0100
Subject: [PATCH 03/53] logicals
---
.../lfric2lfric_infrastructure_mod.X90 | 58 +++++++++++++------
1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index ee2260bf65..dd07d8d36d 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -204,8 +204,9 @@ contains
type(coupler_exchange_2d_type) :: coupler_exchange_2d
integer(kind=i_def) :: ierror
logical(kind=l_def) :: is_running
- logical(kind=l_def) :: extrusion_change
-
+ logical(kind=l_def) :: vertical_change
+ logical(kind=l_def) :: horizontal_change
+
!------------------------
! XIOS contexts
!------------------------
@@ -240,11 +241,6 @@ contains
call dst_extrusion_nml%get_value( 'number_of_layers', dst_number_of_layers )
call dst_extrusion_nml%get_value( 'domain_height', dst_domain_height )
- extrusion_change=.false.
- if ( src_extrusion_method \= dst_extrusion_method ) then extrusion_change=.true.
- if ( src_number_of_layers \= dst_number_of_layers ) then extrusion_change=.true.
- if ( src_domain_height \= dst_domain_height ) then extrusion_change=.true.
-
! Check lfric2lfric configuration settings are allowed
call lfric2lfric_check_configuration( lfric2lfric_nml )
@@ -259,6 +255,14 @@ contains
call finite_element_nml%get_value( 'element_order_h', element_order_h)
call finite_element_nml%get_value( 'element_order_v', element_order_v)
+ vertical_change = .false.
+ if ( src_extrusion_method \= dst_extrusion_method ) then vertical_change = .true.
+ if ( src_number_of_layers \= dst_number_of_layers ) then vertical_change = .true.
+ if ( src_domain_height \= dst_domain_height ) then vertical_change = .true.
+
+ horizontal_change = .false.
+ if ( mesh_names(dst) \= mesh_names(src) ) then horizontal_change = .true.
+
!=======================================================================
! Mesh
!=======================================================================
@@ -328,7 +332,7 @@ contains
end select
- if (extrusion_change) then
+ if (vertical_change) then
select case (dst_extrusion_method)
case (method_uniform, method_quadratic, method_geometric)
@@ -398,8 +402,7 @@ contains
src_extrusion, &
stencil_depth, regrid_method )
- ! If dst extrusion is different to src extrusion
- if (extrusion_change) then
+ if (vertical_change) then
allocate( mesh_names_dst_ext, source=mesh_names )
do i=1, size(mesh_names)
mesh_names_dst_ext(i) = trim(mesh_names(i))//'_dst_ext'
@@ -432,9 +435,19 @@ contains
!-----------------------------------------------------------------------
mesh_src => mesh_collection%get_mesh(trim(mesh_names(src)))
twod_mesh_src => mesh_collection%get_mesh(trim(twod_names(src)))
- mesh_dst => mesh_collection%get_mesh(trim(mesh_names(dst)))
- twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
+ if (vertical_change) then
+ mesh_dst => mesh_collection%get_mesh(trim(mesh_names_dst_ext(dst)))
+ twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
+ else
+ mesh_dst => mesh_collection%get_mesh(trim(mesh_names(dst)))
+ twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
+ end if
+
+ if (vertical_change and horizontal_change) then
+ mesh_inter => mesh_collection%get_mesh(trim(mesh_names_dst(dst)))
+ end if
+
! Log this change
call log_event('Source mesh set to: ' // mesh_names(src), &
log_level_debug)
@@ -456,12 +469,21 @@ contains
files_init_ptr => init_lfric2lfric_dst_files
! Initialise the IO context with all the required info
- call init_io( context_dst, &
- mesh_names(dst), &
- modeldb, &
- chi_inventory, &
- panel_id_inventory, &
- populate_filelist=files_init_ptr )
+ if (vertical_change) then
+ call init_io( context_dst, &
+ mesh_names_dst_ext(dst), &
+ modeldb, &
+ chi_inventory, &
+ panel_id_inventory, &
+ populate_filelist=files_init_ptr )
+ else
+ call init_io( context_dst, &
+ mesh_names(dst), &
+ modeldb, &
+ chi_inventory, &
+ panel_id_inventory, &
+ populate_filelist=files_init_ptr )
+ end if
call modeldb%io_contexts%get_io_context(context_dst, io_context_dst)
From f81bfc90c1e3d77286f4c97e6f76fb635d07a217 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 1 Jul 2026 14:12:27 +0100
Subject: [PATCH 04/53] More mesh extrusions and regridding infrastructure
---
.../source/algorithm/lfric2lfric_vert_mod.x90 | 55 ++++++++
.../source/driver/lfric2lfric_driver_mod.F90 | 68 +++++++++-
.../source/driver/lfric2lfric_init_mod.f90 | 53 ++++++--
.../lfric2lfric_infrastructure_mod.X90 | 120 ++++++++++--------
4 files changed, 231 insertions(+), 65 deletions(-)
create mode 100644 applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
new file mode 100644
index 0000000000..c06d0c5c6f
--- /dev/null
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -0,0 +1,55 @@
+module lfric2lfric_vert_mod
+
+ use field_parent_mod, only: field_parent_type
+ use field_mod, only: field_type
+ use field_collection_mod, only: field_collection_type
+ use field_collection_iterator_mod, only: &
+ field_collection_iterator_type
+ use log_mod, only: log_event, &
+ log_level_info, &
+ log_scratch_space
+
+ implicit none
+
+ private
+ public :: lfric2lfric_vert
+
+contains
+
+ subroutine lfric2lfric_vert( source_fields, target_fields )
+
+ implicit none
+
+ type(field_collection_type), intent(inout) :: source_fields
+ type(field_collection_type), intent(inout) :: target_fields
+
+ type(field_collection_iterator_type) :: iter
+
+ class(field_parent_type), pointer :: field => null()
+ type(field_type), pointer :: field_src => null()
+ type(field_type), pointer :: field_dst => null()
+
+ character(len=str_def) :: field_name
+
+ ! Main loop over fields to be processed
+ call iter%initialise(source_fields)
+ do
+ ! Locate the field to be processed in the field collections
+ if ( .not.iter%has_next() ) exit
+ field => iter%next()
+ field_name = field%get_name()
+
+ call source_fields%get_field(field_name, field_src)
+ call target_fields%get_field(field_name, field_dst)
+
+ write(log_scratch_space, '(A,A)') "Processing lfric field ", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_info)
+ ! Dummy initialisation - to be replaced with actual
+ ! vertical regridding
+ call setval_X(field_dst, 1.0_r_def)
+ enddo
+
+ end subroutine lfric2lfric_vert
+
+end module lfric2lfric_vert_mod
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index e02dd55801..b33b0297d5 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -34,8 +34,10 @@ module lfric2lfric_driver_mod
use lfric2lfric_infrastructure_mod, only: initialise_infrastructure, &
context_dst, context_src, &
source_collection_name, &
- target_collection_name
+ target_collection_name, &
+ interm_collection_name
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
+ use lfric2lfric_vert_mod, only: lfric2lfric_vert
implicit none
@@ -92,6 +94,8 @@ subroutine run( modeldb, oasis_clock )
! Local parameters
type(namelist_type), pointer :: files_nml
type(namelist_type), pointer :: lfric2lfric_nml
+ type(namelist_type), pointer :: src_extrusion_nml
+ type(namelist_type), pointer :: dst_extrusion_nml
integer(kind=i_def) :: step, time_steps
logical(kind=l_def) :: is_running
@@ -101,32 +105,79 @@ subroutine run( modeldb, oasis_clock )
type(field_collection_type), pointer :: source_fields
type(field_collection_type), pointer :: target_fields
+ type(field_collection_type), pointer :: interm_fields
type(lfric_xios_context_type), pointer :: io_context
+ character(len=str_def) :: mesh_names(2)
+ integer(kind=i_def) :: src_extrusion_method
+ integer(kind=i_def) :: dst_extrusion_method
+ integer(kind=i_def) :: src_number_of_layers
+ integer(kind=i_def) :: dst_number_of_layers
+ real(kind=r_def) :: src_domain_height
+ real(kind=r_def) :: dst_domain_height
+
! Namelist pointers
files_nml => modeldb%configuration%get_namelist('files')
lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric')
+ src_extrusion_nml => modeldb%configuration%get_namelist('extrusion', &
+ 'source')
+ dst_extrusion_nml => modeldb%configuration%get_namelist('extrusion', &
+ 'destination')
! Extract configuration variables
call files_nml%get_value( 'start_dump_filename', start_dump_filename )
call files_nml%get_value( 'checkpoint_stem_name', checkpoint_stem_name )
call lfric2lfric_nml%get_value( 'mode', mode )
call lfric2lfric_nml%get_value( 'regrid_method', regrid_method )
+
+ call lfric2lfric_nml%get_value( 'destination_mesh_name', &
+ mesh_names(dst) )
+ call lfric2lfric_nml%get_value( 'source_mesh_name', &
+ mesh_names(src) )
+ call src_extrusion_nml%get_value( 'method', src_extrusion_method )
+ call src_extrusion_nml%get_value( 'number_of_layers', src_number_of_layers )
+ call src_extrusion_nml%get_value( 'domain_height', src_domain_height )
+ call dst_extrusion_nml%get_value( 'method', dst_extrusion_method )
+ call dst_extrusion_nml%get_value( 'number_of_layers', dst_number_of_layers )
+ call dst_extrusion_nml%get_value( 'domain_height', dst_domain_height )
+
+ vertical_change = .false.
+ if ( src_extrusion_method \= dst_extrusion_method ) then vertical_change = .true.
+ if ( src_number_of_layers \= dst_number_of_layers ) then vertical_change = .true.
+ if ( src_domain_height \= dst_domain_height ) then vertical_change = .true.
+
+ horizontal_change = .false.
+ if ( mesh_names(dst) \= mesh_names(src) ) then horizontal_change = .true.
! Point to source and target field collections
source_fields => modeldb%fields%get_field_collection(source_collection_name)
target_fields => modeldb%fields%get_field_collection(target_collection_name)
+ if (horizontal_change .and. vertical_change) then
+ interm_fields => modeldb%fields%get_field_collection(intermediate_collection_name)
+
+ else if (horizontal_change .and. .not. vertical_change) then
+ interm_fields => modeldb%fields%get_field_collection(target_collection_name)
+
+ else if (vertical_change .and. .not. horizontal_change) then
+ interm_fields => modeldb%fields%get_field_collection(source_collection_name)
+ end if
+
! Read fields and perform the regridding
if (mode == mode_ics) then
call read_checkpoint(source_fields, &
start_timestep, &
start_dump_filename )
- call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, &
- target_fields, regrid_method)
-
+ if (horizontal_change) then
+ call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, &
+ interm_fields, regrid_method)
+ end if
+ if (vertical_change) then
+ call lfric2lfric_vert(interm_fields, target_fields)
+ end if
+
! Write output
call modeldb%io_contexts%get_io_context(context_dst, io_context)
call io_context%set_current()
@@ -148,8 +199,13 @@ subroutine run( modeldb, oasis_clock )
call read_state(source_fields)
- call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, &
- target_fields, regrid_method)
+ if (horizontal_change) then
+ call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, &
+ interm_fields, regrid_method)
+ end if
+ if (vertical_change) then
+ call lfric2lfric_vert(interm_fields, target_fields)
+ end if
is_running = modeldb%clock%tick()
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index ab2a73b094..43a0c05c7a 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -40,17 +40,25 @@ module lfric2lfric_init_mod
!! will hold the file to be written
!> @param [in] start_dump_filename File to get field names from
!> @param [in] mode Process ics or lbcs
+ !> @param [in] horizontal_change Logical for horizontal regridding
+ !> @param [in] vertical_change Logical for vertical regridding
!> @param [in] origin_collection_name Holds the origin fields
!> @param [in] origin_mesh Mesh to initialise 3D fields
!> @param [in] origin_twod_mesh Mesh to initialise 2D fields
+ !> @param [in] interm_collection_name Holds the intermediate fields
+ !> @param [in] interm_mesh Mesh for intermediate 3D fields
+ !> @param [in] interm_twod_mesh Mesh for intermediate 2D fields
!> @param [in] target_collection_name Holds target fields
!> @param [in] target_mesh Mesh for target 3D fields
!> @param [in] target_twod_mesh Mesh for target 2D fields
- subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
- start_dump_filename, mode, &
- origin_collection_name, &
- origin_mesh, origin_twod_mesh, &
- target_collection_name, &
+ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
+ start_dump_filename, mode, &
+ horizontal_change, vertical_change, &
+ origin_collection_name, &
+ origin_mesh, origin_twod_mesh, &
+ interm_collection_name, &
+ interm_mesh, interm_twod_mesh, &
+ target_collection_name, &
target_mesh, target_twod_mesh )
implicit none
@@ -60,10 +68,14 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
character(len=*), intent(in) :: context_dst
character(len=*), intent(in) :: start_dump_filename
integer(i_def), intent(in) :: mode
+ logical(l_def), intent(in) :: horizontal_change
+ logical(l_def), intent(in) :: vertical_change
character(len=*), intent(in) :: origin_collection_name
type(mesh_type), intent(in), pointer :: origin_mesh
type(mesh_type), intent(in), pointer :: origin_twod_mesh
- ! Optionals
+ character(len=*), intent(in) :: interm_collection_name
+ type(mesh_type), intent(in), pointer :: interm_mesh
+ type(mesh_type), intent(in), pointer :: interm_twod_mesh
character(len=*), intent(in) :: target_collection_name
type(mesh_type), intent(in), pointer :: target_mesh
type(mesh_type), intent(in), pointer :: target_twod_mesh
@@ -116,9 +128,6 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
field_collection => &
modeldb%fields%get_field_collection(target_collection_name)
- call modeldb%io_contexts%get_io_context(context_dst, io_context)
- call io_context%set_current()
-
if (mode == mode_ics) then
prefix = 'checkpoint_'
else if (mode == mode_lbc) then
@@ -133,9 +142,35 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
prefix )
end do
+ !--------------------------------------------------------------------------
+ ! Initialise Intermediate Fields
+ !--------------------------------------------------------------------------
+ if (horizontal_change .and. vertical_change) then
+ call modeldb%fields%add_empty_field_collection(interm_collection_name)
+ field_collection => &
+ modeldb%fields%get_field_collection(interm_collection_name)
+
+ if (mode == mode_ics) then
+ prefix = 'checkpoint_'
+ else if (mode == mode_lbc) then
+ prefix = 'lbc_'
+ end if
+
+ do i = 1, num_fields
+ call field_maker( field_collection, &
+ config_list(i), &
+ interm_mesh, &
+ interm_twod_mesh, &
+ prefix )
+ end do
+ end if
+
call modeldb%io_contexts%get_io_context(context_src, io_context)
call io_context%set_current()
+ call modeldb%io_contexts%get_io_context(context_dst, io_context)
+ call io_context%set_current()
+
! Now finished with config_list, deallocate
deallocate(config_list)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index dd07d8d36d..a0b449c716 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -113,6 +113,7 @@ module lfric2lfric_infrastructure_mod
! Source and destination field collection names
character(len=*), public, parameter :: source_collection_name = "source_fields"
character(len=*), public, parameter :: target_collection_name = "target_fields"
+ character(len=*), public, parameter :: interm_collection_name = "intermediate_fields"
integer(kind=i_def), public, parameter :: dst = 1 ! destination mesh, destination extrusion
integer(kind=i_def), public, parameter :: src = 2 ! source mesh, source extrusion
@@ -155,8 +156,11 @@ contains
type(mesh_type), pointer :: twod_mesh_src
type(mesh_type), pointer :: mesh_dst
type(mesh_type), pointer :: twod_mesh_dst
- type(mesh_type), pointer :: orography_twod_mesh
- type(mesh_type), pointer :: orography_mesh
+ type(mesh_type), pointer :: mesh_interm
+ type(mesh_type), pointer :: orography_twod_mesh_src
+ type(mesh_type), pointer :: orography_mesh_src
+ type(mesh_type), pointer :: orography_twod_mesh_dst
+ type(mesh_type), pointer :: orography_mesh_dst
class(extrusion_type), allocatable :: src_extrusion
class(extrusion_type), allocatable :: dst_extrusion
@@ -402,14 +406,20 @@ contains
src_extrusion, &
stencil_depth, regrid_method )
+
+ allocate( mesh_names_dst_ext, source=mesh_names )
+
if (vertical_change) then
- allocate( mesh_names_dst_ext, source=mesh_names )
do i=1, size(mesh_names)
mesh_names_dst_ext(i) = trim(mesh_names(i))//'_dst_ext'
end do
call create_mesh( mesh_names, &
dst_extrusion, &
alt_name=mesh_names_dst_ext )
+ else
+ do i=1, size(mesh_names)
+ mesh_names_dst_ext(i) = trim(mesh_names(i))
+ end do
end if
allocate( twod_names, source=mesh_names )
@@ -433,30 +443,36 @@ contains
!-----------------------------------------------------------------------
! Assign pointers to the correct meshes
!-----------------------------------------------------------------------
+ ! If the source extrusion is the same as the destination extrusion,
+ ! mesh_dst = mesh_interm and only horizontal interpolation is applied.
+ !
+ ! If the source mesh is the same as the destination mesh,
+ ! mesh_src = mesh_interm and only vertical interpolation is applied.
+ !
+ ! The source meshes
mesh_src => mesh_collection%get_mesh(trim(mesh_names(src)))
twod_mesh_src => mesh_collection%get_mesh(trim(twod_names(src)))
- if (vertical_change) then
- mesh_dst => mesh_collection%get_mesh(trim(mesh_names_dst_ext(dst)))
- twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
- else
- mesh_dst => mesh_collection%get_mesh(trim(mesh_names(dst)))
- twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
- end if
+ ! The interim mesh (horizontal interpolation of mesh_names(src)
+ ! to mesh_names(dst))
+ mesh_interm => mesh_collection%get_mesh(trim(mesh_names(dst)))
- if (vertical_change and horizontal_change) then
- mesh_inter => mesh_collection%get_mesh(trim(mesh_names_dst(dst)))
- end if
-
+ ! The destination mesh (vertical interpolation of mesh_names(dst) to
+ ! mesh_names_dst_ext(dst)
+ mesh_dst => mesh_collection%get_mesh(trim(mesh_names_dst_ext(dst)))
+ twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
+
! Log this change
call log_event('Source mesh set to: ' // mesh_names(src), &
log_level_debug)
call log_event('Source 2D mesh set to: ' // twod_names(src), &
log_level_debug)
- call log_event('Destination mesh set to: ' // mesh_names(dst), &
+ call log_event('Destination mesh set to: ' // mesh_names_dst_ext(dst), &
log_level_debug)
call log_event('Destination 2D mesh set to: ' // twod_names(dst), &
log_level_debug)
+ call log_event('Intermediate mesh set to: ' // mesh_names(dst), &
+ log_level_debug)
!=======================================================================
! Setup I/O system
@@ -469,21 +485,13 @@ contains
files_init_ptr => init_lfric2lfric_dst_files
! Initialise the IO context with all the required info
- if (vertical_change) then
- call init_io( context_dst, &
- mesh_names_dst_ext(dst), &
- modeldb, &
- chi_inventory, &
- panel_id_inventory, &
- populate_filelist=files_init_ptr )
- else
- call init_io( context_dst, &
- mesh_names(dst), &
- modeldb, &
- chi_inventory, &
- panel_id_inventory, &
- populate_filelist=files_init_ptr )
- end if
+ call init_io( context_dst, &
+ mesh_names_dst_ext(dst), &
+ modeldb, &
+ chi_inventory, &
+ panel_id_inventory, &
+ populate_filelist=files_init_ptr )
+
call modeldb%io_contexts%get_io_context(context_dst, io_context_dst)
@@ -511,11 +519,11 @@ contains
halo_depth = twod_mesh_dst%get_halo_depth())
! Get pointers to the destination mesh:
- orography_mesh => mesh_collection%get_mesh(mesh_names(dst))
- orography_twod_mesh => mesh_collection%get_mesh(orography_mesh, TWOD)
+ orography_mesh_dst => mesh_collection%get_mesh(mesh_names(dst))
+ orography_twod_mesh_dst => mesh_collection%get_mesh(orography_mesh, TWOD)
! Set up surface altitude field - this will be used to generate orography
- call init_altitude( orography_twod_mesh, surface_altitude_dst )
+ call init_altitude( orography_twod_mesh_dst, surface_altitude_dst )
end if
!-----------------------------------------------------------------------
@@ -554,35 +562,39 @@ contains
orog_init_option == orog_init_option_start_dump ) then
! Get pointers to the source mesh:
- orography_mesh => mesh_collection%get_mesh(mesh_names(src))
- orography_twod_mesh => mesh_collection%get_mesh(orography_mesh, TWOD)
+ orography_mesh_src => mesh_collection%get_mesh(mesh_names(src))
+ orography_twod_mesh_src => mesh_collection%get_mesh(orography_mesh, TWOD)
call surface_altitude_src%initialise(vector_space, &
name='surface_altitude_src', &
halo_depth = twod_mesh_src%get_halo_depth())
! Set up surface altitude field - this will be used to generate orography
- call init_altitude( orography_twod_mesh, surface_altitude_src )
+ call init_altitude( orography_twod_mesh_src, surface_altitude_src )
end if
!=======================================================================
! Create and initialise prognostic fields
!=======================================================================
if (mode == mode_ics) then
- call init_lfric2lfric( modeldb, context_src, context_dst, &
- start_dump_filename, mode, &
- source_collection_name, mesh_src, twod_mesh_src, &
- target_collection_name, mesh_dst, twod_mesh_dst )
+ call init_lfric2lfric( modeldb, context_src, context_dst, &
+ start_dump_filename, mode, &
+ horizontal_change, vertical_change, &
+ source_collection_name, mesh_src, twod_mesh_src, &
+ interm_collection_name, mesh_interm, twod_mesh_dst, &
+ target_collection_name, mesh_dst, twod_mesh_dst )
else if (mode == mode_lbc) then
call lfric2lfric_nml%get_value( 'source_file_lbc', source_file_lbc )
- call init_lfric2lfric( modeldb, context_src, context_dst, &
- source_file_lbc, mode, &
- source_collection_name, mesh_src, twod_mesh_src, &
- target_collection_name, mesh_dst, twod_mesh_dst )
+ call init_lfric2lfric( modeldb, context_src, context_dst, &
+ source_file_lbc, mode, &
+ horizontal_change, vertical_change, &
+ source_collection_name, mesh_src, twod_mesh_src, &
+ interm_collection_name, mesh_interm, twod_mesh_dst, &
+ target_collection_name, mesh_dst, twod_mesh_dst )
end if
!=======================================================================
- ! Initialize variables for each regrid method
+ ! Initialize variables for each horizontal regrid method
!=======================================================================
select case (regrid_method)
case (regrid_method_map)
@@ -613,7 +625,7 @@ contains
call log_event( log_scratch_space, log_level_error )
#endif
end select
-
+
!=======================================================================
! The lateral boundary conditions of limited-area models (LAMs) are
! implemented by updating the data values at the boundaries with values
@@ -671,10 +683,18 @@ contains
call blend_orography(surface_altitude_dst, surface_altitude_src_on_dst, &
mesh_names(dst))
- call setup_orography_alg( mesh_names(dst:dst), &
- orography_mesh%get_mesh_name(), &
- chi_inventory, &
- panel_id_inventory, &
+ ! Adjust the chi fields to account for the orography
+ ! --------------------------------------------------------
+ call setup_orography_alg( mesh_names(src), &
+ orography_mesh_src%get_mesh_name(), &
+ chi_inventory, &
+ panel_id_inventory, &
+ surface_altitude_src )
+
+ call setup_orography_alg( mesh_names_dst_ext(dst), &
+ orography_mesh_dst%get_mesh_name(), &
+ chi_inventory, &
+ panel_id_inventory, &
surface_altitude_dst )
end if
From a2d157ada4632ec56614f2429fa409704bdf0bbc Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 1 Jul 2026 14:54:10 +0100
Subject: [PATCH 05/53] local build completes
---
.../source/algorithm/lfric2lfric_vert_mod.x90 | 3 +-
.../source/driver/lfric2lfric_driver_mod.F90 | 26 +++++++++++-----
.../source/driver/lfric2lfric_init_mod.f90 | 2 +-
.../lfric2lfric_infrastructure_mod.X90 | 30 +++++++++++--------
4 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index c06d0c5c6f..cc46af3010 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -1,5 +1,6 @@
module lfric2lfric_vert_mod
+ use constants_mod, only: str_def
use field_parent_mod, only: field_parent_type
use field_mod, only: field_type
use field_collection_mod, only: field_collection_type
@@ -47,7 +48,7 @@ contains
call log_event(log_scratch_space, log_level_info)
! Dummy initialisation - to be replaced with actual
! vertical regridding
- call setval_X(field_dst, 1.0_r_def)
+ call invoke(setval_C(field_dst, 1.0_r_def))
enddo
end subroutine lfric2lfric_vert
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index b33b0297d5..0005050a65 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -7,7 +7,7 @@
!>
module lfric2lfric_driver_mod
- use constants_mod, only: str_def, i_def, l_def, r_second
+ use constants_mod, only: str_def, i_def, l_def, r_def, r_second
use driver_fem_mod, only: final_fem
use driver_io_mod, only: final_io
use driver_modeldb_mod, only: modeldb_type
@@ -35,7 +35,8 @@ module lfric2lfric_driver_mod
context_dst, context_src, &
source_collection_name, &
target_collection_name, &
- interm_collection_name
+ interm_collection_name, &
+ src, dst
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
use lfric2lfric_vert_mod, only: lfric2lfric_vert
@@ -117,6 +118,8 @@ subroutine run( modeldb, oasis_clock )
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
+ logical(l_def) :: horizontal_change, vertical_change
+
! Namelist pointers
files_nml => modeldb%configuration%get_namelist('files')
lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric')
@@ -143,19 +146,26 @@ subroutine run( modeldb, oasis_clock )
call dst_extrusion_nml%get_value( 'domain_height', dst_domain_height )
vertical_change = .false.
- if ( src_extrusion_method \= dst_extrusion_method ) then vertical_change = .true.
- if ( src_number_of_layers \= dst_number_of_layers ) then vertical_change = .true.
- if ( src_domain_height \= dst_domain_height ) then vertical_change = .true.
-
+ if ( src_extrusion_method /= dst_extrusion_method ) then
+ vertical_change = .true.
+ end if
+ if ( src_number_of_layers /= dst_number_of_layers ) then
+ vertical_change = .true.
+ end if
+ if ( src_domain_height /= dst_domain_height ) then
+ vertical_change = .true.
+ end if
horizontal_change = .false.
- if ( mesh_names(dst) \= mesh_names(src) ) then horizontal_change = .true.
+ if ( mesh_names(dst) /= mesh_names(src) ) then
+ horizontal_change = .true.
+ end if
! Point to source and target field collections
source_fields => modeldb%fields%get_field_collection(source_collection_name)
target_fields => modeldb%fields%get_field_collection(target_collection_name)
if (horizontal_change .and. vertical_change) then
- interm_fields => modeldb%fields%get_field_collection(intermediate_collection_name)
+ interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
else if (horizontal_change .and. .not. vertical_change) then
interm_fields => modeldb%fields%get_field_collection(target_collection_name)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index 43a0c05c7a..2506439513 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -11,7 +11,7 @@
module lfric2lfric_init_mod
- use constants_mod, only: i_def, r_def, str_def
+ use constants_mod, only: i_def, r_def, str_def, l_def
use driver_modeldb_mod, only: modeldb_type
use field_collection_mod, only: field_collection_type
use lfric_xios_context_mod, only: lfric_xios_context_type
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index a0b449c716..adf7601246 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -176,7 +176,7 @@ contains
! Namelist parameters
character(len=str_def) :: mesh_names(2)
- character(len=str_def), allocatable :: mesh_names_dst_ext(2)
+ character(len=str_def), allocatable :: mesh_names_dst_ext(:)
character(len=str_def), allocatable :: twod_names(:)
character(len=str_def) :: start_dump_filename
character(len=str_def) :: source_file_lbc
@@ -260,13 +260,19 @@ contains
call finite_element_nml%get_value( 'element_order_v', element_order_v)
vertical_change = .false.
- if ( src_extrusion_method \= dst_extrusion_method ) then vertical_change = .true.
- if ( src_number_of_layers \= dst_number_of_layers ) then vertical_change = .true.
- if ( src_domain_height \= dst_domain_height ) then vertical_change = .true.
-
+ if ( src_extrusion_method /= dst_extrusion_method ) then
+ vertical_change = .true.
+ end if
+ if ( src_number_of_layers /= dst_number_of_layers ) then
+ vertical_change = .true.
+ end if
+ if ( src_domain_height /= dst_domain_height ) then
+ vertical_change = .true.
+ end if
horizontal_change = .false.
- if ( mesh_names(dst) \= mesh_names(src) ) then horizontal_change = .true.
-
+ if ( mesh_names(dst) /= mesh_names(src) ) then
+ horizontal_change = .true.
+ end if
!=======================================================================
! Mesh
!=======================================================================
@@ -520,7 +526,7 @@ contains
! Get pointers to the destination mesh:
orography_mesh_dst => mesh_collection%get_mesh(mesh_names(dst))
- orography_twod_mesh_dst => mesh_collection%get_mesh(orography_mesh, TWOD)
+ orography_twod_mesh_dst => mesh_collection%get_mesh(orography_mesh_dst, TWOD)
! Set up surface altitude field - this will be used to generate orography
call init_altitude( orography_twod_mesh_dst, surface_altitude_dst )
@@ -563,7 +569,7 @@ contains
! Get pointers to the source mesh:
orography_mesh_src => mesh_collection%get_mesh(mesh_names(src))
- orography_twod_mesh_src => mesh_collection%get_mesh(orography_mesh, TWOD)
+ orography_twod_mesh_src => mesh_collection%get_mesh(orography_mesh_src, TWOD)
call surface_altitude_src%initialise(vector_space, &
name='surface_altitude_src', &
@@ -685,13 +691,13 @@ contains
! Adjust the chi fields to account for the orography
! --------------------------------------------------------
- call setup_orography_alg( mesh_names(src), &
+ call setup_orography_alg( mesh_names(src:src), &
orography_mesh_src%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
surface_altitude_src )
- call setup_orography_alg( mesh_names_dst_ext(dst), &
+ call setup_orography_alg( mesh_names_dst_ext(dst:dst), &
orography_mesh_dst%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
@@ -699,7 +705,7 @@ contains
end if
deallocate(twod_names)
- deallocate(extrusion)
+ deallocate(src_extrusion, dst_extrusion)
end subroutine initialise_infrastructure
From bafc1ff80c919de6ceac41a03880bde44c872e9a Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 1 Jul 2026 17:59:52 +0100
Subject: [PATCH 06/53] rose
---
.../app/lfric2lfric/opt/rose-app-clim_gal9.conf | 9 ++++++++-
.../opt/rose-app-clim_gal9_ral_seuk.conf | 9 ++++++++-
rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf | 9 ++++++++-
.../app/lfric2lfric/opt/rose-app-ral_seuk.conf | 9 ++++++++-
rose-stem/app/lfric2lfric/rose-app.conf | 14 ++++++++++++--
5 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
index 723f79bc39..97859764ba 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
@@ -1,7 +1,14 @@
[file:lfric2lfric_clim_gal9_C12_MG.nc]
source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_clim_gal9_C12_dt-1800p0_intel_64-bit_fast-debug_000072.nc"
-[namelist:extrusion]
+[namelist:extrusion(source)]
+domain_height=80000.0
+method='um_L70_50t_20s_80km'
+number_of_layers=70
+stretching_height=17507.0
+stretching_method='smooth'
+
+[namelist:extrusion(destination)]
domain_height=80000.0
method='um_L70_50t_20s_80km'
number_of_layers=70
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
index c9a2536321..0e17efbd7d 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
@@ -1,7 +1,14 @@
[file:lfric2lfric_clim_gal9_C12_MG.nc]
source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_clim_gal9_C12_dt-1800p0_intel_64-bit_fast-debug_000072.nc"
-[namelist:extrusion]
+[namelist:extrusion(source)]
+domain_height=80000.0
+method='um_L70_50t_20s_80km'
+number_of_layers=70
+stretching_height=17507.0
+stretching_method='smooth'
+
+[namelist:extrusion(destination)]
domain_height=80000.0
method='um_L70_50t_20s_80km'
number_of_layers=70
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf b/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
index 566f047fd3..5fab9e117a 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
@@ -4,7 +4,14 @@ source=$ROSE_SUITE_DIR/app/lfric2lfric/file/iodef_ral3.xml
[file:lfric2lfric_ral3_seuk.nc]
source="$BIG_DATA_DIR/start_dumps/proto-ral/Ticket3510/seuk/checkpoint_um2lfric_000001.nc"
-[namelist:extrusion]
+[namelist:extrusion(source)]
+domain_height=40000.0
+method='um_L70_61t_9s_40km'
+number_of_layers=70
+stretching_height=16641.984
+stretching_method='smooth'
+
+[namelist:extrusion(destination)]
domain_height=40000.0
method='um_L70_61t_9s_40km'
number_of_layers=70
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
index 441c46314d..538a836596 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
@@ -4,7 +4,14 @@ source=$ROSE_SUITE_DIR/app/lfric2lfric/file/iodef_ral.xml
[file:lfric2lfric_ral_seuk_MG.nc]
source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_proto_ral_seuk_seuk_MG_dt-50p0_intel_64-bit_fast-debug_000072.nc"
-[namelist:extrusion]
+[namelist:extrusion(source)]
+domain_height=40000.0
+method='um_L70_61t_9s_40km'
+number_of_layers=70
+stretching_height=16641.984
+stretching_method='smooth'
+
+[namelist:extrusion(destination)]
domain_height=40000.0
method='um_L70_61t_9s_40km'
number_of_layers=70
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index 3da09230b2..1a0f54d012 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -16,7 +16,7 @@ mode=mkdir
[file:configuration.nml]
mode=auto
-source=namelist:extrusion
+source=namelist:extrusion(:)
= namelist:finite_element
= namelist:io
= (namelist:jules_hydrology)
@@ -239,9 +239,19 @@ vapour_forcing='none'
vertadvect_forcing=.false.
wind_forcing='none'
-[namelist:extrusion]
+[namelist:extrusion(destination)]
domain_height=39254.833575999997
!!eta_values=''
+mesh_type='destination'
+method='um_L38_29t_9s_40km'
+number_of_layers=38
+planet_radius=6371229.0
+stretching_method='linear'
+
+[namelist:extrusion(source)]
+domain_height=39254.833575999997
+!!eta_values=''
+mesh_type='source'
method='um_L38_29t_9s_40km'
number_of_layers=38
planet_radius=6371229.0
From a2e7291207b12262937c6cf8d73e84c96847a645 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 2 Jul 2026 12:47:22 +0100
Subject: [PATCH 07/53] corrections
---
applications/lfric2lfric/example/configuration.nml | 11 +++++++++++
.../source/driver/lfric2lfric_init_mod.f90 | 7 ++++---
.../initialisation/lfric2lfric_infrastructure_mod.X90 | 3 ++-
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index ea19ff5851..a401ca85a1 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -19,6 +19,17 @@ target_domain = 'global',
&extrusion
domain_height = 80000.0,
+mesh_type = 'source',
+method = 'um_L70_50t_20s_80km',
+number_of_layers = 70,
+planet_radius = 6371229.0,
+stretching_height = 17507.0,
+stretching_method = 'smooth',
+/
+
+&extrusion
+domain_height = 80000.0,
+mesh_type = 'destination',
method = 'um_L70_50t_20s_80km',
number_of_layers = 70,
planet_radius = 6371229.0,
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index 2506439513..ab634f2457 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -128,6 +128,9 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
field_collection => &
modeldb%fields%get_field_collection(target_collection_name)
+ call modeldb%io_contexts%get_io_context(context_dst, io_context)
+ call io_context%set_current()
+
if (mode == mode_ics) then
prefix = 'checkpoint_'
else if (mode == mode_lbc) then
@@ -168,9 +171,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call modeldb%io_contexts%get_io_context(context_src, io_context)
call io_context%set_current()
- call modeldb%io_contexts%get_io_context(context_dst, io_context)
- call io_context%set_current()
-
+
! Now finished with config_list, deallocate
deallocate(config_list)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index adf7601246..55bcb36cd3 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -705,7 +705,8 @@ contains
end if
deallocate(twod_names)
- deallocate(src_extrusion, dst_extrusion)
+ deallocate(src_extrusion)
+ if (allocated(dst_extrusion)) deallocate(dst_extrusion)
end subroutine initialise_infrastructure
From 8a08049abca23046ebfa6c81c5da8c4ee5d8219e Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 2 Jul 2026 14:20:30 +0100
Subject: [PATCH 08/53] new task with vertical regridding
---
.../app/lfric2lfric/opt/rose-app-dst_L38_40km.conf | 7 +++++++
.../app/lfric2lfric/opt/rose-app-src_L70_80km.conf | 7 +++++++
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 13 +++++++++++++
rose-stem/site/meto/groups/groups_lfric2lfric.cylc | 1 +
4 files changed, 28 insertions(+)
create mode 100644 rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
create mode 100644 rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf b/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
new file mode 100644
index 0000000000..030f3f8a39
--- /dev/null
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
@@ -0,0 +1,7 @@
+[namelist:extrusion(destination)]
+domain_height=39254.833575999997
+mesh_type='destination'
+method='um_L38_29t_9s_40km'
+number_of_layers=38
+planet_radius=6371229.0
+stretching_method='linear'
\ No newline at end of file
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf b/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
new file mode 100644
index 0000000000..8c7962d5fc
--- /dev/null
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
@@ -0,0 +1,7 @@
+[namelist:extrusion(source)]
+domain_height=80000.0
+mesh_type='source'
+method='um_L70_50t_20s_80km'
+number_of_layers=70
+stretching_height=17507.0
+stretching_method='smooth'
\ No newline at end of file
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index b68dc1efcd..fed9d13d23 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -96,6 +96,19 @@
"src_type": "global",
}) %}
+{% elif task_ns.conf_name == "oasis_C12L70_to_seukL38" %}
+
+ {% do task_dict.update({
+ "opt_confs": ["clim_gal9_ral_seuk","oasis","src_L70_80km","dst_L38_40km"],
+ "resolution": "C12_C16_lam",
+ "dst_mesh": "seuk_MG",
+ "dst_name": "dynamics",
+ "dst_type": "regional",
+ "src_mesh": "C24_C12",
+ "src_name": "C12",
+ "src_type": "global",
+ }) %}
+
{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam" %}
{% do task_dict.update({
diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
index eca0b1d27d..33e7e6befa 100644
--- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
@@ -15,6 +15,7 @@
"lfric2lfric_oasis_clim_gal9-C24_C12_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_seukL38_azspice_gnu_fast-debug-64bit",
"lfric2lfric_azspice_canned",
],
"lfric2lfric_azspice_extra": [
From ddd9ac9cde06a53a68b7fe9b4acaa50e38603514 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 3 Jul 2026 10:20:11 +0100
Subject: [PATCH 09/53] C12 to C12 extrusions
---
rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf | 5 +++++
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 13 +++++++++++++
rose-stem/site/meto/groups/groups_lfric2lfric.cylc | 1 +
3 files changed, 19 insertions(+)
create mode 100644 rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf
new file mode 100644
index 0000000000..a6d7d25af7
--- /dev/null
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf
@@ -0,0 +1,5 @@
+[namelist:lfric2lfric]
+destination_mesh_name='C12'
+destination_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
+source_mesh_name='C12'
+source_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index fed9d13d23..956485023e 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -109,6 +109,19 @@
"src_type": "global",
}) %}
+{% elif task_ns.conf_name == "oasis_C12L70_to_C12L38" %}
+
+ {% do task_dict.update({
+ "opt_confs": ["clim_gal9","oasis","src_L70_80km","dst_L38_40km"],
+ "resolution": "C12_C12",
+ "dst_mesh": "C24_C12",
+ "dst_name": "C12",
+ "dst_type": "global",
+ "src_mesh": "C24_C12",
+ "src_name": "C12",
+ "src_type": "global",
+ }) %}
+
{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam" %}
{% do task_dict.update({
diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
index 33e7e6befa..39eee63405 100644
--- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
@@ -16,6 +16,7 @@
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_C12L70_to_seukL38_azspice_gnu_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_C12L38_azspice_gnu_fast-debug-64bit",
"lfric2lfric_azspice_canned",
],
"lfric2lfric_azspice_extra": [
From 6ee71864c0999c95f6a1a173ced483bc2ad04507 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 3 Jul 2026 15:45:04 +0100
Subject: [PATCH 10/53] lfric2lfric test suite completes on azspice
---
.../initialisation/lfric2lfric_infrastructure_mod.X90 | 1 +
.../opt/{rose-app-C12_C12.conf => rose-app-C12.conf} | 0
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 2 +-
rose-stem/site/meto/groups/groups_lfric2lfric.cylc | 11 ++---------
4 files changed, 4 insertions(+), 10 deletions(-)
rename rose-stem/app/lfric2lfric/opt/{rose-app-C12_C12.conf => rose-app-C12.conf} (100%)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 4c21f4123d..c159a1f23e 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -445,6 +445,7 @@ contains
end do
call create_mesh( mesh_names, &
dst_extrusion, &
+ inner_halo_tiles, tile_size, &
alt_name=mesh_names_dst_ext )
else
do i=1, size(mesh_names)
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
similarity index 100%
rename from rose-stem/app/lfric2lfric/opt/rose-app-C12_C12.conf
rename to rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index 25fe629c29..f55505b95b 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -154,7 +154,7 @@
{% do task_dict.update({
"opt_confs": ["clim_gal9","oasis","src_L70_80km","dst_L38_40km"],
- "resolution": "C12_C12",
+ "resolution": "C12",
"dst_mesh": "C24_C12",
"dst_name": "C12",
"dst_type": "global",
diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
index d8c3830900..f8a76189b0 100644
--- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
@@ -11,19 +11,12 @@
"lfric2lfric_ral_seuk-C32_lam_MG_1cpu_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_ral_seuk-C32_lam_MG_1cpu_azspice_gnu_fast-debug-64bit",
"lfric2lfric_ral3-seuk_azspice_gnu_fast-debug-64bit",
-<<<<<<< HEAD
- "lfric2lfric_clim_gal9-C24_C12_azspice_gnu_fast-debug-64bit",
- "lfric2lfric_oasis_clim_gal9-C24_C12_azspice_gnu_fast-debug-64bit",
- "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit",
- "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit",
- "lfric2lfric_oasis_C12L70_to_seukL38_azspice_gnu_fast-debug-64bit",
- "lfric2lfric_oasis_C12L70_to_C12L38_azspice_gnu_fast-debug-64bit",
-=======
"lfric2lfric_clim_gal9-C24_C12_1cpu_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9-C24_C12_1cpu_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_1cpu_azspice_gnu_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_1cpu_azspice_gnu_fast-debug-64bit",
->>>>>>> upstream/main
+ "lfric2lfric_oasis_C12L70_to_seukL38_azspice_gnu_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_C12L38_azspice_gnu_fast-debug-64bit",
"lfric2lfric_azspice_canned",
],
"lfric2lfric_azspice_extra": [
From 599cf128646d90a73171171cc73e2c5ca7090f20 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 3 Jul 2026 17:23:43 +0100
Subject: [PATCH 11/53] Pass stretching height through argument list (AI
Claude)
---
.../lfric2lfric_infrastructure_mod.X90 | 10 ++++++--
.../gungho/source/driver/gungho_model_mod.F90 | 4 +++-
.../orography/assign_orography_field_mod.F90 | 24 ++++++++++++++++---
.../orography/setup_orography_alg_mod.x90 | 22 +++++++++++------
4 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index c159a1f23e..3fc3ea7f1a 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -194,6 +194,8 @@ contains
integer(kind=i_def) :: dst_number_of_layers
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
+ real(kind=r_def) :: src_stretching_height
+ real(kind=r_def) :: dst_stretching_height
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
@@ -242,9 +244,11 @@ contains
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
+ src_stretching_height = modeldb%config%extrusion%stretching_height()
dst_extrusion_method = modeldb%config%extrusion_dst%method()
dst_number_of_layers = modeldb%config%extrusion_dst%number_of_layers()
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
+ dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
mode = modeldb%config%lfric2lfric%mode()
regrid_method = modeldb%config%lfric2lfric%regrid_method()
@@ -728,13 +732,15 @@ contains
orography_mesh_src%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude_src )
+ surface_altitude_src, &
+ src_stretching_height )
call setup_orography_alg( mesh_names_dst_ext(dst:dst), &
orography_mesh_dst%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude_dst )
+ surface_altitude_dst, &
+ dst_stretching_height )
end if
deallocate(twod_names)
diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90
index b89f3f2ab1..ca7a376917 100644
--- a/science/gungho/source/driver/gungho_model_mod.F90
+++ b/science/gungho/source/driver/gungho_model_mod.F90
@@ -37,6 +37,7 @@ module gungho_model_mod
shifted_extrusion_type, &
double_level_extrusion_type, &
TWOD, SHIFTED, DOUBLE_LEVEL
+ use extrusion_config_mod, only : stretching_height
use multigrid_mod, only : get_multigrid_tile_size, &
init_multigrid_fs_chain
use field_array_mod, only : field_array_type
@@ -1046,7 +1047,8 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
orography_mesh%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude )
+ surface_altitude, &
+ stretching_height )
!=======================================================================
diff --git a/science/gungho/source/orography/assign_orography_field_mod.F90 b/science/gungho/source/orography/assign_orography_field_mod.F90
index 9b9e4299e5..4d131bd74e 100644
--- a/science/gungho/source/orography/assign_orography_field_mod.F90
+++ b/science/gungho/source/orography/assign_orography_field_mod.F90
@@ -67,6 +67,7 @@ subroutine analytic_orography_interface(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
+ stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -78,6 +79,7 @@ subroutine analytic_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi), map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi)
real(kind=r_def), intent(in) :: chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
@@ -98,6 +100,7 @@ subroutine ancil_orography_interface(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
ndf, undf, map, basis)
@@ -112,6 +115,7 @@ subroutine ancil_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: map(ndf)
real(kind=r_def), intent(in) :: basis(ndf,ndf_chi)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: chi_1_in(undf_chi)
real(kind=r_def), intent(in) :: chi_2_in(undf_chi)
@@ -144,9 +148,10 @@ end subroutine ancil_orography_interface
!! fields, itemised by mesh
!> @param[in] mesh Mesh to apply orography to
!> @param[in] surface_altitude Field containing the surface altitude
+ !> @param[in] stretching_height Vertical stretching height parameter
!=============================================================================
subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
- mesh, surface_altitude)
+ mesh, surface_altitude, stretching_height)
use inventory_by_mesh_mod, only : inventory_by_mesh_type
use field_mod, only : field_type, field_proxy_type
@@ -168,6 +173,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
! We keep the surface_altitude as an optional argument since it is
! not needed for miniapps that only want analytic orography
type(field_type), optional, intent(in) :: surface_altitude
+ real(kind=r_def), intent(in) :: stretching_height
! Local variables
type(field_type), pointer :: chi(:)
@@ -260,7 +266,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
call analytic_orography( &
nlayers, ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
- domain_surface, domain_height, &
+ domain_surface, domain_height, stretching_height, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, &
chi_in_proxy(3)%data, &
chi_proxy(1)%data, chi_proxy(2)%data, chi_proxy(3)%data, &
@@ -336,7 +342,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
nlayers, chi_proxy(1)%data, chi_proxy(2)%data, chi_proxy(3)%data, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, chi_in_proxy(3)%data, &
panel_id_proxy%data, sfc_alt_proxy%data, &
- domain_surface, domain_height, &
+ domain_surface, domain_height, stretching_height, &
ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
ndf_sf, undf_sf, map_sf(:,cell), basis_sf_on_chi &
@@ -382,6 +388,7 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
+ stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -393,6 +400,7 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -478,6 +486,7 @@ subroutine analytic_orography_spherical_native(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
+ stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -490,6 +499,7 @@ subroutine analytic_orography_spherical_native(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -570,6 +580,7 @@ subroutine analytic_orography_cartesian(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
+ stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -582,6 +593,7 @@ subroutine analytic_orography_cartesian(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -656,6 +668,7 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -682,6 +695,7 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
@@ -769,6 +783,7 @@ subroutine ancil_orography_spherical_sph(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -795,6 +810,7 @@ subroutine ancil_orography_spherical_sph(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
@@ -867,6 +883,7 @@ subroutine ancil_orography_cartesian(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -893,6 +910,7 @@ subroutine ancil_orography_cartesian(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
+ real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
diff --git a/science/gungho/source/orography/setup_orography_alg_mod.x90 b/science/gungho/source/orography/setup_orography_alg_mod.x90
index 94ebcca3c5..1476d13aa4 100644
--- a/science/gungho/source/orography/setup_orography_alg_mod.x90
+++ b/science/gungho/source/orography/setup_orography_alg_mod.x90
@@ -57,11 +57,13 @@ contains
!> @param[in] panel_id_inventory Contains the model's panel ID fields
!! paired with their mesh.
!> @param[in] surf_alt_w3 Surface altitude on the orography mesh
+ !> @param[in] stretching_height Vertical stretching height parameter
subroutine setup_orography_alg( all_mesh_names, &
orography_mesh_name, &
chi_inventory, &
panel_id_inventory, &
- surf_alt_w3 )
+ surf_alt_w3, &
+ stretching_height )
use assign_orography_field_mod, only: assign_orography_field
use surface_altitude_alg_mod, only: surface_altitude_alg
@@ -77,6 +79,7 @@ contains
type(inventory_by_mesh_type), intent(inout) :: chi_inventory
type(inventory_by_mesh_type), intent(in) :: panel_id_inventory
type(field_type), intent(in) :: surf_alt_w3
+ real(kind=r_def), intent(in) :: stretching_height
! local variables
integer(kind=i_def) :: i, fs_id
@@ -185,21 +188,24 @@ contains
! Assignment of orography from surface_altitude on orography mesh
call assign_orography_field( &
- chi_inventory, panel_id_inventory, source_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, source_mesh, surf_alt_w0, &
+ stretching_height &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(source_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(source_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0, &
+ stretching_height &
)
end if
if (mesh_collection%check_for(source_mesh, DOUBLE_LEVEL)) then
double_level_mesh => mesh_collection%get_mesh(source_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, double_level_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, double_level_mesh, surf_alt_w0, &
+ stretching_height &
)
end if
@@ -301,14 +307,16 @@ contains
! Adjust coordinates
! ---------------------------------------------------------------------- !
call assign_orography_field( &
- chi_inventory, panel_id_inventory, target_mesh, surf_alt_w0_ptr &
+ chi_inventory, panel_id_inventory, target_mesh, surf_alt_w0_ptr, &
+ stretching_height &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(target_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(target_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0_ptr &
+ chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0_ptr, &
+ stretching_height &
)
end if
@@ -316,7 +324,7 @@ contains
double_level_mesh => mesh_collection%get_mesh(target_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
chi_inventory, panel_id_inventory, double_level_mesh, &
- surf_alt_w0_ptr &
+ surf_alt_w0_ptr, stretching_height &
)
end if
end do
From b978cf6d2886f911a5d9032f8f7a859e4051b3fd Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 9 Jul 2026 10:51:17 +0100
Subject: [PATCH 12/53] Revert "Pass stretching height through argument list
(AI Claude)"
This reverts commit 599cf128646d90a73171171cc73e2c5ca7090f20.
---
.../lfric2lfric_infrastructure_mod.X90 | 10 ++------
.../gungho/source/driver/gungho_model_mod.F90 | 4 +---
.../orography/assign_orography_field_mod.F90 | 24 +++----------------
.../orography/setup_orography_alg_mod.x90 | 22 ++++++-----------
4 files changed, 13 insertions(+), 47 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 3fc3ea7f1a..c159a1f23e 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -194,8 +194,6 @@ contains
integer(kind=i_def) :: dst_number_of_layers
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
- real(kind=r_def) :: src_stretching_height
- real(kind=r_def) :: dst_stretching_height
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
@@ -244,11 +242,9 @@ contains
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
- src_stretching_height = modeldb%config%extrusion%stretching_height()
dst_extrusion_method = modeldb%config%extrusion_dst%method()
dst_number_of_layers = modeldb%config%extrusion_dst%number_of_layers()
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
- dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
mode = modeldb%config%lfric2lfric%mode()
regrid_method = modeldb%config%lfric2lfric%regrid_method()
@@ -732,15 +728,13 @@ contains
orography_mesh_src%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude_src, &
- src_stretching_height )
+ surface_altitude_src )
call setup_orography_alg( mesh_names_dst_ext(dst:dst), &
orography_mesh_dst%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude_dst, &
- dst_stretching_height )
+ surface_altitude_dst )
end if
deallocate(twod_names)
diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90
index ca7a376917..b89f3f2ab1 100644
--- a/science/gungho/source/driver/gungho_model_mod.F90
+++ b/science/gungho/source/driver/gungho_model_mod.F90
@@ -37,7 +37,6 @@ module gungho_model_mod
shifted_extrusion_type, &
double_level_extrusion_type, &
TWOD, SHIFTED, DOUBLE_LEVEL
- use extrusion_config_mod, only : stretching_height
use multigrid_mod, only : get_multigrid_tile_size, &
init_multigrid_fs_chain
use field_array_mod, only : field_array_type
@@ -1047,8 +1046,7 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
orography_mesh%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
- surface_altitude, &
- stretching_height )
+ surface_altitude )
!=======================================================================
diff --git a/science/gungho/source/orography/assign_orography_field_mod.F90 b/science/gungho/source/orography/assign_orography_field_mod.F90
index 4d131bd74e..9b9e4299e5 100644
--- a/science/gungho/source/orography/assign_orography_field_mod.F90
+++ b/science/gungho/source/orography/assign_orography_field_mod.F90
@@ -67,7 +67,6 @@ subroutine analytic_orography_interface(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
- stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -79,7 +78,6 @@ subroutine analytic_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi), map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi)
real(kind=r_def), intent(in) :: chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
@@ -100,7 +98,6 @@ subroutine ancil_orography_interface(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
- stretching_height, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
ndf, undf, map, basis)
@@ -115,7 +112,6 @@ subroutine ancil_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: map(ndf)
real(kind=r_def), intent(in) :: basis(ndf,ndf_chi)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: chi_1_in(undf_chi)
real(kind=r_def), intent(in) :: chi_2_in(undf_chi)
@@ -148,10 +144,9 @@ end subroutine ancil_orography_interface
!! fields, itemised by mesh
!> @param[in] mesh Mesh to apply orography to
!> @param[in] surface_altitude Field containing the surface altitude
- !> @param[in] stretching_height Vertical stretching height parameter
!=============================================================================
subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
- mesh, surface_altitude, stretching_height)
+ mesh, surface_altitude)
use inventory_by_mesh_mod, only : inventory_by_mesh_type
use field_mod, only : field_type, field_proxy_type
@@ -173,7 +168,6 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
! We keep the surface_altitude as an optional argument since it is
! not needed for miniapps that only want analytic orography
type(field_type), optional, intent(in) :: surface_altitude
- real(kind=r_def), intent(in) :: stretching_height
! Local variables
type(field_type), pointer :: chi(:)
@@ -266,7 +260,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
call analytic_orography( &
nlayers, ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
- domain_surface, domain_height, stretching_height, &
+ domain_surface, domain_height, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, &
chi_in_proxy(3)%data, &
chi_proxy(1)%data, chi_proxy(2)%data, chi_proxy(3)%data, &
@@ -342,7 +336,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
nlayers, chi_proxy(1)%data, chi_proxy(2)%data, chi_proxy(3)%data, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, chi_in_proxy(3)%data, &
panel_id_proxy%data, sfc_alt_proxy%data, &
- domain_surface, domain_height, stretching_height, &
+ domain_surface, domain_height, &
ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
ndf_sf, undf_sf, map_sf(:,cell), basis_sf_on_chi &
@@ -388,7 +382,6 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
- stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -400,7 +393,6 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -486,7 +478,6 @@ subroutine analytic_orography_spherical_native(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
- stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -499,7 +490,6 @@ subroutine analytic_orography_spherical_native(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -580,7 +570,6 @@ subroutine analytic_orography_cartesian(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
- stretching_height, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -593,7 +582,6 @@ subroutine analytic_orography_cartesian(nlayers, &
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi), chi_2(undf_chi)
@@ -668,7 +656,6 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
- stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -695,7 +682,6 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
@@ -783,7 +769,6 @@ subroutine ancil_orography_spherical_sph(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
- stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -810,7 +795,6 @@ subroutine ancil_orography_spherical_sph(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
@@ -883,7 +867,6 @@ subroutine ancil_orography_cartesian(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
- stretching_height, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -910,7 +893,6 @@ subroutine ancil_orography_cartesian(nlayers, &
real(kind=r_def), intent(in) :: panel_id(undf_pid)
real(kind=r_def), intent(in) :: surface_altitude(undf)
real(kind=r_def), intent(in) :: domain_surface, domain_height
- real(kind=r_def), intent(in) :: stretching_height
! Internal variables
integer(kind=i_def) :: k, df, dfchi, dfk
diff --git a/science/gungho/source/orography/setup_orography_alg_mod.x90 b/science/gungho/source/orography/setup_orography_alg_mod.x90
index 1476d13aa4..94ebcca3c5 100644
--- a/science/gungho/source/orography/setup_orography_alg_mod.x90
+++ b/science/gungho/source/orography/setup_orography_alg_mod.x90
@@ -57,13 +57,11 @@ contains
!> @param[in] panel_id_inventory Contains the model's panel ID fields
!! paired with their mesh.
!> @param[in] surf_alt_w3 Surface altitude on the orography mesh
- !> @param[in] stretching_height Vertical stretching height parameter
subroutine setup_orography_alg( all_mesh_names, &
orography_mesh_name, &
chi_inventory, &
panel_id_inventory, &
- surf_alt_w3, &
- stretching_height )
+ surf_alt_w3 )
use assign_orography_field_mod, only: assign_orography_field
use surface_altitude_alg_mod, only: surface_altitude_alg
@@ -79,7 +77,6 @@ contains
type(inventory_by_mesh_type), intent(inout) :: chi_inventory
type(inventory_by_mesh_type), intent(in) :: panel_id_inventory
type(field_type), intent(in) :: surf_alt_w3
- real(kind=r_def), intent(in) :: stretching_height
! local variables
integer(kind=i_def) :: i, fs_id
@@ -188,24 +185,21 @@ contains
! Assignment of orography from surface_altitude on orography mesh
call assign_orography_field( &
- chi_inventory, panel_id_inventory, source_mesh, surf_alt_w0, &
- stretching_height &
+ chi_inventory, panel_id_inventory, source_mesh, surf_alt_w0 &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(source_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(source_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0, &
- stretching_height &
+ chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0 &
)
end if
if (mesh_collection%check_for(source_mesh, DOUBLE_LEVEL)) then
double_level_mesh => mesh_collection%get_mesh(source_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, double_level_mesh, surf_alt_w0, &
- stretching_height &
+ chi_inventory, panel_id_inventory, double_level_mesh, surf_alt_w0 &
)
end if
@@ -307,16 +301,14 @@ contains
! Adjust coordinates
! ---------------------------------------------------------------------- !
call assign_orography_field( &
- chi_inventory, panel_id_inventory, target_mesh, surf_alt_w0_ptr, &
- stretching_height &
+ chi_inventory, panel_id_inventory, target_mesh, surf_alt_w0_ptr &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(target_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(target_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0_ptr, &
- stretching_height &
+ chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0_ptr &
)
end if
@@ -324,7 +316,7 @@ contains
double_level_mesh => mesh_collection%get_mesh(target_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
chi_inventory, panel_id_inventory, double_level_mesh, &
- surf_alt_w0_ptr, stretching_height &
+ surf_alt_w0_ptr &
)
end if
end do
From 1a022fe8962a04801b2c606c474ef3829f7a7002 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 9 Jul 2026 12:18:39 +0100
Subject: [PATCH 13/53] correction
---
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index f55505b95b..a2e035a9d1 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -174,19 +174,7 @@
"src_mesh": "C24_C12",
"src_name": "C12",
"src_type": "global",
- }) %}
-
-{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam" %}
- {% do task_dict.update({
- "opt_confs": ["clim_gal9_ral_seuk","oasis"],
- "resolution": "C12_C16_lam",
- "dst_mesh": "seuk_MG",
- "dst_name": "dynamics",
- "dst_type": "regional",
- "src_mesh": "C24_C12",
- "src_name": "C12",
- "src_type": "global",
- "mpi_parts": 6,
+ "mpi_parts": 6,
}) %}
{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam_1cpu" %}
From 5f97a961050b477785c6f1b8c922bdb5bd48e949 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 9 Jul 2026 14:08:56 +0100
Subject: [PATCH 14/53] Add stretching_height as a subroutine parameter
---
.../source/driver/lfric2lfric_driver_mod.F90 | 14 ++++
.../lfric2lfric_infrastructure_mod.X90 | 24 ++++++-
.../gungho/source/driver/gungho_model_mod.F90 | 22 ++++---
.../orography/assign_orography_field_mod.F90 | 66 +++++++++++++++++--
.../orography/setup_orography_alg_mod.x90 | 24 +++++--
5 files changed, 129 insertions(+), 21 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 0e8eb42adc..681b4a49bc 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -110,17 +110,25 @@ subroutine run( modeldb, oasis_clock )
integer(kind=i_def) :: dst_extrusion_method
integer(kind=i_def) :: src_number_of_layers
integer(kind=i_def) :: dst_number_of_layers
+ integer(kind=i_def) :: src_stretching_method
+ integer(kind=i_def) :: dst_stretching_method
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
+ real(kind=r_def) :: src_stretching_height
+ real(kind=r_def) :: dst_stretching_height
logical(l_def) :: horizontal_change, vertical_change
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
+ src_stretching_height = modeldb%config%extrusion%stretching_height()
+ src_stretching_method = modeldb%config%extrusion%stretching_method()
dst_extrusion_method = modeldb%config%extrusion_dst%method()
dst_number_of_layers = modeldb%config%extrusion_dst%number_of_layers()
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
+ dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
+ dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
mesh_names(src) = modeldb%config%lfric2lfric%source_mesh_name()
@@ -135,6 +143,12 @@ subroutine run( modeldb, oasis_clock )
if ( src_domain_height /= dst_domain_height ) then
vertical_change = .true.
end if
+ if ( src_stretching_height /= dst_stretching_height ) then
+ vertical_change = .true.
+ end if
+ if ( src_stretching_method /= dst_stretching_method ) then
+ vertical_change = .true.
+ end if
horizontal_change = .false.
if ( mesh_names(dst) /= mesh_names(src) ) then
horizontal_change = .true.
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index c159a1f23e..8ad7d6cec0 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -192,8 +192,15 @@ contains
integer(kind=i_def) :: dst_extrusion_method
integer(kind=i_def) :: src_number_of_layers
integer(kind=i_def) :: dst_number_of_layers
+ integer(kind=i_def) :: src_stretching_method
+ integer(kind=i_def) :: dst_stretching_method
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
+ real(kind=r_def) :: src_stretching_height
+ real(kind=r_def) :: dst_stretching_height
+
+ logical(kind=l_def) :: vertical_change
+ logical(kind=l_def) :: horizontal_change
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
@@ -210,8 +217,6 @@ contains
type(coupler_exchange_2d_type) :: coupler_exchange_2d
integer(kind=i_def) :: ierror
logical(kind=l_def) :: is_running
- logical(kind=l_def) :: vertical_change
- logical(kind=l_def) :: horizontal_change
!------------------------
! XIOS contexts
@@ -242,9 +247,13 @@ contains
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
+ src_stretching_height = modeldb%config%extrusion%stretching_height()
+ src_stretching_method = modeldb%config%extrusion%stretching_method()
dst_extrusion_method = modeldb%config%extrusion_dst%method()
dst_number_of_layers = modeldb%config%extrusion_dst%number_of_layers()
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
+ dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
+ dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
mode = modeldb%config%lfric2lfric%mode()
regrid_method = modeldb%config%lfric2lfric%regrid_method()
@@ -273,10 +282,17 @@ contains
if ( src_domain_height /= dst_domain_height ) then
vertical_change = .true.
end if
+ if ( src_stretching_height /= dst_stretching_height ) then
+ vertical_change = .true.
+ end if
+ if ( src_stretching_method /= dst_stretching_method ) then
+ vertical_change = .true.
+ end if
horizontal_change = .false.
if ( mesh_names(dst) /= mesh_names(src) ) then
horizontal_change = .true.
end if
+
!=======================================================================
! Mesh
!=======================================================================
@@ -728,12 +744,16 @@ contains
orography_mesh_src%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
+ src_stretching_height, &
+ src_stretching_method, &
surface_altitude_src )
call setup_orography_alg( mesh_names_dst_ext(dst:dst), &
orography_mesh_dst%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
+ dst_stretching_height, &
+ dst_stretching_method, &
surface_altitude_dst )
end if
diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90
index b89f3f2ab1..f488c7df4b 100644
--- a/science/gungho/source/driver/gungho_model_mod.F90
+++ b/science/gungho/source/driver/gungho_model_mod.F90
@@ -563,6 +563,8 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
character(str_def), allocatable :: twod_names(:)
character(str_def), allocatable :: shifted_names(:)
character(str_def), allocatable :: double_names(:)
+ integer(i_def) :: stretching_method
+ real(r_def) :: stretching_height
character(str_def), allocatable :: meshes_to_check(:)
@@ -620,14 +622,16 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
chain_mesh_tags = modeldb%config%multigrid%chain_mesh_tags()
end if
- prime_mesh_name = modeldb%config%base_mesh%prime_mesh_name()
- geometry = modeldb%config%base_mesh%geometry()
- topology = modeldb%config%base_mesh%topology()
- prepartitioned = modeldb%config%base_mesh%prepartitioned()
- domain_height = modeldb%config%extrusion%domain_height()
- extrusion_method = modeldb%config%extrusion%method()
- number_of_layers = modeldb%config%extrusion%number_of_layers()
- scaled_radius = modeldb%config%planet%scaled_radius()
+ prime_mesh_name = modeldb%config%base_mesh%prime_mesh_name()
+ geometry = modeldb%config%base_mesh%geometry()
+ topology = modeldb%config%base_mesh%topology()
+ prepartitioned = modeldb%config%base_mesh%prepartitioned()
+ domain_height = modeldb%config%extrusion%domain_height()
+ extrusion_method = modeldb%config%extrusion%method()
+ stretching_method = modeldb%config%extrusion%stretching_method()
+ stretching_height = modeldb%config%extrusion%stretching_height()
+ number_of_layers = modeldb%config%extrusion%number_of_layers()
+ scaled_radius = modeldb%config%planet%scaled_radius()
if (prepartitioned) then
tile_size_x = 1
@@ -1046,6 +1050,8 @@ subroutine initialise_infrastructure( io_context_name, modeldb )
orography_mesh%get_mesh_name(), &
chi_inventory, &
panel_id_inventory, &
+ stretching_height, &
+ stretching_method, &
surface_altitude )
diff --git a/science/gungho/source/orography/assign_orography_field_mod.F90 b/science/gungho/source/orography/assign_orography_field_mod.F90
index 9b9e4299e5..06c2e31018 100644
--- a/science/gungho/source/orography/assign_orography_field_mod.F90
+++ b/science/gungho/source/orography/assign_orography_field_mod.F90
@@ -29,9 +29,7 @@ module assign_orography_field_mod
eta2z_linear, &
eta2z_smooth
use analytic_orography_mod, only : orography_profile
- use extrusion_config_mod, only : stretching_height, &
- stretching_method, &
- stretching_method_linear
+ use extrusion_config_mod, only : stretching_method_linear
use log_mod, only : log_event, &
LOG_LEVEL_INFO, &
LOG_LEVEL_ERROR
@@ -67,6 +65,8 @@ subroutine analytic_orography_interface(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -77,6 +77,8 @@ subroutine analytic_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: nlayers, undf_chi, undf_pid
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi), map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: domain_surface, domain_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi)
real(kind=r_def), intent(in) :: chi_2_in(undf_chi)
@@ -98,6 +100,8 @@ subroutine ancil_orography_interface(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
ndf, undf, map, basis)
@@ -110,6 +114,8 @@ subroutine ancil_orography_interface(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid, ndf
integer(kind=i_def), intent(in) :: map_chi(ndf_chi), map_pid(ndf_pid)
integer(kind=i_def), intent(in) :: map(ndf)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: basis(ndf,ndf_chi)
real(kind=r_def), intent(in) :: domain_surface, domain_height
real(kind=r_def), intent(in) :: surface_altitude(undf)
@@ -143,10 +149,14 @@ end subroutine ancil_orography_interface
!> @param[in] panel_id_inventory Contains all of the model's panel ID
!! fields, itemised by mesh
!> @param[in] mesh Mesh to apply orography to
+ !> @param[in] stretching_height Physical height above which surface altitude
+ !! does not influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] surface_altitude Field containing the surface altitude
!=============================================================================
- subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
- mesh, surface_altitude)
+ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
+ mesh, stretching_height, &
+ stretching_method, surface_altitude)
use inventory_by_mesh_mod, only : inventory_by_mesh_type
use field_mod, only : field_type, field_proxy_type
@@ -164,6 +174,8 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
type(inventory_by_mesh_type), intent(inout) :: chi_inventory
type(inventory_by_mesh_type), intent(in) :: panel_id_inventory
type(mesh_type), pointer, intent(in) :: mesh
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
! We keep the surface_altitude as an optional argument since it is
! not needed for miniapps that only want analytic orography
@@ -261,6 +273,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
nlayers, ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
domain_surface, domain_height, &
+ stretching_height, stretching_method, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, &
chi_in_proxy(3)%data, &
chi_proxy(1)%data, chi_proxy(2)%data, chi_proxy(3)%data, &
@@ -337,6 +350,7 @@ subroutine assign_orography_field(chi_inventory, panel_id_inventory, &
chi_in_proxy(1)%data, chi_in_proxy(2)%data, chi_in_proxy(3)%data, &
panel_id_proxy%data, sfc_alt_proxy%data, &
domain_surface, domain_height, &
+ stretching_height, stretching_method, &
ndf_chi, undf_chi, map_chi(:,cell), &
ndf_pid, undf_pid, map_pid(:,cell), &
ndf_sf, undf_sf, map_sf(:,cell), basis_sf_on_chi &
@@ -370,6 +384,9 @@ end subroutine assign_orography_field
!> @param[in] map_pid Indirection map for panel_id
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] chi_1_in 1st coordinate field in Wchi (input)
!> @param[in] chi_2_in 2nd coordinate field in Wchi (input)
!> @param[in] chi_3_in 3rd coordinate field in Wchi (input)
@@ -382,6 +399,8 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
ndf_chi, undf_chi, map_chi, &
ndf_pid, undf_pid, map_pid, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, panel_id)
@@ -392,6 +411,8 @@ subroutine analytic_orography_spherical_xyz(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: domain_surface, domain_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
@@ -465,6 +486,9 @@ end subroutine analytic_orography_spherical_xyz
!> @param[in] map_pid Indirection map for panel_id
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] chi_1_in 1st coordinate field in Wchi (input)
!> @param[in] chi_2_in 2nd coordinate field in Wchi (input)
!> @param[in] chi_3_in 3rd coordinate field in Wchi (input)
@@ -478,6 +502,8 @@ subroutine analytic_orography_spherical_native(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
+ stretching_height, &
+ stretching_method, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -489,6 +515,8 @@ subroutine analytic_orography_spherical_native(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: domain_surface, domain_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
@@ -557,6 +585,9 @@ end subroutine analytic_orography_spherical_native
!> @param[in] map_pid Indirection map for panel_id
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] chi_1_in 1st coordinate field in Wchi (input)
!> @param[in] chi_2_in 2nd coordinate field in Wchi (input)
!> @param[in] chi_3_in 3rd coordinate field in Wchi (input)
@@ -570,6 +601,8 @@ subroutine analytic_orography_cartesian(nlayers, &
ndf_pid, undf_pid, map_pid, &
domain_surface, &
domain_height, &
+ stretching_height, &
+ stretching_method, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id)
@@ -581,6 +614,8 @@ subroutine analytic_orography_cartesian(nlayers, &
integer(kind=i_def), intent(in) :: ndf_chi, ndf_pid
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: domain_surface, domain_height
real(kind=r_def), intent(in) :: chi_1_in(undf_chi), chi_2_in(undf_chi)
real(kind=r_def), intent(in) :: chi_3_in(undf_chi)
@@ -639,6 +674,9 @@ end subroutine analytic_orography_cartesian
!> @param[in] surface_altitude Surface altitude field data
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] ndf_chi Num DoFs per cell for map_chi
!> @param[in] undf_chi Column coords' num DoFs this partition
!> @param[in] map_chi Indirection map for coordinate field
@@ -656,6 +694,8 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -672,6 +712,8 @@ subroutine ancil_orography_spherical_xyz(nlayers, &
integer(kind=i_def), intent(in) :: map(ndf)
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: basis(ndf, ndf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi)
real(kind=r_def), intent(inout) :: chi_2(undf_chi)
@@ -752,6 +794,9 @@ end subroutine ancil_orography_spherical_xyz
!> @param[in] surface_altitude Surface altitude field data
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] ndf_chi Num DoFs per cell for map_chi
!> @param[in] undf_chi Column coords' num DoFs this partition
!> @param[in] map_chi Indirection map for coordinate field
@@ -769,6 +814,8 @@ subroutine ancil_orography_spherical_sph(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -785,6 +832,8 @@ subroutine ancil_orography_spherical_sph(nlayers, &
integer(kind=i_def), intent(in) :: map(ndf)
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: basis(ndf, ndf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi)
real(kind=r_def), intent(inout) :: chi_2(undf_chi)
@@ -850,6 +899,9 @@ end subroutine ancil_orography_spherical_sph
!> @param[in] surface_altitude Surface altitude field data
!> @param[in] domain_surface Physical height of flat domain surface (m)
!> @param[in] domain_height Physical height of domain top (m)
+ !> @param[in] stretching_height Physical height above which surface altitude does not
+ !! influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] ndf_chi Num DoFs per cell for map_chi
!> @param[in] undf_chi Column coords' num DoFs this partition
!> @param[in] map_chi Indirection map for coordinate field
@@ -867,6 +919,8 @@ subroutine ancil_orography_cartesian(nlayers, &
panel_id, &
surface_altitude, &
domain_surface, domain_height, &
+ stretching_height, &
+ stretching_method, &
ndf_chi, undf_chi, &
map_chi, &
ndf_pid, undf_pid, &
@@ -883,6 +937,8 @@ subroutine ancil_orography_cartesian(nlayers, &
integer(kind=i_def), intent(in) :: map(ndf)
integer(kind=i_def), intent(in) :: map_chi(ndf_chi)
integer(kind=i_def), intent(in) :: map_pid(ndf_pid)
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
real(kind=r_def), intent(in) :: basis(ndf, ndf_chi)
real(kind=r_def), intent(inout) :: chi_1(undf_chi)
real(kind=r_def), intent(inout) :: chi_2(undf_chi)
diff --git a/science/gungho/source/orography/setup_orography_alg_mod.x90 b/science/gungho/source/orography/setup_orography_alg_mod.x90
index 94ebcca3c5..fe68dd423f 100644
--- a/science/gungho/source/orography/setup_orography_alg_mod.x90
+++ b/science/gungho/source/orography/setup_orography_alg_mod.x90
@@ -56,11 +56,16 @@ contains
!! paired with their mesh.
!> @param[in] panel_id_inventory Contains the model's panel ID fields
!! paired with their mesh.
+ !> @param[in] stretching_height Physical height above which surface altitude
+ !! does not influence layer height (m)
+ !> @param[in] stretching_method Method of generating stretching
!> @param[in] surf_alt_w3 Surface altitude on the orography mesh
subroutine setup_orography_alg( all_mesh_names, &
orography_mesh_name, &
chi_inventory, &
panel_id_inventory, &
+ stretching_height, &
+ stretching_method, &
surf_alt_w3 )
use assign_orography_field_mod, only: assign_orography_field
@@ -77,6 +82,8 @@ contains
type(inventory_by_mesh_type), intent(inout) :: chi_inventory
type(inventory_by_mesh_type), intent(in) :: panel_id_inventory
type(field_type), intent(in) :: surf_alt_w3
+ integer(kind=i_def), intent(in) :: stretching_method
+ real(kind=r_def), intent(in) :: stretching_height
! local variables
integer(kind=i_def) :: i, fs_id
@@ -185,21 +192,24 @@ contains
! Assignment of orography from surface_altitude on orography mesh
call assign_orography_field( &
- chi_inventory, panel_id_inventory, source_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, source_mesh, &
+ stretching_height, stretching_method, surf_alt_w0 &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(source_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(source_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, shifted_mesh, &
+ stretching_height, stretching_method, surf_alt_w0 &
)
end if
if (mesh_collection%check_for(source_mesh, DOUBLE_LEVEL)) then
double_level_mesh => mesh_collection%get_mesh(source_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, double_level_mesh, surf_alt_w0 &
+ chi_inventory, panel_id_inventory, double_level_mesh, &
+ stretching_height, stretching_method, surf_alt_w0 &
)
end if
@@ -301,14 +311,16 @@ contains
! Adjust coordinates
! ---------------------------------------------------------------------- !
call assign_orography_field( &
- chi_inventory, panel_id_inventory, target_mesh, surf_alt_w0_ptr &
+ chi_inventory, panel_id_inventory, target_mesh, &
+ stretching_height, stretching_method, surf_alt_w0_ptr &
)
! Assign for shifted and double level meshes if they exist
if (mesh_collection%check_for(target_mesh, SHIFTED)) then
shifted_mesh => mesh_collection%get_mesh(target_mesh, SHIFTED)
call assign_orography_field( &
- chi_inventory, panel_id_inventory, shifted_mesh, surf_alt_w0_ptr &
+ chi_inventory, panel_id_inventory, shifted_mesh, &
+ stretching_height, stretching_method, surf_alt_w0_ptr &
)
end if
@@ -316,7 +328,7 @@ contains
double_level_mesh => mesh_collection%get_mesh(target_mesh, DOUBLE_LEVEL)
call assign_orography_field( &
chi_inventory, panel_id_inventory, double_level_mesh, &
- surf_alt_w0_ptr &
+ stretching_height, stretching_method, surf_alt_w0_ptr &
)
end if
end do
From 6d899ce80c1d89800a79704952573114c5a54057 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 9 Jul 2026 15:15:51 +0100
Subject: [PATCH 15/53] Add get_height to vertical regridding
---
.../source/algorithm/lfric2lfric_vert_mod.x90 | 60 ++++++++++++++-----
.../source/driver/lfric2lfric_driver_mod.F90 | 4 +-
2 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index cc46af3010..f54d199d65 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -1,11 +1,15 @@
module lfric2lfric_vert_mod
- use constants_mod, only: str_def
+ use constants_mod, only: str_def, i_def
+ use driver_modeldb_mod, only: modeldb_type
use field_parent_mod, only: field_parent_type
use field_mod, only: field_type
use field_collection_mod, only: field_collection_type
- use field_collection_iterator_mod, only: &
- field_collection_iterator_type
+ use field_collection_iterator_mod, &
+ only: field_collection_iterator_type
+ use sci_geometric_constants_mod, &
+ only: get_height_fv
+ use mesh_mod, only: mesh_type
use log_mod, only: log_event, &
log_level_info, &
log_scratch_space
@@ -17,21 +21,34 @@ module lfric2lfric_vert_mod
contains
- subroutine lfric2lfric_vert( source_fields, target_fields )
+ !> @brief Apply vertical regridding
+ !> @details Loop over the fields in the source_fields collection,
+ !! and apply the vertical regridding to obtain the regridded
+ !! field in the target_fields collection.
+ !> @param modeldb Model state object
+ !> @param source_fields The collection of fields to be regridded
+ !> @param target_fields The collection of regridded fields
+ subroutine lfric2lfric_vert( modeldb, source_fields, target_fields )
implicit none
+ type(modeldb_type), intent(inout) :: modeldb
type(field_collection_type), intent(inout) :: source_fields
type(field_collection_type), intent(inout) :: target_fields
type(field_collection_iterator_type) :: iter
- class(field_parent_type), pointer :: field => null()
- type(field_type), pointer :: field_src => null()
- type(field_type), pointer :: field_dst => null()
-
- character(len=str_def) :: field_name
-
+ class(field_parent_type), pointer :: field
+ type(field_type), pointer :: field_src
+ type(field_type), pointer :: field_dst
+ type(field_type), pointer :: height_src
+ type(field_type), pointer :: height_dst
+ type(mesh_type), pointer :: mesh_src
+ type(mesh_type), pointer :: mesh_dst
+
+ character(len=str_def) :: field_name
+ integer(kind=i_def) :: fs_src, fs_dst
+
! Main loop over fields to be processed
call iter%initialise(source_fields)
do
@@ -42,13 +59,26 @@ contains
call source_fields%get_field(field_name, field_src)
call target_fields%get_field(field_name, field_dst)
-
+
write(log_scratch_space, '(A,A)') "Processing lfric field ", &
- trim(field_name)
+ trim(field_name)
call log_event(log_scratch_space, log_level_info)
- ! Dummy initialisation - to be replaced with actual
- ! vertical regridding
- call invoke(setval_C(field_dst, 1.0_r_def))
+
+ mesh_src => field_src%get_mesh()
+ mesh_dst => field_dst%get_mesh()
+ fs_src = field_src%which_function_space()
+ fs_dst = field_dst%which_function_space()
+
+ ! Get the associated heights, ready for vertical interpolation kernels
+ height_src => get_height_fv(modeldb%config, mesh_src, fs_src)
+ height_dst => get_height_fv(modeldb%config, mesh_dst, fs_dst)
+
+ ! Dummy initialisation. This will be replaced with actual
+ ! vertical regridding from #253.
+ ! call invoke( lfric2lfric_vert_lin_interp_lin_extrap_code_r_single( &
+ ! field_dst, field_src, height_dst, height_src))
+ ! At the moment just writing out the heights.
+ call invoke(setval_X(field_dst, height_dst))
enddo
end subroutine lfric2lfric_vert
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 681b4a49bc..071af9bb00 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -184,7 +184,7 @@ subroutine run( modeldb, oasis_clock )
interm_fields, regrid_method)
end if
if (vertical_change) then
- call lfric2lfric_vert(interm_fields, target_fields)
+ call lfric2lfric_vert(modeldb, interm_fields, target_fields)
end if
! Write output
@@ -212,7 +212,7 @@ subroutine run( modeldb, oasis_clock )
interm_fields, regrid_method)
end if
if (vertical_change) then
- call lfric2lfric_vert(interm_fields, target_fields)
+ call lfric2lfric_vert(modeldb, interm_fields, target_fields)
end if
is_running = modeldb%clock%tick()
From ea75009f35686d20999756a4c65cfd1c72b48ebc Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 13 Jul 2026 10:34:38 +0100
Subject: [PATCH 16/53] Blended orography corrections
---
.../lfric2lfric_infrastructure_mod.X90 | 11 ++++++
rose-stem/app/lfric2lfric/rose-app.conf | 34 ++++++-------------
.../limited_area_masks_alg_mod.x90 | 5 +++
.../orography/blend_orography_alg_mod.x90 | 8 +++++
4 files changed, 35 insertions(+), 23 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 8ad7d6cec0..d97bc13728 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -740,6 +740,7 @@ contains
! Adjust the chi fields to account for the orography
! --------------------------------------------------------
+ ! source mesh, source extrusion, source orography
call setup_orography_alg( mesh_names(src:src), &
orography_mesh_src%get_mesh_name(), &
chi_inventory, &
@@ -748,6 +749,16 @@ contains
src_stretching_method, &
surface_altitude_src )
+ ! destination mesh, source extrusion, source orog on destination mesh
+ call setup_orography_alg( mesh_names(dst:dst), &
+ orography_mesh_dst%get_mesh_name(), &
+ chi_inventory, &
+ panel_id_inventory, &
+ src_stretching_height, &
+ src_stretching_method, &
+ surface_altitude_src_on_dst )
+
+ ! destination mesh, destination extrusion, destination orog
call setup_orography_alg( mesh_names_dst_ext(dst:dst), &
orography_mesh_dst%get_mesh_name(), &
chi_inventory, &
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index e9468e1913..35d5a0c808 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -19,6 +19,7 @@ mode=mkdir
mode=auto
source=namelist:extrusion
=namelist:extrusion_dst
+ =namelist:boundaries
= namelist:finite_element
= namelist:io
= (namelist:jules_hydrology)
@@ -104,29 +105,16 @@ sg_orog_mixing='none'
!!zhloc_depth_fac=0
[namelist:boundaries]
-!!blend_frequency='inner'
-!!blending_weights=0
-!!blending_weights_w2v=0
-!!boundary_e=0
-!!boundary_n=0
-!!boundary_s=0
-!!boundary_w=0
-!!edge_cells_ew=0
-!!edge_cells_ns=0
-!!inner_width_ew=0
-!!inner_width_ns=0
-!!lbc_eos_height=0
-!!lbc_method='onion_layer'
-limited_area=.false.
-!!normal_only=.false.
-!!outer_width_ew=0
-!!outer_width_ns=0
-!!output_lbcs=.false.
-!!rim_width_ew=0
-!!rim_width_ns=0
-!!solver_boundary_depth=0
-!!transport_boundary_depth=0
-transport_overwrite_freq='final'
+blend_frequency='inner'
+blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
+blending_weights_w2v=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
+lbc_eos_height=10
+lbc_method='onion_layer'
+limited_area=.true.
+normal_only=.true.
+output_lbcs=.true.
+solver_boundary_depth=4
+transport_boundary_depth=4
[namelist:checks]
limit_cfl=.false.
diff --git a/science/gungho/source/algorithm/limited_area/limited_area_masks_alg_mod.x90 b/science/gungho/source/algorithm/limited_area/limited_area_masks_alg_mod.x90
index a5cbfb514c..4a0be42d87 100644
--- a/science/gungho/source/algorithm/limited_area/limited_area_masks_alg_mod.x90
+++ b/science/gungho/source/algorithm/limited_area/limited_area_masks_alg_mod.x90
@@ -21,6 +21,7 @@ module limited_area_masks_alg_mod
log_scratch_space, &
LOG_LEVEL_ERROR, &
LOG_LEVEL_INFO, &
+ LOG_LEVEL_DEBUG, &
LOG_LEVEL_WARNING
use function_space_mod, only: function_space_type
use function_space_collection_mod, only: function_space_collection
@@ -532,6 +533,8 @@ contains
if ( lbc_method == lbc_method_onion_layer )then
+ call log_event('Creating blend mask using onion layers', LOG_LEVEL_DEBUG)
+
fs_enum = mask%which_function_space()
select case(fs_enum)
@@ -555,6 +558,8 @@ contains
else
+ call log_event('Creating blend mask using coordinates', LOG_LEVEL_DEBUG)
+
! |<-------------rim_width------------>|
! | | | |
! |<--outer--> |<--inner-->| |
diff --git a/science/gungho/source/orography/blend_orography_alg_mod.x90 b/science/gungho/source/orography/blend_orography_alg_mod.x90
index c5e498de38..8038bf9b03 100644
--- a/science/gungho/source/orography/blend_orography_alg_mod.x90
+++ b/science/gungho/source/orography/blend_orography_alg_mod.x90
@@ -15,6 +15,11 @@ module blend_orography_alg_mod
use limited_area_constants_mod, only: get_blend_mask, &
get_lbc_mask_fv
use mesh_mod, only: mesh_type
+ use log_mod, only: log_event, &
+ LOG_LEVEL_INFO, &
+ LOG_LEVEL_DEBUG, &
+ LOG_LEVEL_ERROR
+
implicit none
public :: blend_orography
@@ -43,6 +48,9 @@ contains
integer(kind=i_def) :: fs_enum
type(mesh_type), pointer :: mesh
+ call log_event( "Creating the blended orography (for LAMs)", &
+ LOG_LEVEL_DEBUG )
+
! Define the function space required for masks.
fs_enum = lam_orog%which_function_space()
mesh => lam_orog%get_mesh()
From c8d9b6a35e256d94b38b40974e805e87cf61ab54 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Tue, 14 Jul 2026 11:25:54 +0100
Subject: [PATCH 17/53] Add orography to the output files
---
.../source/driver/lfric2lfric_init_mod.f90 | 11 +++++++++++
.../initialisation/lfric2lfric_field_init_mod.f90 | 6 +++++-
.../lfric2lfric_infrastructure_mod.X90 | 12 ++++++++++++
rose-stem/app/lfric2lfric/file/iodef_orography.xml | 2 ++
4 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index ab634f2457..b2f5dcf828 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -19,6 +19,10 @@ module lfric2lfric_init_mod
log_level_info
use mesh_mod, only: mesh_type
use netcdf, only: nf90_max_name
+ use orography_config_mod, only: orog_init_option, &
+ orog_init_option_analytic, &
+ orog_init_option_ancil, &
+ orog_init_option_start_dump
! lfric2lfric mods
use lfric2lfric_config_mod, only: mode_ics, mode_lbc
@@ -145,6 +149,13 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
prefix )
end do
+ if ( orog_init_option == orog_init_option_analytic .or. &
+ orog_init_option == orog_init_option_ancil .or. &
+ orog_init_option == orog_init_option_start_dump ) then
+ call field_maker(field_collection, trim('surface_altitude'), &
+ target_mesh, target_twod_mesh, prefix)
+ end if
+
!--------------------------------------------------------------------------
! Initialise Intermediate Fields
!--------------------------------------------------------------------------
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
index 1b41ed2aa0..fe2be646bd 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
@@ -160,10 +160,14 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
cp_write_behaviour => checkpoint_write_xios
if ( .NOT. field_collection%field_exists(field_name) ) then
- ! Get function space from metadata
+ ! Get function space from metadata
+ call log_event("Before", &
+ LOG_LEVEL_INFO)
vector_space => space_from_metadata(trim(prefix)//trim(field_name), &
mesh_3d=mesh, &
mesh_2d=twod_mesh )
+ call log_event("After", &
+ LOG_LEVEL_INFO)
! Initialise the field
call field%initialise(vector_space=vector_space, &
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index d97bc13728..8231ad2a9d 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -71,6 +71,8 @@ module lfric2lfric_infrastructure_mod
use lfric2lfric_init_coupler_mod,only: lfric2lfric_init_coupler_src, &
lfric2lfric_init_coupler_dst, &
lfric2lfric_end_coupler_init
+ use lfric2lfric_field_init_mod, only: field_maker
+ use netcdf, only: nf90_max_name
#ifdef MCT
use coupling_mod, only: coupling_type, &
get_coupling_from_collection
@@ -217,6 +219,9 @@ contains
type(coupler_exchange_2d_type) :: coupler_exchange_2d
integer(kind=i_def) :: ierror
logical(kind=l_def) :: is_running
+
+ type(field_collection_type), pointer :: target_collection
+ type(field_type), pointer :: field
!------------------------
! XIOS contexts
@@ -738,6 +743,13 @@ contains
call blend_orography(surface_altitude_dst, surface_altitude_src_on_dst, &
mesh_names(dst))
+ ! Copy the destination (possibly blended) orography to the output fields
+ ! --------------------------------------------------------
+
+ target_collection => modeldb%fields%get_field_collection(target_collection_name)
+ call target_collection%get_field("surface_altitude", field)
+ call invoke(setval_X(field,surface_altitude_dst))
+
! Adjust the chi fields to account for the orography
! --------------------------------------------------------
! source mesh, source extrusion, source orography
diff --git a/rose-stem/app/lfric2lfric/file/iodef_orography.xml b/rose-stem/app/lfric2lfric/file/iodef_orography.xml
index 787a8bb186..8cc65056a8 100644
--- a/rose-stem/app/lfric2lfric/file/iodef_orography.xml
+++ b/rose-stem/app/lfric2lfric/file/iodef_orography.xml
@@ -63,6 +63,8 @@
+
+
From ac9165b15712020c910216150633fe7a3bef9570 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Tue, 14 Jul 2026 12:12:34 +0100
Subject: [PATCH 18/53] vertical_change horizontal_change logic
---
.../source/driver/lfric2lfric_driver_mod.F90 | 38 ++++++------------
.../lfric2lfric_infrastructure_mod.X90 | 39 +++++++++++--------
.../lfric2lfric/source/lfric2lfric.F90 | 9 +++--
3 files changed, 40 insertions(+), 46 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 071af9bb00..70026d240b 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -24,6 +24,9 @@ module lfric2lfric_driver_mod
use sci_checksum_alg_mod, only: checksum_alg
use xios, only: xios_date, xios_get_current_date, &
xios_date_convert_to_string
+ use orography_config_mod, only: orog_init_option_analytic, &
+ orog_init_option_ancil, &
+ orog_init_option_start_dump
!------------------------------------
! lfric2lfric modules
@@ -53,15 +56,17 @@ module lfric2lfric_driver_mod
!! and fields.
!> @param [in,out] modeldb The structure holding model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine initialise( modeldb, oasis_clock )
+ subroutine initialise( modeldb, oasis_clock, vertical_change, horizontal_change )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
+ logical(kind=l_def), intent(inout) :: vertical_change
+ logical(kind=l_def), intent(inout) :: horizontal_change
- call initialise_infrastructure( modeldb, oasis_clock )
+ call initialise_infrastructure( modeldb, oasis_clock, vertical_change, horizontal_change )
end subroutine initialise
@@ -73,13 +78,15 @@ end subroutine initialise
!! XIOS context and writes to an output file.
!> @param [in,out] modeldb The structure that holds model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine run( modeldb, oasis_clock )
+ subroutine run( modeldb, oasis_clock, vertical_change, horizontal_change )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
+ logical(kind=l_def), intent(in) :: vertical_change
+ logical(kind=l_def), intent(in) :: horizontal_change
! LFRic-XIOS constants
integer(kind=i_def), parameter :: start_timestep = 1_i_def
@@ -112,13 +119,12 @@ subroutine run( modeldb, oasis_clock )
integer(kind=i_def) :: dst_number_of_layers
integer(kind=i_def) :: src_stretching_method
integer(kind=i_def) :: dst_stretching_method
+ integer(kind=i_def) :: orog_init_option
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
real(kind=r_def) :: src_stretching_height
real(kind=r_def) :: dst_stretching_height
- logical(l_def) :: horizontal_change, vertical_change
-
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
@@ -129,30 +135,10 @@ subroutine run( modeldb, oasis_clock )
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
+ orog_init_option = modeldb%config%orography%orog_init_option()
mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
mesh_names(src) = modeldb%config%lfric2lfric%source_mesh_name()
-
- vertical_change = .false.
- if ( src_extrusion_method /= dst_extrusion_method ) then
- vertical_change = .true.
- end if
- if ( src_number_of_layers /= dst_number_of_layers ) then
- vertical_change = .true.
- end if
- if ( src_domain_height /= dst_domain_height ) then
- vertical_change = .true.
- end if
- if ( src_stretching_height /= dst_stretching_height ) then
- vertical_change = .true.
- end if
- if ( src_stretching_method /= dst_stretching_method ) then
- vertical_change = .true.
- end if
- horizontal_change = .false.
- if ( mesh_names(dst) /= mesh_names(src) ) then
- horizontal_change = .true.
- end if
! Extract configuration variables
start_dump_filename = modeldb%config%files%start_dump_filename()
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 8231ad2a9d..f8046e4b11 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -105,6 +105,9 @@ module lfric2lfric_infrastructure_mod
source_topology_non_periodic, &
source_geometry_planar, &
source_geometry_spherical
+ use orography_config_mod, only: orog_init_option_analytic, &
+ orog_init_option_ancil, &
+ orog_init_option_start_dump
implicit none
@@ -134,14 +137,16 @@ contains
!! fields.
!> @param [in,out] modeldb The structure holding model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine initialise_infrastructure( modeldb, oasis_clock )
+ subroutine initialise_infrastructure( modeldb, oasis_clock, vertical_change, horizontal_change )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
-
+ logical(kind=l_def), intent(inout) :: vertical_change
+ logical(kind=l_def), intent(inout) :: horizontal_change
+
! Coordinate field
type(field_type), pointer :: chi(:)
type(field_type), pointer :: panel_id
@@ -172,7 +177,6 @@ contains
class(extrusion_type), allocatable :: dst_extrusion
type(uniform_extrusion_type), allocatable :: extrusion_2d
-
! Namelist parameters
character(len=str_def) :: mesh_names(2)
character(len=str_def), allocatable :: mesh_names_dst_ext(:)
@@ -196,14 +200,12 @@ contains
integer(kind=i_def) :: dst_number_of_layers
integer(kind=i_def) :: src_stretching_method
integer(kind=i_def) :: dst_stretching_method
+ integer(kind=i_def) :: orog_init_option
real(kind=r_def) :: src_domain_height
real(kind=r_def) :: dst_domain_height
real(kind=r_def) :: src_stretching_height
real(kind=r_def) :: dst_stretching_height
- logical(kind=l_def) :: vertical_change
- logical(kind=l_def) :: horizontal_change
-
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
logical(l_def) :: inner_halo_tiles
@@ -259,6 +261,7 @@ contains
dst_domain_height = modeldb%config%extrusion_dst%domain_height()
dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
+ orog_init_option = modeldb%config%orography%orog_init_option()
mode = modeldb%config%lfric2lfric%mode()
regrid_method = modeldb%config%lfric2lfric%regrid_method()
@@ -277,22 +280,24 @@ contains
tile_size_y = 1
inner_halo_tiles = .false.
+ ! Vertical interpolation is required if there is a change in the vertical
+ ! extrusion, or a change in the orography
vertical_change = .false.
- if ( src_extrusion_method /= dst_extrusion_method ) then
+ if ( src_extrusion_method /= dst_extrusion_method .or. &
+ src_number_of_layers /= dst_number_of_layers .or. &
+ src_domain_height /= dst_domain_height .or. &
+ src_stretching_height /= dst_stretching_height .or. &
+ src_stretching_method /= dst_stretching_method ) then
vertical_change = .true.
end if
- if ( src_number_of_layers /= dst_number_of_layers ) then
- vertical_change = .true.
- end if
- if ( src_domain_height /= dst_domain_height ) then
- vertical_change = .true.
- end if
- if ( src_stretching_height /= dst_stretching_height ) then
- vertical_change = .true.
- end if
- if ( src_stretching_method /= dst_stretching_method ) then
+ if ( orog_init_option == orog_init_option_analytic .or. &
+ orog_init_option == orog_init_option_ancil .or. &
+ orog_init_option == orog_init_option_start_dump ) then
vertical_change = .true.
end if
+
+ ! Horizontal interpolation is required if there is a change
+ ! in the mesh (horizontal grid)
horizontal_change = .false.
if ( mesh_names(dst) /= mesh_names(src) ) then
horizontal_change = .true.
diff --git a/applications/lfric2lfric/source/lfric2lfric.F90 b/applications/lfric2lfric/source/lfric2lfric.F90
index 6a260e03ca..2e1f1e9067 100644
--- a/applications/lfric2lfric/source/lfric2lfric.F90
+++ b/applications/lfric2lfric/source/lfric2lfric.F90
@@ -15,7 +15,7 @@
program lfric2lfric
use cli_mod, only: parse_command_line
- use constants_mod, only: precision_real
+ use constants_mod, only: precision_real, l_def
use driver_collections_mod, only: init_collections, final_collections
use driver_config_mod, only: init_config, final_config
use driver_comm_mod, only: init_comm, final_comm
@@ -48,6 +48,9 @@ program lfric2lfric
! Clock for OASIS exchanges
type(model_clock_type), allocatable :: oasis_clock
+ logical(kind=l_def) :: vertical_change
+ logical(kind=l_def) :: horizontal_change
+
call parse_command_line( filename )
call modeldb%config%initialise( program_name )
@@ -86,9 +89,9 @@ program lfric2lfric
call modeldb%io_contexts%initialise(program_name, 100)
call log_event( 'Initialising ' // program_name // ' ...', log_level_trace )
- call initialise( modeldb, oasis_clock )
+ call initialise( modeldb, oasis_clock, vertical_change, horizontal_change )
- call run( modeldb, oasis_clock )
+ call run( modeldb, oasis_clock, vertical_change, horizontal_change )
call log_event( 'Finalising ' // program_name // ' ...', log_level_trace )
call finalise( program_name, modeldb )
From 6beaf6d83b7c54b184bed6aba8a510df69d37e1d Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Tue, 14 Jul 2026 17:43:54 +0100
Subject: [PATCH 19/53] corrections
---
applications/lfric2lfric/example/configuration.nml | 4 ++++
.../source/driver/lfric2lfric_init_mod.f90 | 8 ++++++--
.../lfric2lfric_infrastructure_mod.X90 | 12 +++++++-----
.../app/lfric2lfric/opt/rose-app-C12_C16_lam.conf | 2 --
4 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index fe12fd4a2b..1a4edc1deb 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -106,3 +106,7 @@ coord_space = 'Wchi',
&planet
scaling_factor = 125.0,
/
+
+&orography
+ orog_init_option = 'none'
+/
\ No newline at end of file
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index b2f5dcf828..c2518ea437 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -152,8 +152,12 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
if ( orog_init_option == orog_init_option_analytic .or. &
orog_init_option == orog_init_option_ancil .or. &
orog_init_option == orog_init_option_start_dump ) then
- call field_maker(field_collection, trim('surface_altitude'), &
- target_mesh, target_twod_mesh, prefix)
+ if ( mode == mode_ics ) then
+
+ call field_maker(field_collection, trim('surface_altitude'), &
+ target_mesh, target_twod_mesh, prefix)
+
+ end if
end if
!--------------------------------------------------------------------------
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index f8046e4b11..bc5f267010 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -750,11 +750,13 @@ contains
! Copy the destination (possibly blended) orography to the output fields
! --------------------------------------------------------
-
- target_collection => modeldb%fields%get_field_collection(target_collection_name)
- call target_collection%get_field("surface_altitude", field)
- call invoke(setval_X(field,surface_altitude_dst))
-
+
+ if (mode == mode_ics) then
+ target_collection => modeldb%fields%get_field_collection(target_collection_name)
+ call target_collection%get_field("surface_altitude", field)
+ call invoke(setval_X(field,surface_altitude_dst))
+ end if
+
! Adjust the chi fields to account for the orography
! --------------------------------------------------------
! source mesh, source extrusion, source orography
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
index 330c8f6e26..950011de21 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
@@ -15,5 +15,3 @@ source_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
src_ancil_directory='$BIG_DATA_DIR/ancils/basic-gagl/Puku/C12/n96e'
src_orography_mean_ancil_path='orography/globe30/qrparm.orog.ugrid'
-[namelist:orography]
-orog_init_option='ancil'
From 64f858402092d53e303676511fbc7b17acdcae2c Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 08:44:40 +0100
Subject: [PATCH 20/53] correction
---
applications/lfric2lfric/example/configuration.nml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index 1a4edc1deb..d25b8274cf 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -109,4 +109,4 @@ coord_space = 'Wchi',
&orography
orog_init_option = 'none'
-/
\ No newline at end of file
+/
From 2325001d3de7ec719a4ff0be515113debb82afaa Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 09:50:34 +0100
Subject: [PATCH 21/53] use modeldb for logicals horizontal_change and
vertical_change
---
.../source/driver/lfric2lfric_driver_mod.F90 | 23 ++++++++++---------
.../source/driver/lfric2lfric_init_mod.f90 | 11 +++++----
.../lfric2lfric_infrastructure_mod.X90 | 12 ++++++----
.../lfric2lfric/source/lfric2lfric.F90 | 7 ++----
4 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 70026d240b..983e0d2800 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -56,17 +56,15 @@ module lfric2lfric_driver_mod
!! and fields.
!> @param [in,out] modeldb The structure holding model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine initialise( modeldb, oasis_clock, vertical_change, horizontal_change )
+ subroutine initialise( modeldb, oasis_clock )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
- logical(kind=l_def), intent(inout) :: vertical_change
- logical(kind=l_def), intent(inout) :: horizontal_change
- call initialise_infrastructure( modeldb, oasis_clock, vertical_change, horizontal_change )
+ call initialise_infrastructure( modeldb, oasis_clock )
end subroutine initialise
@@ -78,15 +76,13 @@ end subroutine initialise
!! XIOS context and writes to an output file.
!> @param [in,out] modeldb The structure that holds model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine run( modeldb, oasis_clock, vertical_change, horizontal_change )
+ subroutine run( modeldb, oasis_clock )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
- logical(kind=l_def), intent(in) :: vertical_change
- logical(kind=l_def), intent(in) :: horizontal_change
! LFRic-XIOS constants
integer(kind=i_def), parameter :: start_timestep = 1_i_def
@@ -125,6 +121,10 @@ subroutine run( modeldb, oasis_clock, vertical_change, horizontal_change )
real(kind=r_def) :: src_stretching_height
real(kind=r_def) :: dst_stretching_height
+ logical(kind=l_def), pointer :: vertical_change
+ logical(kind=l_def), pointer :: horizontal_change
+
+ ! Extract configuration variables
src_extrusion_method = modeldb%config%extrusion%method()
src_number_of_layers = modeldb%config%extrusion%number_of_layers()
src_domain_height = modeldb%config%extrusion%domain_height()
@@ -137,10 +137,8 @@ subroutine run( modeldb, oasis_clock, vertical_change, horizontal_change )
dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
orog_init_option = modeldb%config%orography%orog_init_option()
- mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
- mesh_names(src) = modeldb%config%lfric2lfric%source_mesh_name()
-
- ! Extract configuration variables
+ mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
+ mesh_names(src) = modeldb%config%lfric2lfric%source_mesh_name()
start_dump_filename = modeldb%config%files%start_dump_filename()
checkpoint_stem_name = modeldb%config%files%checkpoint_stem_name()
@@ -151,6 +149,9 @@ subroutine run( modeldb, oasis_clock, vertical_change, horizontal_change )
source_fields => modeldb%fields%get_field_collection(source_collection_name)
target_fields => modeldb%fields%get_field_collection(target_collection_name)
+ call modeldb%values%get_value("vertical_change", vertical_change)
+ call modeldb%values%get_value("horizontal_change", horizontal_change)
+
if (horizontal_change .and. vertical_change) then
interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index c2518ea437..7ca5bf329a 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -44,8 +44,6 @@ module lfric2lfric_init_mod
!! will hold the file to be written
!> @param [in] start_dump_filename File to get field names from
!> @param [in] mode Process ics or lbcs
- !> @param [in] horizontal_change Logical for horizontal regridding
- !> @param [in] vertical_change Logical for vertical regridding
!> @param [in] origin_collection_name Holds the origin fields
!> @param [in] origin_mesh Mesh to initialise 3D fields
!> @param [in] origin_twod_mesh Mesh to initialise 2D fields
@@ -57,7 +55,6 @@ module lfric2lfric_init_mod
!> @param [in] target_twod_mesh Mesh for target 2D fields
subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
start_dump_filename, mode, &
- horizontal_change, vertical_change, &
origin_collection_name, &
origin_mesh, origin_twod_mesh, &
interm_collection_name, &
@@ -72,8 +69,6 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
character(len=*), intent(in) :: context_dst
character(len=*), intent(in) :: start_dump_filename
integer(i_def), intent(in) :: mode
- logical(l_def), intent(in) :: horizontal_change
- logical(l_def), intent(in) :: vertical_change
character(len=*), intent(in) :: origin_collection_name
type(mesh_type), intent(in), pointer :: origin_mesh
type(mesh_type), intent(in), pointer :: origin_twod_mesh
@@ -84,6 +79,9 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
type(mesh_type), intent(in), pointer :: target_mesh
type(mesh_type), intent(in), pointer :: target_twod_mesh
+ logical(l_def), pointer :: horizontal_change
+ logical(l_def), pointer :: vertical_change
+
! For field creation and storage
type(field_collection_type), pointer :: field_collection
@@ -100,6 +98,9 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call log_event( 'lfric2lfric: Initialising miniapp ...', log_level_info )
+ call modeldb%values%get_value("vertical_change", vertical_change)
+ call modeldb%values%get_value("horizontal_change", horizontal_change)
+
if (mode == mode_ics) then
prefix = 'restart_'
else if (mode == mode_lbc) then
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index bc5f267010..4bf0e10bb2 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -137,15 +137,13 @@ contains
!! fields.
!> @param [in,out] modeldb The structure holding model state
!> @param [in,out] oasis_clock Clock for OASIS exchanges
- subroutine initialise_infrastructure( modeldb, oasis_clock, vertical_change, horizontal_change )
+ subroutine initialise_infrastructure( modeldb, oasis_clock )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
- logical(kind=l_def), intent(inout) :: vertical_change
- logical(kind=l_def), intent(inout) :: horizontal_change
! Coordinate field
type(field_type), pointer :: chi(:)
@@ -206,6 +204,9 @@ contains
real(kind=r_def) :: src_stretching_height
real(kind=r_def) :: dst_stretching_height
+ logical(kind=l_def) :: vertical_change
+ logical(kind=l_def) :: horizontal_change
+
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
logical(l_def) :: inner_halo_tiles
@@ -303,6 +304,9 @@ contains
horizontal_change = .true.
end if
+ call modeldb%values%add_key_value('vertical_change', vertical_change)
+ call modeldb%values%add_key_value('horizontal_change', horizontal_change)
+
!=======================================================================
! Mesh
!=======================================================================
@@ -645,14 +649,12 @@ contains
if (mode == mode_ics) then
call init_lfric2lfric( modeldb, context_src, context_dst, &
start_dump_filename, mode, &
- horizontal_change, vertical_change, &
source_collection_name, mesh_src, twod_mesh_src, &
interm_collection_name, mesh_interm, twod_mesh_dst, &
target_collection_name, mesh_dst, twod_mesh_dst )
else if (mode == mode_lbc) then
call init_lfric2lfric( modeldb, context_src, context_dst, &
source_file_lbc, mode, &
- horizontal_change, vertical_change, &
source_collection_name, mesh_src, twod_mesh_src, &
interm_collection_name, mesh_interm, twod_mesh_dst, &
target_collection_name, mesh_dst, twod_mesh_dst )
diff --git a/applications/lfric2lfric/source/lfric2lfric.F90 b/applications/lfric2lfric/source/lfric2lfric.F90
index 2e1f1e9067..dccb133db8 100644
--- a/applications/lfric2lfric/source/lfric2lfric.F90
+++ b/applications/lfric2lfric/source/lfric2lfric.F90
@@ -47,9 +47,6 @@ program lfric2lfric
#endif
! Clock for OASIS exchanges
type(model_clock_type), allocatable :: oasis_clock
-
- logical(kind=l_def) :: vertical_change
- logical(kind=l_def) :: horizontal_change
call parse_command_line( filename )
@@ -89,9 +86,9 @@ program lfric2lfric
call modeldb%io_contexts%initialise(program_name, 100)
call log_event( 'Initialising ' // program_name // ' ...', log_level_trace )
- call initialise( modeldb, oasis_clock, vertical_change, horizontal_change )
+ call initialise( modeldb, oasis_clock )
- call run( modeldb, oasis_clock, vertical_change, horizontal_change )
+ call run( modeldb, oasis_clock )
call log_event( 'Finalising ' // program_name // ' ...', log_level_trace )
call finalise( program_name, modeldb )
From f732f3e76f84075687090d6212a465eeca4a1dab Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 10:25:57 +0100
Subject: [PATCH 22/53] log messages
---
.../lfric2lfric_field_init_mod.f90 | 4 ----
.../lfric2lfric_infrastructure_mod.X90 | 17 ++++++++++++++++-
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
index fe2be646bd..867ab70a23 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
@@ -161,13 +161,9 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
if ( .NOT. field_collection%field_exists(field_name) ) then
! Get function space from metadata
- call log_event("Before", &
- LOG_LEVEL_INFO)
vector_space => space_from_metadata(trim(prefix)//trim(field_name), &
mesh_3d=mesh, &
mesh_2d=twod_mesh )
- call log_event("After", &
- LOG_LEVEL_INFO)
! Initialise the field
call field%initialise(vector_space=vector_space, &
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 4bf0e10bb2..75b663bf1d 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -47,6 +47,7 @@ module lfric2lfric_infrastructure_mod
use lfric_xios_action_mod, only: advance
use log_mod, only: log_event, &
log_scratch_space, &
+ log_level_info, &
log_level_error, &
log_level_debug
use mesh_mod, only: mesh_type
@@ -306,7 +307,21 @@ contains
call modeldb%values%add_key_value('vertical_change', vertical_change)
call modeldb%values%add_key_value('horizontal_change', horizontal_change)
-
+
+ if ( horizontal_change == .true. ) then
+ call log_event("Horizontal interpolation logical set to TRUE", &
+ log_level_info)
+ else
+ call log_event("Horizontal interpolation logical set to FALSE", &
+ log_level_info)
+ end if
+ if ( vertical_change == .true. ) then
+ call log_event("Vertical interpolation logical set to TRUE", &
+ log_level_info)
+ else
+ call log_event("Vertical interpolation logical set to FALSE", &
+ log_level_info)
+ end if
!=======================================================================
! Mesh
!=======================================================================
From d27bb22451f286fdd6a93cbf6a3bb0e85d608aaf Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 11:04:52 +0100
Subject: [PATCH 23/53] tidy
---
applications/lfric2lfric/source/lfric2lfric.F90 | 3 +--
rose-stem/app/lfric2lfric/opt/rose-app-C12.conf | 8 ++++----
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 10 +++++-----
rose-stem/site/meto/groups/groups_lfric2lfric.cylc | 2 ++
4 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/applications/lfric2lfric/source/lfric2lfric.F90 b/applications/lfric2lfric/source/lfric2lfric.F90
index dccb133db8..0a0e1ee539 100644
--- a/applications/lfric2lfric/source/lfric2lfric.F90
+++ b/applications/lfric2lfric/source/lfric2lfric.F90
@@ -15,7 +15,7 @@
program lfric2lfric
use cli_mod, only: parse_command_line
- use constants_mod, only: precision_real, l_def
+ use constants_mod, only: precision_real
use driver_collections_mod, only: init_collections, final_collections
use driver_config_mod, only: init_config, final_config
use driver_comm_mod, only: init_comm, final_comm
@@ -47,7 +47,6 @@ program lfric2lfric
#endif
! Clock for OASIS exchanges
type(model_clock_type), allocatable :: oasis_clock
-
call parse_command_line( filename )
call modeldb%config%initialise( program_name )
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
index a6d7d25af7..87cbe9951d 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
@@ -1,5 +1,5 @@
[namelist:lfric2lfric]
-destination_mesh_name='C12'
-destination_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
-source_mesh_name='C12'
-source_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
+destination_mesh_name='dynamics'
+destination_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
+source_mesh_name='dynamics'
+source_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index a2e035a9d1..07019d9b27 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -155,11 +155,11 @@
{% do task_dict.update({
"opt_confs": ["clim_gal9","oasis","src_L70_80km","dst_L38_40km"],
"resolution": "C12",
- "dst_mesh": "C24_C12",
- "dst_name": "C12",
+ "dst_mesh": "C12",
+ "dst_name": "dynamics",
"dst_type": "global",
- "src_mesh": "C24_C12",
- "src_name": "C12",
+ "src_mesh": "C12",
+ "src_name": "dynamics",
"src_type": "global",
}) %}
@@ -174,7 +174,7 @@
"src_mesh": "C24_C12",
"src_name": "C12",
"src_type": "global",
- "mpi_parts": 6,
+ "mpi_parts": 6,
}) %}
{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam_1cpu" %}
diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
index f8a76189b0..23c622d4d2 100644
--- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
@@ -52,6 +52,8 @@
"lfric2lfric_oasis_clim_gal9-C24_C12_6cpu_ex1a_cce_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_1cpu_ex1a_cce_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_1cpu_ex1a_cce_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_seukL38_ex1a_cce_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_C12L38_ex1a_cce_fast-debug-64bit",
"lfric2lfric_ex1a_canned",
],
"lfric2lfric_ex1a_extra": [
From 159085e09e6bc0e120660f721e1aa5051b6d56b7 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 11:21:58 +0100
Subject: [PATCH 24/53] tidy
---
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 14 +++++++-------
.../source/algorithm/lfric2lfric_vert_mod.x90 | 16 ++++++++++++----
.../lfric2lfric_infrastructure_mod.X90 | 4 ++--
3 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index 93b8ca5936..ecb0cdc604 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -318,12 +318,12 @@ type=real
compulsory=true
description=Method for generating eta coordinate
!enumeration=true
-fail-if=this == 'um_L38_29t_9s_40km' and namelist:extrusion=number_of_layers != 38 ;
- =this == 'um_L70_50t_20s_80km' and namelist:extrusion=number_of_layers != 70 ;
- =this == 'um_L85_50t_35s_85km' and namelist:extrusion=number_of_layers != 85 ;
- =this == 'um_L70_61t_9s_40km' and namelist:extrusion=number_of_layers != 70 ;
- =this == 'um_L120_99t_21s_40km' and namelist:extrusion=number_of_layers != 120 ;
- =this == 'um_L140_122t_18s_40km' and namelist:extrusion=number_of_layers != 140 ;
+fail-if=this == 'um_L38_29t_9s_40km' and namelist:extrusion_dst=number_of_layers != 38 ;
+ =this == 'um_L70_50t_20s_80km' and namelist:extrusion_dst=number_of_layers != 70 ;
+ =this == 'um_L85_50t_35s_85km' and namelist:extrusion_dst=number_of_layers != 85 ;
+ =this == 'um_L70_61t_9s_40km' and namelist:extrusion_dst=number_of_layers != 70 ;
+ =this == 'um_L120_99t_21s_40km' and namelist:extrusion_dst=number_of_layers != 120 ;
+ =this == 'um_L140_122t_18s_40km' and namelist:extrusion_dst=number_of_layers != 140 ;
help=Available extrusion methods are (\f$n$ is number of layers):
=1) Uniform eta spacing (\f$\frac{k}{n}\f$);
=2) Quadratic eta spacing (\f$\frac{k}{n}^2\f$);
@@ -389,7 +389,7 @@ help=Available stretching methods are:
=1) Linear (linear multiple of physical depth)
=2) Smooth (quadratic below stretching_height, linear above)
sort-key=Panel-A01
-trigger=namelist:extrusion=stretching_height: 'smooth' ;
+trigger=namelist:extrusion_dst=stretching_height: 'smooth' ;
value-titles=Linear, Smooth
values='linear', 'smooth'
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index f54d199d65..d13d88b281 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -1,3 +1,11 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Apply vertical regridding using the vertical regridding kernels
+!! and height values for the source and target vertically extruded
+!! meshes.
module lfric2lfric_vert_mod
use constants_mod, only: str_def, i_def
@@ -23,7 +31,7 @@ contains
!> @brief Apply vertical regridding
!> @details Loop over the fields in the source_fields collection,
- !! and apply the vertical regridding to obtain the regridded
+ !! and apply the vertical regridding kernels to obtain the regridded
!! field in the target_fields collection.
!> @param modeldb Model state object
!> @param source_fields The collection of fields to be regridded
@@ -73,11 +81,11 @@ contains
height_src => get_height_fv(modeldb%config, mesh_src, fs_src)
height_dst => get_height_fv(modeldb%config, mesh_dst, fs_dst)
- ! Dummy initialisation. This will be replaced with actual
- ! vertical regridding from #253.
+ ! Dummy initialisation - just writing out the heights
+ ! TODO Replaced the dummy initialisation with actual
+ ! vertical regridding from #253. i.e.
! call invoke( lfric2lfric_vert_lin_interp_lin_extrap_code_r_single( &
! field_dst, field_src, height_dst, height_src))
- ! At the moment just writing out the heights.
call invoke(setval_X(field_dst, height_dst))
enddo
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 75b663bf1d..8d0daaf343 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -308,14 +308,14 @@ contains
call modeldb%values%add_key_value('vertical_change', vertical_change)
call modeldb%values%add_key_value('horizontal_change', horizontal_change)
- if ( horizontal_change == .true. ) then
+ if ( horizontal_change ) then
call log_event("Horizontal interpolation logical set to TRUE", &
log_level_info)
else
call log_event("Horizontal interpolation logical set to FALSE", &
log_level_info)
end if
- if ( vertical_change == .true. ) then
+ if ( vertical_change ) then
call log_event("Vertical interpolation logical set to TRUE", &
log_level_info)
else
From 2468580d89731865a8555351c767184c65b59108 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 12:14:43 +0100
Subject: [PATCH 25/53] tidy
---
applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 | 1 -
.../source/initialisation/lfric2lfric_field_init_mod.f90 | 2 +-
applications/lfric2lfric/source/lfric2lfric.F90 | 1 +
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index 7ca5bf329a..ddf4404bf0 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -187,7 +187,6 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call modeldb%io_contexts%get_io_context(context_src, io_context)
call io_context%set_current()
-
! Now finished with config_list, deallocate
deallocate(config_list)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
index 867ab70a23..1b41ed2aa0 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
@@ -160,7 +160,7 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
cp_write_behaviour => checkpoint_write_xios
if ( .NOT. field_collection%field_exists(field_name) ) then
- ! Get function space from metadata
+ ! Get function space from metadata
vector_space => space_from_metadata(trim(prefix)//trim(field_name), &
mesh_3d=mesh, &
mesh_2d=twod_mesh )
diff --git a/applications/lfric2lfric/source/lfric2lfric.F90 b/applications/lfric2lfric/source/lfric2lfric.F90
index 0a0e1ee539..6a260e03ca 100644
--- a/applications/lfric2lfric/source/lfric2lfric.F90
+++ b/applications/lfric2lfric/source/lfric2lfric.F90
@@ -47,6 +47,7 @@ program lfric2lfric
#endif
! Clock for OASIS exchanges
type(model_clock_type), allocatable :: oasis_clock
+
call parse_command_line( filename )
call modeldb%config%initialise( program_name )
From d14bbe0fee9a3e3adbd8abc5036e3e9bf61be954 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 13:35:58 +0100
Subject: [PATCH 26/53] reorganise extrusions, and whitespace
---
.../source/algorithm/lfric2lfric_vert_mod.x90 | 10 +-
.../source/driver/lfric2lfric_driver_mod.F90 | 8 +-
.../source/driver/lfric2lfric_init_mod.f90 | 8 +-
.../lfric2lfric_infrastructure_mod.X90 | 125 +++---------------
4 files changed, 28 insertions(+), 123 deletions(-)
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index d13d88b281..dbbd966d00 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -23,7 +23,7 @@ module lfric2lfric_vert_mod
log_scratch_space
implicit none
-
+
private
public :: lfric2lfric_vert
@@ -53,10 +53,10 @@ contains
type(field_type), pointer :: height_dst
type(mesh_type), pointer :: mesh_src
type(mesh_type), pointer :: mesh_dst
-
+
character(len=str_def) :: field_name
integer(kind=i_def) :: fs_src, fs_dst
-
+
! Main loop over fields to be processed
call iter%initialise(source_fields)
do
@@ -67,7 +67,7 @@ contains
call source_fields%get_field(field_name, field_src)
call target_fields%get_field(field_name, field_dst)
-
+
write(log_scratch_space, '(A,A)') "Processing lfric field ", &
trim(field_name)
call log_event(log_scratch_space, log_level_info)
@@ -88,7 +88,7 @@ contains
! field_dst, field_src, height_dst, height_src))
call invoke(setval_X(field_dst, height_dst))
enddo
-
+
end subroutine lfric2lfric_vert
end module lfric2lfric_vert_mod
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 983e0d2800..0e5f16b007 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -151,13 +151,13 @@ subroutine run( modeldb, oasis_clock )
call modeldb%values%get_value("vertical_change", vertical_change)
call modeldb%values%get_value("horizontal_change", horizontal_change)
-
+
if (horizontal_change .and. vertical_change) then
interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
-
+
else if (horizontal_change .and. .not. vertical_change) then
interm_fields => modeldb%fields%get_field_collection(target_collection_name)
-
+
else if (vertical_change .and. .not. horizontal_change) then
interm_fields => modeldb%fields%get_field_collection(source_collection_name)
end if
@@ -173,7 +173,7 @@ subroutine run( modeldb, oasis_clock )
if (vertical_change) then
call lfric2lfric_vert(modeldb, interm_fields, target_fields)
end if
-
+
! Write output
call modeldb%io_contexts%get_io_context(context_dst, io_context)
call io_context%set_current()
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index ddf4404bf0..c6be9c3651 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -81,7 +81,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
logical(l_def), pointer :: horizontal_change
logical(l_def), pointer :: vertical_change
-
+
! For field creation and storage
type(field_collection_type), pointer :: field_collection
@@ -100,7 +100,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call modeldb%values%get_value("vertical_change", vertical_change)
call modeldb%values%get_value("horizontal_change", horizontal_change)
-
+
if (mode == mode_ics) then
prefix = 'restart_'
else if (mode == mode_lbc) then
@@ -154,7 +154,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
orog_init_option == orog_init_option_ancil .or. &
orog_init_option == orog_init_option_start_dump ) then
if ( mode == mode_ics ) then
-
+
call field_maker(field_collection, trim('surface_altitude'), &
target_mesh, target_twod_mesh, prefix)
@@ -183,7 +183,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
prefix )
end do
end if
-
+
call modeldb%io_contexts%get_io_context(context_src, io_context)
call io_context%set_current()
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 8d0daaf343..4763e6da94 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -16,8 +16,7 @@ module lfric2lfric_infrastructure_mod
use blend_orography_alg_mod, only: blend_orography
use constants_mod, only: str_def, str_max_filename, &
r_def, i_def, l_def, r_second
- use create_mesh_mod, only: create_extrusion, &
- create_mesh
+ use create_mesh_mod, only: create_mesh
use driver_modeldb_mod, only: modeldb_type
use driver_fem_mod, only: init_fem
use driver_io_mod, only: init_io, &
@@ -31,13 +30,7 @@ module lfric2lfric_infrastructure_mod
use fs_continuity_mod, only: W3
use function_space_collection_mod,only: function_space_collection
use function_space_mod, only: function_space_type
- use gungho_extrusion_mod, only: dcmip_extrusion_type, &
- um_L38_29t_9s_40km_extrusion_type, &
- um_L85_50t_35s_85km_extrusion_type, &
- um_L70_61t_9s_40km_extrusion_type, &
- um_L120_99t_21s_40km_extrusion_type, &
- um_L140_122t_18s_40km_extrusion_type, &
- um_L70_50t_20s_80km_extrusion_type
+ use gungho_extrusion_mod, only: create_extrusion
use sci_geometric_constants_mod, only: get_chi_inventory, &
get_panel_id_inventory
use init_altitude_mod, only: init_altitude
@@ -356,109 +349,21 @@ contains
log_level_error)
end select
- select case (src_extrusion_method)
- case (method_uniform, method_quadratic, method_geometric)
- allocate( src_extrusion, source=create_extrusion( &
- src_extrusion_method, src_domain_height, &
- domain_bottom, src_number_of_layers, &
- prime_extrusion ) )
-
- case (method_dcmip)
- allocate( src_extrusion, source=dcmip_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L38_29t_9s_40km)
- allocate( src_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L85_50t_35s_85km)
- allocate( src_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_50t_20s_80km)
- allocate( src_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_61t_9s_40km)
- allocate( src_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L120_99t_21s_40km)
- allocate( src_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case (method_um_L140_122t_18s_40km)
- allocate( src_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
- domain_bottom, src_domain_height, &
- src_number_of_layers, prime_extrusion ) )
-
- case default
- write( log_scratch_space, '(A)' ) &
- "lfric2lfric_infrastructure_mod" // &
- ': Unrecognised source extrusion method: ' // &
- trim(key_from_method( src_extrusion_method ))
- call log_event( log_scratch_space, log_level_error )
-
- end select
-
+ allocate( src_extrusion, source = &
+ create_extrusion( src_extrusion_method, &
+ source_geometry, &
+ src_number_of_layers, &
+ src_domain_height, &
+ scaled_radius ))
+
if (vertical_change) then
- select case (dst_extrusion_method)
- case (method_uniform, method_quadratic, method_geometric)
- allocate( dst_extrusion, source=create_extrusion( &
- dst_extrusion_method, dst_domain_height, &
- domain_bottom, dst_number_of_layers, &
- prime_extrusion ) )
-
- case (method_dcmip)
- allocate( dst_extrusion, source=dcmip_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L38_29t_9s_40km)
- allocate( dst_extrusion, source=um_l38_29t_9s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L85_50t_35s_85km)
- allocate( dst_extrusion, source=um_l85_50t_35s_85km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_50t_20s_80km)
- allocate( dst_extrusion, source=um_l70_50t_20s_80km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L70_61t_9s_40km)
- allocate( dst_extrusion, source=um_l70_61t_9s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L120_99t_21s_40km)
- allocate( dst_extrusion, source=um_L120_99t_21s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case (method_um_L140_122t_18s_40km)
- allocate( dst_extrusion, source=um_L140_122t_18s_40km_extrusion_type( &
- domain_bottom, dst_domain_height, &
- dst_number_of_layers, prime_extrusion ) )
-
- case default
- write( log_scratch_space, '(A)' ) &
- "lfric2lfric_infrastructure_mod" // &
- ': Unrecognised destination extrusion method: ' // &
- trim(key_from_method( dst_extrusion_method ))
- call log_event( log_scratch_space, log_level_error )
-
- end select
+ allocate( dst_extrusion, source = &
+ create_extrusion( dst_extrusion_method, &
+ source_geometry, &
+ dst_number_of_layers, &
+ dst_domain_height, &
+ scaled_radius ))
end if
From 9ecb788f7f91a9862d5fbc04701d76ee4654cbb7 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 14:10:24 +0100
Subject: [PATCH 27/53] corrections and whitespace
---
.../lfric2lfric_infrastructure_mod.X90 | 30 +++++++++----------
.../orography/blend_orography_alg_mod.x90 | 4 +--
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 4763e6da94..7d68aedde3 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -138,7 +138,7 @@ contains
type(modeldb_type), intent(inout) :: modeldb
type(model_clock_type), allocatable, &
intent(inout) :: oasis_clock
-
+
! Coordinate field
type(field_type), pointer :: chi(:)
type(field_type), pointer :: panel_id
@@ -200,7 +200,7 @@ contains
logical(kind=l_def) :: vertical_change
logical(kind=l_def) :: horizontal_change
-
+
integer(i_def) :: tile_size_x
integer(i_def) :: tile_size_y
logical(l_def) :: inner_halo_tiles
@@ -219,7 +219,7 @@ contains
type(field_collection_type), pointer :: target_collection
type(field_type), pointer :: field
-
+
!------------------------
! XIOS contexts
!------------------------
@@ -240,7 +240,7 @@ contains
! -------------------------------
! Extract namelist variables
! -------------------------------
-
+
! Check lfric2lfric configuration settings are allowed
call lfric2lfric_check_configuration( modeldb%config )
@@ -278,7 +278,7 @@ contains
! Vertical interpolation is required if there is a change in the vertical
! extrusion, or a change in the orography
vertical_change = .false.
- if ( src_extrusion_method /= dst_extrusion_method .or. &
+ if ( src_extrusion_method /= dst_extrusion_method .or. &
src_number_of_layers /= dst_number_of_layers .or. &
src_domain_height /= dst_domain_height .or. &
src_stretching_height /= dst_stretching_height .or. &
@@ -290,7 +290,7 @@ contains
orog_init_option == orog_init_option_start_dump ) then
vertical_change = .true.
end if
-
+
! Horizontal interpolation is required if there is a change
! in the mesh (horizontal grid)
horizontal_change = .false.
@@ -351,16 +351,16 @@ contains
allocate( src_extrusion, source = &
create_extrusion( src_extrusion_method, &
- source_geometry, &
+ geometry, &
src_number_of_layers, &
src_domain_height, &
scaled_radius ))
-
+
if (vertical_change) then
allocate( dst_extrusion, source = &
create_extrusion( dst_extrusion_method, &
- source_geometry, &
+ geometry, &
dst_number_of_layers, &
dst_domain_height, &
scaled_radius ))
@@ -385,7 +385,7 @@ contains
mesh_names, src_extrusion, &
inner_halo_tiles, tile_size, &
stencil_depth, regrid_method )
-
+
allocate( mesh_names_dst_ext, source=mesh_names )
@@ -400,9 +400,9 @@ contains
else
do i=1, size(mesh_names)
mesh_names_dst_ext(i) = trim(mesh_names(i))
- end do
+ end do
end if
-
+
allocate( twod_names, source=mesh_names )
do i=1, size(twod_names)
twod_names(i) = trim(twod_names(i))//'_2d'
@@ -443,7 +443,7 @@ contains
! mesh_names_dst_ext(dst)
mesh_dst => mesh_collection%get_mesh(trim(mesh_names_dst_ext(dst)))
twod_mesh_dst => mesh_collection%get_mesh(trim(twod_names(dst)))
-
+
! Log this change
call log_event('Source mesh set to: ' // mesh_names(src), &
log_level_debug)
@@ -474,7 +474,7 @@ contains
panel_id_inventory, &
geometry, topology, &
populate_filelist=files_init_ptr )
-
+
call modeldb%io_contexts%get_io_context(context_dst, io_context_dst)
@@ -612,7 +612,7 @@ contains
call log_event( log_scratch_space, log_level_error )
#endif
end select
-
+
!=======================================================================
! The lateral boundary conditions of limited-area models (LAMs) are
! implemented by updating the data values at the boundaries with values
diff --git a/science/gungho/source/orography/blend_orography_alg_mod.x90 b/science/gungho/source/orography/blend_orography_alg_mod.x90
index 8038bf9b03..58815a7baa 100644
--- a/science/gungho/source/orography/blend_orography_alg_mod.x90
+++ b/science/gungho/source/orography/blend_orography_alg_mod.x90
@@ -19,7 +19,7 @@ module blend_orography_alg_mod
LOG_LEVEL_INFO, &
LOG_LEVEL_DEBUG, &
LOG_LEVEL_ERROR
-
+
implicit none
public :: blend_orography
@@ -50,7 +50,7 @@ contains
call log_event( "Creating the blended orography (for LAMs)", &
LOG_LEVEL_DEBUG )
-
+
! Define the function space required for masks.
fs_enum = lam_orog%which_function_space()
mesh => lam_orog%get_mesh()
From 6e599629db2b04ba5a05a1503715e4d0c6a98ce7 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 14:36:13 +0100
Subject: [PATCH 28/53] validate rose corrections
---
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 215 ++++++++++--------
.../lfric2lfric/opt/rose-app-C12_C16_lam.conf | 4 -
.../opt/rose-app-clim_gal9_ral_seuk.conf | 12 +
.../opt/rose-app-dst_L38_40km.conf | 2 +-
.../opt/rose-app-src_L70_80km.conf | 2 +-
rose-stem/app/lfric2lfric/rose-app.conf | 33 ++-
6 files changed, 152 insertions(+), 116 deletions(-)
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index ecb0cdc604..2103c06787 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -7,6 +7,121 @@ compulsory=false
compulsory=false
!!trigger=namelist:partitioning: .false.;
+[namelist:extrusion_dst]
+compulsory=true
+description=Vertical extrusion settings for the destination mesh.
+help=
+ns=namelist/Model/Mesh/Extrusion
+sort-key=Section-A03
+
+[namelist:extrusion_dst=domain_height]
+compulsory=true
+description=Height of domain above the surface [m]
+fail-if=this < 0.0 ;
+help=Height of the model domain above the surface.
+ =Surface is 0m for planar domains and planet_radius for spherical.
+!kind=default
+range=this > 0.0:
+sort-key=Panel-A02
+type=real
+
+[namelist:extrusion_dst=eta_values]
+!bounds=namelist:extrusion=number_of_layers-1
+compulsory=true
+description=Eta values, excluding 0 and 1
+help=Non-dimensional height values defining the model vertical levels.
+ =The length should be smaller by number_of_layers by one.
+ =
+ =The values must strictly be between 0 and 1:
+ =0 < eta_values < 1
+ =because 0 and 1 are appended to the list automatically.
+!kind=default
+length=:
+range=0.0:1.0
+sort-key=Panel-A04
+type=real
+
+[namelist:extrusion_dst=method]
+compulsory=true
+description=Method for generating eta coordinate
+!enumeration=true
+fail-if=this == 'um_L38_29t_9s_40km' and namelist:extrusion_dst=number_of_layers != 38 ;
+ =this == 'um_L70_50t_20s_80km' and namelist:extrusion_dst=number_of_layers != 70 ;
+ =this == 'um_L85_50t_35s_85km' and namelist:extrusion_dst=number_of_layers != 85 ;
+ =this == 'um_L70_61t_9s_40km' and namelist:extrusion_dst=number_of_layers != 70 ;
+ =this == 'um_L120_99t_21s_40km' and namelist:extrusion_dst=number_of_layers != 120 ;
+ =this == 'um_L140_122t_18s_40km' and namelist:extrusion_dst=number_of_layers != 140 ;
+help=Available extrusion methods are (\f$n$ is number of layers):
+ =0) Specified by user;
+ =1) Uniform eta spacing (\f$\frac{k}{n}\f$);
+ =2) Quadratic eta spacing (\f$\frac{k}{n}^2\f$);
+ =3) Geometric eta spacing (\f$d\eta = \frac{(s - 1)}{(s^{n} - 1)}$)
+ = with stretching factor prescribed (\f$s=1.03$);
+ =4) DCMIP eta spacing (Ullrich et al. (2012) DCMIP documentation, Appendix F.2.)
+ = with flattening parameter prescribed.
+ =5) L38 40km UM specific eta spacing;
+ =6) L70 80km UM specific eta spacing;
+ =7) L85 85km UM specific eta spacing;
+ =8) L70 40km UM specific eta spacing
+ =9) L120 40km UM specific eta spacing
+ =10) L140 40km UM specific eta spacing
+sort-key=Panel-A01
+trigger=namelist:extrusion_dst=eta_values: 'specified_values';
+value-titles=Uniform, Quadratic, Geometric, DCMIP,
+ = um_L38_29t_9s_40km, um_L70_50t_20s_80km, um_L85_50t_35s_85km, um_L70_61t_9s_40km,
+ = um_L120_99t_21s_40km, um_L140_122t_18s_40km
+values='uniform', 'quadratic', 'geometric', 'dcmip',
+ ='um_L38_29t_9s_40km', 'um_L70_50t_20s_80km', 'um_L85_50t_35s_85km', 'um_L70_61t_9s_40km',
+ ='um_L120_99t_21s_40km', 'um_L140_122t_18s_40km'
+
+[namelist:extrusion_dst=number_of_layers]
+compulsory=true
+description=Number of layers in the vertical
+fail-if=this < 1 ;
+help=Setting for number of layers of 3D-mesh in vertical.
+!kind=default
+range=1:
+sort-key=Panel-A03
+type=integer
+
+[namelist:extrusion_dst=planet_radius]
+compulsory=true
+description=Radius of the planet surface [m]
+fail-if=this <= 0.0 ;
+help=Radius of domain bottom. Note: Orography not included.
+!kind=default
+range=this > 0.0:
+sort-key=Panel-A02
+type=real
+
+[namelist:extrusion_dst=stretching_height]
+compulsory=false
+description=Physical height above which surface altitude does not
+ = influence layer height
+fail-if=this < 0.0 ;
+help=Physical height above which surface altitude does not
+ =influence layer height.
+ =Note that in order to reproduce the vertical stretching used in
+ =the UM 'smooth' extrusion, this value should be set to
+ =the value of eta_rho corresponding to the UM level
+ =first_constant_r_rho_level and multiplied by domain_height.
+!kind=default
+range=0:
+sort-key=Panel-A02 ;1
+type=real
+
+[namelist:extrusion_dst=stretching_method]
+compulsory=false
+description=Method of generating stretching
+!enumeration=true
+help=Available stretching methods are:
+ =1) Linear (linear multiple of physical depth)
+ =2) Smooth (quadratic below stretching_height, linear above)
+sort-key=Panel-A01
+trigger=namelist:extrusion_dst=stretching_height: 'smooth' ;
+value-titles=Linear, Smooth
+values='linear', 'smooth'
+
[namelist:lfric2lfric]
compulsory=true
description=
@@ -28,7 +143,6 @@ values='planar', 'spherical'
[namelist:lfric2lfric=destination_mesh_name]
compulsory=true
description=Tag-name for destination-mesh
-fail-if=this == namelist:lfric2lfric=source_mesh_name ;
help=Mesh topologies are held in UGRID conformant NetCDF files which
=may contain more than one mesh topology. This tag-name identifies
=the mesh topology to use from the mesh file namelist:lfric2lfric=destination_meshfile_prefix.
@@ -183,7 +297,6 @@ values='planar', 'spherical'
[namelist:lfric2lfric=source_mesh_name]
compulsory=true
description=Tag-name for source-mesh
-fail-if=this == namelist:lfric2lfric=destination_mesh_name ;
help=Mesh topologies are held in UGRID conformant NetCDF files which
=may contain more than one mesh topology. This tag-name identifies
=the mesh topology to use from the mesh file namelist:lfric2lfric=source_meshfile_prefix.
@@ -295,101 +408,3 @@ help=The designation of the mesh to which this
ns=namelist/lfric2lfric/configuration
!string_length=default
type=character
-
-[namelist:extrusion_dst]
-compulsory=true
-description=Vertical extrusion settings for the destination mesh.
-help=
-ns=namelist/Model/Mesh/Extrusion
-sort-key=Section-A03
-
-[namelist:extrusion_dst=domain_height]
-compulsory=true
-description=Height of domain above the surface [m]
-fail-if=this < 0.0 ;
-help=Height of the model domain above the surface.
- =Surface is 0m for planar domains and planet_radius for spherical.
-!kind=default
-range=this > 0.0:
-sort-key=Panel-A02
-type=real
-
-[namelist:extrusion_dst=method]
-compulsory=true
-description=Method for generating eta coordinate
-!enumeration=true
-fail-if=this == 'um_L38_29t_9s_40km' and namelist:extrusion_dst=number_of_layers != 38 ;
- =this == 'um_L70_50t_20s_80km' and namelist:extrusion_dst=number_of_layers != 70 ;
- =this == 'um_L85_50t_35s_85km' and namelist:extrusion_dst=number_of_layers != 85 ;
- =this == 'um_L70_61t_9s_40km' and namelist:extrusion_dst=number_of_layers != 70 ;
- =this == 'um_L120_99t_21s_40km' and namelist:extrusion_dst=number_of_layers != 120 ;
- =this == 'um_L140_122t_18s_40km' and namelist:extrusion_dst=number_of_layers != 140 ;
-help=Available extrusion methods are (\f$n$ is number of layers):
- =1) Uniform eta spacing (\f$\frac{k}{n}\f$);
- =2) Quadratic eta spacing (\f$\frac{k}{n}^2\f$);
- =3) Geometric eta spacing (\f$d\eta = \frac{(s - 1)}{(s^{n} - 1)}$)
- = with stretching factor prescribed (\f$s=1.03$);
- =4) DCMIP eta spacing (Ullrich et al. (2012) DCMIP documentation, Appendix F.2.)
- = with flattening parameter prescribed.
- =5) L38 40km UM specific eta spacing;
- =6) L70 80km UM specific eta spacing;
- =7) L85 85km UM specific eta spacing;
- =8) L70 40km UM specific eta spacing
- =9) L120 40km UM specific eta spacing
- =10) L140 40km UM specific eta spacing
-sort-key=Panel-A01
-value-titles=Uniform, Quadratic, Geometric, DCMIP,
- = um_L38_29t_9s_40km, um_L70_50t_20s_80km, um_L85_50t_35s_85km, um_L70_61t_9s_40km,
- = um_L120_99t_21s_40km, um_L140_122t_18s_40km
-values='uniform', 'quadratic', 'geometric', 'dcmip',
- ='um_L38_29t_9s_40km', 'um_L70_50t_20s_80km', 'um_L85_50t_35s_85km', 'um_L70_61t_9s_40km',
- ='um_L120_99t_21s_40km', 'um_L140_122t_18s_40km'
-
-[namelist:extrusion_dst=number_of_layers]
-compulsory=true
-description=Number of layers in the vertical
-fail-if=this < 1 ;
-help=Setting for number of layers of 3D-mesh in vertical.
-!kind=default
-range=1:
-sort-key=Panel-A03
-type=integer
-
-[namelist:extrusion_dst=planet_radius]
-compulsory=true
-description=Radius of the planet surface [m]
-fail-if=this <= 0.0 ;
-help=Radius of domain bottom. Note: Orography not included.
-!kind=default
-range=this > 0.0:
-sort-key=Panel-A02
-type=real
-
-[namelist:extrusion_dst=stretching_height]
-compulsory=false
-description=Physical height above which surface altitude does not
- = influence layer height
-fail-if=this < 0.0 ;
-help=Physical height above which surface altitude does not
- =influence layer height.
- =Note that in order to reproduce the vertical stretching used in
- =the UM 'smooth' extrusion, this value should be set to
- =the value of eta_rho corresponding to the UM level
- =first_constant_r_rho_level and multiplied by domain_height.
-!kind=default
-range=0:
-sort-key=Panel-A02 ;1
-type=real
-
-[namelist:extrusion_dst=stretching_method]
-compulsory=false
-description=Method of generating stretching
-!enumeration=true
-help=Available stretching methods are:
- =1) Linear (linear multiple of physical depth)
- =2) Smooth (quadratic below stretching_height, linear above)
-sort-key=Panel-A01
-trigger=namelist:extrusion_dst=stretching_height: 'smooth' ;
-value-titles=Linear, Smooth
-values='linear', 'smooth'
-
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
index 950011de21..6facf39303 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-C12_C16_lam.conf
@@ -1,9 +1,6 @@
[file:iodef.xml]
source=$ROSE_SUITE_DIR/app/lfric2lfric/file/iodef_orography.xml
-[namelist:files]
-orography_mean_ancil_path=''
-
[namelist:lfric2lfric]
destination_mesh_name='dynamics'
destination_meshfile_prefix='${MESH_DIR}/seuk_MG/mesh_seuk_MG'
@@ -14,4 +11,3 @@ source_mesh_name='C12'
source_meshfile_prefix='${MESH_DIR}/C24_C12/mesh_C24_C12'
src_ancil_directory='$BIG_DATA_DIR/ancils/basic-gagl/Puku/C12/n96e'
src_orography_mean_ancil_path='orography/globe30/qrparm.orog.ugrid'
-
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
index 02877f4ad7..16e0206d4e 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
@@ -1,6 +1,18 @@
[file:lfric2lfric_clim_gal9_C12_MG.nc]
source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_clim_gal9_C12_dt-1800p0_intel_64-bit_fast-debug_000072.nc"
+[namelist:boundaries]
+blend_frequency='inner'
+blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
+blending_weights_w2v=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
+lbc_eos_height=10
+lbc_method='onion_layer'
+limited_area=.true.
+normal_only=.true.
+output_lbcs=.true.
+solver_boundary_depth=4
+transport_boundary_depth=4
+
[namelist:extrusion]
domain_height=80000.0
method='um_L70_50t_20s_80km'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf b/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
index 33fd5d9900..ae8fce007f 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-dst_L38_40km.conf
@@ -3,4 +3,4 @@ domain_height=39254.833575999997
method='um_L38_29t_9s_40km'
number_of_layers=38
planet_radius=6371229.0
-stretching_method='linear'
\ No newline at end of file
+stretching_method='linear'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf b/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
index 116aa7c5f2..d97fabaebe 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-src_L70_80km.conf
@@ -3,4 +3,4 @@ domain_height=80000.0
method='um_L70_50t_20s_80km'
number_of_layers=70
stretching_height=17507.0
-stretching_method='smooth'
\ No newline at end of file
+stretching_method='smooth'
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index 6d0cf21677..7fead03c32 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -105,16 +105,29 @@ sg_orog_mixing='none'
!!zhloc_depth_fac=0
[namelist:boundaries]
-blend_frequency='inner'
-blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
-blending_weights_w2v=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1
-lbc_eos_height=10
-lbc_method='onion_layer'
-limited_area=.true.
-normal_only=.true.
-output_lbcs=.true.
-solver_boundary_depth=4
-transport_boundary_depth=4
+!!blend_frequency='final'
+!!blending_weights=0.0
+!!blending_weights_w2v=0.0
+!!boundary_e=1
+!!boundary_n=1
+!!boundary_s=1
+!!boundary_w=1
+!!edge_cells_ew=1
+!!edge_cells_ns=1
+!!inner_width_ew=1
+!!inner_width_ns=1
+!!lbc_eos_height=100
+!!lbc_method='coordinate_based'
+limited_area=.false.
+!!normal_only=.true.
+!!outer_width_ew=1
+!!outer_width_ns=1
+!!output_lbcs=.false.
+!!rim_width_ew=1
+!!rim_width_ns=1
+!!solver_boundary_depth=1
+!!transport_boundary_depth=6
+transport_overwrite_freq='final'
[namelist:checks]
limit_cfl=.false.
From 4a8b6d0431711ff68ffb123b20ff2ccfc5fdd3b4 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 14:47:49 +0100
Subject: [PATCH 29/53] Remove tabs
---
rose-stem/site/meto/groups/groups_lfric2lfric.cylc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
index 23c622d4d2..4fcf2f7d51 100644
--- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc
@@ -52,7 +52,7 @@
"lfric2lfric_oasis_clim_gal9-C24_C12_6cpu_ex1a_cce_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_1cpu_ex1a_cce_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_1cpu_ex1a_cce_fast-debug-64bit",
- "lfric2lfric_oasis_C12L70_to_seukL38_ex1a_cce_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_seukL38_ex1a_cce_fast-debug-64bit",
"lfric2lfric_oasis_C12L70_to_C12L38_ex1a_cce_fast-debug-64bit",
"lfric2lfric_ex1a_canned",
],
From ae186821db725f08ddc9fa51d7848685b2b7bf73 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 15:05:37 +0100
Subject: [PATCH 30/53] rose corrections
---
rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf | 1 -
rose-stem/app/lfric2lfric/rose-app.conf | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
index 16e0206d4e..4af46b8816 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
@@ -11,7 +11,6 @@ limited_area=.true.
normal_only=.true.
output_lbcs=.true.
solver_boundary_depth=4
-transport_boundary_depth=4
[namelist:extrusion]
domain_height=80000.0
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index 7fead03c32..468f1fd6e2 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -1,4 +1,4 @@
-meta=lfric-lfric2lfric/vn3.2
+meta=lfric-lfric2lfric/HEAD
[command]
default=$CORE_ROOT_DIR/bin/tweak_iodef; \
From abdcd78e8b1877c6a99ca65f402cc98e6357fd53 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 15 Jul 2026 16:58:40 +0100
Subject: [PATCH 31/53] correction
---
.../lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index 2103c06787..f392e31b3f 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -26,7 +26,7 @@ sort-key=Panel-A02
type=real
[namelist:extrusion_dst=eta_values]
-!bounds=namelist:extrusion=number_of_layers-1
+!bounds=namelist:extrusion_dst=number_of_layers-1
compulsory=true
description=Eta values, excluding 0 and 1
help=Non-dimensional height values defining the model vertical levels.
From 4882762955dd2beb749c23f4b6b2b4c114599a2b Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 16 Jul 2026 14:12:10 +0100
Subject: [PATCH 32/53] gungho unit tests
---
.../analytic_orography_field_cartesian_mod_test.pf | 7 +++++--
.../analytic_orography_field_spherical_mod_test.pf | 9 ++++++---
.../orography/ancil_orography_cartesian_mod_test.pf | 9 ++++++---
.../orography/ancil_orography_spherical_mod_test.pf | 9 ++++++---
4 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/science/gungho/unit-test/orography/analytic_orography_field_cartesian_mod_test.pf b/science/gungho/unit-test/orography/analytic_orography_field_cartesian_mod_test.pf
index c38cf9bd3e..2e43fae74a 100644
--- a/science/gungho/unit-test/orography/analytic_orography_field_cartesian_mod_test.pf
+++ b/science/gungho/unit-test/orography/analytic_orography_field_cartesian_mod_test.pf
@@ -12,6 +12,7 @@ module analytic_orography_field_cartesian_mod_test
use global_mesh_mod, only : global_mesh_type
use analytic_orography_mod, only : orography_profile
use ugrid_mesh_data_mod, only : ugrid_mesh_data_type
+ use extrusion_config_mod, only : method_uniform, stretching_method_linear
use funit
@@ -40,6 +41,7 @@ module analytic_orography_field_cartesian_mod_test
real(r_def), parameter :: domain_bottom = 0.0_r_def
real(r_def), parameter :: domain_height = 10000.0_r_def
+ real(r_def), parameter :: stretching_height = 1.0_r_def
real(r_def), parameter :: surface_pressure = 1000.0e2_r_def
integer(i_def), parameter :: nlayers = 10_i_def
@@ -71,7 +73,6 @@ contains
feign_orography_schar_cartesian_config
use orography_schar_cartesian_config_mod, &
only : direction_x
- use extrusion_config_mod, only : method_uniform, stretching_method_linear
use initial_pressure_config_mod, only : method_balanced
@@ -93,7 +94,7 @@ contains
planet_radius=6000.0_r_def, &
domain_height=domain_height, &
number_of_layers=nlayers, &
- stretching_height=1.0_r_def, &
+ stretching_height=stretching_height, &
stretching_method=stretching_method_linear, &
eta_values=(/0.5_r_def/) )
@@ -253,6 +254,8 @@ contains
ndf, undf, map, &
height_flat_surface, &
height_domain_top, &
+ stretching_height, &
+ stretching_method_linear, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1, chi_2, chi_3, &
panel_id )
diff --git a/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf b/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf
index 9d1571fc7e..8d76cdba76 100644
--- a/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf
+++ b/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf
@@ -13,6 +13,8 @@ module analytic_orography_field_spherical_mod_test
use global_mesh_mod, only : global_mesh_type
use analytic_orography_mod, only : orography_profile
use ugrid_mesh_data_mod, only : ugrid_mesh_data_type
+ use extrusion_config_mod, only : method_uniform, &
+ stretching_method_linear
use funit
@@ -40,6 +42,7 @@ module analytic_orography_field_spherical_mod_test
real(r_def), parameter :: radius = 6371229.0_r_def
real(r_def), parameter :: domain_height = 10000.0_r_def
+ real(r_def), parameter :: stretching_height = 1.0_r_def
integer(i_def), parameter :: nlayers = 10_i_def
integer(i_def), parameter :: total_ranks = 1_i_def
@@ -60,8 +63,6 @@ contains
use agnesi_orography_spherical_mod, only : agnesi_spherical_type
use base_mesh_config_mod, only : geometry_spherical, &
topology_fully_periodic
- use extrusion_config_mod, only : method_uniform, &
- stretching_method_linear
use finite_element_config_mod, only : cellshape_quadrilateral, &
coord_system_xyz, &
coord_space_wchi
@@ -95,7 +96,7 @@ contains
planet_radius=radius, &
domain_height=domain_height, &
number_of_layers=nlayers, &
- stretching_height=1.0_r_def, &
+ stretching_height=stretching_height, &
stretching_method=stretching_method_linear, &
eta_values=(/0.5_r_def/) )
@@ -270,6 +271,8 @@ contains
ndf, undf, map, &
height_flat_surface, &
height_domain_top, &
+ stretching_height, &
+ stretching_method_linear, &
chi_1_in, chi_2_in, chi_3_in, &
chi_1_cart, chi_2_cart, chi_3_cart, &
panel_id )
diff --git a/science/gungho/unit-test/orography/ancil_orography_cartesian_mod_test.pf b/science/gungho/unit-test/orography/ancil_orography_cartesian_mod_test.pf
index 0d8031b075..5b4f51bcfa 100644
--- a/science/gungho/unit-test/orography/ancil_orography_cartesian_mod_test.pf
+++ b/science/gungho/unit-test/orography/ancil_orography_cartesian_mod_test.pf
@@ -6,6 +6,8 @@
module ancil_orography_cartesian_mod_test
use constants_mod, only : i_def, r_def
+ use extrusion_config_mod, only : method_uniform, &
+ stretching_method_linear
use funit
implicit none
@@ -17,6 +19,7 @@ module ancil_orography_cartesian_mod_test
real(r_def), parameter :: dx = 6000.0_r_def
real(r_def), parameter :: dy = 1000.0_r_def
real(r_def), parameter :: dz = 2000.0_r_def
+ real(r_def), parameter :: stretching_height = 1.0_r_def
real(r_def), parameter :: domain_height = nlayers*dz
real(r_def), parameter :: domain_surface = 0.0_r_def
@@ -30,8 +33,6 @@ contains
use base_mesh_config_mod, only : geometry_planar, &
topology_fully_periodic
- use extrusion_config_mod, only : method_uniform, &
- stretching_method_linear
use finite_element_config_mod, only : cellshape_quadrilateral, &
coord_system_xyz, coord_space_wchi
use feign_config_mod, only : feign_finite_element_config, &
@@ -54,7 +55,7 @@ contains
planet_radius = 0.0_r_def, &
domain_height = domain_height, &
number_of_layers = nlayers, &
- stretching_height= 1.0_r_def, &
+ stretching_height= stretching_height, &
stretching_method= stretching_method_linear,&
eta_values=(/0.5_r_def/) )
@@ -213,6 +214,8 @@ contains
srf_alt_w0, &
domain_surface, &
domain_height, &
+ stretching_height, &
+ stretching_method_linear, &
ndf_wchi, &
undf_wchi, &
map_wchi(:, cell), &
diff --git a/science/gungho/unit-test/orography/ancil_orography_spherical_mod_test.pf b/science/gungho/unit-test/orography/ancil_orography_spherical_mod_test.pf
index ad8625391e..255e20237c 100644
--- a/science/gungho/unit-test/orography/ancil_orography_spherical_mod_test.pf
+++ b/science/gungho/unit-test/orography/ancil_orography_spherical_mod_test.pf
@@ -6,6 +6,8 @@
module ancil_orography_spherical_mod_test
use constants_mod, only : i_def, r_def
+ use extrusion_config_mod, only : method_uniform, &
+ stretching_method_linear
use funit
implicit none
@@ -17,6 +19,7 @@ module ancil_orography_spherical_mod_test
real(r_def), parameter :: dlat = 1.0_r_def/180.0_r_def
real(r_def), parameter :: dlon = 1.0_r_def/180.0_r_def
real(r_def), parameter :: dr = 1000.0_r_def
+ real(r_def), parameter :: stretching_height = 1.0_r_def
real(r_def), parameter :: domain_height = nlayers*dr
real(r_def), parameter :: radius = 6371229.0_r_def
real(r_def), parameter :: domain_surface = radius
@@ -31,8 +34,6 @@ contains
use base_mesh_config_mod, only : geometry_spherical, &
topology_fully_periodic
- use extrusion_config_mod, only : method_uniform, &
- stretching_method_linear
use finite_element_config_mod, only : cellshape_quadrilateral, &
coord_system_xyz, coord_space_wchi
use feign_config_mod, only : feign_finite_element_config, &
@@ -55,7 +56,7 @@ contains
planet_radius = radius, &
domain_height = domain_height, &
number_of_layers = nlayers, &
- stretching_height= 1.0_r_def, &
+ stretching_height= stretching_height, &
stretching_method= stretching_method_linear,&
eta_values=(/0.5_r_def/) )
@@ -217,6 +218,8 @@ contains
srf_alt_w0, &
domain_surface, &
domain_height, &
+ stretching_height, &
+ stretching_method_linear, &
ndf_wchi, &
undf_wchi, &
map_wchi(:, cell), &
From 4ca5114e6be46f8f14619f078af30e216ac6ecf1 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 20 Jul 2026 10:49:01 +0100
Subject: [PATCH 33/53] Added nci
---
rose-stem/site/nci/groups/groups_lfric2lfric.cylc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rose-stem/site/nci/groups/groups_lfric2lfric.cylc b/rose-stem/site/nci/groups/groups_lfric2lfric.cylc
index 252921b31b..a61ba97663 100644
--- a/rose-stem/site/nci/groups/groups_lfric2lfric.cylc
+++ b/rose-stem/site/nci/groups/groups_lfric2lfric.cylc
@@ -14,6 +14,8 @@
"lfric2lfric_clim_gal9-C24_C12_6cpu_gadi_intel_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9-C24_C12_6cpu_gadi_intel_fast-debug-64bit",
"lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_4cpu_gadi_intel_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_seukL38_gadi_intel_fast-debug-64bit",
+ "lfric2lfric_oasis_C12L70_to_C12L38_gadi_intel_fast-debug-64bit",
"lfric2lfric_gadi_canned",
],
"lfric2lfric_gadi_extra": [
From 13a4f3fc4bb06b558322faf16264063103447246 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 30 Jul 2026 14:51:37 +0100
Subject: [PATCH 34/53] source_config_list and target_config_list
---
.../source/driver/lfric2lfric_init_mod.f90 | 47 ++++++++++---------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index ab2a73b094..b9ffb2fad5 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -73,8 +73,10 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
! For get_field_list returns
integer(kind=i_def) :: num_fields
- character(len=str_def), allocatable :: config_list(:)
- character(len=nf90_max_name) :: prefix
+ character(len=str_def), allocatable :: source_config_list(:)
+ character(len=str_def), allocatable :: target_config_list(:)
+ character(len=nf90_max_name) :: source_prefix
+ character(len=nf90_max_name) :: target_prefix
! Source context pointer and temporary context for setup
type(lfric_xios_context_type), pointer :: io_context
@@ -85,14 +87,23 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call log_event( 'lfric2lfric: Initialising miniapp ...', log_level_info )
if (mode == mode_ics) then
- prefix = 'restart_'
+ source_prefix = 'restart_'
else if (mode == mode_lbc) then
- prefix = ''
+ source_prefix = ''
+ end if
+ if (mode == mode_ics) then
+ target_prefix = 'checkpoint_'
+ else if (mode == mode_lbc) then
+ target_prefix = 'lbc_'
end if
! Get field names from filename and validate presence in iodef.xml
- call get_field_list( num_fields, config_list, start_dump_filename, prefix )
-
+ call get_field_list( num_fields, target_config_list, &
+ start_dump_filename, target_prefix )
+
+ call get_field_list( num_fields, source_config_list, &
+ start_dump_filename, source_prefix )
+
!--------------------------------------------------------------------------
! Initialise Source Fields
!--------------------------------------------------------------------------
@@ -102,10 +113,10 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
! Now need to loop over length of config_list make field for each
do i = 1, num_fields
- call field_maker( field_collection, &
- config_list(i), &
- origin_mesh, &
- origin_twod_mesh, &
+ call field_maker( field_collection, &
+ source_config_list(i), &
+ origin_mesh, &
+ origin_twod_mesh, &
prefix )
end do
@@ -119,18 +130,12 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call modeldb%io_contexts%get_io_context(context_dst, io_context)
call io_context%set_current()
- if (mode == mode_ics) then
- prefix = 'checkpoint_'
- else if (mode == mode_lbc) then
- prefix = 'lbc_'
- end if
-
do i = 1, num_fields
- call field_maker( field_collection, &
- config_list(i), &
- target_mesh, &
- target_twod_mesh, &
- prefix )
+ call field_maker( field_collection, &
+ target_config_list(i), &
+ target_mesh, &
+ target_twod_mesh, &
+ target_prefix )
end do
call modeldb%io_contexts%get_io_context(context_src, io_context)
From 19d9ad8ba3d7e4cfc986bf329bc43e142ede510c Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 30 Jul 2026 15:38:27 +0100
Subject: [PATCH 35/53] Revert "source_config_list and target_config_list"
This reverts commit 13a4f3fc4bb06b558322faf16264063103447246.
---
.../source/driver/lfric2lfric_init_mod.f90 | 47 +++++++++----------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index b9ffb2fad5..ab2a73b094 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -73,10 +73,8 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
! For get_field_list returns
integer(kind=i_def) :: num_fields
- character(len=str_def), allocatable :: source_config_list(:)
- character(len=str_def), allocatable :: target_config_list(:)
- character(len=nf90_max_name) :: source_prefix
- character(len=nf90_max_name) :: target_prefix
+ character(len=str_def), allocatable :: config_list(:)
+ character(len=nf90_max_name) :: prefix
! Source context pointer and temporary context for setup
type(lfric_xios_context_type), pointer :: io_context
@@ -87,23 +85,14 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call log_event( 'lfric2lfric: Initialising miniapp ...', log_level_info )
if (mode == mode_ics) then
- source_prefix = 'restart_'
+ prefix = 'restart_'
else if (mode == mode_lbc) then
- source_prefix = ''
- end if
- if (mode == mode_ics) then
- target_prefix = 'checkpoint_'
- else if (mode == mode_lbc) then
- target_prefix = 'lbc_'
+ prefix = ''
end if
! Get field names from filename and validate presence in iodef.xml
- call get_field_list( num_fields, target_config_list, &
- start_dump_filename, target_prefix )
-
- call get_field_list( num_fields, source_config_list, &
- start_dump_filename, source_prefix )
-
+ call get_field_list( num_fields, config_list, start_dump_filename, prefix )
+
!--------------------------------------------------------------------------
! Initialise Source Fields
!--------------------------------------------------------------------------
@@ -113,10 +102,10 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
! Now need to loop over length of config_list make field for each
do i = 1, num_fields
- call field_maker( field_collection, &
- source_config_list(i), &
- origin_mesh, &
- origin_twod_mesh, &
+ call field_maker( field_collection, &
+ config_list(i), &
+ origin_mesh, &
+ origin_twod_mesh, &
prefix )
end do
@@ -130,12 +119,18 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
call modeldb%io_contexts%get_io_context(context_dst, io_context)
call io_context%set_current()
+ if (mode == mode_ics) then
+ prefix = 'checkpoint_'
+ else if (mode == mode_lbc) then
+ prefix = 'lbc_'
+ end if
+
do i = 1, num_fields
- call field_maker( field_collection, &
- target_config_list(i), &
- target_mesh, &
- target_twod_mesh, &
- target_prefix )
+ call field_maker( field_collection, &
+ config_list(i), &
+ target_mesh, &
+ target_twod_mesh, &
+ prefix )
end do
call modeldb%io_contexts%get_io_context(context_src, io_context)
From 78917301cd1517b699735b52eccc2aa379a2b667 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 30 Jul 2026 16:32:26 +0100
Subject: [PATCH 36/53] Check for ndata difference
---
.../source/driver/lfric2lfric_regrid_mod.F90 | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90
index 4859100c77..5cc9886c00 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90
@@ -89,6 +89,7 @@ subroutine lfric2lfric_regrid( modeldb, oasis_clock, &
integer(kind=i_def) :: fs_id
type(function_space_type), pointer :: fs_w3_src, fs_w3_dst
type(function_space_type), pointer :: fs_wth_src, fs_wth_dst
+ type(function_space_type), pointer :: fs_type
type(mesh_type), pointer :: mesh_dst
character(len=str_def) :: mesh_names(2)
@@ -101,7 +102,7 @@ subroutine lfric2lfric_regrid( modeldb, oasis_clock, &
integer(kind=i_def), parameter :: dst = 1
integer(kind=i_def), parameter :: src = 2
-
+ integer(kind=i_def) :: ndata_src, ndata_dst
! Obtain namelist parameters
mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
@@ -151,6 +152,16 @@ subroutine lfric2lfric_regrid( modeldb, oasis_clock, &
trim(field_name)
call log_event(log_scratch_space, log_level_info)
+ ! Is this a multidata field and is ndata the same?
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+ if (ndata_dst /= ndata_src) then
+ write(log_scratch_space, '(A)') "ndata not equal "
+ call log_event(log_scratch_space, log_level_info)
+ end if
+
! Convert W2 fields to a set of W3 and Wtheta fields
fs_id = field_src%which_function_space()
if (fs_id == W2) then
From 4a6c03f087d9be60ca8d9e4184153678743392ec Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Thu, 30 Jul 2026 16:48:01 +0100
Subject: [PATCH 37/53] example data with tiles and different ndata
---
applications/lfric2lfric/example/iodef.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/example/iodef.xml b/applications/lfric2lfric/example/iodef.xml
index 09a1fa0727..ced820e220 100644
--- a/applications/lfric2lfric/example/iodef.xml
+++ b/applications/lfric2lfric/example/iodef.xml
@@ -24,6 +24,7 @@
+
@@ -63,7 +64,8 @@
-
+
+
From 96da3f420d23b6f6cce63d348db446e4fec88ddb Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 3 Aug 2026 17:05:46 +0100
Subject: [PATCH 38/53] iodef
---
applications/lfric2lfric/example/iodef.xml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/applications/lfric2lfric/example/iodef.xml b/applications/lfric2lfric/example/iodef.xml
index ced820e220..4568a3f594 100644
--- a/applications/lfric2lfric/example/iodef.xml
+++ b/applications/lfric2lfric/example/iodef.xml
@@ -23,8 +23,9 @@
-
-
+
+
+
From b2665f60aaa6222ffc388ca5d5bd00e2923a6077 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Tue, 4 Aug 2026 15:03:17 +0100
Subject: [PATCH 39/53] infrastructure for tiles
---
.../algorithm/lfric2lfric_tiles_mod.x90 | 76 +++++++++++++++++
.../source/driver/lfric2lfric_driver_mod.F90 | 17 +++-
.../source/driver/lfric2lfric_init_mod.f90 | 29 ++++---
.../lfric2lfric_query_multilayer_mod.f90 | 81 +++++++++++++++++++
4 files changed, 189 insertions(+), 14 deletions(-)
create mode 100644 applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
create mode 100644 applications/lfric2lfric/source/initialisation/lfric2lfric_query_multilayer_mod.f90
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
new file mode 100644
index 0000000000..8ee7c924d2
--- /dev/null
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
@@ -0,0 +1,76 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Reconfiguration associated with changes in tiles
+module lfric2lfric_tiles_mod
+
+ use constants_mod, only: str_def, i_def
+ use driver_modeldb_mod, only: modeldb_type
+ use extrusion_mod, only: TWOD
+ use field_parent_mod, only: field_parent_type
+ use field_mod, only: field_type
+ use field_collection_mod, only: field_collection_type
+ use field_collection_iterator_mod, &
+ only: field_collection_iterator_type
+ use mesh_mod, only: mesh_type
+ use log_mod, only: log_event, &
+ log_level_info, &
+ log_scratch_space
+
+ implicit none
+
+ private
+ public :: lfric2lfric_tiles
+
+contains
+
+ !> @brief Apply the changes associated with the change in tiles.
+ !> @details Loop over the fields in the source_fields collection,
+ !! and deal with the change in tiles.
+ !> @param modeldb Model state object
+ !> @param source_fields The collection of fields to be regridded
+ !> @param target_fields The collection of regridded fields
+ subroutine lfric2lfric_tiles( modeldb, source_fields, target_fields )
+
+ implicit none
+
+ type(modeldb_type), intent(inout) :: modeldb
+ type(field_collection_type), intent(inout) :: source_fields
+ type(field_collection_type), intent(inout) :: target_fields
+
+ type(field_collection_iterator_type) :: iter
+
+ class(field_parent_type), pointer :: field
+ type(field_type), pointer :: field_src
+ type(field_type), pointer :: field_dst
+ type(mesh_type), pointer :: mesh
+
+ character(len=str_def) :: field_name
+
+ ! Main loop over fields to be processed
+ call iter%initialise(source_fields)
+ do
+ ! Locate the field to be processed in the field collections
+ if ( .not.iter%has_next() ) exit
+ field => iter%next()
+ field_name = field%get_name()
+
+ call source_fields%get_field(field_name, field_src)
+ call target_fields%get_field(field_name, field_dst)
+
+ mesh => field_src%get_mesh()
+ if (mesh%get_extrusion_id() == TWOD) then
+
+ write(log_scratch_space, '(A,A)') "Processing lfric field ", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_info)
+
+ ! Apply changes associated with tiles
+ end if
+ end do
+
+ end subroutine lfric2lfric_tiles
+
+end module lfric2lfric_tiles_mod
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 0e5f16b007..dfb709241f 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -40,6 +40,8 @@ module lfric2lfric_driver_mod
src, dst
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
use lfric2lfric_vert_mod, only: lfric2lfric_vert
+ use lfric2lfric_tiles_mod, only: lfric2lfric_tiles
+
implicit none
@@ -123,6 +125,8 @@ subroutine run( modeldb, oasis_clock )
logical(kind=l_def), pointer :: vertical_change
logical(kind=l_def), pointer :: horizontal_change
+ logical(kind=l_def), pointer :: tile_change
+ logical(kind=l_def) :: vertical_or_tile_change
! Extract configuration variables
src_extrusion_method = modeldb%config%extrusion%method()
@@ -151,14 +155,18 @@ subroutine run( modeldb, oasis_clock )
call modeldb%values%get_value("vertical_change", vertical_change)
call modeldb%values%get_value("horizontal_change", horizontal_change)
+ call modeldb%values%get_value("tile_change", tile_change)
- if (horizontal_change .and. vertical_change) then
+ if (vertical_change .or. tile_change) then
+ vertical_or_tile_change = .true.
+ end if
+ if (horizontal_change .and. vertical_or_tile_change) then
interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
- else if (horizontal_change .and. .not. vertical_change) then
+ else if (horizontal_change .and. .not. vertical_or_tile_change) then
interm_fields => modeldb%fields%get_field_collection(target_collection_name)
- else if (vertical_change .and. .not. horizontal_change) then
+ else if (vertical_or_tile_change .and. .not. horizontal_change) then
interm_fields => modeldb%fields%get_field_collection(source_collection_name)
end if
@@ -173,6 +181,9 @@ subroutine run( modeldb, oasis_clock )
if (vertical_change) then
call lfric2lfric_vert(modeldb, interm_fields, target_fields)
end if
+ if (tile_change) then
+ call lfric2lfric_tiles(modeldb, interm_fields, target_fields)
+ end if
! Write output
call modeldb%io_contexts%get_io_context(context_dst, io_context)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index c6be9c3651..69fc77c0f1 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -27,6 +27,8 @@ module lfric2lfric_init_mod
! lfric2lfric mods
use lfric2lfric_config_mod, only: mode_ics, mode_lbc
use lfric2lfric_field_init_mod, only: get_field_list, field_maker
+ use lfric2lfric_query_multilayer_mod, &
+ only: query_multilayer
implicit none
private
@@ -81,9 +83,12 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
logical(l_def), pointer :: horizontal_change
logical(l_def), pointer :: vertical_change
+ logical(l_def), pointer :: tile_change
! For field creation and storage
- type(field_collection_type), pointer :: field_collection
+ type(field_collection_type), pointer :: target_fields
+ type(field_collection_type), pointer :: source_fields
+ type(field_collection_type), pointer :: interm_fields
! For get_field_list returns
integer(kind=i_def) :: num_fields
@@ -115,11 +120,11 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
!--------------------------------------------------------------------------
! Initialise our field collection
call modeldb%fields%add_empty_field_collection(origin_collection_name)
- field_collection => modeldb%fields%get_field_collection(origin_collection_name)
+ source_fields => modeldb%fields%get_field_collection(origin_collection_name)
! Now need to loop over length of config_list make field for each
do i = 1, num_fields
- call field_maker( field_collection, &
+ call field_maker( source_fields, &
config_list(i), &
origin_mesh, &
origin_twod_mesh, &
@@ -130,8 +135,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
! Initialise Target Fields
!--------------------------------------------------------------------------
call modeldb%fields%add_empty_field_collection(target_collection_name)
- field_collection => &
- modeldb%fields%get_field_collection(target_collection_name)
+ target_fields => modeldb%fields%get_field_collection(target_collection_name)
call modeldb%io_contexts%get_io_context(context_dst, io_context)
call io_context%set_current()
@@ -143,7 +147,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
end if
do i = 1, num_fields
- call field_maker( field_collection, &
+ call field_maker( target_fields, &
config_list(i), &
target_mesh, &
target_twod_mesh, &
@@ -155,19 +159,22 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
orog_init_option == orog_init_option_start_dump ) then
if ( mode == mode_ics ) then
- call field_maker(field_collection, trim('surface_altitude'), &
+ call field_maker(target_fields, trim('surface_altitude'), &
target_mesh, target_twod_mesh, prefix)
end if
end if
+ call query_multilayer( modeldb, source_fields, target_fields )
+ call modeldb%values%get_value("tile_change", tile_change)
+
!--------------------------------------------------------------------------
! Initialise Intermediate Fields
!--------------------------------------------------------------------------
- if (horizontal_change .and. vertical_change) then
+ if ( (horizontal_change .and. vertical_change) .or. &
+ (horizontal_change .and. tile_change)) then
call modeldb%fields%add_empty_field_collection(interm_collection_name)
- field_collection => &
- modeldb%fields%get_field_collection(interm_collection_name)
+ interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
if (mode == mode_ics) then
prefix = 'checkpoint_'
@@ -176,7 +183,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
end if
do i = 1, num_fields
- call field_maker( field_collection, &
+ call field_maker( interm_fields, &
config_list(i), &
interm_mesh, &
interm_twod_mesh, &
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_query_multilayer_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_query_multilayer_mod.f90
new file mode 100644
index 0000000000..ecb7d0e0df
--- /dev/null
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_query_multilayer_mod.f90
@@ -0,0 +1,81 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Query whether extra work is required for the multi-layer fields.
+module lfric2lfric_query_multilayer_mod
+
+ use constants_mod, only: str_def, i_def, l_def
+ use driver_modeldb_mod, only: modeldb_type
+ use field_mod, only: field_type
+ use field_collection_mod, only: field_collection_type
+ use field_parent_mod, only: field_parent_type
+ use field_collection_iterator_mod, only: &
+ field_collection_iterator_type
+ use function_space_mod, only: function_space_type
+ use log_mod, only: log_event, &
+ log_scratch_space, &
+ log_level_info, &
+ log_level_error
+
+ implicit none
+
+ private
+ public :: query_multilayer
+
+contains
+
+ !> @brief Set the tile_change logical to true or false
+ !> @details tile_change is true if there is a change in the number of tiles
+ !! for any field between the source_fields and target_fields.
+ subroutine query_multilayer( modeldb, source_fields, target_fields )
+
+ implicit none
+
+ type(modeldb_type), intent(inout) :: modeldb
+ type(field_collection_type), pointer, intent(in) :: source_fields
+ type(field_collection_type), pointer, intent(in) :: target_fields
+
+ type(field_collection_iterator_type) :: iter
+
+ class(field_parent_type), pointer :: field
+ type(field_type), pointer :: field_src
+ type(field_type), pointer :: field_dst
+ type(function_space_type), pointer :: fs_type
+
+ character(len=str_def) :: field_name
+ integer(kind=i_def) :: ndata_src, ndata_dst
+ logical(kind=l_def) :: tile_change
+
+ tile_change = .false.
+
+ ! Main loop over fields to be processed
+ call iter%initialise(source_fields)
+ do
+ ! Locate the field to be processed in the field collections
+ if ( .not.iter%has_next() ) exit
+ field => iter%next()
+ field_name = field%get_name()
+
+ call source_fields%get_field(field_name, field_src)
+ call target_fields%get_field(field_name, field_dst)
+
+ ! Is this a multidata field and is ndata the same?
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+ if (ndata_dst /= ndata_src) then
+ write(log_scratch_space, '(A)') "ndata not equal "
+ call log_event(log_scratch_space, log_level_info)
+
+ tile_change = .true.
+ end if
+ end do
+
+ call modeldb%values%add_key_value('tile_change', tile_change)
+
+ end subroutine query_multilayer
+
+end module lfric2lfric_query_multilayer_mod
From b267540ee55e3594c067b71e38f0ba15a686d6f0 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 7 Aug 2026 16:20:09 +0100
Subject: [PATCH 40/53] tile mapping
---
.../lfric2lfric/example/configuration.nml | 6 +-
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 17 +++
.../algorithm/lfric2lfric_tiles_mod.x90 | 59 ++++++++-
.../source/driver/lfric2lfric_init_mod.f90 | 14 ++-
.../lfric2lfric_field_init_mod.f90 | 29 +++--
.../lfric2lfric_multidata_map_kernel_mod.F90 | 117 ++++++++++++++++++
6 files changed, 221 insertions(+), 21 deletions(-)
create mode 100644 applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_kernel_mod.F90
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index d25b8274cf..c51a1dc063 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -68,7 +68,7 @@ coord_space = 'Wchi',
/
&logging
- run_log_level = 'info',
+ run_log_level = 'debug',
/
&time
@@ -110,3 +110,7 @@ coord_space = 'Wchi',
&orography
orog_init_option = 'none'
/
+
+&dst_jules_surface_types
+ multidata_map = 1,2,11,6,6,6,7,8,9
+/
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index f392e31b3f..a2a48c90eb 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -408,3 +408,20 @@ help=The designation of the mesh to which this
ns=namelist/lfric2lfric/configuration
!string_length=default
type=character
+
+[namelist:dst_jules_surface_types]
+compulsory=true
+description=
+ns=namelist/dst_jules_surface_types
+title=dst_jules_surface_types
+
+[namelist:dst_jules_surface_types=multidata_map]
+compulsory=true
+description=Multidata map for surface/land tiles.
+help=List multidata levels to map to the
+ =destination multidata field.
+!kind=default
+length=:
+ns=namelist/lfric2lfric/configuration
+range=0:
+type=integer
\ No newline at end of file
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
index 8ee7c924d2..d3e10c0bec 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
@@ -6,7 +6,7 @@
!> @brief Reconfiguration associated with changes in tiles
module lfric2lfric_tiles_mod
- use constants_mod, only: str_def, i_def
+ use constants_mod, only: str_def, i_def, l_def
use driver_modeldb_mod, only: modeldb_type
use extrusion_mod, only: TWOD
use field_parent_mod, only: field_parent_type
@@ -14,9 +14,14 @@ module lfric2lfric_tiles_mod
use field_collection_mod, only: field_collection_type
use field_collection_iterator_mod, &
only: field_collection_iterator_type
+ use function_space_mod, only: function_space_type
use mesh_mod, only: mesh_type
- use log_mod, only: log_event, &
- log_level_info, &
+ use lfric2lfric_multidata_map_kernel_mod, &
+ only: lfric2lfric_multidata_map_type
+ use log_mod, only: log_event, &
+ log_level_debug, &
+ log_level_info, &
+ log_level_error, &
log_scratch_space
implicit none
@@ -46,9 +51,15 @@ contains
type(field_type), pointer :: field_src
type(field_type), pointer :: field_dst
type(mesh_type), pointer :: mesh
-
+ type(function_space_type), pointer :: fs_type
+ integer(i_def), allocatable :: multidata_map(:)
+ integer(kind=i_def) :: ndata_dst, ndata_src
character(len=str_def) :: field_name
+ logical(l_def), parameter :: ndata_first = .false.
+ write(log_scratch_space, '(A)') "Tiles "
+ call log_event(log_scratch_space, log_level_info)
+
! Main loop over fields to be processed
call iter%initialise(source_fields)
do
@@ -60,6 +71,7 @@ contains
call source_fields%get_field(field_name, field_src)
call target_fields%get_field(field_name, field_dst)
+ ! Continue if it is a 2D mesh field
mesh => field_src%get_mesh()
if (mesh%get_extrusion_id() == TWOD) then
@@ -67,10 +79,45 @@ contains
trim(field_name)
call log_event(log_scratch_space, log_level_info)
- ! Apply changes associated with tiles
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+
+ write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
+ call log_event(log_scratch_space, log_level_debug)
+ write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
+ call log_event(log_scratch_space, log_level_debug)
+
+ if (ndata_src /= ndata_dst) then
+
+ ! Need to add full list of fields on surface tiles
+ if ( field_name == 'tile_snow_rgrain' ) then
+
+ multidata_map = modeldb%config%dst_jules_surface_types%multidata_map()
+
+ write(log_scratch_space, '(*(g0,1x))') "multidata ", multidata_map
+ call log_event(log_scratch_space, log_level_debug)
+
+ if ( size(multidata_map) /= ndata_dst ) then
+ write(log_scratch_space, '(A,I5,A,I5)') &
+ "size of multidata map = ", size(multidata_map), &
+ " not equal to ndata_dst = ", ndata_dst
+ call log_event(log_scratch_space, log_level_error)
+ end if
+
+ call invoke( lfric2lfric_multidata_map_type( field_dst, ndata_dst, &
+ field_src, ndata_src, &
+ ndata_first ))
+ end if
+ ! If field name is a sea-ice field
+ ! rederive
+
+ end if
+
end if
end do
- end subroutine lfric2lfric_tiles
+ end subroutine lfric2lfric_tiles
end module lfric2lfric_tiles_mod
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
index 69fc77c0f1..6da02eeaf1 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90
@@ -84,6 +84,7 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
logical(l_def), pointer :: horizontal_change
logical(l_def), pointer :: vertical_change
logical(l_def), pointer :: tile_change
+ logical(l_def), parameter :: no_xios = .true.
! For field creation and storage
type(field_collection_type), pointer :: target_fields
@@ -171,15 +172,18 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
!--------------------------------------------------------------------------
! Initialise Intermediate Fields
!--------------------------------------------------------------------------
+ call modeldb%io_contexts%get_io_context(context_src, io_context)
+ call io_context%set_current()
+
if ( (horizontal_change .and. vertical_change) .or. &
(horizontal_change .and. tile_change)) then
call modeldb%fields%add_empty_field_collection(interm_collection_name)
interm_fields => modeldb%fields%get_field_collection(interm_collection_name)
if (mode == mode_ics) then
- prefix = 'checkpoint_'
+ prefix = 'restart_'
else if (mode == mode_lbc) then
- prefix = 'lbc_'
+ prefix = ''
end if
do i = 1, num_fields
@@ -187,13 +191,11 @@ subroutine init_lfric2lfric( modeldb, context_src, context_dst, &
config_list(i), &
interm_mesh, &
interm_twod_mesh, &
- prefix )
+ prefix, &
+ no_xios )
end do
end if
- call modeldb%io_contexts%get_io_context(context_src, io_context)
- call io_context%set_current()
-
! Now finished with config_list, deallocate
deallocate(config_list)
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
index 1b41ed2aa0..9c8d7aebf1 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90
@@ -7,7 +7,7 @@
!> routine for field creation.
module lfric2lfric_field_init_mod
- use constants_mod, only: i_def, str_def
+ use constants_mod, only: i_def, str_def, l_def
use field_collection_mod, only: field_collection_type
use field_mod, only: field_type
use field_parent_mod, only: read_interface, &
@@ -135,14 +135,18 @@ end subroutine get_field_list
!! initalised on
!> @param [in] twod_mesh The 2D mesh the field could be
!! intialised on
- subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
+ !> @param [in, optional] input_no_xios Don't apply xios associated parts
+ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix, input_no_xios)
type(field_collection_type), pointer, intent(inout) :: field_collection
character(len=*), intent(in) :: field_name
type(mesh_type), pointer, intent(in) :: mesh
type(mesh_type), pointer, intent(in) :: twod_mesh
character(len=nf90_max_name), intent(in) :: prefix
-
+ logical(l_def), optional, intent(in) :: input_no_xios
+
+ logical(l_def) :: no_xios
+
! Field object to initialise
type(field_type) :: field
@@ -153,6 +157,13 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
procedure(checkpoint_write_interface), pointer :: cp_write_behaviour
procedure(checkpoint_read_interface), pointer :: cp_read_behaviour
+ no_xios = .false.
+ if (present(input_no_xios)) then
+ if (input_no_xios) then
+ no_xios = .true.
+ end if
+ endif
+
! Set write behaviour to generic
write_behaviour => write_field_generic
read_behaviour => read_field_generic
@@ -170,11 +181,13 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix)
name=field_name)
! Set the generic write behaviours
- call field%set_read_behaviour(read_behaviour)
- call field%set_write_behaviour(write_behaviour)
- call field%set_checkpoint_read_behaviour(cp_read_behaviour)
- call field%set_checkpoint_write_behaviour(cp_write_behaviour)
-
+ if ( .NOT. no_xios ) then
+ call field%set_read_behaviour(read_behaviour)
+ call field%set_write_behaviour(write_behaviour)
+ call field%set_checkpoint_read_behaviour(cp_read_behaviour)
+ call field%set_checkpoint_write_behaviour(cp_write_behaviour)
+ end if
+
call log_event("Adding " // trim(field_name) // &
" to field collection " // &
field_collection%get_name(), &
diff --git a/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_kernel_mod.F90 b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_kernel_mod.F90
new file mode 100644
index 0000000000..0c97936a97
--- /dev/null
+++ b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_kernel_mod.F90
@@ -0,0 +1,117 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Map multidata fields with different ndata numbers.
+!> @details This is used for lfric2lfric reconfiguration, most likely
+!! for regridding 2D fields on surface tiles. The multidata_map
+!! is read from configuration and is an integer array (of size of
+!! the destination ndata) containing a list of the array positions
+!! from the source data.
+module lfric2lfric_multidata_map_kernel_mod
+
+ use argument_mod, only: arg_type, &
+ GH_FIELD, &
+ GH_SCALAR, &
+ GH_REAL, &
+ GH_INTEGER, &
+ GH_READ, &
+ GH_WRITE, &
+ GH_LOGICAL, &
+ CELL_COLUMN, &
+ ANY_SPACE_1, &
+ ANY_SPACE_2
+ use constants_mod, only: i_def, r_def, l_def
+ use kernel_mod, only: kernel_type
+ use dst_jules_surface_types_config_mod, &
+ only: multidata_map
+
+ implicit none
+
+ private
+
+ type, public, extends(kernel_type) :: lfric2lfric_multidata_map_type
+ private
+ type(arg_type), dimension(5) :: meta_args = (/ &
+ arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_SPACE_1), & ! field_dst
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! ndata_dst
+ arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_SPACE_2), & ! field_src
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! ndata_src
+ arg_type(GH_SCALAR, GH_LOGICAL, GH_READ) & ! ndata_first
+ /)
+ integer :: operates_on = CELL_COLUMN
+ contains
+ procedure, nopass :: lfric2lfric_multidata_map_code
+ end type lfric2lfric_multidata_map_type
+
+ public :: lfric2lfric_multidata_map_code
+
+contains
+
+!> @brief Map a multidata field to another multidata field
+!! @param[in] nlayers Number of layers
+!! @param[in,out] field_dst Output (destination) multidata field
+!! @param[in] ndata_dst Number of data points in field_dst
+!! @param[in] field_src Input (source) multidata field
+!! @param[in] ndata_src Number of data points in field_src
+!! @param[in] ndata_first Data layout (data- or layer-first)
+!! @param[in] ndf_dst Number of dofs per cell for field_dst
+!! @param[in] undf_dst Total number of dofs per cell for field_dst
+!! @param[in] map_dst Cell dofmap for field_dst
+!! @param[in] ndf_src Number of dofs per cell for field_src
+!! @param[in] undf_src Total number of dofs per cell for field_src
+!! @param[in] map_src Cell dofmap for field_src
+subroutine lfric2lfric_multidata_map_code(nlayers, &
+ field_dst, &
+ ndata_dst, &
+ field_src, &
+ ndata_src, &
+ ndata_first, &
+ ndf_dst, &
+ undf_dst, &
+ map_dst, &
+ ndf_src, &
+ undf_src, &
+ map_src)
+
+ integer(kind=i_def), intent(in) :: nlayers
+
+ integer(kind=i_def), intent(in) :: ndata_src
+ integer(kind=i_def), intent(in) :: ndf_src
+ integer(kind=i_def), intent(in) :: undf_src
+ integer(kind=i_def), intent(in) :: map_src(ndf_src)
+
+ integer(kind=i_def), intent(in) :: ndata_dst
+ integer(kind=i_def), intent(in) :: ndf_dst
+ integer(kind=i_def), intent(in) :: undf_dst
+ integer(kind=i_def), intent(in) :: map_dst(ndf_dst)
+
+ logical(kind=l_def), intent(in) :: ndata_first
+
+ real(kind=r_def), intent(in) :: field_src(undf_src)
+ real(kind=r_def), intent(out) :: field_dst(undf_dst)
+
+ integer(kind=i_def) :: df, i_dst, i_src, k
+
+ if (ndata_first) then
+ do k = 0, nlayers - 1
+ i_dst = map_dst(1) + k * ndata_dst
+ i_src = map_src(1) + k * ndata_src
+ do df = 0, ndata_dst -1
+ field_dst( i_dst + df ) = field_src( i_src + multidata_map(df+1) -1 )
+ end do
+ end do
+ else
+ do df = 0, ndata_dst - 1
+ i_dst = map_dst(1) + df * nlayers
+ i_src = map_src(1) + (multidata_map(df+1) - 1) * nlayers
+ do k =0, nlayers-1
+ field_dst( i_dst + k ) = field_src( i_src + k )
+ end do
+ end do
+ end if
+
+end subroutine lfric2lfric_multidata_map_code
+
+end module lfric2lfric_multidata_map_kernel_mod
From 3123afea6ab35a7d813d4d9a90e0fd7a5bcdc506 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Tue, 1 Sep 2026 16:45:03 +0100
Subject: [PATCH 41/53] code review response # This is a combination of 9
commits.
upgrade macro
code review response
correction
correction
correction
correction
correction (to allow for opts)
metadata default
rose meta compulsory false
---
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 12 +--
.../rose-meta/lfric-lfric2lfric/versions.py | 73 +++++++++++++++++++
.../source/driver/lfric2lfric_driver_mod.F90 | 36 +--------
.../lfric2lfric_infrastructure_mod.X90 | 8 +-
.../lfric2lfric/opt/rose-app-clim_gal9.conf | 7 --
.../opt/rose-app-clim_gal9_ral_seuk.conf | 7 --
.../app/lfric2lfric/opt/rose-app-ral3.conf | 7 --
.../lfric2lfric/opt/rose-app-ral_seuk.conf | 7 --
rose-stem/app/lfric2lfric/rose-app.conf | 48 +++++-------
9 files changed, 107 insertions(+), 98 deletions(-)
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index f392e31b3f..9eb4cf6863 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -8,14 +8,14 @@ compulsory=false
!!trigger=namelist:partitioning: .false.;
[namelist:extrusion_dst]
-compulsory=true
+compulsory=false
description=Vertical extrusion settings for the destination mesh.
help=
ns=namelist/Model/Mesh/Extrusion
sort-key=Section-A03
[namelist:extrusion_dst=domain_height]
-compulsory=true
+compulsory=false
description=Height of domain above the surface [m]
fail-if=this < 0.0 ;
help=Height of the model domain above the surface.
@@ -27,7 +27,7 @@ type=real
[namelist:extrusion_dst=eta_values]
!bounds=namelist:extrusion_dst=number_of_layers-1
-compulsory=true
+compulsory=false
description=Eta values, excluding 0 and 1
help=Non-dimensional height values defining the model vertical levels.
=The length should be smaller by number_of_layers by one.
@@ -42,7 +42,7 @@ sort-key=Panel-A04
type=real
[namelist:extrusion_dst=method]
-compulsory=true
+compulsory=false
description=Method for generating eta coordinate
!enumeration=true
fail-if=this == 'um_L38_29t_9s_40km' and namelist:extrusion_dst=number_of_layers != 38 ;
@@ -75,7 +75,7 @@ values='uniform', 'quadratic', 'geometric', 'dcmip',
='um_L120_99t_21s_40km', 'um_L140_122t_18s_40km'
[namelist:extrusion_dst=number_of_layers]
-compulsory=true
+compulsory=false
description=Number of layers in the vertical
fail-if=this < 1 ;
help=Setting for number of layers of 3D-mesh in vertical.
@@ -85,7 +85,7 @@ sort-key=Panel-A03
type=integer
[namelist:extrusion_dst=planet_radius]
-compulsory=true
+compulsory=false
description=Radius of the planet surface [m]
fail-if=this <= 0.0 ;
help=Radius of domain bottom. Note: Orography not included.
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py
index 01e65a2b91..3b09e937d1 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py
@@ -31,3 +31,76 @@ def upgrade(self, config, meta_config=None):
# Add settings
return config, self.reports
"""
+
+class vn32_t581(MacroUpgrade):
+ # Upgrade macro for #581 by Christine Johnson
+
+ BEFORE_TAG = "vn3.2"
+ AFTER_TAG = "vn3.2_t581"
+
+ def upgrade(self, config, meta_config=None):
+ # Add settings
+
+ domain_height = self.get_setting_value(
+ config, ["namelist:extrusion", "domain_height"]
+ )
+ eta_values = self.get_setting_value(
+ config, ["namelist:extrusion", "eta_values"]
+ )
+ method = self.get_setting_value(
+ config, ["namelist:extrusion", "method"]
+ )
+ number_of_layers = self.get_setting_value(
+ config, ["namelist:extrusion", "number_of_layers"]
+ )
+ planet_radius = self.get_setting_value(
+ config, ["namelist:extrusion", "planet_radius"]
+ )
+ stretching_method = self.get_setting_value(
+ config, ["namelist:extrusion", "stretching_method"]
+ )
+ stretching_height = self.get_setting_value(
+ config, ["namelist:extrusion", "stretching_height"]
+ )
+ start_dump_filename = self.get_setting_value(
+ config, ["namelist:files", "start_dump_filename"]
+ )
+
+ if start_dump_filename != "'lfric2lfric_dump'" :
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "domain_height"],
+ domain_height,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "eta_values"],
+ eta_values,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "method"],
+ method,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "number_of_layers"],
+ number_of_layers,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "planet_radius"],
+ planet_radius,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "stretching_method"],
+ stretching_method,
+ )
+ self.add_setting(
+ config,
+ ["namelist:extrusion_dst", "stretching_height"],
+ stretching_height,
+ )
+
+ return config, self.reports
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 0e5f16b007..6e78690249 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -24,9 +24,6 @@ module lfric2lfric_driver_mod
use sci_checksum_alg_mod, only: checksum_alg
use xios, only: xios_date, xios_get_current_date, &
xios_date_convert_to_string
- use orography_config_mod, only: orog_init_option_analytic, &
- orog_init_option_ancil, &
- orog_init_option_start_dump
!------------------------------------
! lfric2lfric modules
@@ -36,8 +33,7 @@ module lfric2lfric_driver_mod
context_dst, context_src, &
source_collection_name, &
target_collection_name, &
- interm_collection_name, &
- src, dst
+ interm_collection_name
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
use lfric2lfric_vert_mod, only: lfric2lfric_vert
@@ -108,37 +104,10 @@ subroutine run( modeldb, oasis_clock )
type(lfric_xios_context_type), pointer :: io_context
- character(len=str_def) :: mesh_names(2)
- integer(kind=i_def) :: src_extrusion_method
- integer(kind=i_def) :: dst_extrusion_method
- integer(kind=i_def) :: src_number_of_layers
- integer(kind=i_def) :: dst_number_of_layers
- integer(kind=i_def) :: src_stretching_method
- integer(kind=i_def) :: dst_stretching_method
- integer(kind=i_def) :: orog_init_option
- real(kind=r_def) :: src_domain_height
- real(kind=r_def) :: dst_domain_height
- real(kind=r_def) :: src_stretching_height
- real(kind=r_def) :: dst_stretching_height
-
logical(kind=l_def), pointer :: vertical_change
logical(kind=l_def), pointer :: horizontal_change
! Extract configuration variables
- src_extrusion_method = modeldb%config%extrusion%method()
- src_number_of_layers = modeldb%config%extrusion%number_of_layers()
- src_domain_height = modeldb%config%extrusion%domain_height()
- src_stretching_height = modeldb%config%extrusion%stretching_height()
- src_stretching_method = modeldb%config%extrusion%stretching_method()
- dst_extrusion_method = modeldb%config%extrusion_dst%method()
- dst_number_of_layers = modeldb%config%extrusion_dst%number_of_layers()
- dst_domain_height = modeldb%config%extrusion_dst%domain_height()
- dst_stretching_height = modeldb%config%extrusion_dst%stretching_height()
- dst_stretching_method = modeldb%config%extrusion_dst%stretching_method()
- orog_init_option = modeldb%config%orography%orog_init_option()
-
- mesh_names(dst) = modeldb%config%lfric2lfric%destination_mesh_name()
- mesh_names(src) = modeldb%config%lfric2lfric%source_mesh_name()
start_dump_filename = modeldb%config%files%start_dump_filename()
checkpoint_stem_name = modeldb%config%files%checkpoint_stem_name()
@@ -160,6 +129,9 @@ subroutine run( modeldb, oasis_clock )
else if (vertical_change .and. .not. horizontal_change) then
interm_fields => modeldb%fields%get_field_collection(source_collection_name)
+
+ else
+ interm_fields => null()
end if
! Read fields and perform the regridding
diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
index 7d68aedde3..76152a2d0e 100644
--- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
+++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90
@@ -303,17 +303,17 @@ contains
if ( horizontal_change ) then
call log_event("Horizontal interpolation logical set to TRUE", &
- log_level_info)
+ log_level_debug)
else
call log_event("Horizontal interpolation logical set to FALSE", &
- log_level_info)
+ log_level_debug)
end if
if ( vertical_change ) then
call log_event("Vertical interpolation logical set to TRUE", &
- log_level_info)
+ log_level_debug)
else
call log_event("Vertical interpolation logical set to FALSE", &
- log_level_info)
+ log_level_debug)
end if
!=======================================================================
! Mesh
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
index 4cb9093333..723f79bc39 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9.conf
@@ -8,13 +8,6 @@ number_of_layers=70
stretching_height=17507.0
stretching_method='smooth'
-[namelist:extrusion_dst]
-domain_height=80000.0
-method='um_L70_50t_20s_80km'
-number_of_layers=70
-stretching_height=17507.0
-stretching_method='smooth'
-
[namelist:files]
checkpoint_stem_name='restart_lfric2lfric_clim_gal9_C12_MG'
start_dump_filename='lfric2lfric_clim_gal9_C12_MG'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
index 4af46b8816..2da98c9872 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-clim_gal9_ral_seuk.conf
@@ -19,13 +19,6 @@ number_of_layers=70
stretching_height=17507.0
stretching_method='smooth'
-[namelist:extrusion_dst]
-domain_height=80000.0
-method='um_L70_50t_20s_80km'
-number_of_layers=70
-stretching_height=17507.0
-stretching_method='smooth'
-
[namelist:files]
checkpoint_stem_name='restart_lfric2lfric_ral_seuk_MG'
start_dump_filename='lfric2lfric_clim_gal9_C12_MG'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf b/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
index 5d9d3e097f..4235bafd08 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-ral3.conf
@@ -11,13 +11,6 @@ number_of_layers=70
stretching_height=16641.984
stretching_method='smooth'
-[namelist:extrusion_dst]
-domain_height=40000.0
-method='um_L70_61t_9s_40km'
-number_of_layers=70
-stretching_height=16641.984
-stretching_method='smooth'
-
[namelist:files]
checkpoint_stem_name='restart_lfric2lfric_ral3_seuk'
!!lbc_directory='$BIG_DATA_DIR/lbcs/proto-ral/Ticket3510/seuk'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf b/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
index 1def0d95c3..558c0e5789 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-ral_seuk.conf
@@ -11,13 +11,6 @@ number_of_layers=70
stretching_height=16641.984
stretching_method='smooth'
-[namelist:extrusion_dst]
-domain_height=40000.0
-method='um_L70_61t_9s_40km'
-number_of_layers=70
-stretching_height=16641.984
-stretching_method='smooth'
-
[namelist:files]
checkpoint_stem_name='restart_lfric2lfric_ral_seuk_MG'
start_dump_filename='lfric2lfric_ral_seuk_MG'
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index 468f1fd6e2..58e0688dcc 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -1,4 +1,4 @@
-meta=lfric-lfric2lfric/HEAD
+meta=lfric-lfric2lfric/vn3.2
[command]
default=$CORE_ROOT_DIR/bin/tweak_iodef; \
@@ -105,28 +105,28 @@ sg_orog_mixing='none'
!!zhloc_depth_fac=0
[namelist:boundaries]
-!!blend_frequency='final'
-!!blending_weights=0.0
-!!blending_weights_w2v=0.0
-!!boundary_e=1
-!!boundary_n=1
-!!boundary_s=1
-!!boundary_w=1
-!!edge_cells_ew=1
-!!edge_cells_ns=1
-!!inner_width_ew=1
-!!inner_width_ns=1
-!!lbc_eos_height=100
+!!blend_frequency='inner'
+!!blending_weights=0
+!!blending_weights_w2v=0
+!!boundary_e=0
+!!boundary_n=0
+!!boundary_s=0
+!!boundary_w=0
+!!edge_cells_ew=0
+!!edge_cells_ns=0
+!!inner_width_ew=0
+!!inner_width_ns=0
+!!lbc_eos_height=0
!!lbc_method='coordinate_based'
limited_area=.false.
-!!normal_only=.true.
-!!outer_width_ew=1
-!!outer_width_ns=1
+!!normal_only=.false.
+!!outer_width_ew=0
+!!outer_width_ns=0
!!output_lbcs=.false.
-!!rim_width_ew=1
-!!rim_width_ns=1
-!!solver_boundary_depth=1
-!!transport_boundary_depth=6
+!!rim_width_ew=0
+!!rim_width_ns=0
+!!solver_boundary_depth=0
+!!transport_boundary_depth=0
transport_overwrite_freq='final'
[namelist:checks]
@@ -271,14 +271,6 @@ number_of_layers=38
planet_radius=6371229.0
stretching_method='linear'
-[namelist:extrusion_dst]
-domain_height=39254.833575999997
-!!eta_values=''
-method='um_L38_29t_9s_40km'
-number_of_layers=38
-planet_radius=6371229.0
-stretching_method='linear'
-
[namelist:files]
!!aerosols_ancil_path=''
!!albedo_nir_ancil_path=''
From 887abdffc19ee647e5f998e10e29395d5c1ec368 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 2 Sep 2026 15:06:34 +0100
Subject: [PATCH 42/53] Additional
---
rose-stem/app/lfric2lfric/rose-app.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf
index 58e0688dcc..bb21c8afb5 100644
--- a/rose-stem/app/lfric2lfric/rose-app.conf
+++ b/rose-stem/app/lfric2lfric/rose-app.conf
@@ -117,7 +117,7 @@ sg_orog_mixing='none'
!!inner_width_ew=0
!!inner_width_ns=0
!!lbc_eos_height=0
-!!lbc_method='coordinate_based'
+!!lbc_method='onion_layer'
limited_area=.false.
!!normal_only=.false.
!!outer_width_ew=0
From c58c7d3d1492aa88b9ba01268b6f1dc4dddac70a Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Wed, 2 Sep 2026 15:09:05 +0100
Subject: [PATCH 43/53] additional2
---
.../lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 6e78690249..bd88bde9b2 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -8,7 +8,7 @@
module lfric2lfric_driver_mod
use constants_mod, only: str_def, str_max_filename, &
- i_def, r_def, l_def, r_second
+ i_def, l_def, r_second
use driver_fem_mod, only: final_fem
use driver_io_mod, only: final_io
use driver_modeldb_mod, only: modeldb_type
From 54ac29ad4f34355b212ae203725ed1e44a4bdd51 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 4 Sep 2026 16:25:04 +0100
Subject: [PATCH 44/53] correction after merge
---
rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index ace55daf93..e5faee9aa9 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -148,7 +148,7 @@
{% do task_dict.update({
"opt_confs": ["clim_gal9_ral_seuk","oasis","src_L70_80km","dst_L38_40km"],
- "resolution": "C12_C16_lam",
+ "resolution": ["C24_C12", "seuk_MG"],
"dst_mesh": "seuk_MG",
"dst_name": "dynamics",
"dst_type": "regional",
From 6e4036b3d052524be903744b214f8b88ddd9db9e Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 4 Sep 2026 17:11:30 +0100
Subject: [PATCH 45/53] additional changes since merge
---
rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index e5faee9aa9..5a1f503ef7 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -147,7 +147,7 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_seukL38" %}
{% do task_dict.update({
- "opt_confs": ["clim_gal9_ral_seuk","oasis","src_L70_80km","dst_L38_40km"],
+ "opt_confs": ["oasis","src_L70_80km","dst_L38_40km"],
"resolution": ["C24_C12", "seuk_MG"],
"dst_mesh": "seuk_MG",
"dst_name": "dynamics",
@@ -160,7 +160,7 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_C12L38" %}
{% do task_dict.update({
- "opt_confs": ["clim_gal9","oasis","src_L70_80km","dst_L38_40km"],
+ "opt_confs": ["oasis","src_L70_80km","dst_L38_40km"],
"resolution": "C12",
"dst_mesh": "C12",
"dst_name": "dynamics",
From a3b363cbb45ee8965c22efac73285eb7b320af8d Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Fri, 4 Sep 2026 17:57:47 +0100
Subject: [PATCH 46/53] correction after merge
---
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index 5a1f503ef7..24dede6112 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -147,7 +147,7 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_seukL38" %}
{% do task_dict.update({
- "opt_confs": ["oasis","src_L70_80km","dst_L38_40km"],
+ "opt_confs": ["oasis","src_C12_L70","src_L70_80km","dst_L38_40km"],
"resolution": ["C24_C12", "seuk_MG"],
"dst_mesh": "seuk_MG",
"dst_name": "dynamics",
@@ -160,13 +160,13 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_C12L38" %}
{% do task_dict.update({
- "opt_confs": ["oasis","src_L70_80km","dst_L38_40km"],
- "resolution": "C12",
- "dst_mesh": "C12",
- "dst_name": "dynamics",
+ "opt_confs": ["oasis","src_C12_L70","src_L70_80km","dst_L38_40km"],
+ "resolution": "C24_C12",
+ "dst_mesh": "C24_C12",
+ "dst_name": "C12",
"dst_type": "global",
- "src_mesh": "C12",
- "src_name": "dynamics",
+ "src_mesh": "C24_C12",
+ "src_name": "C12",
"src_type": "global",
}) %}
From c3602a99385c0d31c70c2077d9d867eb8dda8362 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 7 Sep 2026 10:38:08 +0100
Subject: [PATCH 47/53] separate src_c12 and dst_c12
---
.../{rose-app-C12.conf => rose-app-dst_C12.conf} | 2 --
.../app/lfric2lfric/opt/rose-app-src_C12.conf | 8 ++++++++
.../site/common/lfric2lfric/tasks_lfric2lfric.cylc | 14 +++++++-------
3 files changed, 15 insertions(+), 9 deletions(-)
rename rose-stem/app/lfric2lfric/opt/{rose-app-C12.conf => rose-app-dst_C12.conf} (58%)
create mode 100644 rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-dst_C12.conf
similarity index 58%
rename from rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
rename to rose-stem/app/lfric2lfric/opt/rose-app-dst_C12.conf
index 87cbe9951d..95c1cb635c 100644
--- a/rose-stem/app/lfric2lfric/opt/rose-app-C12.conf
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-dst_C12.conf
@@ -1,5 +1,3 @@
[namelist:lfric2lfric]
destination_mesh_name='dynamics'
destination_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
-source_mesh_name='dynamics'
-source_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
new file mode 100644
index 0000000000..6e98d032c4
--- /dev/null
+++ b/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
@@ -0,0 +1,8 @@
+[file:lfric2lfric_clim_gal9_C12_MG.nc]
+source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_clim_gal9_C12_dt-1800p0_intel_64-bit_fast-debug_000072.nc"
+
+[namelist:lfric2lfric]
+source_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
+
+[namelist:files]
+start_dump_filename='lfric2lfric_clim_gal9_C12_MG'
\ No newline at end of file
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index 24dede6112..3d9dedd05d 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -147,7 +147,7 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_seukL38" %}
{% do task_dict.update({
- "opt_confs": ["oasis","src_C12_L70","src_L70_80km","dst_L38_40km"],
+ "opt_confs": ["oasis","src_C12_L70","dst_seuk","src_L70_80km","dst_L38_40km"],
"resolution": ["C24_C12", "seuk_MG"],
"dst_mesh": "seuk_MG",
"dst_name": "dynamics",
@@ -160,13 +160,13 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_C12L38" %}
{% do task_dict.update({
- "opt_confs": ["oasis","src_C12_L70","src_L70_80km","dst_L38_40km"],
- "resolution": "C24_C12",
- "dst_mesh": "C24_C12",
- "dst_name": "C12",
+ "opt_confs": ["oasis","src_C12","dst_C12","src_L70_80km","dst_L38_40km"],
+ "resolution": "C12",
+ "dst_mesh": "C12",
+ "dst_name": "dynamics",
"dst_type": "global",
- "src_mesh": "C24_C12",
- "src_name": "C12",
+ "src_mesh": "C12",
+ "src_name": "dynamics",
"src_type": "global",
}) %}
From 145f84de509d719d8216402008fddbcae011a8fb Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 7 Sep 2026 11:35:21 +0100
Subject: [PATCH 48/53] src_C12 should be src_c12_c70
---
rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf | 8 --------
rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc | 8 ++++----
2 files changed, 4 insertions(+), 12 deletions(-)
delete mode 100644 rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf b/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
deleted file mode 100644
index 6e98d032c4..0000000000
--- a/rose-stem/app/lfric2lfric/opt/rose-app-src_C12.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-[file:lfric2lfric_clim_gal9_C12_MG.nc]
-source="$BIG_DATA_DIR/start_dumps/proto-ral/AppsTicket110/lfric_atm_clim_gal9_C12_dt-1800p0_intel_64-bit_fast-debug_000072.nc"
-
-[namelist:lfric2lfric]
-source_meshfile_prefix='${MESH_DIR}/C12/mesh_C12'
-
-[namelist:files]
-start_dump_filename='lfric2lfric_clim_gal9_C12_MG'
\ No newline at end of file
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index 3d9dedd05d..e32dde76b8 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -160,13 +160,13 @@
{% elif task_ns.conf_name == "oasis_C12L70_to_C12L38" %}
{% do task_dict.update({
- "opt_confs": ["oasis","src_C12","dst_C12","src_L70_80km","dst_L38_40km"],
- "resolution": "C12",
+ "opt_confs": ["oasis","src_C12_L70","dst_C12","src_L70_80km","dst_L38_40km"],
+ "resolution": ["C24_C12", C12"],
"dst_mesh": "C12",
"dst_name": "dynamics",
"dst_type": "global",
- "src_mesh": "C12",
- "src_name": "dynamics",
+ "src_mesh": "C24_C12",
+ "src_name": "C12",
"src_type": "global",
}) %}
From e46d21ed38b0aab820d2a8d00424670d1d57198b Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 7 Sep 2026 11:38:10 +0100
Subject: [PATCH 49/53] typo
---
rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
index e32dde76b8..ebdb1a500b 100644
--- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
+++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc
@@ -161,7 +161,7 @@
{% do task_dict.update({
"opt_confs": ["oasis","src_C12_L70","dst_C12","src_L70_80km","dst_L38_40km"],
- "resolution": ["C24_C12", C12"],
+ "resolution": ["C24_C12", "C12"],
"dst_mesh": "C12",
"dst_name": "dynamics",
"dst_type": "global",
From 3623bd66a0a8773e0583685dd3900f8d6146772c Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 14 Sep 2026 10:49:25 +0100
Subject: [PATCH 50/53] compiles and runs example
---
.../lfric2lfric/example/configuration.nml | 3 +-
applications/lfric2lfric/example/iodef.xml | 31 +-
.../lfric-lfric2lfric/HEAD/rose-meta.conf | 8 +-
.../algorithm/lfric2lfric_multidata_mod.x90 | 275 ++++++++++++++++++
.../algorithm/lfric2lfric_tiles_mod.x90 | 123 --------
.../source/driver/lfric2lfric_driver_mod.F90 | 5 +-
...lfric_multidata_map_surface_kernel_mod.F90 | 99 +++++++
.../lfric2lfric_multidata_snow_kernel_mod.F90 | 126 ++++++++
8 files changed, 530 insertions(+), 140 deletions(-)
create mode 100644 applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
delete mode 100644 applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
create mode 100644 applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_surface_kernel_mod.F90
create mode 100644 applications/lfric2lfric/source/kernel/lfric2lfric_multidata_snow_kernel_mod.F90
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index c51a1dc063..407f6555d0 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -112,5 +112,6 @@ coord_space = 'Wchi',
/
&dst_jules_surface_types
- multidata_map = 1,2,11,6,6,6,7,8,9
+! https://github.com/MetOffice/um/blob/main/rose-stem/app/um_seukv_eg/opt/rose-app-reconukv.conf
+ multidata_map = 1,2,3,4,5,6,6,7,8,9
/
diff --git a/applications/lfric2lfric/example/iodef.xml b/applications/lfric2lfric/example/iodef.xml
index 4568a3f594..f36076995a 100644
--- a/applications/lfric2lfric/example/iodef.xml
+++ b/applications/lfric2lfric/example/iodef.xml
@@ -2,7 +2,7 @@
-
+
@@ -15,17 +15,21 @@
-
+
+
-
+
-
+
-
+
+
+
+
@@ -44,12 +48,12 @@
-
+
-
+
@@ -57,17 +61,20 @@
-
+
-
+
-
+
-
-
+
+
+
+
+
diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
index dfb8e75960..bec7946a78 100644
--- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
+++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf
@@ -415,8 +415,14 @@ title=dst_jules_surface_types
[namelist:dst_jules_surface_types=multidata_map]
compulsory=true
description=Multidata map for surface/land tiles.
-help=List multidata levels to map to the
+help=List the multidata levels to map to the
=destination multidata field.
+ =For example, if src_field has 4 multidata fields
+ =and dst_field has 3 multidata fields.
+ =If multidata_map = 1,4,2 then
+ =dst_field(1) = src_field(1)
+ =dst_field(2) = src_field(4)
+ =dst_field(3) = src_field(2)
!kind=default
length=:
ns=namelist/lfric2lfric/configuration
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
new file mode 100644
index 0000000000..2eb6f1a699
--- /dev/null
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
@@ -0,0 +1,275 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Reconfiguration associated with changes in number of multidata fields (tiles).
+module lfric2lfric_multidata_mod
+
+ use constants_mod, only: str_def, i_def, r_def, l_def
+ use driver_modeldb_mod, only: modeldb_type
+ use extrusion_mod, only: TWOD
+ use field_parent_mod, only: field_parent_type
+ use field_mod, only: field_type
+ use field_collection_mod, only: field_collection_type
+ use field_collection_iterator_mod, &
+ only: field_collection_iterator_type
+ use function_space_mod, only: function_space_type
+ use mesh_mod, only: mesh_type
+ use lfric2lfric_multidata_map_surface_kernel_mod, &
+ only: lfric2lfric_multidata_map_surface_type
+ use lfric2lfric_multidata_snow_kernel_mod, &
+ only: lfric2lfric_multidata_snow_type
+ use sci_field_minmax_alg_mod, only: get_field_minmax
+ use log_mod, only: log_event, &
+ log_level_debug, &
+ log_level_info, &
+ log_level_error, &
+ log_scratch_space
+
+ implicit none
+
+ private
+ public :: lfric2lfric_multidata, lfric2lfric_retile_surface_tiles
+
+contains
+
+ !> @brief Apply the changes associated with the change in size of multidata fields.
+ !> @details Loop over the fields in the source_fields collection,
+ !! and deal with the change in tiles, depending on the tile type.
+ !> @param modeldb Model state object
+ !> @param source_fields The collection of fields to be regridded
+ !> @param target_fields The collection of regridded fields
+ subroutine lfric2lfric_multidata( modeldb, source_fields, target_fields )
+
+ implicit none
+
+ type(modeldb_type), intent(inout) :: modeldb
+ type(field_collection_type), intent(inout) :: source_fields
+ type(field_collection_type), intent(inout) :: target_fields
+
+ type(field_collection_iterator_type) :: iter
+
+ class(field_parent_type), pointer :: field
+ type(field_type), pointer :: field_src
+ type(field_type), pointer :: field_dst
+ type(field_type), pointer :: field_src_n_snow_layers
+ type(field_type), pointer :: field_src_snow_layer
+ type(field_type), pointer :: field_dst_snow_layer
+ type(mesh_type), pointer :: mesh
+ type(function_space_type), pointer :: fs_type
+
+ integer(kind=i_def) :: ndata_dst, ndata_src
+ integer(kind=i_def) :: n_snow_layers_src, n_snow_layers_dst
+ integer(kind=i_def) :: n_land_tiles_src, n_land_tiles_dst
+ real(kind=r_def) :: number_snow_layers, dummy
+ character(len=str_def) :: field_name
+ integer(i_def), allocatable :: multidata_map(:)
+
+ write(log_scratch_space, '(A)') "Starting lfric2lfric_multidata"
+ call log_event(log_scratch_space, log_level_debug)
+
+ !---- Precalculations
+
+ !-- Find the number of snow layers in the source data
+ call source_fields%get_field('n_snow_layers', field_src_n_snow_layers)
+ call get_field_minmax(field_src_n_snow_layers, dummy, number_snow_layers)
+ n_snow_layers_src = nint(number_snow_layers)
+
+ !-- Determine the number of snow layers in the target data
+ ! Assume for now that it is the same as the source data
+ ! Otherwise this could be added to a rose namelist
+ n_snow_layers_dst = n_snow_layers_src
+
+ !-- Determine n_land_tiles_src
+ ! Derive effective number of land tiles in source field from snow fields
+ call source_fields%get_field('snow_layer_temp', field_src_snow_layer)
+ fs_type => field_src_snow_layer%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ n_land_tiles_src = ndata_src / n_snow_layers_src
+
+ !-- Determine n_land_tiles_dst
+ ! Derive effective number of land tiles in destination field from snow fields
+ call target_fields%get_field('snow_layer_temp', field_dst_snow_layer)
+ fs_type => field_dst_snow_layer%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+ n_land_tiles_dst = ndata_dst / n_snow_layers_dst
+
+ !-- Check multidata map
+ multidata_map = modeldb%config%dst_jules_surface_types%multidata_map()
+
+ write(log_scratch_space, '(*(g0,1x))') "multidata ", multidata_map
+ call log_event(log_scratch_space, log_level_debug)
+
+ if ( size(multidata_map) /= n_land_tiles_dst ) then
+ write(log_scratch_space, '(A,I5,A,I5)') &
+ "size of multidata map = ", size(multidata_map), &
+ " not equal to n_land_tiles_dst = ", n_land_tiles_dst
+ call log_event(log_scratch_space, log_level_error)
+ end if
+
+ !------ Main loop over fields to be processed
+ call iter%initialise(source_fields)
+ do
+ ! Locate the field to be processed in the field collections
+ if ( .not. iter%has_next() ) exit
+ field => iter%next()
+ field_name = field%get_name()
+
+ call source_fields%get_field(field_name, field_src)
+ call target_fields%get_field(field_name, field_dst)
+
+ ! Continue if it is a 2D mesh field
+ mesh => field_src%get_mesh()
+ if (mesh%get_extrusion_id() == TWOD) then
+
+ write(log_scratch_space, '(A,A)') "Processing lfric field", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_debug)
+
+ ! Find the size of the multidata field
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+
+ write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
+ call log_event(log_scratch_space, log_level_debug)
+ write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
+ call log_event(log_scratch_space, log_level_debug)
+
+ ! if multidata field
+ if ((ndata_dst > 1) .or. (ndata_src > 1)) then
+
+ ! Based on UM rcf_field_calcs
+ select case (field_name)
+
+ ! Surface tiles - based on rcf_calc_tiles, rcf_init_field_on_tiles (L240)
+ case ('tile_fraction' , &
+ 'tile_temperature' , &
+ 'screen_temperature' , &
+ 'tile_canopy_water' , &
+ 'tile_lw_grey_albedo', &
+ 'tile_snow_mass' , &
+ 'tile_snow_rgrain' , &
+ 'n_snow_layers' , &
+ 'snow_depth' , &
+ 'snowpack_density' , &
+ 'snow_under_canopy' )
+
+ if (n_land_tiles_src /= n_land_tiles_dst) then
+ ! As the fields might use surface_tiles, only loop over land_tiles
+ call lfric2lfric_retile_surface_tiles( &
+ modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
+ else
+ ! Copy field_src to field_dst - but careful if one is n_land tiles and one is n_surface
+ !...
+ end if
+
+ ! Snow Layers and Tiles - based on rcf_ml_snowpack
+ case ('snow_layer_temp' , &
+ 'snow_layer_thickness' , &
+ 'snow_layer_ice_mass' , &
+ 'snow_layer_liq_mass' , &
+ 'snow_layer_rgrain')
+
+ if ( (n_land_tiles_src /= n_land_tiles_dst) ) then
+ ! Assume size land_tiles & n_snow - need to check
+ ! Assume snow layers same - need to check
+ call lfric2lfric_retile_snow( &
+ modeldb, field_dst, field_src, n_snow_layers_dst, n_land_tiles_dst, n_snow_layers_src, n_land_tiles_src )
+ else
+ ! Copy
+ end if
+
+ ! Sea Ice Categories - sea_ice_temperature based on rcf_derv_sea_ice_temp
+ case ('sea_ice_temperature')
+ ! Need to check, add error message or copy
+
+ ! Sea Ice Categories - sea_ice_thickness based on rcf_derv_ice_cat_thick
+ case ('sea_ice_thickness')
+ ! Need to check, add error message or copy
+
+ ! Soil Levels - based on rcf_init_soil_temp
+ case ('soil_temperature')
+ ! Need to check, add error message or copy
+
+ case default
+ write(log_scratch_space, '(A,A)') &
+ trim(field_name), " needs to have code added"
+ call log_event(log_scratch_space, log_level_error)
+
+ end select
+ else
+ ! Straightforward copy if not multidata ??
+ call invoke( setval_X(field_dst, field_src))
+ end if
+ end if
+ end do
+
+ end subroutine lfric2lfric_multidata
+
+ !> @brief Retile a field with surface_tiles
+ !> @details Map a multidata field where the source and destination have different sizes
+ !! and the mapping is governed by a multidata map.
+ !> @param modeldb Model state object
+ !> @param field_dst Destination multidata field
+ !> @param field_src Source multidata field
+ !> @param nland_tiles_dst Number of land tiles in destination field
+ !> @param nland_tiles_src Number of land tiles in source field
+ subroutine lfric2lfric_retile_surface_tiles( modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
+
+ implicit none
+
+ type(modeldb_type), intent(inout) :: modeldb
+ type(field_type), intent(inout) :: field_dst
+ type(field_type), intent(in) :: field_src
+ integer(kind=i_def), intent(in) :: n_land_tiles_dst
+ integer(kind=i_def), intent(in) :: n_land_tiles_src
+
+ write(log_scratch_space, '(A)') "Starting lfric2lfric_retile_surface_tiles"
+ call log_event(log_scratch_space, log_level_debug)
+
+ call invoke( lfric2lfric_multidata_map_surface_type( field_dst, n_land_tiles_dst, &
+ field_src, n_land_tiles_src))
+
+ end subroutine lfric2lfric_retile_surface_tiles
+
+ !> @brief Retile a field with snow_layers_and_tiles
+ !> @details Map a multidata snow field where the source and destination have different sizes
+ !> @param modeldb Model state object
+ !> @param field_dst Destination multidata field
+ !> @param field_src Source multidata field
+ !> @param n_snow_layers_dst Source number of snow layers in destination
+ !> @param n_tiles_dst Source number of land tiles in destination
+ !> @param n_snow_layers_src Source number of snow layers in source
+ !> @param n_tiles_src Source number of land tiles in source
+ subroutine lfric2lfric_retile_snow( modeldb, field_dst, field_src, &
+ n_snow_layers_dst, n_tiles_dst, n_snow_layers_src, n_tiles_src )
+
+ implicit none
+
+ type(modeldb_type), intent(inout) :: modeldb
+ type(field_type), intent(inout) :: field_dst
+ type(field_type), intent(in) :: field_src
+ integer(kind=i_def), intent(in) :: n_snow_layers_dst
+ integer(kind=i_def), intent(in) :: n_tiles_dst
+ integer(kind=i_def), intent(in) :: n_snow_layers_src
+ integer(kind=i_def), intent(in) :: n_tiles_src
+
+ logical(l_def), parameter :: ndata_first = .false.
+
+ write(log_scratch_space, '(A)') "Starting lfric2lfric_retile_snow"
+ call log_event(log_scratch_space, log_level_debug)
+
+ call invoke( lfric2lfric_multidata_snow_type( field_dst, &
+ field_src, &
+ n_snow_layers_dst, &
+ n_tiles_dst, &
+ n_snow_layers_src, &
+ n_tiles_src, &
+ ndata_first ))
+
+ end subroutine lfric2lfric_retile_snow
+
+end module lfric2lfric_multidata_mod
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
deleted file mode 100644
index d3e10c0bec..0000000000
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_tiles_mod.x90
+++ /dev/null
@@ -1,123 +0,0 @@
-!-----------------------------------------------------------------------------
-! (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.
-!-----------------------------------------------------------------------------
-!> @brief Reconfiguration associated with changes in tiles
-module lfric2lfric_tiles_mod
-
- use constants_mod, only: str_def, i_def, l_def
- use driver_modeldb_mod, only: modeldb_type
- use extrusion_mod, only: TWOD
- use field_parent_mod, only: field_parent_type
- use field_mod, only: field_type
- use field_collection_mod, only: field_collection_type
- use field_collection_iterator_mod, &
- only: field_collection_iterator_type
- use function_space_mod, only: function_space_type
- use mesh_mod, only: mesh_type
- use lfric2lfric_multidata_map_kernel_mod, &
- only: lfric2lfric_multidata_map_type
- use log_mod, only: log_event, &
- log_level_debug, &
- log_level_info, &
- log_level_error, &
- log_scratch_space
-
- implicit none
-
- private
- public :: lfric2lfric_tiles
-
-contains
-
- !> @brief Apply the changes associated with the change in tiles.
- !> @details Loop over the fields in the source_fields collection,
- !! and deal with the change in tiles.
- !> @param modeldb Model state object
- !> @param source_fields The collection of fields to be regridded
- !> @param target_fields The collection of regridded fields
- subroutine lfric2lfric_tiles( modeldb, source_fields, target_fields )
-
- implicit none
-
- type(modeldb_type), intent(inout) :: modeldb
- type(field_collection_type), intent(inout) :: source_fields
- type(field_collection_type), intent(inout) :: target_fields
-
- type(field_collection_iterator_type) :: iter
-
- class(field_parent_type), pointer :: field
- type(field_type), pointer :: field_src
- type(field_type), pointer :: field_dst
- type(mesh_type), pointer :: mesh
- type(function_space_type), pointer :: fs_type
- integer(i_def), allocatable :: multidata_map(:)
- integer(kind=i_def) :: ndata_dst, ndata_src
- character(len=str_def) :: field_name
- logical(l_def), parameter :: ndata_first = .false.
-
- write(log_scratch_space, '(A)') "Tiles "
- call log_event(log_scratch_space, log_level_info)
-
- ! Main loop over fields to be processed
- call iter%initialise(source_fields)
- do
- ! Locate the field to be processed in the field collections
- if ( .not.iter%has_next() ) exit
- field => iter%next()
- field_name = field%get_name()
-
- call source_fields%get_field(field_name, field_src)
- call target_fields%get_field(field_name, field_dst)
-
- ! Continue if it is a 2D mesh field
- mesh => field_src%get_mesh()
- if (mesh%get_extrusion_id() == TWOD) then
-
- write(log_scratch_space, '(A,A)') "Processing lfric field ", &
- trim(field_name)
- call log_event(log_scratch_space, log_level_info)
-
- fs_type => field_src%get_function_space()
- ndata_src = fs_type%get_ndata()
- fs_type => field_dst%get_function_space()
- ndata_dst = fs_type%get_ndata()
-
- write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
- call log_event(log_scratch_space, log_level_debug)
- write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
- call log_event(log_scratch_space, log_level_debug)
-
- if (ndata_src /= ndata_dst) then
-
- ! Need to add full list of fields on surface tiles
- if ( field_name == 'tile_snow_rgrain' ) then
-
- multidata_map = modeldb%config%dst_jules_surface_types%multidata_map()
-
- write(log_scratch_space, '(*(g0,1x))') "multidata ", multidata_map
- call log_event(log_scratch_space, log_level_debug)
-
- if ( size(multidata_map) /= ndata_dst ) then
- write(log_scratch_space, '(A,I5,A,I5)') &
- "size of multidata map = ", size(multidata_map), &
- " not equal to ndata_dst = ", ndata_dst
- call log_event(log_scratch_space, log_level_error)
- end if
-
- call invoke( lfric2lfric_multidata_map_type( field_dst, ndata_dst, &
- field_src, ndata_src, &
- ndata_first ))
- end if
- ! If field name is a sea-ice field
- ! rederive
-
- end if
-
- end if
- end do
-
- end subroutine lfric2lfric_tiles
-
-end module lfric2lfric_tiles_mod
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index 00e63865fa..e254c24988 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -36,8 +36,7 @@ module lfric2lfric_driver_mod
interm_collection_name
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
use lfric2lfric_vert_mod, only: lfric2lfric_vert
- use lfric2lfric_tiles_mod, only: lfric2lfric_tiles
-
+ use lfric2lfric_multidata_mod, only: lfric2lfric_multidata
implicit none
@@ -154,7 +153,7 @@ subroutine run( modeldb, oasis_clock )
call lfric2lfric_vert(modeldb, interm_fields, target_fields)
end if
if (tile_change) then
- call lfric2lfric_tiles(modeldb, interm_fields, target_fields)
+ call lfric2lfric_multidata(modeldb, interm_fields, target_fields)
end if
! Write output
diff --git a/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_surface_kernel_mod.F90 b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_surface_kernel_mod.F90
new file mode 100644
index 0000000000..c5f8267065
--- /dev/null
+++ b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_map_surface_kernel_mod.F90
@@ -0,0 +1,99 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Map 2D multidata fields with different ndata numbers.
+!> @details This is used for lfric2lfric reconfiguration, most likely
+!! for regridding 2D fields on surface tiles. The multidata_map
+!! is read from configuration and is an integer array (of size of
+!! the destination ndata) containing a list of the array positions
+!! from the source data.
+module lfric2lfric_multidata_map_surface_kernel_mod
+
+ use argument_mod, only: arg_type, &
+ GH_FIELD, &
+ GH_SCALAR, &
+ GH_REAL, &
+ GH_INTEGER, &
+ GH_READ, &
+ GH_WRITE, &
+ CELL_COLUMN, &
+ ANY_SPACE_1, &
+ ANY_SPACE_2
+ use constants_mod, only: i_def, r_def, l_def
+ use kernel_mod, only: kernel_type
+ use dst_jules_surface_types_config_mod, &
+ only: multidata_map
+
+ implicit none
+
+ private
+
+ type, public, extends(kernel_type) :: lfric2lfric_multidata_map_surface_type
+ private
+ type(arg_type), dimension(4) :: meta_args = (/ &
+ arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_SPACE_1), & ! field_dst
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), &
+ arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_SPACE_2), & ! field_src
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ) &
+ /)
+ integer :: operates_on = CELL_COLUMN
+ contains
+ procedure, nopass :: lfric2lfric_multidata_map_surface_code
+ end type lfric2lfric_multidata_map_surface_type
+
+ public :: lfric2lfric_multidata_map_surface_code
+
+contains
+
+!> @brief Map a multidata field to another multidata field
+!! @param[in] nlayers Number of layers
+!! @param[in,out] field_dst Output (destination) multidata field
+!! @param[in] ndata_dst
+!! @param[in] field_src Input (source) multidata field
+!! @param[in] ndata_src
+!! @param[in] ndf_dst Number of dofs per cell for field_dst
+!! @param[in] undf_dst Total number of dofs per cell for field_dst
+!! @param[in] map_dst Cell dofmap for field_dst
+!! @param[in] ndf_src Number of dofs per cell for field_src
+!! @param[in] undf_src Total number of dofs per cell for field_src
+!! @param[in] map_src Cell dofmap for field_src
+subroutine lfric2lfric_multidata_map_surface_code(nlayers, &
+ field_dst, &
+ ndata_dst, &
+ field_src, &
+ ndata_src, &
+ ndf_dst, &
+ undf_dst, &
+ map_dst, &
+ ndf_src, &
+ undf_src, &
+ map_src)
+
+ integer(kind=i_def), intent(in) :: nlayers
+
+ integer(kind=i_def), intent(in) :: ndata_src
+ integer(kind=i_def), intent(in) :: ndf_src
+ integer(kind=i_def), intent(in) :: undf_src
+ integer(kind=i_def), intent(in) :: map_src(ndf_src)
+
+ integer(kind=i_def), intent(in) :: ndata_dst
+ integer(kind=i_def), intent(in) :: ndf_dst
+ integer(kind=i_def), intent(in) :: undf_dst
+ integer(kind=i_def), intent(in) :: map_dst(ndf_dst)
+
+ real(kind=r_def), intent(in) :: field_src(undf_src)
+ real(kind=r_def), intent(out) :: field_dst(undf_dst)
+
+ integer(kind=i_def) :: df, i_dst, i_src
+
+ i_dst = map_dst(1)
+ i_src = map_src(1)
+ do df = 0, ndata_dst -1
+ field_dst( i_dst + df ) = field_src( i_src + multidata_map(df+1) -1 )
+ end do
+
+end subroutine lfric2lfric_multidata_map_surface_code
+
+end module lfric2lfric_multidata_map_surface_kernel_mod
diff --git a/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_snow_kernel_mod.F90 b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_snow_kernel_mod.F90
new file mode 100644
index 0000000000..a9cc78b0ef
--- /dev/null
+++ b/applications/lfric2lfric/source/kernel/lfric2lfric_multidata_snow_kernel_mod.F90
@@ -0,0 +1,126 @@
+!-----------------------------------------------------------------------------
+! (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.
+!-----------------------------------------------------------------------------
+!> @brief Map multidata snow fields with different ndata numbers.
+!> @details This is used for lfric2lfric reconfiguration, most likely
+!! for regridding 2D fields on snow layers and tiles.
+module lfric2lfric_multidata_snow_kernel_mod
+
+ use argument_mod, only: arg_type, &
+ GH_FIELD, &
+ GH_SCALAR, &
+ GH_REAL, &
+ GH_INTEGER, &
+ GH_READ, &
+ GH_WRITE, &
+ GH_LOGICAL, &
+ CELL_COLUMN, &
+ ANY_SPACE_1, &
+ ANY_SPACE_2
+ use constants_mod, only: i_def, r_def, l_def
+ use kernel_mod, only: kernel_type
+ use dst_jules_surface_types_config_mod, &
+ only: multidata_map
+
+ implicit none
+
+ private
+
+ type, public, extends(kernel_type) :: lfric2lfric_multidata_snow_type
+ private
+ type(arg_type), dimension(7) :: meta_args = (/ &
+ arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_SPACE_1), & ! field_dst
+ arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_SPACE_2), & ! field_src
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! n_snow_layers_dst
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! n_land_tiles_dst
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! n_snow_layers_src
+ arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! n_land_tiles_src
+ arg_type(GH_SCALAR, GH_LOGICAL, GH_READ) & ! ntiles_first
+ /)
+ integer :: operates_on = CELL_COLUMN
+ contains
+ procedure, nopass :: lfric2lfric_multidata_snow_code
+ end type lfric2lfric_multidata_snow_type
+
+ public :: lfric2lfric_multidata_snow_code
+
+contains
+
+!> @brief Map a multidata field to another multidata field
+!! @param[in] nlayers Number of layers
+!! @param[in,out] field_dst Output (destination) multidata field
+!! @param[in] field_src Input (source) multidata field
+!! @parm[in] n_snow_layers_dst
+!! @param[in] n_tiles_dst
+!! @parm[in] n_snow_layers_src
+!! @param[in] n_tiles_src
+!! @param[in] ntiles_first Data layout (tiles- or layer-first)
+!! @param[in] ndf_dst Number of dofs per cell for field_dst
+!! @param[in] undf_dst Total number of dofs per cell for field_dst
+!! @param[in] map_dst Cell dofmap for field_dst
+!! @param[in] ndf_src Number of dofs per cell for field_src
+!! @param[in] undf_src Total number of dofs per cell for field_src
+!! @param[in] map_src Cell dofmap for field_src
+subroutine lfric2lfric_multidata_snow_code(nlayers, &
+ field_dst, &
+ field_src, &
+ n_snow_layers_dst, &
+ n_tiles_dst, &
+ n_snow_layers_src, &
+ n_tiles_src, &
+ ntiles_first, &
+ ndf_dst, &
+ undf_dst, &
+ map_dst, &
+ ndf_src, &
+ undf_src, &
+ map_src)
+
+ integer(kind=i_def), intent(in) :: nlayers
+
+ integer(kind=i_def), intent(in) :: ndf_src
+ integer(kind=i_def), intent(in) :: undf_src
+ integer(kind=i_def), intent(in) :: map_src(ndf_src)
+
+ integer(kind=i_def), intent(in) :: ndf_dst
+ integer(kind=i_def), intent(in) :: undf_dst
+ integer(kind=i_def), intent(in) :: map_dst(ndf_dst)
+
+ integer(kind=i_def), intent(in) :: n_snow_layers_dst, n_tiles_dst
+ integer(kind=i_def), intent(in) :: n_snow_layers_src, n_tiles_src
+
+ logical(kind=l_def), intent(in) :: ntiles_first
+
+ real(kind=r_def), intent(in) :: field_src(undf_src)
+ real(kind=r_def), intent(out) :: field_dst(undf_dst)
+
+ integer(kind=i_def) :: df, i_dst, i_src, k
+
+ if (ntiles_first) then
+ ! Data layout is tiles first:
+ ! L1T1, L1T2, L1T3, ..., L2T1, L2T2, L2T3, ...
+ do k = 0, n_snow_layers_dst - 1
+ i_dst = map_dst(1) + k * n_tiles_dst
+ i_src = map_src(1) + k * n_tiles_src
+ do df = 0, n_tiles_dst -1
+ field_dst( i_dst + df ) = field_src( i_src + multidata_map(df+1) -1 )
+ end do
+ end do
+
+ else
+ ! Data layout is layers first:
+ ! L1T1, L2T1, ..., L1T2, L2T2, ..., L1T3, L2T3, ...
+ do df = 0, n_tiles_dst - 1
+ i_dst = map_dst(1) + df * n_snow_layers_dst
+ i_src = map_src(1) + (multidata_map(df+1) - 1) * n_snow_layers_src
+ do k =0, n_snow_layers_dst - 1
+ field_dst( i_dst + k ) = field_src( i_src + k )
+ end do
+ end do
+ end if
+
+end subroutine lfric2lfric_multidata_snow_code
+
+end module lfric2lfric_multidata_snow_kernel_mod
From 2430f821a5091db946ddcf9587e29309a26b65b5 Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 14 Sep 2026 13:29:49 +0100
Subject: [PATCH 51/53] Copy fields if not vertical regrid or multidata
---
.../algorithm/lfric2lfric_multidata_mod.x90 | 73 +++++++++++--------
.../source/algorithm/lfric2lfric_vert_mod.x90 | 64 +++++++++++-----
.../source/driver/lfric2lfric_driver_mod.F90 | 7 +-
3 files changed, 90 insertions(+), 54 deletions(-)
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
index 2eb6f1a699..0c56fcd9be 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
@@ -65,12 +65,16 @@ contains
real(kind=r_def) :: number_snow_layers, dummy
character(len=str_def) :: field_name
integer(i_def), allocatable :: multidata_map(:)
+
+ logical(kind=l_def), pointer :: tile_change
write(log_scratch_space, '(A)') "Starting lfric2lfric_multidata"
call log_event(log_scratch_space, log_level_debug)
!---- Precalculations
+ call modeldb%values%get_value("tile_change", tile_change)
+
!-- Find the number of snow layers in the source data
call source_fields%get_field('n_snow_layers', field_src_n_snow_layers)
call get_field_minmax(field_src_n_snow_layers, dummy, number_snow_layers)
@@ -119,29 +123,30 @@ contains
call source_fields%get_field(field_name, field_src)
call target_fields%get_field(field_name, field_dst)
- ! Continue if it is a 2D mesh field
mesh => field_src%get_mesh()
+
+ ! Find the size of the multidata field
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+
+ ! If it is a 2D
if (mesh%get_extrusion_id() == TWOD) then
- write(log_scratch_space, '(A,A)') "Processing lfric field", &
- trim(field_name)
- call log_event(log_scratch_space, log_level_debug)
-
- ! Find the size of the multidata field
- fs_type => field_src%get_function_space()
- ndata_src = fs_type%get_ndata()
- fs_type => field_dst%get_function_space()
- ndata_dst = fs_type%get_ndata()
-
- write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
- call log_event(log_scratch_space, log_level_debug)
- write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
- call log_event(log_scratch_space, log_level_debug)
-
- ! if multidata field
- if ((ndata_dst > 1) .or. (ndata_src > 1)) then
-
- ! Based on UM rcf_field_calcs
+ ! If multidata field and multidata regridding (tile_change) is on
+ if ( ((ndata_src >1) .or. (ndata_dst >1)) .and. &
+ tile_change ) then
+
+ write(log_scratch_space, '(A,A)') "Multidata Mapping lfric field", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_debug)
+
+ write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
+ call log_event(log_scratch_space, log_level_debug)
+ write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
+ call log_event(log_scratch_space, log_level_debug)
+
select case (field_name)
! Surface tiles - based on rcf_calc_tiles, rcf_init_field_on_tiles (L240)
@@ -158,12 +163,12 @@ contains
'snow_under_canopy' )
if (n_land_tiles_src /= n_land_tiles_dst) then
- ! As the fields might use surface_tiles, only loop over land_tiles
+ ! As the fields might use surface_tiles, only loop over land_tiles
call lfric2lfric_retile_surface_tiles( &
- modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
+ modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
else
- ! Copy field_src to field_dst - but careful if one is n_land tiles and one is n_surface
- !...
+ ! Copy field_src to field_dst - but careful if one is n_land tiles and one is n_surface
+ !...
end if
! Snow Layers and Tiles - based on rcf_ml_snowpack
@@ -174,10 +179,10 @@ contains
'snow_layer_rgrain')
if ( (n_land_tiles_src /= n_land_tiles_dst) ) then
- ! Assume size land_tiles & n_snow - need to check
- ! Assume snow layers same - need to check
+ ! Assume size land_tiles & n_snow - need to check
+ ! Assume snow layers same - need to check
call lfric2lfric_retile_snow( &
- modeldb, field_dst, field_src, n_snow_layers_dst, n_land_tiles_dst, n_snow_layers_src, n_land_tiles_src )
+ modeldb, field_dst, field_src, n_snow_layers_dst, n_land_tiles_dst, n_snow_layers_src, n_land_tiles_src )
else
! Copy
end if
@@ -186,11 +191,11 @@ contains
case ('sea_ice_temperature')
! Need to check, add error message or copy
- ! Sea Ice Categories - sea_ice_thickness based on rcf_derv_ice_cat_thick
+ ! Sea Ice Categories - sea_ice_thickness based on rcf_derv_ice_cat_thick
case ('sea_ice_thickness')
! Need to check, add error message or copy
- ! Soil Levels - based on rcf_init_soil_temp
+ ! Soil Levels - based on rcf_init_soil_temp
case ('soil_temperature')
! Need to check, add error message or copy
@@ -200,9 +205,15 @@ contains
call log_event(log_scratch_space, log_level_error)
end select
+
else
- ! Straightforward copy if not multidata ??
- call invoke( setval_X(field_dst, field_src))
+ ! copy 2D from src to dst
+ write(log_scratch_space, '(A,A)') "Copying lfric field ", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_debug)
+
+ call invoke(setval_X(field_dst, field_src))
+
end if
end if
end do
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index dbbd966d00..906bbe787d 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -8,8 +8,9 @@
!! meshes.
module lfric2lfric_vert_mod
- use constants_mod, only: str_def, i_def
+ use constants_mod, only: str_def, i_def, l_def
use driver_modeldb_mod, only: modeldb_type
+ use extrusion_mod, only: TWOD
use field_parent_mod, only: field_parent_type
use field_mod, only: field_type
use field_collection_mod, only: field_collection_type
@@ -57,6 +58,10 @@ contains
character(len=str_def) :: field_name
integer(kind=i_def) :: fs_src, fs_dst
+ logical(kind=l_def), pointer :: vertical_change
+
+ call modeldb%values%get_value("vertical_change", vertical_change)
+
! Main loop over fields to be processed
call iter%initialise(source_fields)
do
@@ -68,26 +73,45 @@ contains
call source_fields%get_field(field_name, field_src)
call target_fields%get_field(field_name, field_dst)
- write(log_scratch_space, '(A,A)') "Processing lfric field ", &
- trim(field_name)
- call log_event(log_scratch_space, log_level_info)
-
mesh_src => field_src%get_mesh()
- mesh_dst => field_dst%get_mesh()
- fs_src = field_src%which_function_space()
- fs_dst = field_dst%which_function_space()
-
- ! Get the associated heights, ready for vertical interpolation kernels
- height_src => get_height_fv(modeldb%config, mesh_src, fs_src)
- height_dst => get_height_fv(modeldb%config, mesh_dst, fs_dst)
-
- ! Dummy initialisation - just writing out the heights
- ! TODO Replaced the dummy initialisation with actual
- ! vertical regridding from #253. i.e.
- ! call invoke( lfric2lfric_vert_lin_interp_lin_extrap_code_r_single( &
- ! field_dst, field_src, height_dst, height_src))
- call invoke(setval_X(field_dst, height_dst))
- enddo
+
+ ! Vertical regridding is only for 3D fields
+ if (mesh_src%get_extrusion_id() /= TWOD) then
+
+ if (vertical_change) then
+
+ ! All 3D fields are regridded in vertical
+
+ write(log_scratch_space, '(A,A)') "Vertical regridding lfric field ", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_info)
+
+ mesh_src => field_src%get_mesh()
+ mesh_dst => field_dst%get_mesh()
+ fs_src = field_src%which_function_space()
+ fs_dst = field_dst%which_function_space()
+
+ ! Get the associated heights, ready for vertical interpolation kernels
+ height_src => get_height_fv(modeldb%config, mesh_src, fs_src)
+ height_dst => get_height_fv(modeldb%config, mesh_dst, fs_dst)
+
+ ! Dummy initialisation - just writing out the heights
+ ! TODO Replaced the dummy initialisation with actual
+ ! vertical regridding from #253. i.e.
+ ! call invoke( lfric2lfric_vert_lin_interp_lin_extrap_code_r_single( &
+ ! field_dst, field_src, height_dst, height_src))
+ call invoke(setval_X(field_dst, height_dst))
+ else
+
+ ! All 3D fields are copied from src to dst
+ write(log_scratch_space, '(A,A)') "Copying lfric field ", &
+ trim(field_name)
+ call log_event(log_scratch_space, log_level_info)
+
+ call invoke(setval_X(field_dst, field_src))
+ end if
+ end if
+ end do
end subroutine lfric2lfric_vert
diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
index e254c24988..451fa57c69 100644
--- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
+++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90
@@ -36,6 +36,7 @@ module lfric2lfric_driver_mod
interm_collection_name
use lfric2lfric_regrid_mod, only: lfric2lfric_regrid
use lfric2lfric_vert_mod, only: lfric2lfric_vert
+ use lfric2lfric_copy_mod, only: lfric2lfric_copy
use lfric2lfric_multidata_mod, only: lfric2lfric_multidata
implicit none
@@ -149,10 +150,10 @@ subroutine run( modeldb, oasis_clock )
call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, &
interm_fields, regrid_method)
end if
- if (vertical_change) then
+ if (vertical_or_tile_change) then
+ ! 3D fields
call lfric2lfric_vert(modeldb, interm_fields, target_fields)
- end if
- if (tile_change) then
+ ! 2D fields
call lfric2lfric_multidata(modeldb, interm_fields, target_fields)
end if
From 9086c7a3a30d3ff90cad6188c833432d562a02fb Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 14 Sep 2026 14:42:49 +0100
Subject: [PATCH 52/53] tidy
---
.../algorithm/lfric2lfric_multidata_mod.x90 | 244 +++++++++++-------
.../source/algorithm/lfric2lfric_vert_mod.x90 | 13 +-
2 files changed, 156 insertions(+), 101 deletions(-)
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
index 0c56fcd9be..adeeefb147 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
@@ -29,8 +29,8 @@ module lfric2lfric_multidata_mod
implicit none
- private
- public :: lfric2lfric_multidata, lfric2lfric_retile_surface_tiles
+ private :: lfric2lfric_retile_surface_tiles, lfric2lfric_retile_snow
+ public :: lfric2lfric_multidata
contains
@@ -68,84 +68,94 @@ contains
logical(kind=l_def), pointer :: tile_change
- write(log_scratch_space, '(A)') "Starting lfric2lfric_multidata"
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(A)') "Starting lfric2lfric_multidata"
+ call log_event( log_scratch_space, log_level_debug )
- !---- Precalculations
+ !---- Precalculations and checks
- call modeldb%values%get_value("tile_change", tile_change)
+ ! Determine whether retiling is required for any fields
- !-- Find the number of snow layers in the source data
- call source_fields%get_field('n_snow_layers', field_src_n_snow_layers)
- call get_field_minmax(field_src_n_snow_layers, dummy, number_snow_layers)
+ call modeldb%values%get_value( "tile_change", tile_change )
+
+ ! Determine the number of snow layers in the source data
+
+ call source_fields%get_field( 'n_snow_layers', field_src_n_snow_layers )
+ call get_field_minmax( field_src_n_snow_layers, dummy, number_snow_layers )
n_snow_layers_src = nint(number_snow_layers)
- !-- Determine the number of snow layers in the target data
+ ! Determine the number of snow layers in the target data
! Assume for now that it is the same as the source data
- ! Otherwise this could be added to a rose namelist
+ ! Otherwise this could be added to a rose namelist or be derived from jules
+
n_snow_layers_dst = n_snow_layers_src
- !-- Determine n_land_tiles_src
+ ! Determine n_land_tiles_src
! Derive effective number of land tiles in source field from snow fields
- call source_fields%get_field('snow_layer_temp', field_src_snow_layer)
+
+ call source_fields%get_field( 'snow_layer_temp', field_src_snow_layer )
+
fs_type => field_src_snow_layer%get_function_space()
ndata_src = fs_type%get_ndata()
n_land_tiles_src = ndata_src / n_snow_layers_src
- !-- Determine n_land_tiles_dst
+ ! Determine n_land_tiles_dst
! Derive effective number of land tiles in destination field from snow fields
- call target_fields%get_field('snow_layer_temp', field_dst_snow_layer)
+
+ call target_fields%get_field( 'snow_layer_temp', field_dst_snow_layer )
+
fs_type => field_dst_snow_layer%get_function_space()
ndata_dst = fs_type%get_ndata()
n_land_tiles_dst = ndata_dst / n_snow_layers_dst
- !-- Check multidata map
+ ! Check multidata map
+
multidata_map = modeldb%config%dst_jules_surface_types%multidata_map()
- write(log_scratch_space, '(*(g0,1x))') "multidata ", multidata_map
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(*(g0,1x))' ) "multidata ", multidata_map
+ call log_event( log_scratch_space, log_level_debug )
- if ( size(multidata_map) /= n_land_tiles_dst ) then
- write(log_scratch_space, '(A,I5,A,I5)') &
- "size of multidata map = ", size(multidata_map), &
+ if ( size( multidata_map ) /= n_land_tiles_dst ) then
+ write( log_scratch_space, '(A,I5,A,I5)' ) &
+ "size of multidata map = ", size( multidata_map ), &
" not equal to n_land_tiles_dst = ", n_land_tiles_dst
- call log_event(log_scratch_space, log_level_error)
+ call log_event( log_scratch_space, log_level_error )
end if
!------ Main loop over fields to be processed
- call iter%initialise(source_fields)
+ call iter%initialise( source_fields )
do
! Locate the field to be processed in the field collections
if ( .not. iter%has_next() ) exit
field => iter%next()
field_name = field%get_name()
- call source_fields%get_field(field_name, field_src)
- call target_fields%get_field(field_name, field_dst)
+ call source_fields%get_field( field_name, field_src )
+ call target_fields%get_field( field_name, field_dst )
mesh => field_src%get_mesh()
- ! Find the size of the multidata field
- fs_type => field_src%get_function_space()
- ndata_src = fs_type%get_ndata()
- fs_type => field_dst%get_function_space()
- ndata_dst = fs_type%get_ndata()
-
- ! If it is a 2D
- if (mesh%get_extrusion_id() == TWOD) then
+ ! Only consider 2D fields
+ if ( mesh%get_extrusion_id() == TWOD ) then
- ! If multidata field and multidata regridding (tile_change) is on
- if ( ((ndata_src >1) .or. (ndata_dst >1)) .and. &
+ ! Find the size of the multidata field
+ fs_type => field_src%get_function_space()
+ ndata_src = fs_type%get_ndata()
+ fs_type => field_dst%get_function_space()
+ ndata_dst = fs_type%get_ndata()
+
+ ! If multidata field and multidata regridding (tile_change) is true
+ ! apply field-specific multidata mapping (retiling).
+ if ( ( ( ndata_src >1 ) .or. ( ndata_dst >1 ) ) .and. &
tile_change ) then
- write(log_scratch_space, '(A,A)') "Multidata Mapping lfric field", &
- trim(field_name)
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(A,A)' ) "Multidata Mapping lfric field", &
+ trim( field_name )
+ call log_event( log_scratch_space, log_level_debug )
- write(log_scratch_space, '(A,I5)') "ndata_dst ", ndata_dst
- call log_event(log_scratch_space, log_level_debug)
- write(log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(A,I5)' ) "ndata_dst ", ndata_dst
+ call log_event( log_scratch_space, log_level_debug )
+ write( log_scratch_space, '(A,I5)') "ndata_src ", ndata_src
+ call log_event( log_scratch_space, log_level_debug )
select case (field_name)
@@ -162,14 +172,9 @@ contains
'snowpack_density' , &
'snow_under_canopy' )
- if (n_land_tiles_src /= n_land_tiles_dst) then
- ! As the fields might use surface_tiles, only loop over land_tiles
- call lfric2lfric_retile_surface_tiles( &
- modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
- else
- ! Copy field_src to field_dst - but careful if one is n_land tiles and one is n_surface
- !...
- end if
+ call lfric2lfric_retile_surface_tiles( &
+ modeldb, field_dst, field_src, ndata_dst, ndata_src, &
+ n_land_tiles_dst, n_land_tiles_src )
! Snow Layers and Tiles - based on rcf_ml_snowpack
case ('snow_layer_temp' , &
@@ -178,41 +183,30 @@ contains
'snow_layer_liq_mass' , &
'snow_layer_rgrain')
- if ( (n_land_tiles_src /= n_land_tiles_dst) ) then
- ! Assume size land_tiles & n_snow - need to check
- ! Assume snow layers same - need to check
- call lfric2lfric_retile_snow( &
- modeldb, field_dst, field_src, n_snow_layers_dst, n_land_tiles_dst, n_snow_layers_src, n_land_tiles_src )
- else
- ! Copy
- end if
+ call lfric2lfric_retile_snow( &
+ modeldb, field_dst, field_src, ndata_dst, ndata_src, &
+ n_snow_layers_dst, n_snow_layers_src, &
+ n_land_tiles_dst, n_land_tiles_src )
- ! Sea Ice Categories - sea_ice_temperature based on rcf_derv_sea_ice_temp
- case ('sea_ice_temperature')
- ! Need to check, add error message or copy
+ case default
+ write( log_scratch_space, '(A,A)' ) &
+ trim( field_name ), " needs retiling code to be added"
+ call log_event( log_scratch_space, log_level_error )
+ ! Other possible fields and categories are:
+ ! Sea Ice Categories - sea_ice_temperature based on rcf_derv_sea_ice_temp
! Sea Ice Categories - sea_ice_thickness based on rcf_derv_ice_cat_thick
- case ('sea_ice_thickness')
- ! Need to check, add error message or copy
-
! Soil Levels - based on rcf_init_soil_temp
- case ('soil_temperature')
- ! Need to check, add error message or copy
-
- case default
- write(log_scratch_space, '(A,A)') &
- trim(field_name), " needs to have code added"
- call log_event(log_scratch_space, log_level_error)
-
end select
else
- ! copy 2D from src to dst
+ ! If not a multidata field or multidata mapping is not required then
+ ! copy from src to dst
write(log_scratch_space, '(A,A)') "Copying lfric field ", &
trim(field_name)
- call log_event(log_scratch_space, log_level_debug)
+ call log_event( log_scratch_space, log_level_debug)
- call invoke(setval_X(field_dst, field_src))
+ call invoke( setval_X( field_dst, field_src ) )
end if
end if
@@ -226,24 +220,53 @@ contains
!> @param modeldb Model state object
!> @param field_dst Destination multidata field
!> @param field_src Source multidata field
- !> @param nland_tiles_dst Number of land tiles in destination field
- !> @param nland_tiles_src Number of land tiles in source field
- subroutine lfric2lfric_retile_surface_tiles( modeldb, field_dst, field_src, n_land_tiles_dst, n_land_tiles_src )
+ !> @param n_data_dst Number of multidata levels in destination field
+ !> @param n_data_src Number of multidata levels in source field
+ !> @param n_land_tiles_dst Number of land tiles in destination field
+ !> @param n_land_tiles_src Number of land tiles in source field
+ subroutine lfric2lfric_retile_surface_tiles( modeldb, field_dst, field_src, &
+ n_data_dst, n_data_src, &
+ n_land_tiles_dst, n_land_tiles_src )
implicit none
type(modeldb_type), intent(inout) :: modeldb
type(field_type), intent(inout) :: field_dst
type(field_type), intent(in) :: field_src
+ integer(kind=i_def), intent(in) :: n_data_dst
+ integer(kind=i_def), intent(in) :: n_data_src
integer(kind=i_def), intent(in) :: n_land_tiles_dst
integer(kind=i_def), intent(in) :: n_land_tiles_src
- write(log_scratch_space, '(A)') "Starting lfric2lfric_retile_surface_tiles"
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(A)' ) "Starting lfric2lfric_retile_surface_tiles"
+ call log_event( log_scratch_space, log_level_debug )
- call invoke( lfric2lfric_multidata_map_surface_type( field_dst, n_land_tiles_dst, &
- field_src, n_land_tiles_src))
+ if ( ( n_land_tiles_src == n_land_tiles_dst ) .and. &
+ ( ndata_src /= ndata_dst ) ) then
+ write( log_scratch_space, '(A)' ) &
+ "The number of land tiles has not changed but the multidata axis size is different "
+ call log_event( log_scratch_space, log_level_error )
+ end if
+ if ( ndata_dst < n_land_tiles_dst ) then
+ write( log_scratch_space, '(A)' ) &
+ "The number of surface tiles is smaller than the number of land tiles "
+ call log_event( log_scratch_space, log_level_error )
+ end if
+
+ if ( n_land_tiles_src /= n_land_tiles_dst ) then
+ ! Retile using the multidata map
+ call invoke( lfric2lfric_multidata_map_surface_type( field_dst, &
+ n_land_tiles_dst, &
+ field_src, &
+ n_land_tiles_src ) )
+
+ else
+ ! Copy
+ call invoke( setval_X( field_dst, field_src ) )
+
+ end if
+
end subroutine lfric2lfric_retile_surface_tiles
!> @brief Retile a field with snow_layers_and_tiles
@@ -251,12 +274,16 @@ contains
!> @param modeldb Model state object
!> @param field_dst Destination multidata field
!> @param field_src Source multidata field
+ !> @param n_data_dst Number of multidata levels in destination field
+ !> @param n_data_src Number of multidata levels in source field
!> @param n_snow_layers_dst Source number of snow layers in destination
- !> @param n_tiles_dst Source number of land tiles in destination
!> @param n_snow_layers_src Source number of snow layers in source
+ !> @param n_tiles_dst Source number of land tiles in destination
!> @param n_tiles_src Source number of land tiles in source
- subroutine lfric2lfric_retile_snow( modeldb, field_dst, field_src, &
- n_snow_layers_dst, n_tiles_dst, n_snow_layers_src, n_tiles_src )
+ subroutine lfric2lfric_retile_snow( modeldb, field_dst, field_src, &
+ ndata_dst, ndata_src, &
+ n_snow_layers_dst, n_snow_layers_src, &
+ n_tiles_dst, n_tiles_src )
implicit none
@@ -264,22 +291,49 @@ contains
type(field_type), intent(inout) :: field_dst
type(field_type), intent(in) :: field_src
integer(kind=i_def), intent(in) :: n_snow_layers_dst
- integer(kind=i_def), intent(in) :: n_tiles_dst
integer(kind=i_def), intent(in) :: n_snow_layers_src
+ integer(kind=i_def), intent(in) :: n_tiles_dst
integer(kind=i_def), intent(in) :: n_tiles_src
+ integer(kind=i_def), intent(in) :: ndata_dst
+ integer(kind=i_def), intent(in) :: ndata_src
logical(l_def), parameter :: ndata_first = .false.
- write(log_scratch_space, '(A)') "Starting lfric2lfric_retile_snow"
- call log_event(log_scratch_space, log_level_debug)
+ write( log_scratch_space, '(A)' ) "Starting lfric2lfric_retile_snow"
+ call log_event( log_scratch_space, log_level_debug )
+
+ ! Assume size land_tiles * n_snow = number snow layers and tiles
+ if ( n_snow_layers_dst * n_tiles_dst /= ndata_dst ) then
+ write( log_scratch_space, '(A)' ) &
+ "The number of snow layers x number of tiles is not equal to the number of snow_layers_tiles in the destination "
+ call log_event( log_scratch_space, log_level_error )
+ end if
+ if ( n_snow_layers_src * n_tiles_src /= ndata_src ) then
+ write( log_scratch_space, '(A)' ) &
+ "The number of snow layers x number of tiles is not equal to the number of snow_layers_tiles in the source "
+ call log_event( log_scratch_space, log_level_error )
+ end if
+
+ ! Assume snow layers same in source and destination
+ if ( n_snow_layers_src /= n_snow_layers_dst ) then
+ write( log_scratch_space, '(A)' ) &
+ "The number of snow layers in the destination is not the same as the source "
+ call log_event( log_scratch_space, log_level_error )
+ end if
- call invoke( lfric2lfric_multidata_snow_type( field_dst, &
- field_src, &
- n_snow_layers_dst, &
- n_tiles_dst, &
- n_snow_layers_src, &
- n_tiles_src, &
- ndata_first ))
+ if ( ( n_land_tiles_src /= n_land_tiles_dst ) ) then
+ ! Retile
+ call invoke( lfric2lfric_multidata_snow_type( field_dst, &
+ field_src, &
+ n_snow_layers_dst, &
+ n_tiles_dst, &
+ n_snow_layers_src, &
+ n_tiles_src, &
+ ndata_first ) )
+ else
+ ! Copy
+ call invoke( setval_X( field_dst, field_src ) )
+ end if
end subroutine lfric2lfric_retile_snow
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index 906bbe787d..ba0fe033b2 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -21,6 +21,7 @@ module lfric2lfric_vert_mod
use mesh_mod, only: mesh_type
use log_mod, only: log_event, &
log_level_info, &
+ log_level_debug
log_scratch_space
implicit none
@@ -75,21 +76,21 @@ contains
mesh_src => field_src%get_mesh()
- ! Vertical regridding is only for 3D fields
+ ! Only consider 3D fields
if (mesh_src%get_extrusion_id() /= TWOD) then
if (vertical_change) then
- ! All 3D fields are regridded in vertical
+ ! All 3D fields are regridded in vertical if vertical_change is true
write(log_scratch_space, '(A,A)') "Vertical regridding lfric field ", &
trim(field_name)
- call log_event(log_scratch_space, log_level_info)
+ call log_event(log_scratch_space, log_level_debug)
mesh_src => field_src%get_mesh()
mesh_dst => field_dst%get_mesh()
fs_src = field_src%which_function_space()
- fs_dst = field_dst%which_function_space()
+ fs_dst = field_dst%which_function_space()
! Get the associated heights, ready for vertical interpolation kernels
height_src => get_height_fv(modeldb%config, mesh_src, fs_src)
@@ -103,10 +104,10 @@ contains
call invoke(setval_X(field_dst, height_dst))
else
- ! All 3D fields are copied from src to dst
+ ! All 3D fields are copied from src to dst if vertical change is false
write(log_scratch_space, '(A,A)') "Copying lfric field ", &
trim(field_name)
- call log_event(log_scratch_space, log_level_info)
+ call log_event(log_scratch_space, log_level_debug)
call invoke(setval_X(field_dst, field_src))
end if
From 84711238f1d2c7e58a55e12c911208e022bdbb8f Mon Sep 17 00:00:00 2001
From: Christine Johnson <74597224+cjohnson-pi@users.noreply.github.com>
Date: Mon, 14 Sep 2026 15:40:09 +0100
Subject: [PATCH 53/53] Loop surface fields over surface fields
---
.../lfric2lfric/example/configuration.nml | 2 +-
.../algorithm/lfric2lfric_multidata_mod.x90 | 48 +++++++------------
.../source/algorithm/lfric2lfric_vert_mod.x90 | 6 +--
3 files changed, 22 insertions(+), 34 deletions(-)
diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml
index 407f6555d0..d44ca96dff 100644
--- a/applications/lfric2lfric/example/configuration.nml
+++ b/applications/lfric2lfric/example/configuration.nml
@@ -113,5 +113,5 @@ coord_space = 'Wchi',
&dst_jules_surface_types
! https://github.com/MetOffice/um/blob/main/rose-stem/app/um_seukv_eg/opt/rose-app-reconukv.conf
- multidata_map = 1,2,3,4,5,6,6,7,8,9
+ multidata_map = 1,2,3,4,5,6,6,7,8,9,10
/
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
index adeeefb147..145bb8c729 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_multidata_mod.x90
@@ -54,12 +54,14 @@ contains
type(field_type), pointer :: field_src
type(field_type), pointer :: field_dst
type(field_type), pointer :: field_src_n_snow_layers
+ type(field_type), pointer :: field_dst_n_snow_layers
type(field_type), pointer :: field_src_snow_layer
type(field_type), pointer :: field_dst_snow_layer
type(mesh_type), pointer :: mesh
type(function_space_type), pointer :: fs_type
integer(kind=i_def) :: ndata_dst, ndata_src
+ integer(kind=i_def) :: n_surface_tiles_dst
integer(kind=i_def) :: n_snow_layers_src, n_snow_layers_dst
integer(kind=i_def) :: n_land_tiles_src, n_land_tiles_dst
real(kind=r_def) :: number_snow_layers, dummy
@@ -89,6 +91,12 @@ contains
n_snow_layers_dst = n_snow_layers_src
+ ! Determine the number of surface tiles
+
+ call source_fields%get_field( 'n_snow_layers', field_dst_n_snow_layers )
+ fs_type => field_dst_n_snow_layers%get_function_space()
+ n_surface_tiles_dst = fs_type%get_ndata()
+
! Determine n_land_tiles_src
! Derive effective number of land tiles in source field from snow fields
@@ -114,10 +122,10 @@ contains
write( log_scratch_space, '(*(g0,1x))' ) "multidata ", multidata_map
call log_event( log_scratch_space, log_level_debug )
- if ( size( multidata_map ) /= n_land_tiles_dst ) then
+ if ( size( multidata_map ) /= n_surface_tiles_dst ) then
write( log_scratch_space, '(A,I5,A,I5)' ) &
"size of multidata map = ", size( multidata_map ), &
- " not equal to n_land_tiles_dst = ", n_land_tiles_dst
+ " not equal to n_surface_tiles_dst = ", n_surface_tiles_dst
call log_event( log_scratch_space, log_level_error )
end if
@@ -173,8 +181,7 @@ contains
'snow_under_canopy' )
call lfric2lfric_retile_surface_tiles( &
- modeldb, field_dst, field_src, ndata_dst, ndata_src, &
- n_land_tiles_dst, n_land_tiles_src )
+ modeldb, field_dst, field_src, ndata_dst, ndata_src )
! Snow Layers and Tiles - based on rcf_ml_snowpack
case ('snow_layer_temp' , &
@@ -222,11 +229,8 @@ contains
!> @param field_src Source multidata field
!> @param n_data_dst Number of multidata levels in destination field
!> @param n_data_src Number of multidata levels in source field
- !> @param n_land_tiles_dst Number of land tiles in destination field
- !> @param n_land_tiles_src Number of land tiles in source field
subroutine lfric2lfric_retile_surface_tiles( modeldb, field_dst, field_src, &
- n_data_dst, n_data_src, &
- n_land_tiles_dst, n_land_tiles_src )
+ n_data_dst, n_data_src )
implicit none
@@ -235,32 +239,16 @@ contains
type(field_type), intent(in) :: field_src
integer(kind=i_def), intent(in) :: n_data_dst
integer(kind=i_def), intent(in) :: n_data_src
- integer(kind=i_def), intent(in) :: n_land_tiles_dst
- integer(kind=i_def), intent(in) :: n_land_tiles_src
write( log_scratch_space, '(A)' ) "Starting lfric2lfric_retile_surface_tiles"
call log_event( log_scratch_space, log_level_debug )
- if ( ( n_land_tiles_src == n_land_tiles_dst ) .and. &
- ( ndata_src /= ndata_dst ) ) then
- write( log_scratch_space, '(A)' ) &
- "The number of land tiles has not changed but the multidata axis size is different "
- call log_event( log_scratch_space, log_level_error )
- end if
-
- if ( ndata_dst < n_land_tiles_dst ) then
- write( log_scratch_space, '(A)' ) &
- "The number of surface tiles is smaller than the number of land tiles "
- call log_event( log_scratch_space, log_level_error )
- end if
-
- if ( n_land_tiles_src /= n_land_tiles_dst ) then
+ if ( n_data_src /= n_data_dst ) then
! Retile using the multidata map
- call invoke( lfric2lfric_multidata_map_surface_type( field_dst, &
- n_land_tiles_dst, &
- field_src, &
- n_land_tiles_src ) )
-
+ call invoke( lfric2lfric_multidata_map_surface_type( field_dst, &
+ n_data_dst, &
+ field_src, &
+ n_data_src ) )
else
! Copy
call invoke( setval_X( field_dst, field_src ) )
@@ -321,7 +309,7 @@ contains
call log_event( log_scratch_space, log_level_error )
end if
- if ( ( n_land_tiles_src /= n_land_tiles_dst ) ) then
+ if ( ( n_tiles_src /= n_tiles_dst ) ) then
! Retile
call invoke( lfric2lfric_multidata_snow_type( field_dst, &
field_src, &
diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
index ba0fe033b2..a4aec1f976 100644
--- a/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
+++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_vert_mod.x90
@@ -19,9 +19,9 @@ module lfric2lfric_vert_mod
use sci_geometric_constants_mod, &
only: get_height_fv
use mesh_mod, only: mesh_type
- use log_mod, only: log_event, &
- log_level_info, &
- log_level_debug
+ use log_mod, only: log_event, &
+ log_level_info, &
+ log_level_debug, &
log_scratch_space
implicit none