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/32] 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 dbe84fe41..fbf710484 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 83f7f6c1f..2a5c73acf 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/32] 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 2a5c73acf..ee2260bf6 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/32] 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 ee2260bf6..dd07d8d36 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/32] 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 000000000..c06d0c5c6 --- /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 e02dd5580..b33b0297d 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 ab2a73b09..43a0c05c7 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 dd07d8d36..a0b449c71 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/32] 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 c06d0c5c6..cc46af301 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 b33b0297d..0005050a6 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 43a0c05c7..250643951 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 a0b449c71..adf760124 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/32] 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 723f79bc3..97859764b 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 c9a253632..0e17efbd7 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 566f047fd..5fab9e117 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 441c46314..538a83659 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 3da09230b..1a0f54d01 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/32] 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 ea19ff585..a401ca85a 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 250643951..ab634f245 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 adf760124..55bcb36cd 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/32] 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 000000000..030f3f8a3 --- /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 000000000..8c7962d5f --- /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 b68dc1efc..fed9d13d2 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 eca0b1d27..33e7e6bef 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/32] 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 000000000..a6d7d25af --- /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 fed9d13d2..956485023 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 33e7e6bef..39eee6340 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/32] 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 4c21f4123..c159a1f23 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 25fe629c2..f55505b95 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 d8c383090..f8a76189b 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/32] 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 c159a1f23..3fc3ea7f1 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 b89f3f2ab..ca7a37691 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 9b9e4299e..4d131bd74 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 94ebcca3c..1476d13aa 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/32] 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 3fc3ea7f1..c159a1f23 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 ca7a37691..b89f3f2ab 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 4d131bd74..9b9e4299e 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 1476d13aa..94ebcca3c 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/32] 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 f55505b95..a2e035a9d 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/32] 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 0e8eb42ad..681b4a49b 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 c159a1f23..8ad7d6cec 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 b89f3f2ab..f488c7df4 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 9b9e4299e..06c2e3101 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 94ebcca3c..fe68dd423 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/32] 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 cc46af301..f54d199d6 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 681b4a49b..071af9bb0 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/32] 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 8ad7d6cec..d97bc1372 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 e9468e191..35d5a0c80 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 a5cbfb514..4a0be42d8 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 c5e498de3..8038bf9b0 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/32] 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 ab634f245..b2f5dcf82 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 1b41ed2aa..fe2be646b 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 d97bc1372..8231ad2a9 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 787a8bb18..8cc65056a 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/32] 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 071af9bb0..70026d240 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 8231ad2a9..f8046e4b1 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 6a260e03c..2e1f1e906 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/32] 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 fe12fd4a2..1a4edc1de 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 b2f5dcf82..c2518ea43 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 f8046e4b1..bc5f26701 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 330c8f6e2..950011de2 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/32] 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 1a4edc1de..d25b8274c 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/32] 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 70026d240..983e0d280 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 c2518ea43..7ca5bf329 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 bc5f26701..4bf0e10bb 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 2e1f1e906..dccb133db 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/32] 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 fe2be646b..867ab70a2 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 4bf0e10bb..75b663bf1 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/32] 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 dccb133db..0a0e1ee53 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 a6d7d25af..87cbe9951 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 a2e035a9d..07019d9b2 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 f8a76189b..23c622d4d 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/32] 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 93b8ca593..ecb0cdc60 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 f54d199d6..d13d88b28 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 75b663bf1..8d0daaf34 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/32] 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 7ca5bf329..ddf4404bf 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 867ab70a2..1b41ed2aa 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 0a0e1ee53..6a260e03c 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/32] 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 d13d88b28..dbbd966d0 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 983e0d280..0e5f16b00 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 ddf4404bf..c6be9c365 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 8d0daaf34..4763e6da9 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/32] 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 4763e6da9..7d68aedde 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 8038bf9b0..58815a7ba 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/32] 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 ecb0cdc60..2103c0678 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 950011de2..6facf3930 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 02877f4ad..16e0206d4 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 33fd5d990..ae8fce007 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 116aa7c5f..d97fabaeb 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 6d0cf2167..7fead03c3 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/32] 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 23c622d4d..4fcf2f7d5 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/32] 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 16e0206d4..4af46b881 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 7fead03c3..468f1fd6e 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/32] 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 2103c0678..f392e31b3 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/32] 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 c38cf9bd3..2e43fae74 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 9d1571fc7..8d76cdba7 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 0d8031b07..5b4f51bcf 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 ad8625391..255e20237 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), &