From 2d404b5bf24f6652ea14c008b30b99f7a9e34252 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 7 Jan 2026 10:23:48 +0000 Subject: [PATCH 01/68] All changes except updating canned test namelist --- applications/adjoint_tests/example/C12.nml | 53 - applications/adjoint_tests/example/iodef.xml | 211 ++-- .../adjoint_tests/example/mesh_C12.nc | Bin 85708 -> 0 bytes .../adjoint_tests/source/adjoint_tests.f90 | 3 + ...djt_mixed_schur_preconditioner_alg_mod.x90 | 59 +- .../solver/adjt_mixed_solver_alg_mod.x90 | 58 +- .../solver/adjt_pressure_precon_alg_mod.x90 | 59 +- ...adjt_semi_implicit_solver_step_alg_mod.x90 | 56 +- .../timestepping/atlt_si_timestep_alg_mod.x90 | 48 +- .../driver/adjoint_test_parameters_mod.F90 | 12 +- rose-stem/app/adjoint_tests/file/iodef.xml | 66 +- .../adjoint_tests/opt/rose-app-C12_MG.conf | 8 + .../adjoint_tests/opt/rose-app-default.conf | 3 + .../opt/rose-app-nwp_gal9_c12.conf | 20 + .../opt/rose-app-rrt_equals_dt.conf | 2 + .../opt/rose-app-strict_solver.conf | 15 + .../opt/rose-app-suite_controlled.conf | 2 +- rose-stem/app/adjoint_tests/rose-app.conf | 1034 +++++++++-------- .../adjoint_tests/tasks_adjoint_tests.cylc | 20 +- .../meto/groups/groups_adjoint_tests.cylc | 10 +- .../adj_semi_implicit_solver_alg_mod.x90 | 28 +- 21 files changed, 804 insertions(+), 963 deletions(-) delete mode 100644 applications/adjoint_tests/example/C12.nml delete mode 100644 applications/adjoint_tests/example/mesh_C12.nc create mode 100644 rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf create mode 100644 rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf create mode 100644 rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf create mode 100644 rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf diff --git a/applications/adjoint_tests/example/C12.nml b/applications/adjoint_tests/example/C12.nml deleted file mode 100644 index d609be41..00000000 --- a/applications/adjoint_tests/example/C12.nml +++ /dev/null @@ -1,53 +0,0 @@ -!-------------------------------------------------------------------- -! Example namelists for mesh generation -!-------------------------------------------------------------------- -! These example namelists will result in the mesh generators -! producing an output file () which will -! contain mesh topologies which are identified by -! the by . -! -! Additional intergrid mappings may be produced and included -! in the output file. Each map is specified by an item in the -! list. Maps are specified by a string of the two -! mesh names spearated by a ":". Each item will cause a -! map to be added to the maps source mesh, i.e. -! -! 'dynamics:physics' will result in a map added to the -! -! * "dynamics" mesh (source) object mapping to "physics" (target) -! * "physics" mesh (source) object mapping to "dynamics" (target) -! -! Notes: -! * Only the first "n_meshes" listed in mesh_names will be -! output in the mesh file. -! * All spherical co-ordinates are given the order -! [longitude, latitude] in the units, degrees_east, degrees_north -! respectively -!=================================================================== -&mesh - mesh_file_prefix = 'mesh_C12' - geometry = 'spherical' - topology = 'periodic' - n_meshes = 1 - mesh_names = 'C12' - partition_mesh = .false. - coord_sys = 'll' - rotate_mesh = .false. -/ - -!================================================================== -! Cubedsphere Meshes: Only used by the Cubedsphere mesh generator -!================================================================== -! Each cubesphere mesh is specified by the corresponding number of -! cells on a panel edge. These are listed in the variable -! and correspond to the order of names given by . -! -! Any smoothing iterations specified will be applied to all meshes -! requested. Smoothing is experimental (especially with regards to -! intergrid mesh maps) is advised to be left as 0 for general use. - -&cubedsphere_mesh - edge_cells = 12 - equatorial_latitude = 0.0 - smooth_passes = 0 -/ diff --git a/applications/adjoint_tests/example/iodef.xml b/applications/adjoint_tests/example/iodef.xml index 8d0934e6..8591084d 100644 --- a/applications/adjoint_tests/example/iodef.xml +++ b/applications/adjoint_tests/example/iodef.xml @@ -3,7 +3,6 @@ - @@ -11,10 +10,9 @@ - + - @@ -68,26 +66,28 @@ - + + + - - - - - - + + + + + + @@ -102,14 +102,19 @@ - - - - - - - - + + + + + + + + + + + + + @@ -123,6 +128,9 @@ + + + @@ -144,6 +152,15 @@ + + + + + + + + + processed__tot_col_uv_kinetic_energy + processed__tot_col_w_kinetic_energy @@ -171,39 +188,36 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - @@ -240,44 +254,24 @@ - + - + + - - - - - - + + - - - - - - - - - - - - - - - - - @@ -285,72 +279,55 @@ - - - - - + - - - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/applications/adjoint_tests/example/mesh_C12.nc b/applications/adjoint_tests/example/mesh_C12.nc deleted file mode 100644 index f7ea6988e22a06194aac0d17b6e3be62cd539773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85708 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 Rwf*lmDjqBQ-|O@_{yzW$Qgi?S diff --git a/applications/adjoint_tests/source/adjoint_tests.f90 b/applications/adjoint_tests/source/adjoint_tests.f90 index 5fa5b223..f8435fd9 100644 --- a/applications/adjoint_tests/source/adjoint_tests.f90 +++ b/applications/adjoint_tests/source/adjoint_tests.f90 @@ -15,6 +15,7 @@ program adjoint_tests use driver_comm_mod, only : init_comm, final_comm use driver_config_mod, only : init_config, final_config use driver_log_mod, only : init_logger, final_logger + use driver_timer_mod, only : init_timers, final_timers use driver_time_mod, only : init_time, final_time use gungho_mod, only : gungho_required_namelists use driver_modeldb_mod, only : modeldb_type @@ -61,6 +62,7 @@ program adjoint_tests call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) + call init_timers( application_name ) call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -78,6 +80,7 @@ program adjoint_tests call final_time( modeldb ) call final_collections() call final_logger( application_name ) + call final_timers( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 index 7a456093..cf4d79ec 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 @@ -29,24 +29,13 @@ module adjt_mixed_schur_preconditioner_alg_mod use copy_field_alg_mod, only: copy_field use driver_modeldb_mod, only: modeldb_type use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_preconditioner_mod, only: abstract_preconditioner_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use semi_implicit_solver_alg_mod, only: create_pressure_preconditioner, & @@ -86,25 +75,18 @@ contains type(r_solver_field_type), dimension(bundle_size) :: rhs_rsol ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time ! Solver type(pressure_operator_type) :: pressure_operator @@ -166,52 +148,17 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke( name="adjt_msp_itr", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - ! Overwrite ls_u with randoms on [0,1] - call invoke( setval_random(ls_u), & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End of LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) @@ -219,7 +166,7 @@ contains call create_mixed_preconditioner( rhs, pressure_solver, mixed_preconditioner ) adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 index 67317630..48c05049 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 @@ -34,27 +34,16 @@ module adjt_mixed_solver_alg_mod use driver_modeldb_mod, only: modeldb_type use solver_constants_mod, only: get_normalisation use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use operator_mod, only: operator_type use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_iterative_solver_mod, only: abstract_iterative_solver_type, & bicgstab_type, & block_gcr_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use sci_preconditioner_mod, only: abstract_preconditioner_type use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type @@ -99,22 +88,15 @@ contains ! LS - type(field_type) :: ls_rdef(bundle_size) - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. - real(kind=r_def) :: initial_time - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr @@ -195,51 +177,17 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke(initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test )) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke(enforce_bc_kernel_type(ls_u)) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - call invoke(enforce_bc_kernel_type(ls_rdef(igh_u))) - - ! End LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) @@ -248,7 +196,7 @@ contains call create_mixed_solver( mixed_preconditioner, mixed_operator, mixed_solver ) adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) call create_adj_mixed_solver( adj_mixed_preconditioner, adj_mixed_operator, adj_mixed_solver ) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 index 225e7610..e0e4bba8 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 @@ -27,24 +27,13 @@ module adjt_pressure_precon_alg_mod use copy_field_alg_mod, only: copy_field use driver_modeldb_mod, only: modeldb_type use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_preconditioner_mod, only: abstract_preconditioner_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use semi_implicit_solver_alg_mod, only: create_pressure_preconditioner @@ -80,25 +69,18 @@ contains type(r_solver_field_type), dimension(bundle_size) :: rhs_rsol ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time ! Solver type(pressure_operator_type) :: pressure_operator @@ -155,56 +137,23 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - call invoke( name="adjt_msp_itr", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - ! Overwrite ls_u with randoms on [0,1] - call invoke( setval_random(ls_u), & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End of LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) ! Size = 1 as only P field needed vector_x = r_solver_field_vector_type(1_i_def) @@ -276,7 +225,7 @@ contains deallocate( pressure_preconditioner, adj_pressure_preconditioner ) - if (subroutine_timers) call timer('adjt_pressure_preconditioner_alg') + if (subroutine_timers) call timer('adjt_pressure_precon_alg') end subroutine adjt_pressure_precon_alg diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 index 6672c772..de7d4940 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 @@ -32,18 +32,8 @@ module adjt_semi_implicit_solver_step_alg_mod use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg implicit none @@ -79,16 +69,12 @@ contains type(field_type), dimension(nummr) :: mr_in ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. @@ -96,9 +82,6 @@ contains type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time integer(kind=i_def) :: i if (subroutine_timers) call timer('adjt_semi_implicit_solver_step_alg') @@ -157,52 +140,17 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke( name="adjt_siss_3", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke( name="adjt_siss_4", & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( name="adjt_siss_5", & - setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call adj_semi_implicit_solver%initialise(rhs) diff --git a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 index d7e6cfe0..10022e7b 100644 --- a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 @@ -23,7 +23,6 @@ module atlt_si_timestep_alg_mod use io_config_mod, only: subroutine_timers use derived_config_mod, only: bundle_size use fs_continuity_mod, only: Wtheta, W2, W3 - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use field_mod, only: field_type use field_collection_mod, only: field_collection_type use mesh_mod, only: mesh_type @@ -38,18 +37,7 @@ module atlt_si_timestep_alg_mod use driver_modeldb_mod, only: modeldb_type use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar - use check_configuration_mod, only: check_any_shifted - use timestepping_config_mod, only: dt implicit none @@ -81,7 +69,6 @@ contains type(field_collection_type), pointer :: derived_fields ! LS - type(field_type) :: ls_rdef(bundle_size) type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta @@ -97,9 +84,6 @@ contains type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time integer(kind=i_def) :: i type(atl_si_timestep_type) :: atl_si_timestep @@ -128,7 +112,7 @@ contains vector_space_w2_ptr => function_space_collection%get_fs( mesh, element_order_h, element_order_v, W2 ) vector_space_w3_ptr => function_space_collection%get_fs( mesh, element_order_h, element_order_v, W3 ) - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) call ls_fields%get_field( 'ls_u', ls_u ) @@ -141,34 +125,6 @@ contains ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u, initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - call invoke(initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test )) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke( enforce_bc_kernel_type(ls_u) ) - - call ls_u%copy_field_properties(ls_rdef(igh_u)) - call ls_theta%copy_field_properties(ls_rdef(igh_t)) - call ls_rho%copy_field_properties(ls_rdef(igh_d)) - call ls_exner%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x(ls_rdef(igh_u), ls_u), & - setval_x(ls_rdef(igh_t), ls_theta), & - setval_x(ls_rdef(igh_p), ls_exner), & - setval_x(ls_rdef(igh_d), ls_rho) ) - ! End LS - ! Set up moist_dyn & mr do i = 1, num_moist_factors @@ -230,7 +186,7 @@ contains ls_u, ls_rho, ls_theta, ls_exner, & ls_mr, ls_moist_dyn, (num_steps == 1) ) - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & modeldb%clock, ls_moist_dyn ) do i = 1, num_steps diff --git a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 index 09f74b4c..f4f06ea0 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 @@ -28,12 +28,12 @@ module adjoint_test_parameters_mod ! if the ls is not realistic. ls can still be ! randomly assigned, but in a sensible range ! to prevent these issues. - real(r_def), dimension(2), parameter :: ls_u_range = (/ 0.0_r_def, 10.0_r_def /) + real(r_def), dimension(2), parameter :: ls_u_range = (/ 0.1_r_def, 10.0_r_def /) real(r_def), dimension(2), parameter :: ls_theta_range = (/ 280.0_r_def, 340.0_r_def /) - real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.1_r_def, 1.0_r_def /) end module adjoint_test_parameters_mod diff --git a/rose-stem/app/adjoint_tests/file/iodef.xml b/rose-stem/app/adjoint_tests/file/iodef.xml index ab572277..8591084d 100644 --- a/rose-stem/app/adjoint_tests/file/iodef.xml +++ b/rose-stem/app/adjoint_tests/file/iodef.xml @@ -10,7 +10,7 @@ - + @@ -70,6 +70,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -88,13 +108,13 @@ - - - - - - - + + + + + + + @@ -120,6 +140,27 @@ + + + + + + + + + + + + + + + + + + + + + processed__tot_col_uv_kinetic_energy + processed__tot_col_w_kinetic_energy @@ -225,6 +266,8 @@ + + @@ -279,8 +322,11 @@ - - + + + + + diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 00000000..125a4758 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-default.conf b/rose-stem/app/adjoint_tests/opt/rose-app-default.conf index e69de29b..dba82763 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-default.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-default.conf @@ -0,0 +1,3 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/adjoint_tests/file/iodef.xml diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 00000000..4b375741 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,20 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +ls_filename='final_ls' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2016-01-01 15:00:00' +calendar_start='2016-01-01 15:00:00' diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 00000000..3d974564 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf b/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf new file mode 100644 index 00000000..77270e0f --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf @@ -0,0 +1,15 @@ +[namelist:helmholtz_solver] +gcrk=18 +si_pressure_a_tol=0 +si_pressure_tolerance=1.0e-15 + +[namelist:mixed_solver] +fail_on_non_converged=.false. +gcrk=10 +mixed_solver_a_tol=1.0e-21 +si_maximum_iterations=100 +si_tolerance=1.0e-21 + +[namelist:solver] +maximum_iterations=50 +tolerance=1.0e-18 diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf b/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf index cada49b4..81be8308 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf @@ -18,7 +18,7 @@ checkpoint_read=${RESTART_READ} checkpoint_times= checkpoint_write=${RESTART_WRITE} end_of_run_checkpoint=.true. -!!nodal_output_on_w3=${NODAL_OUTPUT_ON_W3} +nodal_output_on_w3=${NODAL_OUTPUT_ON_W3} use_xios_io=${USE_XIOS_IO} [namelist:logging] diff --git a/rose-stem/app/adjoint_tests/rose-app.conf b/rose-stem/app/adjoint_tests/rose-app.conf index 76c5b014..881bff89 100644 --- a/rose-stem/app/adjoint_tests/rose-app.conf +++ b/rose-stem/app/adjoint_tests/rose-app.conf @@ -5,7 +5,7 @@ default=$LAUNCH_SCRIPT/launch-exe [env] ENSEMBLE_MEMBER=0 -EXEC_NAME=adjoint_test +EXEC_NAME=adjoint_tests OMP_NUM_THREADS=1 TOTAL_RANKS=1 XIOS_SERVER_MODE=True @@ -16,13 +16,19 @@ mode=mkdir [file:configuration.nml] mode=auto -source=namelist:base_mesh +source=(namelist:aerosol) + = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -33,6 +39,7 @@ source=namelist:base_mesh = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -43,26 +50,43 @@ source=namelist:base_mesh = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_nvegparm) + = (namelist:jules_pftparm) + = (namelist:jules_radiation) + = (namelist:jules_sea_seaice) + = (namelist:jules_soil) + = (namelist:jules_snow) + = (namelist:jules_surface) + = (namelist:jules_surface_types) + = (namelist:jules_urban) + = (namelist:jules_vegetation) = namelist:linear = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver + = (namelist:specified_surface) + = (namelist:star) + = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -84,25 +108,25 @@ source=namelist:base_mesh easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. -!!emissions='GC3' -glomap_mode='off' +!!emissions='GC5' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. -!!murk_source_scaling=0 +!!murk_source_scaling=1.0 !!murk_visibility=.false. -!!n_radaer_step=0 -!!prec_file='' -sulphuric_strat_climatology=.false. -!!sulphuric_strat_column=0 +!!n_radaer_step=1 +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. +!!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -110,65 +134,66 @@ prime_mesh_name='dynamics' topology='fully_periodic' [!!namelist:blayer] -a_ent_2=0 -a_ent_shr=0 +a_ent_2=0.056 +a_ent_shr=1.6 +bl_levels=50 bl_mix_w=.false. bl_res_inv='cosine_inv_flux' c_gust=4.0 -!!cbl_mix_fac=0 +!!cbl_mix_fac=0.0 cbl_opt='conventional' -dec_thres_cloud=0 +dec_thres_cloud=0.1 dec_thres_cu=0.05 -dyn_diag='zi_l_sea' +dyn_diag='zi_l_cu' dzrad_disc_opt='level_ntm1' entr_smooth_dec='on' flux_bc_opt='interactive' free_atm_mix='to_sharp' -fric_heating=.false. -interp_local='gradients' +fric_heating=.true. +interp_local='cf_dbdz' kprof_cu='buoy_integ' l_converge_ga=.false. l_use_sml_dsc_fixes=.false. -near_neut_z_on_l=0 -new_kcloudtop=.false. +near_neut_z_on_l=1.6 +new_kcloudtop=.true. ng_stress='BG97_limited' noice_in_turb=.false. num_sweeps_bflux=3 -p_unstable=0 -reduce_fa_mix='inv_and_cu_lcl' -sbl_opt='sharpest' +p_unstable=1.0 +reduce_fa_mix='inv_only' +sbl_opt='sharp_sea_mes_land' sc_diag_opt='orig' sg_orog_mixing='none' -!!zhloc_depth_fac=0 +!!zhloc_depth_fac=0.4 [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' +!!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=.false. -!!outer_width_ew=0 -!!outer_width_ns=0 +!!normal_only=.true. +!!outer_width_ew=1 +!!outer_width_ns=1 !!output_lbcs=.false. -!!rim_width_ew=0 -!!rim_width_ns=0 -!!solver_boundary_depth=0 -!!transport_boundary_depth=0 -transport_overwrite_freq='split_step' +!!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. -!!max_cfl=0 +!!max_cfl=0.75 [!!namelist:chemistry] chem_scheme='none' @@ -184,58 +209,58 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] -!!cff_spread_rate=0 -cld_fsd_hill=.false. +!!cff_spread_rate=1.0e-5 +cld_fsd_hill=.true. cloud_call_b4_conv=.false. !!cloud_horizontal_ice_fsd=0.0 -!!cloud_horizontal_liq_fsd=0 +!!cloud_horizontal_liq_fsd=0.75 cloud_pc2_tol=0.005 cloud_pc2_tol_2=0.001 !!dbsdtbs_turb_0=1.5E-4 !!ent_coef_bm=0.2 -!!ez_max=0 -falliceshear_method='constant' -filter_optical_depth=.false. +!!ez_max=400.0 +falliceshear_method='real' +filter_optical_depth=.true. !!fsd_conv_const=2.81 !!fsd_min_conv_frac=0.0 !!fsd_nonconv_ice_const=1.14 !!fsd_nonconv_liq_const=1.14 -!!i_bm_ez_opt='orig' +!!i_bm_ez_opt='subcrit' !!i_pc2_erosion_numerics='implicit' -!!ice_width=0 +!!ice_width=0.02 !!l_bm_sigma_s_grad=.false. !!l_bm_tweaks=.false. !!max_sigmas=3.0 !!min_sigx_ft=0.0 !!mphys_erosion=.false. -!!opt_depth_thresh=0 +!!opt_depth_thresh=0.01 pc2_init_logic='original' -pc2ini='smith' -rh_crit=0 -rh_crit_opt='namelist' -scheme='smith' -subgrid_qv=.false. +pc2ini='bimodal' +rh_crit=0.920,0.918,0.916,0.912,0.908,0.903,64*0.9 +rh_crit_opt='tke' +scheme='pc2' +subgrid_qv=.true. !!turb_var_fac_bm=1.0 -two_d_fsd_factor=0 -use_fsd_eff_res=.false. +two_d_fsd_factor=1.65 +use_fsd_eff_res=.true. [namelist:convection] -!!cape_timescale=0 +!!cape_timescale=1800.0 !!cv_scheme='gregory_rowntree' dx_ref=50000.0 !!efrac=1.0 l_cvdiag_ctop_qmax=.false. -!!number_of_convection_substeps=0 +!!number_of_convection_substeps=2 !!orig_mdet_fac=1.0 !!par_gen_mass_fac=0.25 !!par_gen_rhpert=0.05 @@ -246,10 +271,10 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. -!!n_subcol_gen=0 +!!n_subcol_gen=64 [namelist:damping_layer] -dl_base=10000.0 +dl_base=40000.0 dl_str=0.05 dl_type='standard' @@ -265,15 +290,15 @@ vertical_sorting=.false. [namelist:energy_correction] encorr_usage='none' integral_method='fd' -!!reset_hours=0 +!!reset_hours=24 [namelist:esm_couple] l_esm_couple_test=.false. [!!namelist:external_forcing] -!!diffusion_coefficient=0 -!!diffusion_order=0 -!!filtering_order=0 +!!diffusion_coefficient=0.05 +!!diffusion_order=1 +!!filtering_order=1 geostrophic_forcing=.false. !!hs_random=.false. !!pc2_force_response=.false. @@ -284,22 +309,23 @@ vertadvect_forcing=.false. wind_forcing='none' [namelist:extrusion] -domain_height=10000.0 +domain_height=80000.0 !!eta_values='' -method='uniform' -number_of_layers=5 +method='um_L70_50t_20s_80km' +number_of_layers=70 planet_radius=6371229.0 -stretching_method='linear' +stretching_height=17507.0 +stretching_method='smooth' [namelist:files] !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' -checkpoint_stem_name='' +checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -!!diag_stem_name='diagGungho' +diag_stem_name='diagGungho' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -350,8 +376,8 @@ checkpoint_stem_name='' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -!!ls_directory='' -!!ls_filename='' +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' @@ -366,8 +392,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='' -start_dump_filename='' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -388,7 +414,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -398,7 +424,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -412,16 +438,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 -!!jacobi_relaxation=0 -method='bicgstab' -monitor_convergence=.true. +!!fail_on_non_converged=.false. +gcrk=8 +!!jacobi_relaxation=0.5 +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 si_pressure_maximum_iterations=400 -si_pressure_tolerance=1.0e-15 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -431,7 +457,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -460,71 +486,71 @@ si_pressure_tolerance=1.0e-15 !!start_time=0 [namelist:ideal_surface] -canopy_height=0 -leaf_area_index=0 -n_snow_layers=0 -snow_depth=0 -snow_layer_ice_mass=0 -snow_layer_temp=0 -snow_layer_thickness=0 -soil_moisture=0 -soil_temperature=0 -surf_tile_fracs=0 -surf_tile_temps=0 -tile_snow_mass=0 +canopy_height=19.01,16.38,0.79,1.26,1.0 +leaf_area_index=5.0,4.0,1.5,1.5,1.5 +n_snow_layers=11*0 +snow_depth=11*0.0 +snow_layer_ice_mass=27*0.0 +snow_layer_temp=27*273.0 +snow_layer_thickness=27*0.0 +soil_moisture=15.86,98.861,274.35,862.27 +soil_temperature=284.508,286.537,289.512,293.066 +surf_tile_fracs=9*0.0,1.0,0.0 +surf_tile_temps=9*295.0,300.0,265.0 +tile_snow_mass=11*0.0 [namelist:idealised] -f_lon_deg=0 +f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 z2=0.0 [namelist:initial_pressure] -method='sampled' +method='balanced' surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=0 -!!profile_heights=0 -!!profile_size=0 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0 -!!profile_heights=0 -!!profile_size=0 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='sbr_with_vertical' -!!profile_data_u=0 -!!profile_data_v=0 -!!profile_data_w=0 -!!profile_heights_uv=0 -!!profile_heights_w=0 -!!profile_size_uv=0 -!!profile_size_w=0 +profile='constant_uv' +!!profile_data_u=0.0 +!!profile_data_v=0.0 +!!profile_data_w=0.0 +!!profile_heights_uv=0.0 +!!profile_heights_w=0.0 +!!profile_size_uv=1 +!!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -533,12 +559,12 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='analytic' +init_option='fd_start_dump' lbc_option='none' -ls_option='analytic' -!!model_eos_height=100 +ls_option='file' +model_eos_height=100 n_orog_smooth=0 -read_w2h_wind=.false. +read_w2h_wind=.true. sea_ice_source='ancillary' snow_source='start_dump' !!sst_source='ancillary' @@ -552,7 +578,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -!!diagnostic_frequency=1 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -562,113 +588,125 @@ subroutine_timers=.true. timer_output_path='timer.txt' use_xios_io=.true. write_conservation_diag=.false. -write_diag=.false. +write_diag=.true. write_dump=.false. write_fluxes=.false. -!!write_minmax_tseries=.false. +write_minmax_tseries=.false. [!!namelist:jules_hydrology] -l_hydrology=.false. -!!l_var_rainfrac=.false. +l_hydrology=.true. +!!l_var_rainfrac=.true. [!!namelist:jules_nvegparm] -albsnc_nvg_io=0 -albsnf_nvg_io=0 -!!albsnf_nvgl_io=0 -!!albsnf_nvgu_io=0 -catch_nvg_io=0 -ch_nvg_io=0 -emis_nvg_io=0 -gs_nvg_io=0 -infil_nvg_io=0 -vf_nvg_io=0 -z0_nvg_io=0 -z0hm_nvg_io=0 +albsnc_nvg_io=0.4,0.8,0.8,0.8 +albsnf_nvg_io=0.18,0.12,-1.0,0.75 +!!albsnf_nvgl_io=0.05,0.06,0.03,0.75 +!!albsnf_nvgu_io=0.20,0.15,0.80,0.75 +catch_nvg_io=0.5,0.0,0.0,0.0 +ch_nvg_io=2.8e5,2.11e7,0.0,0.0 +emis_nvg_io=0.970,0.985,0.900,0.990 +gs_nvg_io=0.0,0.0,1.0e-2,1.0e+6 +infil_nvg_io=0.1,0.0,0.5,0.0 +vf_nvg_io=1.0,1.0,0.0,0.0 +z0_nvg_io=1.0,1.0e-4,1.0e-3,5.0e-4 +z0hm_nvg_io=1.0e-7,2.5e-1,2.0e-1,2.0e-1 [!!namelist:jules_pftparm] -albsnc_max_io=0 -alnir_io=0 -alpar_io=0 +albsnc_max_io=2.5e-1,2.5e-1,6.0e-1,6.0e-1,4.0e-1 +alnir_io=0.341,0.272,0.369,0.368,0.395 +alpar_io=0.057,0.041,0.071,0.083,0.074 catch0_io=5*0.5 dcatch_dlai_io=5*0.05 -fsmc_p0_io=0 -kext_io=0 -knl_io=0 -omega_io=0 -omnir_io=0 -z0hm_pft_io=0 -!!z0v_io=0 +fsmc_p0_io=5*0.6 +kext_io=0.5,0.5,1.0,1.0,0.5 +knl_io=5*0.2 +omega_io=0.101,0.083,0.132,0.135,0.115 +omnir_io=0.788,0.545,0.864,0.787,0.785 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 +!!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] -!!fixed_sea_albedo=0 -i_sea_alb_method='barker' +!!fixed_sea_albedo=0.06 +i_sea_alb_method='jin' l_albedo_obs=.false. -l_hapke_soil=.false. -!!l_niso_direct=.false. -l_partition_albsoil=.false. -!!l_sea_alb_var_chl=.false. +l_hapke_soil=.true. +!!l_niso_direct=.true. +l_partition_albsoil=.true. +!!l_sea_alb_var_chl=.true. l_spec_alb_bs=.false. -!!ratio_albsoil=0 -!!swdn_frac_albsoil=0 +!!ratio_albsoil=2.0 +!!swdn_frac_albsoil=0.5 [!!namelist:jules_sea_seaice] -alpham=0 +alpham=0.72 amip_ice_thick=.false. -beta_evap=0 -buddy_sea='Off' -!!cdn_hw_sea=0 -!!cdn_max_sea=0 -dtice=0 -emis_sea=0 -emis_sice=0 -i_high_wind_drag='null' -iseasurfalg='specified_roughness' -l_10m_neut=.false. -l_iceformdrag_lupkes=.false. -l_sice_heatflux=.false. -!!l_stability_lupkes=.false. +beta_evap=1.0 +buddy_sea='On' +!!cdn_hw_sea=0.002 +!!cdn_max_sea=0.003 +dtice=2.0 +emis_sea=0.985 +emis_sice=0.976 +!!hcap_sea=2.0e6 +i_high_wind_drag='reduced_v1' +iseasurfalg='coare' +kappa_seasurf=0.5 +kappai=2.09 +kappai_snow=0.256 +l_10m_neut=.true. +l_iceformdrag_lupkes=.true. +l_sice_heatflux=.true. +!!l_stability_lupkes=.true. l_use_dtstar_sea=.false. -nice=0 -!!u_cdn_hw=0 -!!u_cdn_max=0 -!!z0h_specified=0 -!!z0m_specified=0 +nice=1 +!!u_cdn_hw=55.0 +!!u_cdn_max=33.0 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] -can_clump=0 -cansnowpft=.false. -i_basal_melting_opt='none' -i_grain_growth_opt='marshall' -i_relayer_opt='original' -n_lai_exposed=0 -unload_rate_u=0 +can_clump=8.0,4.0,1.0,1.0,1.0 +cansnowpft=.true.,.true.,.false.,.false.,.false. +i_basal_melting_opt='instant' +i_grain_growth_opt='taillandier' +i_relayer_opt='inverse' +n_lai_exposed=5*1.0 +rho_snow_fresh=109.0 +unload_rate_u=2.31e-6,2.31e-6,0.0,0.0,0.0 [!!namelist:jules_soil] -l_dpsids_dsdz=.false. -l_soil_sat_down=.false. +l_dpsids_dsdz=.true. +l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' -cor_mo_iter='lim_oblen' +cor_mo_iter='improved' !!fd_stability_dep='none' -formdrag='none' +formdrag='dist_drag' l_anthrop_heat_src=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. -srf_ex_cnv_gust=.false. +l_vary_z0m_soil=.true. +srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] -nnvg=0 -npft=0 -soil=0 -!!urban=0 +brd_leaf=1 +c3_grass=3 +c4_grass=4 +ice=9 +lake=7 +ndl_leaf=2 +nnvg=4 +npft=5 +shrub=5 +soil=8 +!!urban=6 !!urban_canyon=0 !!urban_roof=0 [!!namelist:jules_urban] -!!anthrop_heat_scale=0 +!!anthrop_heat_scale=1.0 l_moruses_albedo=.false. l_moruses_emissivity=.false. l_moruses_rough=.false. @@ -676,29 +714,31 @@ l_moruses_storage=.false. !!l_moruses_storage_thin=.false. [!!namelist:jules_vegetation] -can_rad_mod='one' -l_limit_canhc=.false. -l_spec_veg_z0=.false. +can_rad_mod='six' +l_limit_canhc=.true. +l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.false. +l_stabilise_bl=.true. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' [namelist:logging] log_to_rank_zero_only=.false. run_log_level='info' [!!namelist:microphysics] -!!a_ratio_exp=0 -!!a_ratio_fac=0 +!!a_ratio_exp=-0.2707 +!!a_ratio_fac=0.0517 !!c_r_correl=0.9 !!casim_cdnc_opt='fixed' ci_input=14.3 cic_input=1024.0 droplet_tpr=.false. -!!fcrit=0 +!!fcrit=1.0 !!graupel_scheme='none' heavy_rain_evap_fac=0.0 !!i_update_precfrac='homog' @@ -706,78 +746,96 @@ heavy_rain_evap_fac=0.0 !!l_proc_fluxes=.false. microphysics_casim=.false. !!mp_dz_scal=2.0 -!!ndrop_surf=0 -!!nscalesf=0 -!!nsigmasf=0 -!!orog_block=.false. -!!orog_rain=.false. -!!orog_rime=.false. -!!prog_tnuc=.false. -!!qcl_rime=0 -!!shape_rime=.false. -turb_gen_mixph=.false. -!!z_surf=0 +!!ndrop_surf=50.0e6 +!!nscalesf=1.0 +!!nsigmasf=2.82843 +!!orog_block=.true. +!!orog_rain=.true. +!!orog_rime=.true. +!!prog_tnuc=.true. +!!qcl_rime=1.0e-4 +!!shape_rime=.true. +turb_gen_mixph=.true. +!!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. -!!jacobi_relaxation=0 -mixed_solver_a_tol=1.0e-21 +!!jacobi_relaxation=0.5 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] -!!leonard_kl=0 +!!leonard_kl=2.0 leonard_term=.false. -!!method='3d_smag' -!!mix_factor=0 +!!method='blend_1dbl_fa' +!!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='' -multigrid_chain_nitems=0 +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' +multigrid_chain_nitems=4 +n_coarsesmooth=4 +n_postsmooth=2 +n_presmooth=2 +smooth_relaxation=0.8 + +[!!namelist:multires_coupling] +aerosol_mesh_name='aerosol' +coarse_aerosol_transport=.false. +coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] -!!arg_periapsis=0 -!!arg_periapsis_inc=0 -!!eccentricity=0 -!!eccentricity_inc=0 -elements='user' -!!epoch=0 -!!fixed_azimuth_angle=0 -!!fixed_zenith_angle=0 -!!hour_angle=0 -!!hour_angle_inc=0 -!!mean_anomaly=0 -!!mean_anomaly_inc=0 -!!obliquity=0 -!!obliquity_inc=0 -observer_lat=0 -observer_lon=0 -!!semimajor_axis=0 -!!semimajor_axis_inc=0 -spin='user' +!!arg_periapsis=1.796767421 +!!arg_periapsis_inc=0.0 +!!eccentricity=1.6710222E-02 +!!eccentricity_inc=0.0 +elements='earth_fixed' +!!epoch=2451545.0 +!!fixed_azimuth_angle=0.0 +!!fixed_zenith_angle=0.0 +!!hour_angle=0.0 +!!hour_angle_inc=0.0 +!!mean_anomaly=-0.037278428 +!!mean_anomaly_inc=0.01720278179 +!!obliquity=0.0 +!!obliquity_inc=0.0 +observer_lat=0.0 +observer_lon=0.0 +!!semimajor_axis=1.0 +!!semimajor_axis_inc=0.0 +spin='earth_day' [!!namelist:orographic_drag] -cd_flow_blocking=0 -fr_crit_gwd=0 -fr_sat_gwd=0 -gwd_scaling=0 -mountain_height_scaling=0 -orographic_blocking_heating=.false. -orographic_gwd_heating=.false. -vertical_smoothing=.false. +cd_flow_blocking=4.0 +fr_crit_gwd=4.0 +fr_sat_gwd=0.25 +gwd_scaling=0.7 +include_moisture='lowmoist' +mountain_height_scaling=2.6 +orographic_blocking_heating=.true. +orographic_gwd_heating=.true. +vertical_smoothing=.true. [namelist:orography] orog_init_option='ancil' @@ -785,62 +843,62 @@ orog_init_option='ancil' [!!namelist:orography_agnesi_cartesian] direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -x_centre=0 -y_centre=0 +half_width_x=10.0 +half_width_y=10.0 +mountain_height=100.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_agnesi_spherical] -half_width=0 -lambda_centre_dec=0 -lambda_focus_dec=0 -mountain_height=0 -phi_centre_dec=0 -phi_focus_dec=0 +half_width=2500.0 +lambda_centre_dec=1.5 +lambda_focus_dec=1.5 +mountain_height=100.0 +phi_centre_dec=0.0 +phi_focus_dec=0.3333 [!!namelist:orography_bell_cartesian] -direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -x_centre=0 -y_centre=0 +direction='xy' +half_width_x=1000.0 +half_width_y=1000.0 +mountain_height=400.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_bell_spherical] -lambda_centre1=0 -lambda_centre2=0 -mountain_height=0 -phi_centre1=0 -phi_centre2=0 -radius_lat=0 -radius_lon=0 +lambda_centre1=0.0 +lambda_centre2=0.0 +mountain_height=100.0 +phi_centre1=0.0 +phi_centre2=0.0 +radius_lat=10.0 +radius_lon=10.0 [!!namelist:orography_dcmip200_spherical] -lambda_centre_dec=0 -mountain_height=0 -osc_half_width_dec=0 -phi_centre_dec=0 -radius_dec=0 +lambda_centre_dec=1.5 +mountain_height=2000.0 +osc_half_width_dec=0.0625 +phi_centre_dec=0.0 +radius_dec=0.75 [!!namelist:orography_schar_cartesian] direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -wavelength=0 -x_centre=0 -y_centre=0 +half_width_x=20.0 +half_width_y=20.0 +mountain_height=250.0 +wavelength=20.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_schar_spherical] -half_width=0 -lambda_centre_dec=0 -mountain_height=0 -phi_centre_dec=0 -wavelength=0 +half_width=5000.0 +lambda_centre_dec=0.25 +mountain_height=250.0 +phi_centre_dec=0.0 +wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 @@ -854,15 +912,16 @@ configure_segments=.false. !!electric_placement='slow' !!evap_condense_placement='fast' !!gw_segment=0 -!!limit_drag_incs=.false. -!!lowest_level='constant' +limit_drag_incs=.false. +!!lowest_level='gradient' !!ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.false. -!!sample_physics_winds=.false. -!!smagorinsky_placement='fast' +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. +!!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' !!ussp_segment=0 @@ -877,58 +936,40 @@ scaling_factor=1.0 [!!namelist:radiation] !!cloud_entrapment='zero' -!!cloud_inhomogeneity='homogeneous' -!!cloud_overlap='maximum_random' -cloud_representation='no_cloud' -!!cloud_vertical_decorr=0 -!!constant_droplet_effective_radius=0 -!!droplet_effective_radius='default' -i_cloud_ice_type_lw=0 -!!i_cloud_ice_type_lwinc=0 -i_cloud_ice_type_sw=0 -!!i_cloud_ice_type_swinc=0 -i_cloud_liq_type_lw=0 -!!i_cloud_liq_type_lwinc=0 -i_cloud_liq_type_sw=0 -!!i_cloud_liq_type_swinc=0 -l_cfc113_lw=.false. -l_cfc11_lw=.false. -l_cfc12_lw=.false. -l_ch4_lw=.false. -l_ch4_sw=.false. -l_co2_lw=.false. -l_co2_sw=.false. -l_continuum_lw=.false. -l_continuum_sw=.false. -l_h2o_lw=.false. -l_h2o_sw=.false. -l_hcfc22_lw=.false. -l_hfc134a_lw=.false. +!!cloud_inhomogeneity='mcica' +!!cloud_overlap='exponential_random' +cloud_representation='combined' +!!cloud_vertical_decorr=10000.0 +!!constant_droplet_effective_radius=7.0E-6 +!!droplet_effective_radius='liu' +i_cloud_ice_type_lw=11 +!!i_cloud_ice_type_lwinc=11 +i_cloud_ice_type_sw=11 +!!i_cloud_ice_type_swinc=11 +i_cloud_liq_type_lw=5 +!!i_cloud_liq_type_lwinc=5 +i_cloud_liq_type_sw=5 +!!i_cloud_liq_type_swinc=5 l_inc_radstep=.false. -l_n2o_lw=.false. -l_n2o_sw=.false. -l_o2_sw=.false. -l_o3_lw=.false. -l_o3_sw=.false. l_planet_grey_surface=.false. -l_rayleigh_sw=.false. -l_trans_zen_correction=.false. -!!liu_aparam=0 -!!liu_bparam=0 -mcica_data_file='' -!!n_horiz_ang=0 -!!n_horiz_layer=0 -!!n_inc_radstep=0 -n_radstep=0 -!!planet_albedo=0 -!!planet_emissivity=0 -scatter_method_lw='full' -!!scatter_method_lwinc='full' -spectral_file_lw='' -!!spectral_file_lwinc='' -spectral_file_sw='' -!!spectral_file_swinc='' -topography='flat' +l_rayleigh_sw=.true. +l_trans_zen_correction=.true. +!!liu_aparam=0.077 +!!liu_bparam=-0.1365 +mcica_data_file='spec/mcica_data' +!!n_horiz_ang=16 +!!n_horiz_layer=1 +!!n_inc_radstep=1 +n_radstep=2 +!!planet_albedo=0.06 +!!planet_emissivity=0.985 +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' +spectral_file_lw='spec/sp_lw_ga9' +!!spectral_file_lwinc='spec/sp_lw_cloud9' +spectral_file_sw='spec/sp_sw_ga9' +!!spectral_file_swinc='spec/sp_sw_cloud9' +topography='slope' [namelist:radiative_gases] !!cfc113_clim_fcg_levls=0 @@ -941,26 +982,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1032,8 +1073,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1050,8 +1091,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1060,7 +1101,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1087,10 +1128,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1098,58 +1139,58 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] !!fail_on_non_converged=.false. gcrk=18 -!!jacobi_relaxation=0 -maximum_iterations=50 +!!jacobi_relaxation=0.5 +maximum_iterations=7 method='chebyshev' monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] -!!function_amplitude_e=0 -!!function_amplitude_h=0 +!!function_amplitude_e=200 +!!function_amplitude_h=400 !!function_name_fluxes='constant' !!function_name_sst='constant' -!!function_period_e=0 -!!function_period_h=0 +!!function_period_e=300 +!!function_period_h=600 !!function_phase_e=0 !!function_phase_h=0 !!internal_flux_method='uniform' !!internal_flux_value=0.0 -!!length_of_day=0 -!!profile_size=0 -!!profile_size_sst=0 -!!sea_surf_temps=0 -!!specified_flux_e=0 -!!specified_flux_h=0 +!!length_of_day=10.0 +!!profile_size=1 +!!profile_size_sst=1 +!!sea_surf_temps=300.0 +!!specified_flux_e=300. +!!specified_flux_h=300. !!surf_temp_forcing='none' !!time_data=0 !!time_data_sst=0 -!!time_of_max_flux=0 +!!time_of_max_flux=15.0 !!time_units='seconds' !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=0 -ussp_heating=.false. -ussp_launch_factor=0 -wavelstar=0 +add_cgw=.true. +!!cgw_scale_factor=0.86 +ussp_heating=.true. +ussp_launch_factor=1.2 +wavelstar=4300.0 [!!namelist:star] -stellar_constant=0 -stellar_radius=0 +stellar_constant=1361.0 +stellar_radius=6.957e8 [!!namelist:stochastic_physics] !!blpert_add_vertical_shape=.true. @@ -1163,44 +1204,44 @@ stellar_radius=0 !!blpert_only_near_edge=.true. !!blpert_time_correlation=.true. blpert_type='off' -ens_memb=0 -!!rp_bl_a_ent_1=0 -!!rp_bl_a_ent_shr=0 -!!rp_bl_a_ent_shr_max=0 -!!rp_bl_cbl_mix_fac=0 -!!rp_bl_cld_top_diffusion=0 -!!rp_bl_min_mix_length=0 -!!rp_bl_neutral_mix_length=0 -!!rp_bl_ricrit=0 -!!rp_bl_smag_coef=0 -!!rp_bl_stable_ri_coef=0 -!!rp_callfreq=0 +ens_memb=${ENSEMBLE_MEMBER} +!!rp_bl_a_ent_1=0.100,0.230,0.400 +!!rp_bl_a_ent_shr=1.6 +!!rp_bl_a_ent_shr_max=5.0 +!!rp_bl_cbl_mix_fac=0.0,0.5,1.0 +!!rp_bl_cld_top_diffusion=0.500,0.850,1.500 +!!rp_bl_min_mix_length=8.0,40.0,120.0 +!!rp_bl_neutral_mix_length=0.03,0.15,0.45 +!!rp_bl_ricrit=0.25,1.0,2.0 +!!rp_bl_smag_coef=0.01,0.2,1.0 +!!rp_bl_stable_ri_coef=5.000,10.000,20.000 +!!rp_callfreq=300 !!rp_cycle_in=.false. !!rp_cycle_out=.false. -!!rp_cycle_tm=0 -!!rp_decorr_ts=0 -!!rp_lsfc_alnir= -!!rp_lsfc_alnir_max= -!!rp_lsfc_alnir_min= -!!rp_lsfc_alpar= -!!rp_lsfc_alpar_max= -!!rp_lsfc_alpar_min= -!!rp_lsfc_lai_mult=0 -!!rp_lsfc_lai_mult_max=0 -!!rp_lsfc_lai_mult_min=0 -!!rp_lsfc_omega= -!!rp_lsfc_omega_max= -!!rp_lsfc_omega_min= -!!rp_lsfc_omnir= -!!rp_lsfc_omnir_max= -!!rp_lsfc_omnir_min= +!!rp_cycle_tm=43200 +!!rp_decorr_ts=604800.0 +!!rp_lsfc_alnir=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alnir_max=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alnir_min=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alpar=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_alpar_max=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_alpar_min=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_lai_mult=5*1.0 +!!rp_lsfc_lai_mult_max=5*1.0 +!!rp_lsfc_lai_mult_min=5*1.0 +!!rp_lsfc_omega=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omega_max=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omega_min=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omnir=0.788,0.545,0.864,0.787,0.785 +!!rp_lsfc_omnir_max=0.788,0.545,0.864,0.787,0.785 +!!rp_lsfc_omnir_min=0.788,0.545,0.864,0.787,0.785 !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 -!!rp_lsfc_z0_soil=0,0,0 +!!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=0 -!!rp_lsfc_z0hm_pft_max=0 -!!rp_lsfc_z0hm_pft_min=0 -!!rp_lsfc_z0hm_soil=0,0,0 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= !!rp_lsfc_z0v_min= @@ -1208,44 +1249,44 @@ ens_memb=0 !!rp_mp_ice_fspd=6000000.0,6000000.0,6000000.0 !!rp_mp_mp_czero=10.0,10.0,10.0 !!rp_mp_mpof=0.5,0.5,0.5 -!!rp_mp_ndrop_surf=0 +!!rp_mp_ndrop_surf=2.0e+07,5.0e+07,10.0e+07 !!rp_mp_snow_fspd=12.0,12.0,12.0 -!!rp_ran_max=0 +!!rp_ran_max=30 !!skeb_add_increments=.false. -!!skeb_br=0 -!!skeb_convective_dissipation=.false. -!!skeb_convective_dissipation_factor=0 -!!skeb_convective_dissipation_modulation=.false. -!!skeb_decorrelation_time=0 -!!skeb_div_du='fd' -!!skeb_level_bottom=0 -!!skeb_level_bottom_cap=0 -!!skeb_level_top=0 -!!skeb_n_smoothing_iters=0 -!!skeb_numerical_dissipation='none' -!!skeb_numerical_dissipation_factor=0 +!!skeb_br=0.03 +!!skeb_convective_dissipation=.true. +!!skeb_convective_dissipation_factor=1.0 +!!skeb_convective_dissipation_modulation=.true. +!!skeb_decorrelation_time=2.00e+4 +!!skeb_div_du='fe' +!!skeb_level_bottom=2 +!!skeb_level_bottom_cap=2 +!!skeb_level_top=50 +!!skeb_n_smoothing_iters=3 +!!skeb_numerical_dissipation='fd' +!!skeb_numerical_dissipation_factor=2.0 !!skeb_rot_du='fd' -!!skeb_total_backscatter=0 -!!spt_add_increments=.false. -!!spt_convection_cfl_limit=.false. -!!spt_decorrelation_time=0 -!!spt_level_begin_tapering_bottom=0 -!!spt_level_begin_tapering_top=0 -!!spt_level_bottom=0 -!!spt_level_top=0 -!!spt_moisture_conservation=.false. -!!spt_mse_conservation=.false. -!!spt_n_smoothing_iters=0 -!!spt_orog_forcing_pattern_thresh=0 -!!spt_stddev_convection=0 -!!spt_stddev_microphysics=0 -!!spt_stddev_orog_thres=0 -!!spt_stddev_radiation=0 -!!spt_use_convection=.false. -!!spt_use_microphysics=.false. -!!spt_use_radiation=.false. -stph_n_max=0 -stph_n_min=0 +!!skeb_total_backscatter=1.00e-4 +!!spt_add_increments=.true. +!!spt_convection_cfl_limit=.true. +!!spt_decorrelation_time=2.00e+4 +!!spt_level_begin_tapering_bottom=15 +!!spt_level_begin_tapering_top=41 +!!spt_level_bottom=9 +!!spt_level_top=45 +!!spt_moisture_conservation=.true. +!!spt_mse_conservation=.true. +!!spt_n_smoothing_iters=3 +!!spt_orog_forcing_pattern_thresh=0.5 +!!spt_stddev_convection=1.73 +!!spt_stddev_microphysics=1.73 +!!spt_stddev_orog_thres=500. +!!spt_stddev_radiation=1.73 +!!spt_use_convection=.true. +!!spt_use_microphysics=.true. +!!spt_use_radiation=.true. +stph_n_max=60 +stph_n_min=20 use_random_parameters=.false. use_skeb=.false. use_spt=.false. @@ -1275,29 +1316,30 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2016-01-01 15:00:00' -calendar_start='2016-01-01 15:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' -timestep_end='20' -timestep_start='1' +timestep_end='$RESTART_STOP' +timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 -dt=3600.0 -inner_iterations=2 +dt=$DT +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' spinup_alpha=.false. -!!spinup_period=0 +!!spinup_period=0.0 tau_r=1.0 tau_t=1.0 tau_u=0.55 [namelist:transport] adjust_theta=.false. -!!adjust_theta_above=0.0 +!!adjust_theta_above=30000.0 adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1314,14 +1356,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1331,7 +1374,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1341,17 +1384,18 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. -!!wind_mono_top_depth=0 +!!wind_mono_top_depth=5 [namelist:validity_test] -number_gamma_values=0 -update_ls_frequency=0 +number_gamma_values=2 +update_ls_frequency=1 [!!namelist:vapour_forcing] coordinate='height' diff --git a/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc b/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc index 6a32d88b..a76f3d57 100644 --- a/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc +++ b/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc @@ -5,18 +5,24 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/common/adjoint_tests/tasks_adjoint_tests.cylc") %} -{% if task_ns.conf_name == "default-C12" %} +{% if task_ns.conf_name == "nwp_gal9-C12_MG" %} {% do task_dict.update({ - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "strict_solver", "rrt_equals_dt"], + "resolution": "C12_MG", + "DT": 1800, + "tsteps": 12, + "log_level": "debug", }) %} -{% elif task_ns.conf_name == "varying_ls-C12" %} +{% elif task_ns.conf_name == "nwp_gal9-C12_MG-varying_LS" %} {% do task_dict.update({ - "opt_confs": ["varying_ls"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "strict_solver", "rrt_equals_dt", "varying_ls"], + "resolution": "C12_MG", + "DT": 1800, + "tsteps": 12, + "log_level": "debug", }) %} {% elif task_ns.conf_name == "canned" %} @@ -45,4 +51,4 @@ {% endif %} {% endif %} -{% do LOG.debug("Finished in site/common/adjoint_tests/tasks_jedi_lfric_tests.cylc") %} +{% do LOG.debug("Finished in site/common/adjoint_tests/tasks_adjoint_tests.cylc") %} diff --git a/rose-stem/site/meto/groups/groups_adjoint_tests.cylc b/rose-stem/site/meto/groups/groups_adjoint_tests.cylc index 804f53ee..35ba5c49 100644 --- a/rose-stem/site/meto/groups/groups_adjoint_tests.cylc +++ b/rose-stem/site/meto/groups/groups_adjoint_tests.cylc @@ -8,9 +8,9 @@ {# Azspice Groups #} {% do site_groups.update({ "adjoint_tests_azspice_developer": [ - "adjoint_tests_default-C12_azspice_gnu_fast-debug-64bit-rsolver64", - "adjoint_tests_default-C12_azspice_gnu_full-debug-64bit-rsolver64", - "adjoint_tests_varying_ls-C12_azspice_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_full-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG-varying_LS_azspice_gnu_fast-debug-64bit-rsolver64", "adjoint_tests_azspice_canned", ], "adjoint_tests_azspice": [ @@ -28,8 +28,8 @@ {# EX1A Groups #} {% do site_groups.update({ "adjoint_tests_ex1a_developer": [ - "adjoint_tests_default-C12_ex1a_gnu_fast-debug-64bit-rsolver64", - "adjoint_tests_default-C12_ex1a_gnu_full-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit-rsolver64", "adjoint_tests_ex1a_canned", ], "adjoint_tests_ex1a": [ diff --git a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 index c5da7897..ba8f3844 100644 --- a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 @@ -23,11 +23,13 @@ module adj_semi_implicit_solver_alg_mod use adj_mixed_operator_alg_mod, only: adj_mixed_operator_type use adj_mixed_schur_preconditioner_alg_mod, only: adj_mixed_schur_preconditioner_type use adj_pressure_precon_alg_mod, only: adj_pressure_preconditioner_type + use multigrid_preconditioner_alg_mod, only: multigrid_preconditioner_type use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use sci_null_preconditioner_alg_mod, only: null_preconditioner_type use sci_preconditioner_mod, only: abstract_preconditioner_type use sci_iterative_solver_mod, only: abstract_iterative_solver_type, & + precondition_only_type, & bicgstab_type, block_gcr_type use split_w2_field_kernel_mod, only: split_w2_field_kernel_type use combine_w2_field_kernel_mod, only: combine_w2_field_kernel_type @@ -52,6 +54,7 @@ module adj_semi_implicit_solver_alg_mod si_pressure_a_tol, & helmholtz_method => method, & method_bicgstab, & + method_prec_only, & si_pressure_monitor_convergence => monitor_convergence, & si_pressure_fail_on_non_converged => fail_on_non_converged @@ -85,20 +88,28 @@ contains !> @brief Create adjoint operator and preconditioner for (Helmholtz) pressure problem !> @details Called by init method of this module, but also by !! adjt_mixed_schur_preconditioner_alg_mod and adjt_mixed_solver_alg_mod + !> @param[in] state Prognostic state for the adjoint pressure preconditioner !> @param[out] pressure_operator_out Output (Helmholtz) pressure operator !> @param[out] pressure_preconditioner_out Output (Helmholtz) pressure preconditioner - subroutine create_adj_pressure_preconditioner( adj_pressure_operator_out, adj_pressure_preconditioner_out ) + subroutine create_adj_pressure_preconditioner( state, adj_pressure_operator_out, adj_pressure_preconditioner_out ) use helmholtz_solver_config_mod, only: helmholtz_preconditioner => preconditioner, & preconditioner_none, & - preconditioner_tridiagonal + preconditioner_tridiagonal, & + preconditioner_multigrid implicit none + ! Prognostic fields + type(field_type), dimension(bundle_size), intent(in) :: state + ! Output adjoint operator and preconditioner for (Helmholtz) pressure problem type(adj_pressure_operator_type), intent(out) :: adj_pressure_operator_out class(abstract_preconditioner_type), allocatable, intent(out) :: adj_pressure_preconditioner_out + ! Vertical pressure preconditioner + type(adj_pressure_preconditioner_type) :: adj_Hz_preconditioner + adj_pressure_operator_out = adj_pressure_operator_type(level=1_i_def) call log_event( "adj_semi_implicit_solver_type%create_adj_pressure_preconditioner: starting", LOG_LEVEL_INFO ) @@ -111,6 +122,12 @@ contains case(PRECONDITIONER_TRIDIAGONAL) allocate( adj_pressure_preconditioner_out, & source = adj_pressure_preconditioner_type(level=1_i_def) ) + case(PRECONDITIONER_MULTIGRID) + adj_Hz_preconditioner = adj_pressure_preconditioner_type(level=1_i_def) + allocate( adj_pressure_preconditioner_out, & + source = multigrid_preconditioner_type( state(igh_p)%get_function_space(), & + adj_pressure_operator_out, & + adj_Hz_preconditioner ) ) case default call log_event( "Invalid pressure preconditioner specified for adjoint", LOG_LEVEL_ERROR ) end select @@ -148,6 +165,11 @@ contains si_pressure_maximum_iterations, & si_pressure_monitor_convergence, & si_pressure_fail_on_non_converged ) ) + case(METHOD_PREC_ONLY) + allocate( adj_pressure_solver_out, & + source = precondition_only_type( adj_pressure_operator_in, & + adj_pressure_preconditioner_in, & + si_pressure_monitor_convergence ) ) case default call log_event( "Invalid pressure solver specified for adjoint", LOG_LEVEL_ERROR ) end select @@ -243,7 +265,7 @@ contains type(field_type), dimension(bundle_size), intent(in) :: state self%adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( self%adj_pressure_operator, self%adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( state, self%adj_pressure_operator, self%adj_pressure_preconditioner ) call create_adj_pressure_solver( self%adj_pressure_operator, self%adj_pressure_preconditioner, self%adj_pressure_solver ) call create_adj_mixed_preconditioner( state, self%adj_pressure_solver, self%adj_mixed_preconditioner ) call create_adj_mixed_solver( self%adj_mixed_preconditioner, self%adj_mixed_operator, self%adj_mixed_solver ) From 849470399577c3f5cde8c0bb39b3cfdf5631555f Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 7 Jan 2026 10:54:49 +0000 Subject: [PATCH 02/68] Duplicate of testing from #71 --- .../atl_poly1d_vert_adv_kernel_mod.patch | 163 ++++++++++++++---- ...ly1d_vert_w3_reconstruction_kernel_mod.F90 | 5 +- 2 files changed, 133 insertions(+), 35 deletions(-) diff --git a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch index 7d5737dd..a51fc7de 100644 --- a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch @@ -33,67 +33,162 @@ &ndf_wt, undf_wt, map_wt, ndf_w2v, undf_w2v, map_w2v, ndf_c, undf_c, map_c) integer(kind=i_def), intent(in) :: nlayers integer(kind=i_def), intent(in) :: ndf_wt -@@ -61,7 +61,6 @@ +@@ -61,75 +61,96 @@ real(kind=r_def) :: dpdz real(kind=r_def) :: ls_dpdz real(kind=r_def) :: safe_ls_tracer - real(kind=r_def) :: eps real(kind=r_def), dimension(0:nlayers) :: ls_log_tracer - real(kind=r_def) :: tmp1 - real(kind=r_def) :: tmp2 -@@ -84,7 +83,7 @@ - itmp3 = FLOOR(tmp2) - stencil(p + 1) = -itmp3 + k + p - enddo +- real(kind=r_def) :: tmp1 +- real(kind=r_def) :: tmp2 +- integer(kind=i_def) :: i +- integer(kind=i_def) :: itmp3 + +- dpdz = 0.0_r_def + ij = map_wt(1) +- if (logspace) then +- do k = 0, nlayers, 1 +- ls_log_tracer(k) = LOG(MAX(eps, ABS(ls_tracer(ij + k)))) +- enddo ++ ++ ! For logspace the nonlinear term is: ++ ! dp_{j}/dz = p_j * sum_i a_i * log( p_i) ++ ! The tl term is then: ++ ! dp_{j}/dz = ls_p_j * sum_i a_i * p_i / ls_p_i ! ++ ! + p_j * sum_i a_i * log( ls_p_i ) ++ ++ ! Compute log of tracer. This code should only be used for a positive ++ ! quantity, but adding in the abs ensures no errors are thrown ++ ! if negative numbers are passed through in redundant calculations ++ ! in the halos ++ if ( logspace ) then ++ do k = 0, nlayers ++ ls_log_tracer(k) = log(max(EPS,abs(ls_tracer(ij+k)))) ++ end do + end if +- vertical_order = MIN(global_order, nlayers - 1) +- use_upwind = MOD(vertical_order, 2) ++ ++ ! Ensure that we reduce the order if there are only a few layers ++ vertical_order = min(global_order, nlayers-1) ++ ++ ! If order is odd then we are using an upwind stencil -> use_upwind = 1 ++ ! For even orders it is zero ++ use_upwind = mod(vertical_order, 2_i_def) ++ ++ ! Compute dtracer/dz using precomputed weights + do k = nlayers - 1, 1, -1 +- do p = 0, vertical_order, 1 +- tmp1 = REAL(vertical_order, r_def) +- tmp2 = 0.5 * tmp1 +- itmp3 = FLOOR(tmp2) +- stencil(p + 1) = -itmp3 + k + p +- enddo - upwind = INT(0.5 * SIGN(1.0, ls_wind(k + map_w2v(1))) + 0.5, i_def) -+ upwind = INT(0.5_r_def * SIGN(1.0_r_def, ls_wind(k + map_w2v(1))) + 0.5_r_def, i_def) - upwind_offset = upwind * use_upwind - stencil = stencil - upwind_offset - kmin = stencil(1) -@@ -106,30 +105,41 @@ - if (kmax > 0) then - stencil = -kmax + stencil - end if +- upwind_offset = upwind * use_upwind +- stencil(:) = -upwind_offset + stencil(:) +- kmin = stencil(1) +- do i = 2, vertical_order + 1, 1 +- if (stencil(i) < kmin) then +- kmin = stencil(i) +- end if +- enddo +- if (kmin < 0) then +- stencil(:) = -kmin + stencil(:) +- end if +- kmax = stencil(1) +- do i = 2, vertical_order + 1, 1 +- if (stencil(i) > kmax) then +- kmax = stencil(i) +- end if +- enddo +- kmax = kmax - nlayers +- if (kmax > 0) then +- stencil(:) = -kmax + stencil(:) +- end if ++ ++ ! Compute the stencil of points required ++ do p = 0, vertical_order ++ stencil(p+1) = k - floor(real(vertical_order,r_def)/2.0_r_def) + p ++ end do ++ ++ ! Adjust the stencil based upon the wind sign for upwind (odd order) ++ ! reconstructions only. ++ ! if wind > 0 -> upwind_offset = 1 ++ ! if wind < 0 -> upwind_offset = 0 ++ upwind = int(0.5_r_def*(1.0_r_def + sign(1.0_r_def,ls_wind(map_w2v(1)+k))),i_def) ++ upwind_offset = use_upwind*upwind ++ stencil = stencil - upwind_offset + -+ ! ARP - calculate passive ls_dpdz first. ++ ! Adjust stencil near boundaries to avoid going out of bounds ++ kmin = minval(stencil(1:vertical_order+1)) ++ if ( kmin < 0 ) stencil = stencil - kmin ++ kmax = maxval(stencil(1:vertical_order+1)) - nlayers ++ if ( kmax > 0 ) stencil = stencil - kmax ++ ++ ! Compute the derivative and the advective update ++ dpdz = 0.0_r_def ls_dpdz = 0.0_r_def -+ if (logspace) then -+ do p = vertical_order + 1, 1, -1 +- dpdz = dpdz + advective(map_wt(1) + k) * ls_wind(k + map_w2v(1)) +- wind(k + map_w2v(1)) = wind(k + map_w2v(1)) + ls_dpdz * advective(map_wt(1) + k) +- if (logspace) then +- safe_ls_tracer = SIGN(MAX(eps, ABS(ls_tracer(ij + k))), ls_tracer(ij + k)) +- ls_dpdz = ls_dpdz * safe_ls_tracer +- tracer(ij + k) = tracer(ij + k) + ls_dpdz * dpdz +- dpdz = dpdz * safe_ls_tracer ++ safe_ls_tracer = 1.0_r_def ++ if ( logspace ) then ++ ! dp/dz = p * d(log(p))/dz ++ do p = 1, vertical_order + 1 + ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 + ls_dpdz = ls_dpdz + coeff(ik)*ls_log_tracer(stencil(p)) + end do ++ safe_ls_tracer = sign(max(EPS,abs(ls_tracer(ij + k))), ls_tracer(ij + k)) + else -+ do p = vertical_order + 1, 1, -1 ++ do p = 1, vertical_order + 1 + ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 + ls_dpdz = ls_dpdz + coeff(ik)*ls_tracer(ij + stencil(p)) + end do + end if - dpdz = dpdz + advective(map_wt(1) + k) * ls_wind(k + map_w2v(1)) - wind(k + map_w2v(1)) = wind(k + map_w2v(1)) + ls_dpdz * advective(map_wt(1) + k) + - if (logspace) then - safe_ls_tracer = SIGN(MAX(eps, ABS(ls_tracer(ij + k))), ls_tracer(ij + k)) -- ls_dpdz = ls_dpdz * safe_ls_tracer - tracer(ij + k) = tracer(ij + k) + ls_dpdz * dpdz - dpdz = dpdz * safe_ls_tracer ++ dpdz = dpdz + ls_wind(map_w2v(1)+k) * advective(map_wt(1)+ k) ++ wind(map_w2v(1)+k) = wind(map_w2v(1)+k) + advective(map_wt(1)+ k) * ls_dpdz * safe_ls_tracer ++ ++ if ( logspace ) then ++ ! dp/dz = p * d(log(p))/dz ++ tracer(ij + k) = tracer(ij + k) + dpdz * ls_dpdz ++ dpdz = safe_ls_tracer * dpdz do p = vertical_order + 1, 1, -1 - ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 +- ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 - ls_dpdz = ls_dpdz + coeff(ik) * ls_log_tracer(stencil(p)) - tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / SIGN(MAX(eps, ABS(ls_tracer(ij + stencil(p)))), & - &ls_tracer(ij + stencil(p))) - enddo +- tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / SIGN(MAX(eps, ABS(ls_tracer(ij + stencil(p)))), & +-&ls_tracer(ij + stencil(p))) +- enddo ++ ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 ++ tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / & ++ ! This is a safe version of ls_tracer ++ sign(max(EPS,abs(ls_tracer(ij + stencil(p)))), ls_tracer(ij + stencil(p))) ++ end do ++ else do p = vertical_order + 1, 1, -1 - ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 +- ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 - ls_dpdz = ls_dpdz + coeff(ik) * ls_tracer(ij + stencil(p)) ++ ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz - enddo +- enddo ++ end do end if - dpdz = 0.0 - enddo +- dpdz = 0.0 +- enddo ++ dpdz = 0.0_r_def ++ end do - end subroutine adj_poly1d_vert_adv_code + end subroutine atl_poly1d_vert_adv_code -end module adj_poly1d_vert_adv_kernel_mod +end module atl_poly1d_vert_adv_kernel_mod + +-end module adj_poly1d_vert_adv_kernel_mod ++end module atl_poly1d_vert_adv_kernel_mod diff --git a/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 b/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 index f0fb299e..d2889501 100644 --- a/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 +++ b/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 @@ -136,11 +136,14 @@ subroutine atl_poly1d_vert_w3_reconstruction_code( nlayers, & do f = 1, 0, -1 do k = nlayers - 1, 0, -1 ls_new_tracer = 1.0_r_def + do p = 1, vertical_order + 1 + ik = f * global_order + f + k * ndata + p + map_c(1) - 1 + ls_new_tracer = ls_new_tracer * MAX(eps, ABS(ls_tracer(ij + stencil(p,k,f)))) ** coeff(ik) + end do new_tracer = new_tracer + ls_new_tracer * reconstruction(map_md(1) + f * nlayers + k) reconstruction(map_md(1) + f * nlayers + k) = 0.0_r_def do p = vertical_order + 1, 1, -1 ik = f * global_order + f + k * ndata + p + map_c(1) - 1 - ls_new_tracer = ls_new_tracer * MAX(eps, ABS(ls_tracer(ij + stencil(p,k,f)))) ** coeff(ik) tracer(ij + stencil(p,k,f)) = tracer(ij + stencil(p,k,f)) + coeff(ik) * new_tracer / SIGN(MAX(eps, ls_tracer(ij + & &stencil(p,k,f))), ls_tracer(ij + stencil(p,k,f))) enddo From addf153b64ac5418d28c28b91b78a1194314924a Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 7 Jan 2026 11:49:20 +0000 Subject: [PATCH 03/68] Update canned namelist --- .../adjoint_tests/example/configuration.nml | 253 ++++++++++++------ 1 file changed, 174 insertions(+), 79 deletions(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 84ce2a77..812a000e 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -1,22 +1,42 @@ &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., / §ion_choice +aerosol='none', +boundary_layer='none', +chemistry='none', +cloud='none', dynamics='gungho', external_forcing=.false., iau=.false., +iau_sst=.false., iau_surf=.false., +methane_oxidation=.false., +orographic_drag='none', +radiation='none', +spectral_gwd='none', +stochastic_physics='none', +surface='none', +/ +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., / &damping_layer dl_base=40000.0, @@ -27,29 +47,32 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', -vertical_sorting=.false. +vertical_sorting=.false., / &energy_correction encorr_usage='none', integral_method='fd', / &extrusion -domain_height=10000.0, -method='uniform', -number_of_layers=5, +domain_height=80000.0, +method='um_L70_50t_20s_80km', +number_of_layers=70, planet_radius=6371229.0, -stretching_method='linear', +stretching_height=17507.0, +stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', +checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_adjoint_tests_to_linear_model-2/run1/share/data/restart_adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64_tstep', diag_stem_name='diagGungho', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +ls_filename='final_ls', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +start_dump_filename='final_pert', / &finite_element cellshape='quadrilateral', @@ -65,85 +88,99 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., p2theta_vert=.true., rotating=.true., -theta_moist_source=.false. shallow=.true., si_momentum_equation=.false., +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., gcrk=18, -method='bicgstab', -monitor_convergence=.true., +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', +preconditioner='multigrid', si_pressure_a_tol=0, si_pressure_maximum_iterations=400, si_pressure_tolerance=1.0e-15, / +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau +/ &idealised -f_lon_deg=0, -perturb_init=.false. -test='gravity_wave', +f_lon_deg=0.0, +perturb_init=.false., +test='none', / &ideal_surface -canopy_height=0, -leaf_area_index=0, -n_snow_layers=0, -snow_depth=0, -snow_layer_ice_mass=0, -snow_layer_temp=0, -snow_layer_thickness=0, -soil_moisture=0, -soil_temperature=0, -surf_tile_fracs=0, -surf_tile_temps=0, -tile_snow_mass=0, +canopy_height=19.01,16.38,0.79,1.26,1.0, +leaf_area_index=5.0,4.0,1.5,1.5,1.5, +n_snow_layers=11*0, +snow_depth=11*0.0, +snow_layer_ice_mass=27*0.0, +snow_layer_temp=27*273.0, +snow_layer_thickness=27*0.0, +soil_moisture=15.86,98.861,274.35,862.27, +soil_temperature=284.508,286.537,289.512,293.066, +surf_tile_fracs=9*0.0,1.0,0.0, +surf_tile_temps=9*295.0,300.0,265.0, +tile_snow_mass=11*0.0, / &initialization ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., -init_option='analytic', +coarse_ozone_ancil=.false., +init_option='fd_start_dump', lbc_option='none', -ls_option='analytic', +ls_option='file', model_eos_height=100, n_orog_smooth=0, -read_w2h_wind=.false., +read_w2h_wind=.true., +sea_ice_source='ancillary', +snow_source='start_dump', w0_orography_mapping=.false., zero_w2v_wind=.false., / &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, z2=0.0, / &initial_pressure -method='sampled', +method='balanced', surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -152,39 +189,47 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='solid_body_rotation', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.5, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., -diagnostic_frequency=1, +diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., timer_output_path='timer.txt', use_xios_io=.true., write_conservation_diag=.false., -write_diag=.false., +write_diag=.true., write_dump=.false., write_fluxes=.false., write_minmax_tseries=.false., / &linear -pert_option='analytic', -l_stabilise_bl=.false., +fixed_ls=.true., +l_stabilise_bl=.true., +ls_read_w2h=.false., +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', / &logging -run_log_level='info', +log_to_rank_zero_only=.false., +run_log_level='debug', / &mixed_solver eliminate_variables='discrete', @@ -194,8 +239,8 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=10, +reference_reset_time=1800, +si_maximum_iterations=100, si_method='block_gcr', si_preconditioner='pressure', si_tolerance=1.0e-21, @@ -207,6 +252,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -214,12 +267,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., +limit_drag_incs=.false., +sample_physics_scalars=.true., +sample_physics_winds=.true., +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -229,8 +288,41 @@ p_zero=100000.0, rd=287.05, scaling_factor=1.0, / +&radiative_gases +cfc113_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', +co_rad_opt='off', +cs_rad_opt='off', +h2_rad_opt='off', +h2o_rad_opt='prognostic', +hcfc22_rad_opt='off', +hcn_rad_opt='off', +he_rad_opt='off', +hfc134a_rad_opt='off', +k_rad_opt='off', +l_cts_fcg_rates=.false., +li_rad_opt='off', +n2_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', +na_rad_opt='off', +nh3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', +rb_rad_opt='off', +so2_rad_opt='off', +tio_rad_opt='off', +vo_rad_opt='off', +/ &solver -fail_on_non_converged=.false., gcrk=18, maximum_iterations=50, method='chebyshev', @@ -238,33 +330,35 @@ monitor_convergence=.false., preconditioner='diagonal', tolerance=1.0e-18, / +&specified_surface +/ &time calendar='timestep', calendar_origin='2016-01-01 15:00:00', calendar_start='2016-01-01 15:00:00', calendar_type='gregorian', -timestep_end='1', +timestep_end='12', timestep_start='1', / ×tepping alpha=0.55, -dt=3600.0, +dt=1800, +inner_iterations=1, method='semi_implicit', +outer_iterations=2, runge_kutta_method='forward_euler', spinup_alpha=.false., -spinup_period=0, -tau_u=0.55, tau_r=1.0, tau_t=1.0, -inner_iterations=2, -outer_iterations=2, +tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -274,18 +368,19 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', @@ -293,27 +388,27 @@ min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', panel_edge_high_order=.true., -panel_edge_treatment='none' +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', slice_order='parabola', -special_edges_monotone=0,0,0,1,1 +special_edges_monotone=5*1, splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test -number_gamma_values=0, -update_ls_frequency=0, +number_gamma_values=2, +update_ls_frequency=1, / From 7f80c68a1ede6fb60262d06e89ffa7f413a949d6 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 10:10:22 +0000 Subject: [PATCH 04/68] Signed CLA --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f621dd5b..70ba9e59 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -8,3 +8,4 @@ | mo-marqh | mark Hedley | Met Office | 2025-12-11 | | yaswant | Yaswant Pradhan | Met Office | 2025-12-16 | | oakleybrunt | Oakley Brunt | Met Office | 2025-12-19 | +| tom-j-h | Tom Hill | Met Office | 2026-01-14 | From e3d05de2c39af161ae0b8a8a63c1a17a1ab5e907 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 10:14:36 +0000 Subject: [PATCH 05/68] Added canned mesh namelist and file --- applications/adjoint_tests/example/C12_MG.nml | 54 ++++++++++++++++++ .../adjoint_tests/example/mesh_C12_MG.nc | Bin 0 -> 128056 bytes 2 files changed, 54 insertions(+) create mode 100644 applications/adjoint_tests/example/C12_MG.nml create mode 100644 applications/adjoint_tests/example/mesh_C12_MG.nc diff --git a/applications/adjoint_tests/example/C12_MG.nml b/applications/adjoint_tests/example/C12_MG.nml new file mode 100644 index 00000000..048f0802 --- /dev/null +++ b/applications/adjoint_tests/example/C12_MG.nml @@ -0,0 +1,54 @@ +!-------------------------------------------------------------------- +! Example namelists for mesh generation +!-------------------------------------------------------------------- +! These example namelists will result in the mesh generators +! producing an output file () which will +! contain mesh topologies which are identified by +! the by . +! +! Additional intergrid mappings may be produced and included +! in the output file. Each map is specified by an item in the +! list. Maps are specified by a string of the two +! mesh names spearated by a ":". Each item will cause a +! map to be added to the maps source mesh, i.e. +! +! 'dynamics:physics' will result in a map added to the +! +! * "dynamics" mesh (source) object mapping to "physics" (target) +! * "physics" mesh (source) object mapping to "dynamics" (target) +! +! Notes: +! * Only the first "n_meshes" listed in mesh_names will be +! output in the mesh file. +! * All spherical co-ordinates are given the order +! [longitude, latitude] in the units, degrees_east, degrees_north +! respectively +!=================================================================== +&mesh + mesh_file_prefix = 'mesh_C12_MG' + geometry = 'spherical' + topology = 'periodic' + n_meshes = 3 + mesh_names = 'dynamics','multigrid_l1','multigrid_l2' + mesh_maps = 'dynamics:multigrid_l1','multigrid_l1:multigrid_l2' + partition_mesh = .false. + coord_sys = 'll' + rotate_mesh = .false. +/ + +!================================================================== +! Cubedsphere Meshes: Only used by the Cubedsphere mesh generator +!================================================================== +! Each cubesphere mesh is specified by the corresponding number of +! cells on a panel edge. These are listed in the variable +! and correspond to the order of names given by . +! +! Any smoothing iterations specified will be applied to all meshes +! requested. Smoothing is experimental (especially with regards to +! intergrid mesh maps) is advised to be left as 0 for general use. + +&cubedsphere_mesh + edge_cells = 12 + equatorial_latitude = 0.0 + smooth_passes = 0 +/ diff --git a/applications/adjoint_tests/example/mesh_C12_MG.nc b/applications/adjoint_tests/example/mesh_C12_MG.nc new file mode 100644 index 0000000000000000000000000000000000000000..ebe518907aea38df3c4cc5b3839febbef455ba53 GIT binary patch literal 128056 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%0A>b4`uEX%|n^9rg;UVD07rH4`q%r=Aq2d z%)D(Z(@bRj_U9 zYF6V_v~B9@R^wH&ZR#3UW)@(U9c~;1U1S&oo+SCzSK4kWgpHk4`uE;=Aq2l z-8`-fa_b3dlsW2KjWS0A^HAnE(>#lsQ^ijWWmC=5bw+yI4@8%(293lsT4~ zhmyO@Jd`<>n};&TPV+eDZ3O3=x|7v-ZEc&nv(-GQRWz8HOd@A%|n@En0Y9u zu6ZbPj4%&nj`PeznPa4RD7iPA$92IRy971L9Isi8GRN!Yq0F({Jd`=!Fb`#pH_hXm zUm!T&)MKp1yU@0&FR>c$BHO0E)M~toZJYWstMNwJHuYGm@e;O8o!x4#3-;v-L5;Fc zS6Yp-FISm|vJY3Ahcfpy=Aq1)+dQrda>og3lsT@m8fA{_%|n@Eym=^d++ZHc90knd zx*&I=phm}u8?8o}<0kV^=9pw2${dr;Lz&|w^SCa^y+u%?%yFyLD056P4`q(2=Aq0n z%{-JjPBo9~g4`W~8fA`Gtwx#S74uN$c-cIZIkuaJGRHRarb|=A3_*RH)wf$cQ%c=I zP~Ra^#hq5qvidG5_1%KHz18UM&9j>szJT0PI|`BLf!1a(`h z7f7>-g@XD)s~@s@k(9cPpyt}9&x-{;UnJ=HLP4Jw2>N6Uy)uSg8AE@Jp+CmZD`V)3 zG4#k7dSncJF^0YvGe?V#?TXE=z}rz!I*M_G35ngDhS3@ z6pX1P9uX_VN~>2{{iu}sF+sh{>L;X+izfy3YOB{+{gjmYH9`H1cv?Jb^>bExDfL=G z{kqlbrR&7=f_j718?D|XrQR*5w}{Q+1*>1Q`Xwp#RzdxS)r+O{yhPCRQbC`~1br?S z^voFgV+_4AhF%#%e~h6&#?T{U=#eq>#TYLbLywH1AI8udW9ZEb`e6+HFovEOLr;vM z55~|3W9W%7+^dY?9%jrdf-$cO#_X`aZSb2vOIupMeYK#;f9fBuYVtq%f5pv)}ajhJ zK3>swc)hHvb4G<-S$mCl4W>O?OzV-ah6xSE=N_ z6|?pn@2X~^i=2JkjJLzB0ExLA0HG zy^jCJZRNxzC`sYAAfkk02j2k3;qrl#!dB2U#K$7H`(axOeu0(i9I8HiGrzXXWf6k z3wo{#{<$uU+vJko{*=Ic4W#BphdE-Lh(3p(Eg|2`MSO|BXZbB^uL1-3uu+5Vhu`?JwUef)91eXZZuqJCYQvO61o(eGl{>GiWec<{EI zuG_uY^G{!0%=H@l<5w57_{jCEFzb|FBfoV6_Z50?a_3F1%^5rHZv1Qm*Xivmiq&hi z&~>}-x%D4kn#1)P3i3&^n?#LJ<;0@{HSoPy(K?zZ5kcS{cxo#T&H)N4cePl z)OEZ6sTD;JEp)xo(>i{V=;Qj8eEPmqpZdfNd@tMOl|El@<1at@@yY!;^XT^{ll>0b za!K9>ub<+EEMB#L$Ce3h*p%@%ZGQV!A8GI>`e@vstz$l(`t=kyWLcx!v&(dG!=?^= z@8Fro`ACD`)rWCY-JtDPtsgP@J~w3f+!f!H%BAspcIUdbtHuWner_Me-JkjKncbhv z_3Q1r@Zmc7&f9h4?K<+|y2|D4I`ej2_;8){@pj#KyN-Ogt{(Juo%wKGJnzGG@~OA$ z#@lt|?Yi=Io!R*HM?XGXr+>0P3lHy4xDSrH-{|vJhmAdQUiM^B-!1p3Plw$2p6_+w z)*`dVmhk;&@BBHf^taLTw{JMQ>u33qGWzWT*=LYYe zdHtTRvij1upY!ww{s&+4;X7M?zvkEYb4T=fV`!VDMG_U}_+c$pkEywSzYF6Jx-kAH z`+RmN{u~y@&vnuGus<)`IDMTB`{QhX;`iD9xaf0S=(n)5ex3E}tl#*3zaOvlAsn9! z;}68+?fAs={C;?J-EiB^ScA9E^tjAY0~)N6=Pk~`DtICHK0j z;2*ScxB4*t79ad?d>G#>*2s^>g?W1Tus?Zx*q@JM4Srr9#`W~phqu0b=(lsM!M`jT zm&xOEq4j;Fmle!yM8XS>!!15 zm-xDh#{cK*Cptd);^P?3^R0Fq4#w9_bRC83Av!)&tnbPH(Dl?k#u2*MWw$-l92_KYRIqTV2BR}J~_FD@4+F|d0*XjOAKeldO&9u4; z{sGHd6X!(Zy1qU4?v9gAbCCwWdOR+g|LDg1c)z20qr6BXKlHK2{l1UG`xoYo@}hAA zyp8wvesB91Yw(}4aRcIUc6_|`5v%Qwje9E2iN@J+@sU~|HqK{ye6)Yjyis1Hkspl< z{T}Yaj!Qg$#&N^LckH6?Yq}$ByXbSMy&i36IsE&LxmD*8sp2@1SL72}MK+ONoG7x3 z<3#~cP@Eugh(e;U$SHD(BBH1`Nt`UoigKcuI7O5f{5-d~C?P6}O5#*eQdAaI#A%|G zs4A+7(xQy0E^3IHqLyeR_^#;bqPA!(oH#?&5luu>QCHLx%|x20FB*vEqJ=n9G!!jG zE74lC5#2=((N?q*Jw-3kUhpZrx9B4}icX@h=qEahE~38}Ai9cfVxUMDgT!EQzPLaP z5ktj=;vz9j3>O!RQQ~ZIjuOWO1z+CvFzEi0j1l;#M(5j2AbEsbZR#E@p^(#eL#7al5!*%n>ui9b&GSC+-xp z#C-99xJ%qE7Knx79x+=yC>|1v#KYn-@wiwlmWU_BlVYh@CRU3zV!2o$o)S-sN5o3; zjCfY85|4`KgcobYIR8W ziG$)>@msjHlm88a?^P#6iu@nMkE&C}ajJh3Kda6vvZ?-;_(gSgalAM|uCyA3qUXf1}6Q_v$;zUtgln@0(L2;@mDXNOoL^V-LR2QX14N*qa6lFy% zQBIsL%8S~ff;dA|6m>);QCCzJ^+XlXT+|mWL<7-MoGDs~hN87-B-)6xL|f5Vv=dIW z7fnP5(NuI4%|s`WCi;ucVu0u(28ymCU33$JM0YV*^bkWtPcc;V62nAqFeZc zUOXY57f*@}Vzt;P)`(5wDY02REp~}5;x+MtcwM|Gc8iz98)B zUJ>tzSH-(xhuAB2ihbfe@s)UAd@Vi@--r*ze({kwAU+lc#V6uh@u~Pud?vmZpNk*F z7ve|prGE7-tMn&nHtEmO?9zWpkC*-;Jwf`bG>7z%G^g}8X)cjPaQij)^G2 z1dPOFjKCz6V-BWZHm2f8RA4SDaWtmkD9pfoOvgM_VIgK>0cPP?9D!qSJkG>%I0K7N zjT3Md7ULY8h_i7r&c#Vsf>UumPQiIN9T(y>T!4#k6_(;kT!L$GF|NjCxDJ=%T3n7B zungB@1y*4>Zp2Eg!4+7IwYV2I;U3(A^|%@L;Wj*gTX8?`zy{oo2eA$h<4!z;yYVRQ z!XtPb&*L#XhfR198}S03#LIXBFCm3j@f2Rc)7XN|cn#0u4LpO_@g}z7=lBKQ!rS-| zAK@Lmi(lebcn{m~F@BAo;eGrDpWp**$EWx$euvNSSNsjX$LIJOf5#X265rq-_yhik zf8t;G3V*`C@h$$0zu>#{qki37$~tI-#;A*3&;+}q9`eu>&5)1!*aLf_0d_@mw7_m? zh?Z!Dz0ex%(E)p79~9s~?2G+y5Dv!vNZ=53L>sh4Cmf0c&<>r^1&5(4`k@Hj&>j7e zL=W`D01QMg^u{0z#^LCLAt**)6k;fbp#;M*0TVF-BQXh+QHoKRf^v+;7*t>?#-a?< zP>FFEkLj3^!+*9h<{3s(6TLgu7H3UG@0F~l%sVCPDvH^b9cP_o-Zfco(R(Iq zEsEJ@tY(}w7`=zG{xa{Ntivc~TXvlFnR!QLoks7ctkEcDo3Wa4)^7Cv%DTQaW8pJ>rK!Q#;m(mUEjvSzA(?e?vZ9N z&zN=Bs(p-kF6Y!d`&xId%rj=)@w1OH_k?@M^LY&Si+jwNZLU?55~>)815J2 z#%yz)+Q*n}Jz?Bj&)W;ejoH>4_AzE#0`4Qv>2cgM?lEHtI491dG27e|37G3~+%Lux zu+2HKk1^X^E5^%h4;Pu87#^JLxmu}?>Ig7fNJTR#-et1;`2t7C1fGrGV$`&xHznP<$p<8B{g z-oN*4o_(!5F6J4t?zq{W5k%Z?Rf}t1$691zje?aj#WL>h1X*|54*zaZv*ew9CPhkALf{Aya5`) zW3+?o%p7y=>o}WZu5riFIrA9yvF~p1e4e*48loeNH-Y2Q3HGtCIp*5eF)+tmc;%(2aD=mv9a^H@F679PVq`|baDJSZ_At-B3E1W_4uCnfc`WD0 zdGQztcs_G%^E!IKoCG|UbLkv<4D;-l3)hO*;Bh_oLGT(quW`rA>$S~w;@p~Jn|+;I zbL?Z>@pjB?b4@t6=GbOm=hhti7Cl>=9p{TadPZDhGXOXI>y#r^VW@dUw*cp7uUnR`q{c` z)Vk-jpVw>M(!SoWbxZTSXX{>zdEp)`&2y}*Tbg%JTz7mOQ_pAJy%#L{cb`}{);#`f z-L-C;v9R{7yRL2X{PuHRty`M!yjiz2FU+OqH?JqGTbkD^u3OrtcO3JaVUJl)Ane_+ z*KBVSw}pM=XY0tR23i0h7# z^#Zv54vg!LsdcZ-K3;q1W3Kg(>pHRSy6A+CaBo?6+^lzj>(D)9-SM;T{F~=ohd#Dj z54m2q_3rWCZhe=smHicdvzaQcjsib5o=oTGCd*P$zhrqbUG8jr#z*OXv(`jqDqZF# zcQT%e^HcG4q~hz^>3A52aQ^sj*fQ4>xBuwA)8qNWZ?wYogx^Yqzl96&aGr3TVf?~* zcN~wLa37i9ZQg);osDE!7KE;GLo%KSDc`VA6)BNhMlDfAEJ|NC*`-v%V(zuC_& zGrv_x-!H#Wh<@`G%9*LSe_Vc>X%D{v2xa)2`yKmNWgVZt*^iGO@{7*+@XodcLpFW+ z^rF_=J8w*;KNqKp_HDHOs)p}x`f_cmV!?a)$@J&#sW?B{9Q+gVlck$?KV;$OmC1?K zQB$&V|C2r&wsdQ<^s7?}Hhi=4hj{*=`R$kVsx`lA{oq|c*w`{TCw-h$_*}KAvgC`R zS;;wPMZYObh0mcqD?b&VKNVk3D!#r{Wpw@?Kg6T!TTyF%*cahA@qTzB@9|X?Z?s(y z-7Nov>y7^(%E{bs*gx@cvg7^gude=h@#|lQDz{_Z#&eGs0-`cf}MKNMjQ2BSZc7=mI9z(5SeFpNeC#$Y(cVg$-C65~*c z@fd{)Ou$r3#57DoB_?A!reFrjF&8s&B&u)}j=<5Fg?X5b`Iv(f;QtGYun;HW7%axI zI0?t$WE_vPa0;q%D$d4fI0vU=3C_T|I1?A+JY0hFaVajqWw;Q_uoRc$BCNnQSdOc) z64&7hT#Ku41FppNScO|~BW}hT+=kV-6>D(^Zo=(YhxND<_u+0lfV*%%?!^Y&g9q^t z9>zv&!XtPTPvA*BhR5*~QrL{A@d94NGk6v+;blCB=kW?&#cSAtx9~Pz#~XMD@8V5t I#e3NHJrUY>l>h($ literal 0 HcmV?d00001 From e349cb5b2cefc6dbf2fac2a718c92b3be8144b7f Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 11:23:44 +0000 Subject: [PATCH 06/68] Added namelist variable for adjoint test tolerance to jedi_tlm_tests --- .../jedi_lfric_tests/example_tlm_tests/configuration.nml | 1 + .../example_tlm_tests/configuration_dry.nml | 1 + .../example_tlm_tests/configuration_dry_relaxed.nml | 1 + .../rose-meta/jedi_common/HEAD/rose-meta.conf | 8 ++++++++ applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 | 3 ++- rose-stem/app/jedi_forecast/rose-app.conf | 1 + rose-stem/app/jedi_forecast_pseudo/rose-app.conf | 1 + rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 1 + rose-stem/app/jedi_lfric_tests/rose-app.conf | 1 + rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf | 1 + rose-stem/app/jedi_tlm_tests/rose-app.conf | 1 + 11 files changed, 19 insertions(+), 1 deletion(-) diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 283c5daf..7a0a5914 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -34,6 +34,7 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-4, forecast_length='P0DT6H0M0S', / diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml index c9b94582..4a5237da 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml @@ -34,6 +34,7 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-4, forecast_length='P0DT6H0M0S', / diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml index 1296925a..e574ef7a 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml @@ -33,6 +33,7 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-4, forecast_length='P0DT6H0M0S', / diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf index 683dc953..b62f0ba0 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf @@ -52,6 +52,14 @@ help=Configuration option for JEDI-LFRIC emulator. ns=namelist/JEDI-LFRIC-setup title=JEDI-LFRIC Setings +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=true +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real + [namelist:jedi_lfric_settings=forecast_length] compulsory=true description=The forecast duration diff --git a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 index da7f0342..bd1d338d 100644 --- a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 +++ b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 @@ -74,7 +74,7 @@ program jedi_tlm_tests character( str_def ) :: forecast_length_str real( kind=r_def ) :: dot_product_1 real( kind=r_def ) :: dot_product_2 - real( kind=r_def ), parameter :: absolute_tolerance = 1.0E-4_r_def + real( kind=r_def ) :: absolute_tolerance real( kind=r_def ) :: machine_tolerance real( kind=r_def ) :: absolute_diff real( kind=r_def ) :: relative_diff @@ -165,6 +165,7 @@ program jedi_tlm_tests absolute_diff = abs( dot_product_1 - dot_product_2 ) machine_tolerance = spacing( max( abs( dot_product_1 ), abs( dot_product_2 ) ) ) relative_diff = absolute_diff / machine_tolerance + call jedi_lfric_settings_config%get_value( 'adjoint_test_tolerance', absolute_tolerance ) if (absolute_diff > absolute_tolerance ) then call run%finalise_timers() ! We still want timing info even if the test fails write( log_scratch_space, * ) "Adjoint test FAILED", & diff --git a/rose-stem/app/jedi_forecast/rose-app.conf b/rose-stem/app/jedi_forecast/rose-app.conf index 3848d4ba..5d3a7242 100644 --- a/rose-stem/app/jedi_forecast/rose-app.conf +++ b/rose-stem/app/jedi_forecast/rose-app.conf @@ -599,6 +599,7 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf index 8d5864da..e086fd46 100644 --- a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf +++ b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf @@ -595,6 +595,7 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 1049af56..b7bc02c9 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -604,6 +604,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index a683eda8..99d75977 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -604,6 +604,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index ba5167ca..46818398 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -602,6 +602,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 8e0df802..e41368cc 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -604,6 +604,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] From 4a2516294e88901f459543bc3699f0ff127b7872 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 11:34:33 +0000 Subject: [PATCH 07/68] Moved variable definition so it's not needed where it's irrelevant --- .../rose-meta/jedi_common/HEAD/rose-meta.conf | 8 -------- .../rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf | 8 ++++++++ rose-stem/app/jedi_forecast/rose-app.conf | 1 - rose-stem/app/jedi_forecast_pseudo/rose-app.conf | 1 - rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 1 - rose-stem/app/jedi_lfric_tests/rose-app.conf | 1 - rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf | 1 - 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf index b62f0ba0..683dc953 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf @@ -52,14 +52,6 @@ help=Configuration option for JEDI-LFRIC emulator. ns=namelist/JEDI-LFRIC-setup title=JEDI-LFRIC Setings -[namelist:jedi_lfric_settings=adjoint_test_tolerance] -compulsory=true -description=Tolerance for inner product adjoint tests in jedi_tlm_tests -help=Set as appropriate based on configuration -!kind=default -sort-key= -type=real - [namelist:jedi_lfric_settings=forecast_length] compulsory=true description=The forecast duration diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf index 57a38b5b..0d733c7b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf @@ -3,6 +3,14 @@ import=jedi_common/HEAD #============================================================================== # Increment for the JEDI-LFRIC Emulator #============================================================================== +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=true +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real + [namelist:jedi_increment] compulsory=true description=JEDI-LFRIC emulator increment configuration diff --git a/rose-stem/app/jedi_forecast/rose-app.conf b/rose-stem/app/jedi_forecast/rose-app.conf index 5d3a7242..3848d4ba 100644 --- a/rose-stem/app/jedi_forecast/rose-app.conf +++ b/rose-stem/app/jedi_forecast/rose-app.conf @@ -599,7 +599,6 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf index e086fd46..8d5864da 100644 --- a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf +++ b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf @@ -595,7 +595,6 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index b7bc02c9..1049af56 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -604,7 +604,6 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index 99d75977..a683eda8 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -604,7 +604,6 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index 46818398..ba5167ca 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -602,7 +602,6 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] From 47a08a5dadc014a3e5de84b80a9768926f530e35 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 11:49:06 +0000 Subject: [PATCH 08/68] rose config-dump --- .../rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf index 0d733c7b..c91b0ea5 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf @@ -3,13 +3,6 @@ import=jedi_common/HEAD #============================================================================== # Increment for the JEDI-LFRIC Emulator #============================================================================== -[namelist:jedi_lfric_settings=adjoint_test_tolerance] -compulsory=true -description=Tolerance for inner product adjoint tests in jedi_tlm_tests -help=Set as appropriate based on configuration -!kind=default -sort-key= -type=real [namelist:jedi_increment] compulsory=true @@ -34,3 +27,11 @@ help=Add a comma separted list of variables to instantiate length=: sort-key= type=character + +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=true +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real From fb3fd3a73dbb23c245ac8250bda46fa7674f6110 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 14 Jan 2026 12:07:31 +0000 Subject: [PATCH 09/68] Moved back to jedi_common and made non-compulsory --- .../rose-meta/jedi_common/HEAD/rose-meta.conf | 8 ++++++++ .../rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf | 12 ------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf index 683dc953..57cab669 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf @@ -52,6 +52,14 @@ help=Configuration option for JEDI-LFRIC emulator. ns=namelist/JEDI-LFRIC-setup title=JEDI-LFRIC Setings +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=false +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real + [namelist:jedi_lfric_settings=forecast_length] compulsory=true description=The forecast duration diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf index c91b0ea5..7f405027 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf @@ -1,9 +1,5 @@ import=jedi_common/HEAD -#============================================================================== -# Increment for the JEDI-LFRIC Emulator -#============================================================================== - [namelist:jedi_increment] compulsory=true description=JEDI-LFRIC emulator increment configuration @@ -27,11 +23,3 @@ help=Add a comma separted list of variables to instantiate length=: sort-key= type=character - -[namelist:jedi_lfric_settings=adjoint_test_tolerance] -compulsory=true -description=Tolerance for inner product adjoint tests in jedi_tlm_tests -help=Set as appropriate based on configuration -!kind=default -sort-key= -type=real From 06796046120f6032911410a725e040562dcffc84 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 15 Jan 2026 11:54:53 +0000 Subject: [PATCH 10/68] Fix merge error --- .../patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch | 3 --- 1 file changed, 3 deletions(-) diff --git a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch index a51fc7de..fec1840c 100644 --- a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch @@ -189,6 +189,3 @@ -end module adj_poly1d_vert_adv_kernel_mod +end module atl_poly1d_vert_adv_kernel_mod - --end module adj_poly1d_vert_adv_kernel_mod -+end module atl_poly1d_vert_adv_kernel_mod From bc02651bd544f4698e1ef6937bff93b5cd8c7048 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 15 Jan 2026 14:43:31 +0000 Subject: [PATCH 11/68] Should be all changes for jedi_tlm_tests and jedi_id_tlm_tests. Untested. Need to do jedi_tlm_forecast_tl --- .../opt/rose-app-C12_MG.conf | 8 + .../opt/rose-app-nwp_gal9_c12.conf | 34 +++ rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 282 +++++++++-------- .../jedi_tlm_tests/opt/rose-app-C12_MG.conf | 8 + .../app/jedi_tlm_tests/opt/rose-app-dry.conf | 6 +- .../opt/rose-app-nwp_gal9_c12.conf | 34 +++ .../opt/rose-app-relaxed_solver.conf | 15 - .../opt/rose-app-rrt_equals_dt.conf | 2 + .../opt/rose-app-semi_strict_solver.conf | 9 + .../opt/rose-app-strict_solver.conf | 15 + rose-stem/app/jedi_tlm_tests/rose-app.conf | 286 ++++++++++-------- .../tasks_jedi_lfric_tests.cylc | 142 ++++----- .../meto/groups/groups_jedi_lfric_tests.cylc | 52 ++-- 13 files changed, 516 insertions(+), 377 deletions(-) create mode 100644 rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf create mode 100644 rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf delete mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 00000000..125a4758 --- /dev/null +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 00000000..958b917d --- /dev/null +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,34 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +ls_filename='final_ls' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 1049af56..82baa804 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -62,29 +69,33 @@ source=namelist:jedi_lfric_tests = (namelist:jules_vegetation) = namelist:linear = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) - = (namelist:theta_relax) = namelist:time = namelist:timestepping = namelist:transport @@ -105,24 +116,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -185,7 +196,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +216,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -317,11 +328,11 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${ancil_resolution}' -checkpoint_stem_name='' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' +checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -diag_stem_name='' +diag_stem_name='diagGungho' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -372,13 +383,13 @@ diag_stem_name='' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -!!ls_directory='' -!!ls_filename='' +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -388,8 +399,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='' -start_dump_filename='' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -410,7 +421,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -420,7 +431,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -434,16 +445,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -453,7 +464,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +511,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +531,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +556,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -555,10 +566,10 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='analytic' +init_option='fd_start_dump' lbc_option='none' -ls_option='analytic' -!!model_eos_height=100 +ls_option='file' +model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. sea_ice_source='ancillary' @@ -574,7 +585,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,15 +601,15 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' -io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' -io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' +io_calender_start='2021-06-02T00:00:00' +io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' +io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' @@ -614,12 +625,12 @@ incremental_wind_interpolation=.true. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s' @@ -653,7 +664,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -692,8 +703,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -718,7 +729,7 @@ cor_mo_iter='improved' formdrag='dist_drag' l_anthrop_heat_src=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. +l_vary_z0m_soil=.true. srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -751,9 +762,11 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.false. +l_stabilise_bl=.true. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' [namelist:logging] log_to_rank_zero_only=.false. @@ -781,40 +794,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -822,9 +835,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -919,7 +940,7 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 @@ -933,15 +954,15 @@ configure_segments=.false. !!electric_placement='slow' !!evap_condense_placement='fast' !!gw_segment=0 -!!limit_drag_incs=.false. +limit_drag_incs=.false. !!lowest_level='gradient' !!ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' @@ -984,12 +1005,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1003,26 +1024,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1094,8 +1115,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1112,8 +1133,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1122,7 +1143,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1149,10 +1170,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1160,23 +1181,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1203,10 +1224,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1259,9 +1280,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1306,7 +1327,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1337,8 +1358,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1346,7 +1367,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1360,6 +1381,7 @@ tau_u=0.55 adjust_theta=.false. !!adjust_theta_above=30000.0 adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1376,14 +1398,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1393,7 +1416,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1403,10 +1426,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 00000000..125a4758 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf index 3f2af7e5..8d9144c4 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf @@ -1,4 +1,8 @@ [namelist:formulation] moisture_formulation='dry' moisture_in_solver=.false. -!!theta_moist_source=.false. + +[namelist:section_choice] +!!aerosol='none' +!!cloud='none' +!!methane_oxidation=.false. diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 00000000..958b917d --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,34 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +ls_filename='final_ls' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf deleted file mode 100644 index b435c2bc..00000000 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf +++ /dev/null @@ -1,15 +0,0 @@ -[namelist:helmholtz_solver] -gcrk=8 -si_pressure_a_tol=1.0e-8 -si_pressure_maximum_iterations=400 -si_pressure_tolerance=1.0e-4 - -[namelist:mixed_solver] -gcrk=6 -mixed_solver_a_tol=0.0 -si_maximum_iterations=10 -si_tolerance=1.0e-5 - -[namelist:solver] -maximum_iterations=7 -tolerance=1.0e-6 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 00000000..3d974564 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf new file mode 100644 index 00000000..cf06d8c5 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf @@ -0,0 +1,9 @@ +[namelist:jedi_lfric_settings] +adjoint_test_tolerance=2.0e-2 + +[namelist:mixed_solver] +mixed_solver_a_tol=1.0e-21 +si_tolerance=1.0e-3 + +[namelist:timestepping] +outer_iterations=1 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf new file mode 100644 index 00000000..77270e0f --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf @@ -0,0 +1,15 @@ +[namelist:helmholtz_solver] +gcrk=18 +si_pressure_a_tol=0 +si_pressure_tolerance=1.0e-15 + +[namelist:mixed_solver] +fail_on_non_converged=.false. +gcrk=10 +mixed_solver_a_tol=1.0e-21 +si_maximum_iterations=100 +si_tolerance=1.0e-21 + +[namelist:solver] +maximum_iterations=50 +tolerance=1.0e-18 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index e41368cc..26f49f90 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -62,29 +69,33 @@ source=namelist:jedi_lfric_tests = (namelist:jules_vegetation) = namelist:linear = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) - = (namelist:theta_relax) = namelist:time = namelist:timestepping = namelist:transport @@ -105,24 +116,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -185,7 +196,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +216,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -317,11 +328,11 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${ancil_resolution}' -checkpoint_stem_name='' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' +checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -diag_stem_name='' +diag_stem_name='diagGungho' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -372,13 +383,13 @@ diag_stem_name='' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -!!ls_directory='' -!!ls_filename='' +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -388,8 +399,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='' -start_dump_filename='' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -410,7 +421,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -420,7 +431,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -434,16 +445,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -453,7 +464,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +511,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +531,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +556,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -555,10 +566,10 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='analytic' +init_option='fd_start_dump' lbc_option='none' -ls_option='analytic' -!!model_eos_height=100 +ls_option='file' +model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. sea_ice_source='ancillary' @@ -574,7 +585,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,37 +601,37 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' -io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' -io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' +io_calender_start='2021-06-02T00:00:00' +io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' +io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-4 +adjoint_test_tolerance=1.0e-14 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] test_field='theta' [namelist:jedi_linear_model] -incremental_wind_interpolation=.true. +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s' @@ -654,7 +665,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -693,8 +704,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -719,7 +730,7 @@ cor_mo_iter='improved' formdrag='dist_drag' l_anthrop_heat_src=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. +l_vary_z0m_soil=.true. srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -752,9 +763,11 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.false. +l_stabilise_bl=.true. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' [namelist:logging] log_to_rank_zero_only=.false. @@ -782,40 +795,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -823,9 +836,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -920,7 +941,7 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 @@ -934,15 +955,15 @@ configure_segments=.false. !!electric_placement='slow' !!evap_condense_placement='fast' !!gw_segment=0 -!!limit_drag_incs=.false. +limit_drag_incs=.false. !!lowest_level='gradient' !!ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' @@ -985,12 +1006,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1004,26 +1025,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1095,8 +1116,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1113,8 +1134,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1123,7 +1144,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1150,10 +1171,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1161,23 +1182,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1204,10 +1225,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1260,9 +1281,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1307,7 +1328,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1338,8 +1359,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1347,7 +1368,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1361,6 +1382,7 @@ tau_u=0.55 adjust_theta=.false. !!adjust_theta_above=30000.0 adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1377,14 +1399,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1394,7 +1417,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1404,10 +1427,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index 22c3c074..8b9d6809 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -73,169 +73,162 @@ "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "id_tlm_tests_default-C12" %} +{% elif task_ns.conf_name == "id_tlm_tests_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_id_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "id_tlm_tests_default-1PE-C12" %} +{% elif task_ns.conf_name == "id_tlm_tests_nwp_gal9-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_id_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-1PE-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-1PE-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-1PE-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-1PE-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, "threads": 4, }) %} - -{% elif task_ns.conf_name == "tlm_tests_default-relaxed_solver-C12" %} +{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12_op" %} {% do task_dict.update({ - "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "relaxed_solver"], - "resolution": "C12", + "app_name": "jedi_tlm_forecast_tl", + "opt_confs": ["default"], + "resolution": "C12_op", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-relaxed_solver-1PE-C12" %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-C12_op" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "relaxed_solver"], - "resolution": "C12", - "ancil_resolution": "C12", - "DT": 3600, - "tsteps": 13, - "mpi_parts": 1, - }) %} -{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12_op" %} - {% do task_dict.update({ - "app_name": "jedi_tlm_forecast_tl", - "opt_confs": ["default"], + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], "resolution": "C12_op", "ancil_resolution": "C12", "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-C12_op" %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG" %} + {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12_op", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, + "threads": 4, }) %} {% elif task_ns.conf_name == "integration_tests" %} @@ -262,19 +255,18 @@ {# List of configuration names that have no kgo #} {% set no_kgo = [ - "id_tlm_tests_default-C12", - "id_tlm_tests_default-1PE-C12", - "tlm_tests_default-C12", - "tlm_tests_default-C12_op", - "tlm_tests_default-1PE-C12", - "tlm_tests_default-4OMP-C12", - "tlm_tests_default-1PE-4OMP-C12", - "tlm_tests_default-dry-C12", - "tlm_tests_default-dry-4OMP-C12", - "tlm_tests_default-dry-1PE-C12", - "tlm_tests_default-dry-1PE-4OMP-C12", - "tlm_tests_default-relaxed_solver-C12", - "tlm_tests_default-relaxed_solver-1PE-C12" + "id_tlm_tests_nwp_gal9-C12_MG", + "id_tlm_tests_nwp_gal9-1PE-C12_MG", + "tlm_tests_nwp_gal9-C12_MG", + "tlm_tests_nwp_gal9-C12_op", + "tlm_tests_nwp_gal9-1PE-C12_MG", + "tlm_tests_nwp_gal9-4OMP-C12_MG", + "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG", + "tlm_tests_nwp_gal9-dry-C12_MG", + "tlm_tests_nwp_gal9-dry-4OMP-C12_MG", + "tlm_tests_nwp_gal9-dry-1PE-C12_MG", + "tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG", + "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG" ] %} {% if task_ns.conf_name not in no_kgo %} diff --git a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc index c5dbac60..ce208279 100644 --- a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc +++ b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc @@ -17,23 +17,22 @@ "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_full-debug-64bit", "jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-1PE-C12_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64", "jedi_lfric_tests_azspice_integration_tests", ], "jedi_lfric_tests_op_azspice_developer": [ "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_op_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_op_azspice_gnu_fast-debug-64bit", ], "jedi_lfric_tests_azspice": [ "jedi_lfric_tests_azspice_developer", @@ -44,6 +43,7 @@ ], "jedi_lfric_tests_azspice_build": [ "build_jedi_lfric_tests_azspice_gnu_fast-debug-64bit", + "build_jedi_lfric_tests_azspice_gnu_fast-debug-64bit-rsolver64", "build_jedi_lfric_tests_azspice_gnu_full-debug-64bit", ], }) %} @@ -58,23 +58,22 @@ "jedi_lfric_tests_forecast_pseudo_default-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-1PE-C12_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG_ex1a_cce_fast-debug-64bit-rsolver64", "jedi_lfric_tests_ex1a_integration_tests", ], "jedi_lfric_tests_op_ex1a_developer": [ "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_op_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_op_ex1a_cce_fast-debug-64bit", ], "jedi_lfric_tests_ex1a": [ "jedi_lfric_tests_ex1a_developer", @@ -85,6 +84,7 @@ ], "jedi_lfric_tests_ex1a_build": [ "build_jedi_lfric_tests_ex1a_cce_fast-debug-64bit", + "build_jedi_lfric_tests_ex1a_cce_fast-debug-64bit-rsolver64", ], }) %} From 9aae208f81f16f7b9415d0570a80761c6f945965 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 16 Jan 2026 10:24:00 +0000 Subject: [PATCH 12/68] SR response --- .../adjt_mixed_schur_preconditioner_alg_mod.x90 | 1 - .../algorithm/solver/adjt_mixed_solver_alg_mod.x90 | 1 - .../solver/adjt_pressure_precon_alg_mod.x90 | 1 - .../source/driver/adjoint_test_parameters_mod.F90 | 12 ++++++------ 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 index cf4d79ec..a574546f 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 @@ -165,7 +165,6 @@ contains call create_pressure_solver( pressure_operator, pressure_preconditioner, pressure_solver ) call create_mixed_preconditioner( rhs, pressure_solver, mixed_preconditioner ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 index 48c05049..40df64f6 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 @@ -195,7 +195,6 @@ contains call create_mixed_preconditioner( rhs, pressure_solver, mixed_preconditioner ) call create_mixed_solver( mixed_preconditioner, mixed_operator, mixed_solver ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 index e0e4bba8..d5ae284b 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 @@ -152,7 +152,6 @@ contains call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) call create_adj_pressure_preconditioner( rhs, adj_pressure_operator, adj_pressure_preconditioner ) ! Size = 1 as only P field needed diff --git a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 index f4f06ea0..09f74b4c 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 @@ -28,12 +28,12 @@ module adjoint_test_parameters_mod ! if the ls is not realistic. ls can still be ! randomly assigned, but in a sensible range ! to prevent these issues. - real(r_def), dimension(2), parameter :: ls_u_range = (/ 0.1_r_def, 10.0_r_def /) + real(r_def), dimension(2), parameter :: ls_u_range = (/ 0.0_r_def, 10.0_r_def /) real(r_def), dimension(2), parameter :: ls_theta_range = (/ 280.0_r_def, 340.0_r_def /) - real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.1_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.1_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.1_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.1_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.0_r_def, 1.0_r_def /) end module adjoint_test_parameters_mod From 78a319f8bfa5756e9f18c6632db918c88212830b Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 16 Jan 2026 14:28:42 +0000 Subject: [PATCH 13/68] rose config fix --- rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf index 8d9144c4..ffd315be 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf @@ -1,6 +1,7 @@ [namelist:formulation] moisture_formulation='dry' moisture_in_solver=.false. +!!theta_moist_source=.false. [namelist:section_choice] !!aerosol='none' From ae855bb7f8fb2d7c46dddde47f43cd4d86242a50 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 19 Jan 2026 16:25:30 +0000 Subject: [PATCH 14/68] Adjust test tolerances --- .../app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf | 2 +- rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf index cf06d8c5..d9c5499f 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf @@ -1,5 +1,5 @@ [namelist:jedi_lfric_settings] -adjoint_test_tolerance=2.0e-2 +adjoint_test_tolerance=1.0e-3 [namelist:mixed_solver] mixed_solver_a_tol=1.0e-21 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 26f49f90..99c205f8 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -615,7 +615,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-14 +adjoint_test_tolerance=1.0e-13 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] From 4a5487c69fa280a204e50c3df2431dc5aa1701cb Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 19 Jan 2026 17:18:25 +0000 Subject: [PATCH 15/68] Canned tests --- .../example_id_tlm_tests/configuration.nml | 197 +++++---- .../example_id_tlm_tests/iodef.xml | 8 +- .../example_id_tlm_tests/mesh_C12.nc | Bin 85708 -> 0 bytes .../example_tlm_tests/configuration.nml | 205 +++++---- .../example_tlm_tests/configuration_dry.nml | 405 ------------------ .../example_tlm_tests/iodef.xml | 8 +- .../example_tlm_tests/mesh_C12.nc | Bin 85708 -> 0 bytes 7 files changed, 251 insertions(+), 572 deletions(-) delete mode 100644 applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc delete mode 100644 applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml delete mode 100644 applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml index 53acee0f..16e0fbb7 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml @@ -1,13 +1,10 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -36,19 +33,16 @@ time_step='P0DT1H0M0S', &jedi_lfric_settings forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -70,6 +64,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -79,6 +82,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -96,12 +100,14 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', -diag_stem_name='', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', +checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_jedi_lfric_tests_to_linear_model-jedi_lfric_tests_developer-with_core_3/run1/share/data/restart_jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit_tstep', +diag_stem_name='diagGungho', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +ls_filename='final_ls', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +start_dump_filename='final_pert', / &finite_element cellshape='quadrilateral', @@ -117,10 +123,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -130,27 +136,36 @@ shallow=.true., si_momentum_equation=.false., theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -171,9 +186,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='analytic', +init_option='fd_start_dump', lbc_option='none', -ls_option='analytic', +ls_option='file', model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., @@ -185,10 +200,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -200,7 +215,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -209,22 +224,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -237,26 +255,30 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.true., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., -mixed_solver_a_tol=1.0e-21, +mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., reference_reset_time=3600.0, -si_maximum_iterations=7, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-1, split_w=.true., / &mixing @@ -265,6 +287,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -272,15 +302,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=1, +panel_xproc=6, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., limit_drag_incs=.false., sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -292,10 +325,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -308,24 +345,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -337,8 +377,8 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', outer_iterations=2, runge_kutta_method='forward_euler', @@ -349,10 +389,11 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -362,43 +403,45 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false. -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', slice_order='parabola', +special_edges_monotone=5*1, splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml index 1de565f8..7d20e408 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml @@ -47,7 +47,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -396,7 +396,7 @@ - + diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc b/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc deleted file mode 100644 index f7ea6988e22a06194aac0d17b6e3be62cd539773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85708 zcmbr^2eh39y{-MV)=omN(u;-;Dhenn3P=}FM3mk_fB?~uAcSTG6)ULN3n&&;6uT&b z1?&xb!-@ra!`{&E`K|rp@tonk_l)s5?sMmV&G&^obMFmAj(hL3-()oVpOuSwF>~F{gL^ryO`TeV}oSmC5o7M!_k$@Gu%Yp-_tqO(q0uzcAW%a$xV_59hlS3Gsm zveOqWKhsC=taR2Hr!6{j@ktAp4A1}VbPGUVM^wPg=I@%##)!F>u;9G;|2l{7)0)2h|EE7@`fT=(nV!QRv)=T>@QW>7y6B|ki_clS z{J*~DtNTU%_0H_qdA;e^`2X?8{Og_JkD2~CX1_Vh{;$7|cmDm4nf`%&$Nz6`OBOGE z)a)O#^3r8z`i2ib($l}reBGx1+2imFhO6)I*-MrzSbWx!g-cJ?`Rnmt@7?iId8b8> zK6_z5XNwmuS+Hc`^2N)~p8YG)`*-}TczyMgmz}B$FJ6Au{8RcH)BKZ`ow;<;ne%=B&$>sy^k|i{mM=VW zd4DCIylDCt@*R78eY)@Co&K}3zv};M&wqWN|Mz?T^Uu$J+Oxy|e$Q0IkpJb5J^uTS z|N7bcpF4aV{`2?cKmSbs#~lYO?Qf+11~C8J(-xm}+Wh`@))(KO;H>#e7cD;Zv=e<# z7A@?N^8dACJb#Ki6%uWB8 z?*HS@-oO5s{$}(){<{578+ZD*@0CB)Pg^VJFF$wL>`z&r7B24xuphnYpKkWY?tlCJ zy4seN|MfS^*?-nd|C#%58&>OQc#zHb*PK2begD6^&i;M)f9ty9 zzx@sBKY4C+$MgTJIr^WTtKH!_{d?-H;J>-v{ZdpH`1M-gU1L{#l`O`_Ix6VC3cZxOt8?k$72&V5zbpxY|8 z4&Ju7w+Y@l_qM@X=iV-O>)dw@-a7Z)g163n_n03#_x8bi{&3%;ho=w#9u?@YcCc4&FNVqTsD_pAx)v z?o)%e&V5?&*0~o4Z=L&*!CU8kRPffhm&6I7bKe#=oDiqS(%@~2ds*<-xz7mRI`^Z4 zx6XZL@YcD{3f?;R^5Cs=pB=n)?sI~-&V6q1*169M-a7Z~VT11ccuerN#r@det#dyv zcbPYK?-?(s^c4Z4fsslnS8 z_tS#6&i(Y@t#dykctKx;B zbH6%X6gu~7;>DqJzcyYHI`@_F($KkI7cUE)`}Ohi(7E3bmxZo-ynSpobXS#c3>$25 zzbSa@+*ijHp>w}EcwaHxZz*}}+;0uuI``Xxx6b|c;H`7NBY5lF?+o5L_q)OdUH5pG z*$va~n!0xfZ(H2&3En#QwZU8Ges9>IbNBt6dh6WR2X9;4?+e~K_xppl&i#Slt#f}c zcKxIY}cb?%P@Z=L(2!CUA4Sn$@lKOVew?oR}7o%@r) zTj%~%@YcCM9lUk!&%_O(>mDC6yJ6bhRQK87ZHxPJ!CUA4eDKz}zYx52?k@&!o%>6{ zTj&0A@YcD%61;WpuLf_O`)k2l=l*)wpz9tVH@jil-CXyL;BAZho55S>{#NkTxxXE} zb?)y3Z=L(Q!CU9PC3x%H-wWP4_xFRh&i#Ynt#kh{Y|wR&7td~(cDL63D0tiA{&Dcu zxqlM8b?%=AZ=L&R!CUA4dGOY`e-XEY&i%{aeamqFs^qP6|2lZ<+`kDMblu~#XE#i{ z+v(-U=l)yp*17*4 zHt4#?7tU^&cDL94BY4~5{%7#kb&rdwcb$9e|Kr^j_juCHyUsnH>E>PM9?$9KUFROp z?dDzQ9?$FMUFROJ(9OHfJzlZfhC287lDKfT^LvT$%H6!%;vTQkZ9|=VylV7uy2ZU( z@UEKPtCzfW?lpq9&b?;v*16XT-a7Z%!CU9PQ}EWg*9qP__e;YD-MX<}@V3Rhe(=`0 zHwfN3_l9AE&b?9a*10zh-a7Xt!CU9vG)cm{4Rw?2;`(mh zZE;WD*Uh`mJ$ZjO?>hJ71Kqsq+>;M>^R9DGZs_J+=bqfy&AZM$`A|3SI``zm-Ms7E zlaF-su5(X5+C6`^bI%;!ZG-L}v3YD3+s8d)i_m$tLu?s3&vuNhLg(2|v32M?yH{)z zI?wJM+lJ1wonyPud3K+;Yv???Z`>_(p4~6*9y-r_E#DqG&+Z>Qx$hDW2%b96b`737 z&vpx*I?r|wo;uGS7(8{J?GZe6p6wYtb)M}NJawM!9XxfO?Grq8o_#WG(0R6B@Z`R4 zJSceTJlj8b>O4Cjco;uHt44yjAjtZVS&yEhBI?s*? zo;uHt4W2sBz85y=JUc#kaz8E>1W%o3Cj?KOXA6U;&a)GPr_QsJf~U^2lY^(uvqiyE z=h-R2Q|H;K!BgkiX~9$H*)PKeoo9~>p4=D5qk^Z-vn9b(=h^AOQ|H;z;HmR$S@6_( zc1G~jdG_ewsq^g2;HmTMtl+8hY$^F83a`4o7 z_LShM^X#JFsq^fq!Bgki(}JhYv!@47ooCMoo;uH-89a5KJu7U`d3JH|)b(t#*04e6 z*|UQu_ewQPn~Da51u;DUJyKWp1m-5>O6Z<@YH$s;;=#I z*-L__u4j`?XE#hc&t4WhxxX}C9z1oPT^2lbo?RY1b)LNTsr_Qst1W%o3Zw(uCp1m!2>UuWWd3M9J>)Ff^^*nR;`-+((yLr}m zHgi-r&pOX$j_&4J=h@6L-8}0&n>n_dXPsv=$940p^K9n$Zk~0X%`E8VS?Afz3Eei- zc{a1K+lD&NW=@>lpqoDXK+oP0Z;$uK2jiWg^X!IrSLi&uF|G-nXCI1pht9JP$9qEO z*+=5q(0TUJcyH)D`&e8TI?p~H*N4utPsIB|*R$#WjcYt~o_#8Ka{pv}I(X_l`%LiE zd3ICq)Oq&V;HmTMbHP*R+2@0&&a*EBPn~C944yjAz7#g-Jo|F+)b(uof8$zh=sf#s z@Z|oL_*(GPdG__-sq^gS;HmTM8^KfO**Aly&a-a?Pn~Dq4xT#Cz7srko_#lL(0O)C z@YMBewAJi}Y3JGZgD3az#Sem~&a)o|Pn~DC22Y)5KMI~Y&wd;{b)Nkscvan*>i?&qfPpH%vRv?i@V1ZyI+Ao;uIw z2Tz@6n*~puXPXC4oo8DFPn~C522Y)5TLn*@XIlqPooCyG4LZ-Z4W7E5jZTj?Ogqo+ z8a%mg7k3MuI?wJNJawLJA3SxQ-6MGFJiBM`)Oof;@YH#>WAM~@wo~xbd3LX`LFd`M zgQu=%qw}K;)6TQ|1W)ce$9;pR&a?XkPn~DG1W%o3_Ya;r&mIswb)M}SJawM!7Cd#H z?H)XJo;@&Z(0R5;@YMBebWyZn+VyPaux_5Y&zu;CcJr+BY~~T&JnKB0d3ZO^I?rYf z>E>DI+04VbdDeM0b8t7$I?rYv+Rd}hvzddsdDeM0^N?;E>O7lyaCe?M&t?uBO*iN~ zoBm6{NzeD}eBUhY$zI*p&*Gl!-F@9G?#Vvg@14ax*|+=JS=^KTy5BR4d-9;}chBOU z?B9LOEbhqx-S3*kJ;`(Wd#-oR-jiIXzbAV~pWS``{hn?5H?o<+Zr*VFy6}eE*Nr#a zzOKCC_I2kCx9(lr{r7Wi;69pLcVh5{ z`=sCv_sPK4fm3;0o~*6W;bvj&8s^- zc*DIkc*DIcc*A{0@P_-*!5i)~gE!n~1#h^Q2XDB~4&HE|6TIO*H*7%nc-z?x+(#?a zofo{}K0kQF{g~hl_hW-M+>Z<1a6dkH!~KNd4fhj+H{2HlZ@4cE-f%xDY(V#To7oNA zM=RDnIe5eUl;92bMZp{Hrv`7hpBB8~etPhR`x(I-?q>#XxStig;l4O{!+lBEfbQ|u zvm3aNR;qh;@P_+2!5i-925-184c>4+FL=ZK{NN4u3xYS?FAUyrzbJUa{o>#a_e;VC zbdR^1-N1dca@|XVH{34^-f+J>c*A{J@P_;H;0^aHf;Zf+4Bl{G5xn7kRq%%U)xjI? z*Mtq|9&b6jf%|Bcy4MD8xUUS}aKA2i!~Oc;4fh*@H{4eRZ@AwWyy1RR@P_;9;0^bi zgE!o72^-Ko-ePtG_tC0#Zw=mXzb$yf{r2Du_d9|&-0uwDaK9^f!+lNghWp*Y8}9c6 zZ@8}w-f+J+Y(V#T^VtpDr~kVd-*?_I{om5~zVnXh|8BxYJUo5{AHrV3+a`4u)hWC8+6?>N6v1TcHgP{Zt%9neM|7xxxW{@b?)y6Z=L%G z!CUA4Ver>Tj#z#c)bP|blXtpo>?_)u*JPv@V3Q$Y}lY%J=O@`wz$^}-a7YM!CU8EJ9z8dcM9G* z_d3B_=Uz8>>)h)FZ=HMn;H`6S5WIEn4THDNeO%a}+bA{;-nO_m3En#Qromh1zH{)_ zx$hFZb?*7WTj$;^c=WA$N*?7Dsl-ehx=FhaIw?yHP)DBRgb2 zXQO_$Ms~=4u15VVjqH&99F6-vj@mKmXK2*V&8VN1=?=L^>=|~*y`rCm=?>Y?!Km;3 zbcgKwKI(ft-68uvk9=?Kko}B~`njC$ko`=K`Z=8Lko^pf4h}nHKXW5~cF2ClM*Un( zcgTLG#*52#j1G&#@x-u0UJ(53kWY#yhaK`M`MX*dd=D z&j>r@GvirdhrBp02|MJo<2hl6d~RGCcF5<&^TQ7Lf_P!rAzu_P4m;#ag5L#0zN~zC z*dZ^=|LtWvMwiDc;+0{Cydqu|cF0%9Yr+os+PE_8kgto^haK__aaGtM-xzNSJLJ{z z=CDJ)CEgl#$hQSQJLEg!oneQ3SN@+Y+cCN(-W~4=JLI+T-ne4O>&olH4*9-#f7l^E z5FZRX8#yiWex^|>A6bz{9)zt8QE;|*fNsG8och7&%vK@XOF}`Q)7~2oIQ+e;$VaT1!`^LS7 zykB|$xX+LeD0hophTOf}BX%9queEnPaL9ei{bH{nA5g z#z|p^JUJGH9rBboHSCb5<^TAy9ey7%eq=lr8P5tk}?eP1E@jK$3VTXKIToZQ4cgK6e4tZ_7H|&tt#r0u_ zd|$jj?2sRb4~8A`hPW~8kROTC&0&Z9Mtn2uklzY^cF6CS zv02z5H;*mC4!LFIH{Bt(j%~sYxo!TtmF@8Rh{;{!ZefSKdu$(e$a};+!w$Ja>=<^) zo#I|$hrD;}9Cpb2#C^jKdB4~t?2z}52ZSAR*WhP|+&vx`cE~;QKdfwr-$zXLioL@Q zxlimHcF6tWL1Bm7KMn{xAinEvlAjw_FfqvQBEA&w3G!Z;}wg#P3>B~A?esj)Z~h5nJTBu)#xUuRi7 zD)eW>nXxqVXT{m^=+K`N=f(2SpC6Bnb3^~Q+@D%LCiG8;C&n@H__!c03_J8siYJF1 z`lrN2VTazI>uF(!{^{|IutWdMcvjel=fuD3 z_+;3j|5SWB?9hKEZVEf}pN-Fj9s1A57s3wx7voD|hyKg)m9Rtq)%aT2q5pdDvqS%l z_-5Fl|5pCDmF<}J-zmQvc6>W-iSLCS`tQdN!Vdip@=U z(C?c6A!R$J{qE%h!;alzkJvNp(C-y{haLKTV&AYszh68k?9lHY2ZSB^1LMJAhyEdP zP}re=XdE1N=pPpR?9e|v9uaov56ypZ*^X&{czHzFaabG~M}-~wqvM#cLw{@>7k226 zj|E|e{)AWhmcIeNG^TQ7PW8$%4hyHQ#_^?C&gm_}up}!#b*`a?@ zJUQ&pKPCT{mhG7KPb;4h7sXTKnQ?JEJ@l8vbK+T{e{MW4o*nw<#|z`q(7z~N5-$k7 zU+d-Z;?Q3fuZWk0{+02nxIFZ)j@QN&p}#U-AFm1h8%F)jqI_NG-xzNSJFbeW*=sy*o4m{b%EIVTbJ`qcIdyJ|88YFru{d{Z-yN=$G76!VTb-Z@!haPe@lEX z?9hKdeh_x(e;Buh9r_=|kHZfAPvWOxhyG{r^RPqzi}+>Oq5oCgV*!&lz{yQ9oxA zGu`db&*_CZbNk#5{hWERLZ92ApR;0rg46rl4*i^!W0gL)!|yBRtQxEJxgGjBtH&CB zZijx(nz2@&+o7MccHF7Y?a{!w&skv3J;^-zWABJM{a-gTfB|{&7Iqp+7Jl9Cqj*5(kAH`iI8BVTb-<`Cn7E zW7rBNE{l6g&q3C3Ae_T91?9e|Uo)~uMFBpwRx0dag_D?FG9Cln7Pl=1d z4*gT(X<>){>G6!PL;uWpR@kAxI4%i0^v{mxgdO_l#-(A0{(15IutWcXcwyL~e^IE89 z5LbmA`Zva#!Vdk_@#e5Y|CV@b*r9*hXf$58Y=_?OBSz!yw~t11ckXk)rkwMR@;-ge zSI&87dEY*_LC$$sdA~llU(UIv+@;TbP2`++m-p{;9&*lm$_Mnhud$qSZMkco+a>3` zx7@AIeb3~a>&o5x+}BCYxxRd0pZgh*bKci)gC0}n?Qh0&-e12*$yh& zFL}!^l#eKR%P*FPmb~Sc%EQXMr}^dlm-jjE(aPml>JKk@%deJ4l)UBF$|FnO^6TYM zC2x6id34EJexp35{J%VR>@NTi#kODtXHvm8X=v<&Vo#OWyJ)YS;<@8R-RGv zmcK21eR#{?m1mZ`A_pB8qbLFkgJu?4Bm3}cvkS1YsAHo_cYhce^IwT z;fCc}aY^u&Ysa&Lx9oc~_c_5^t`pA<-g4czG?aq7D zuQ~SXza@B=V}Jg)2Jdq0kAGY6F30yN-yZ(Ba=c6Vj^JI6cP-x;yvy+e%Xfu8Z#mwp zye4>;<9*9_2k&ycfBBy9>z3mOm)Az#a{SQzk1F}RcQl%}Tc7)L%DLB-yZ3pY*_?ZQ z*{?s@Z#L(?uiT^0{Tg!a`^!E1eBf-({Xp5DYx0oUocqCY?>_fy%DFd`{kbO(o6Wg5 zmibQ}KAUqtRQ7944xP=pA1)u%=fh`n?nnB4(9%91nZK|1N9*miLw>A0ptM7Nyv%L7 zLw=&qz8-eSPnNk(cgRom`JmDc`ROwE=??jsJ|A4#A#W<%GTk9R+vh_{JLKoewoP}) z&*y(e*^cqHey3be+9AJN zo>1B$Zz&g+cF6CQCzf`|@0TZ)cE}%;Czp1}AC`+sJLIk9DWx6qN9C!d9rDNJX{88@|Wf5r5*BD<HBYoysdn6X@~r6>FaBU{9SogX@~rM{^ykK7;j$wq23-l$r-|5~13+9Cf|KBlxo{=Ix`X@|VMd|YXV{73ot(hm90@(HCK<-Ae;ew}uV z=l6LWPwcZD<-AE;&}Tc!c{6cgpY15;&50-V*^YAF+<0=I?I`E<3(R{;pY15;tq>RW z*^YAFit*Gw+fmM2DW2A6JIZ-0$J6_4M>%hmct)S?DCe!3e_sbX#&<4Pi)V%%a`kvt zOom*eyg2NTYsMvEhg>V39d^jI<2hl6yi+_k?2zlkrD2C$H=Y-E$o1m+VTW8lUJ!Q3 z4f5~%WXE`ua>ICG*daHH7lj>i<9Kn{A^kBg2|MJb@zStE`kK5f?2vbfmxmqF_x!T3 zLv9wAhaGbBctzMDw}@AU9dgV3pHQ}A%yp}{BJ7Y`$E(6KxlOz}?2y~WYr+n>UA#8z zkavwM!wz}3cwN{b?;fuYJLLB9hOk54Bd!WNucTfz>xbG$X|koSqVg&p#~@%FGo-Y?z}cF0}goneQ(f4nQ~kPnD! z!VbA>{!c2~G46Zh->J-dci2(-cP{hZ6LysToy@#z!;aFwvzhnau%q1dTc_dVB-){j;D+}BD!+8{3N^GDPD zME8clnY%3;1?M(R`;AM^ZJPF*l$_f%?fbc(I=5-s_j5mWZqu~y=YHzkrfEOFbchr0?f`#MvhOw!zsZeLwdj z&Nk`q8k~I}^!?nA=7;ZtzMuOMXWxhUv3+p1Nq>*v%w6Bl{nVMeeuua!`aXRSe(KC!-_QNjnY%6h+)tgk+p=?T=5EVkkgj-1QF&&fN8f1ZVF0hX-fw`bPw3?)pRHrfAb-PI*{x=5EX3!I``Mh~Ug! ze`IjpBlJfFXYTr=gEM#iF~OO;{@CEmU4L9~=B__JICIx82+rK~C&bOsrpcP+!r;u^ zmJ@?Bcl}AhnY;ev;LKgWC^&Q1pAww8>rV~N-1VmgXYTsN!I``Mk-?d}{!wv4aMv%1 zTcb^rP0G`QGk05-250X2Wx<)d{*2(vUH|Cd%w2zGaOSQ*D>!r4FAvV#^=AiX?)r0r zGk5*D!I``Mytpk+$bZ}N{NT*pmd6BV?)t|DXYTsP1!wO1#|LNb`X>Zu?)oPNXYTq7 zf-`shg~6G-{z<`^yZ*_+nY;ceaeK6Ba_{n@;LP2Yrv_*4`lkhF?)s+(XYTrE1ZVF0 zX9j2P`e(%j!CilGaOQqNToRnQ>z^H*x$B=3oVn|t+uwIqD%&*KqkpU(*3FrFTV@U@ zIdiX{*{$Tvy?$oLk~8=EnXO9B-0NpHEID(ppINQs%)NeQTynl3>L-6FIdiX{{IulE zy?*lTGUus#{p1VzuiIyvR*lQ!dG#MHFO65k^ZWd<*?#oO@&$eV_-sGAqI_YWKQY^n zURA!R&!3#_N3Skl+~-ft_M_L7FX{8AXZz7>%a``~Gqe5Z%JOA>zG=1}y{>$DpFca> zk6vG1*5}X7_MPaN&mj!Y?J=|!PzGL2ZFOr`VU6VQ+NFh z`R`KNv_sq&oVnZbq2SD2|KZ@wUH_5b%w7M{;LKhBvEa;I@8^y)cfFrG&fN8W?l^PT ze=0b0*MB;02=4mN zcm0=xGk5)0f-`shSA#Qm{nsMrsk{E``5#i=5c|i?!I`@)-w4j!_1_H6-1XlI&fN9i z4$j>5-wDp#_1_K7-1WBvXYTs%1!wO1?+0h@`X5Bj(@pvx=6_si)1h%|aOQ5ykAgFI z{f~n)cl}R-Gk5(@gEM#i&w?{|{m&FVt+}kpql$^QOk7r8G z-0R14O3vKt$8$^0-0R2lO3vKt$19XMPdC+%SBwk$Y}0w&E0vtNw`II?$(eioc$Mg! zZmJ)z8Vc^kc(vfny<)t2aOPe=UL!bjuOF`&oVnMJ*9y+u>&I&cXYTdmJ4Mbm>BsBD zC4IK(Dc$P^XYOqouNOH_-RsBeN6t1)w`@>yu9|Myu;k2Lzfo}JuHQH~bJuSYoVn{a z4bI&4cMi_n^>+!*-1YP0rD4-^`{(c%x;b-i%jAnCXYTcrFO{5qAL=JxE;;)?)K9)r za^_w?`D)3Td;R2VC1>vSldqSYxz|r_E;)0rpM0a_%)Nf{&5|?s`pLJ-E5oMkWAnPt zx8<_#d&Cxf{z$o5+%vZ9^R;E~jdzHx`h0cSd*dBr>povm_TG4>*rv}fD0^>wuh_QF zPcM6KeDBz<&yOp6Z@hEdwa;giy*Iv3+^x?im%TT>Z`{4lN0z-ezF)k(&krek&p(H! z&bdy1Uv&RIbLMK>1A;SG+jb4kT)nqjaOUd0-Geh%?>#U$bM@XH!I`V~_6*Kky|-6z z=IXt@gELp}?Gx{hHcj8#x8$6we;$wb3(j0^dr)xZ>b?DgGgt2&5S+Ps@4(>9)q4*P z&Ro6c>&BU@_YMlqT)p?u;LO!~2M1@Hy!Wv9WZ2}rLxOXzqZ`VH2WPIfJt8=B_1>Yu znXC5>3(j1b)a^Ggt5VIpECIdq)LluHHL3ICJ&hF~OOu_l}LPgiYQ%E;#2p z{e98#-JH4Fwjelj_1+1=nXC5}24}9`J25zO_1;OrnXC6s4$fS?wcUpWeZ1UdX;GFC9_eGEF=FHW$M+IlD-dhr!xq9#P;LO!~OM^34?=1_?T)lTj zaOUd0M+axF-a9imbM@X?!I`V~md7u{ChwgcoO7N2zUZ88&RlIfH#l?k-g&{9tM|?i z&Ro6snBdISdyfsyT)p?W;LO!~j}OjVz4wIR%+-5O49;A=cR~CmZ1UcP!8zCI?~9() z&6%rhPY%vpz4w&h%+-4r1!u0_dunjz>b<80XRh9RdT{3Iy=MexuHJiQaOUd0X9Z`j z-n+QJcg`(s^4=xEIoIj$i=N%hnX7Hj3C>)-_uSyj)q9r)XRh9RUU25>z2^sKuHJh= zaOUd07Y1jp-g{AS=IXr{N6u4M@4Y1dwMv`3_tN0Zb;WpDaOP^;%Y!pl?_Cz0xq9#N z;LO!~uL#auz4yxC%+-5W1ZS?^dsT4e>b+M7XRh9RP2@av_1 zf-_g!ULTyfdhZRvnXC7%3eH@;_r~DN)q8IW&Ro5Bb#UhDy*CGEuHJh~aOUd0w?@uW zSMR+o|LsbfdT;uB3C>*S_xUF!XRd9V{J!MOwfAO5C1jCb|JJ zk$7*P_bq#G{L#3s&-;|UH~v^$-{-x{-Wz{B-q+{7%HEs)-@C?r-m|;+rvEJF%=Lcp zso>1jwoeCVuHO4haOUd0n}Rb}?|n8nbM@Zmf-_g|eLgsI_1+hPGgt3@F*tMe-k0JN z!PR?T9*st;m2H~7_mz?}S6_p#24}9HjIRY}uHO54aOUd0n}ah~?|maUbM@XggELp} zeJeO~_1?FGGgt3@CpdHU-ghJCsjK&H$$!JrChvVOICFhid_OpIwe1JNnXC7H7@WC! z@7CbV)q6h*&Ro6s7-Q}0by4bC?8-ek4l%(eF>s|RPUy*F7S za-O>O!eq@}I-t*O@}7SdPn~@qF6dr6ICGsFcM8s2+csGzICJg2$-2RrYwu0gi=3yf zy*F7ua-O>O-eiN|%+tM@h!&Ro5>MR4Zoy)A)_1Qd)q|LQ&;b8 zoBzVnChu(*oO7N2-srB~oVnU|x8Tgxdv_1cT)nq_aOUd0djw~$-n(aT=IXs2f-_g| z?HHW7dT*!T%+-7Mikzpe-n)1Hr-6_V_vz-$)wcTvXRhA6UvTE?ynH6oU7kw z%q-~U%(ZPZ$CsSB_TJ2KC1Dje~~shDE8{SzT7h&8hiKoy0U(9aO~6P z_m=gOhsC~qzIL{s98&Jr=l9I^lZTfN>hrs2`^h89{rh~)Y(F`)JfP3-n(Zftl?V3u zowNOf_k;WVj@f=<*F*aJ_St^YZogmS>Td=UUl-0?ZSi&E%vJB}%DD~G-q)RT8>YSQ z3+FaWd*3(CZJ74HubkU3?N2BS!?Zs+e?Jqsj%Lb5 z!I`Tqrvzsk^rr@A8}z3IXB+g3gR>3#M+Rpb^p6V8Ht3fGXB+gV2WK1fOM|lw`el*x zbc6nk{QZpQI+{~HIyiH+<;>vBRex4+=Bi&FoVn`H4$fTl=LBc2`g4ObSN(axnXCT% z;LKJ3nBdG+|JcZRxYo-lPdDhFp8vLGuA_P7GlDZ$Tb>!5x$2)4oVn^R z4$fTlmjq|7`ez4cuKMQ$XRi9^24}ANOM^34{quq|SN-!N=jjIh3-aHl%yqOv`NH7L z)s`0pXRi7e2WPJOmjq|7`j-Z0uKJe+XRi8}2WPJO%Yrjk{pG=#tNs=Bj^taOSFiM{wq< ze`j#!s()8-=BmFYICIs%J2-RIzbA5@ZqQ$w|CVL0qm|3|24}9eTo;_V>aP#ZT=nk@ z&Rq5H56)cm9|+D|^&bq*T=h2uXRi7igELqChk`R#{f8sx=?48r^53G&b+k(P(csM0 zmX8HzuKJG$XRi8B1ZS@LPX=eM`cDOCuKG_0XRi9s1ZS@Ln}Rb}{bz$SSN-QA=jjIh z=kwpZ%yqPCT-wc-wmA3eY1%(Z^>f|4`W`q2wZ&Rpw9FDf~6tslL(<;aBkDI|9N>! zv}xM^qU7ABY5&WTbDO69uS(8sn)bggIk#!r|EA>JrfGj$$+=C_{Hiv>ZPNcOINPNEdvLZ% ze|vDYN&k=FY?J<vSGb@#xx!2FETyo}KKeI}tI^9%1vugft=yRJ! z7x#I!;LN=(Gph$@?)5Wk1ZVE`GiwHC?)5Wk1!wN{GiwKD?)5Ww3eMc?XVwYM-0Nr7 z4bI%_XV#0Hr|$JL>qpKuO}A{2|5e@TkDgU-7@WD=vQcp6uHQH~bJuSYoVn{a4bI&4 zcMi_n^>+!*-1YN=Gk5)F!I`^$^We-~zeVIcb=Pm1{~OCTjh+)--1T=4&fN9e2WRg3djx0h`g=ys(@pvv@_$p=rqMIX z9fLD>TXqW0-1YYg&fN9)4$j>5I|pa(`uhZD?)v)%XYTs@1!wO1U4k=r{r!V8cl`q* z=jkT>uK8bGwrTYAa<|~j-Im>hGk5(1gEM#i9>JNre$U{{UB6dw=C0p6ICIzU6P&s0 z_YKb6_4@^9?)nEs&eKi${quiw*{0Fc$^(KkcUuk&&fN764$j>54++lP^#=uK?)rxY zXYTrggEM#i!-6w+{UO1byZ+(9nY;cGk@Iwu{?Pp2QnqRI)bg<4%-xp5gEM#i5y6?e z{>b3WU4K+?=B__FICIw@6P&s0j}6Y;^~VKg?)u|{Gk5)h$a%U+e?tCmE!#A@sJ}1m z(ao8ATP8d?bFZJ+!I^vg#7@rK>nFaqoVnLee2+PEub=oja^_w?{r5tgxz|tsy%A^b z_0xZ^#F=~j#P{)p;9fuJ`#k-3Rc#uLV-l+k_v*u~n+c!YYYew;&hXj2=5Xug4xim? z4YzLI@Y%igaO+kWKD+NU+`1Kq&+c`GTes5i*}d*?>sB58*m!Xq3^w;3DlQukH=%fw14xO~&#-ZD-;-GL#8y-5`(uRYFPTKIWp_4WoGIY|0hYy{!;Sob8Z8&u3qzyL@-C-r~!^16Y zIAXY^4Mz^0z&x4anb(uQ+~PTFwZ z&`I9658e5t4UY-8wBfPCEp2$*&`BE}KXlTDCk&mm;fX^hZMY!Z(uNC%TiWoXp_4W| zdFZ4KPZ>JdhVe>6cTvgvso|D3JZ-q84No6BX~Q#yPTKIyp_4W|Yv?5Ji-%5L5SN5o z+VJe*mNqD@w&5}-$U{K*Y5>)?{gde^?Tc$`rL+p{a$_RKDS|JqoFIO z{~cxZp)05Voomu(U1`f5|6Nz|zT>~UOB??6?;^g_=QjN7->rPH&uy4|Z0O4Azf-zy zwwwN*;(2wK$EER#;nqEW`0Re=aO++$e0Es~f|cE4`8buS-2yI()ty32;o?l%l~-FUO%vwQpDzN+-K zd1JVxuhE-^Tl(5uJ#_MlcyqX=ufmBz8$K{} z(uNNXowVVGaLYD~_Z{vVOWq#}x3uBI!!2$2$k0g}K00*LhK~)MwBh4JCvEt|&`BFU zIdsy7PYs>4;nPDWd4Fc;`N{4(6qhF=Z0wBgr7CvEu6(8)H8&mOwlO5VQ>x3uAR z!!2$2{m@Ap{xEdXhCdFSwBb)fCvEui&`I8Z89HghUx!ZG@VB9pHvE0)WE;j84&Ch~ z?|+0_+VKCia~AZqEsP--g^K!gb-RFga83TNFjhCs8kVYiXfoU6s4&Y z0g)m_QBd^IK?U>)3eu%YuL_9p?{&{QH_wqsP_uM-Zf{Rvgh2n6K_(3 zB?pfXVh&3V9ud%B{)`DD7taHX2_qLz8pec?izh8(!pOywjxk~6;z`e# zFmmy{%GiT)EbaDW5QqjN2Tw-Egq?P0Vhk)HPi6r$7`X&cgON)X#=yuWD`Q~fl8rGi za>>pZ7`fzN42)cIG6qI2lNrk;jCSW1K!cG>9%?Xh$;%iR?S6dK$oLNtSFD6%Tps3$YbaV)QA=1F?2<0#DaJXU5Og8;yi|~OpRCx z9z$25Myw={p{r6OR*J{a)u<6G&12~5)QFYgF?0=T#Fp?F8smi5Y6{Rd!PH>%Q7y*6 z=$qP%fzc;*7z3j(9%T%SKB&tW7`ZFPz{t5CV_@VO!WbAi)@KZi+(H=xqurYsYaomq z!UWJ@!U#4#TLy z$l*oCz{p`ZV_@Vkf-x|1c!@DEau~@N7&(k$42&E`GX_QuFEa*44zDl21X8( z7z0ZV-U5tG7Dl_L2%y2pVJbBkIZR^=j2zx#42&G!W(p%oi+>zr!p^hTc*caCXPF6djF_$W zdjT{UIs8BkMh-g}10#oBjDeBEkBotl!*0gF$YBp-VC1luF)(u2#~2tn>}L#&91buB zmK^X*(1{%sM!SC!K!cIPA!;ykILsIrIUHdOj2wCHj9Ii74Mh?F-21X7y z7y~1Rn~Z@a2d}&(Vh&3VUXRgWbVoR~0j@%l3+j9k1AFeZ$4nvCX8IX4>Bfbj!pOzHC1b+K#XpiUVdUc9f-zy_;vd17Fmmy4&X_QA z@o&bMFmmw^XG|Em_%~%t*ef~Uxh7)XdXkG*{ug4jw?1{KFmwX}bQpC*>PEuQjRnx+ z=V*9}#&<+sXnB7>e_^x>Z9#jXkq0#LgGS!a=nrW06Eyk{8vP30#%O#u<>+Yfe?W9w zfoN|#>h{zz!q6QA(6Q7VspEv9;|0(OM&mm%N6VP{r4ijpAljQm-I=5sGp|pDGc390NtCq4|QK*=zap|XN<;ofR64j z{^>+ND-i7+K>Zx`Kw;=X0_efiL#T%eLq9Koe!*x@aq3~>pI-Ef0@2>#)FY^05{4cr zfF4CXn)+p7=vM^LuNv(Mq8=mu4~iZu5bYgDJ)U}kF!XBz=+~(yQokV#{iXnVlF^=G z)RVKVe&GX>DIjP?XlzbpP3Mb8$9_RgW6OZ}cO z^gIFd`_%KP7YIWy6hJRB+EbMJ1M$x!da*#XcM0`U>Se;v9}1v9qFzq@u`u)}0_YV+ zdx{v1dlA$K+^e8Q;9drG0rxtn3%D0TjljJUY6R}3P#18og}Q)yG1LXzt2uQ6ZD}eH zPp2M;r&ABa)2RpI>C^-9bn1b4I`u$2oq8aiPCXD$ryevBZY_Xk8$q}rTF^|;R?u9~ zP7onL9cUql5kv|)2wDnI6QTsD1FZz81MrL&z%xMr&qM({I|<;KB!FjU0X(}1;Mr9G z&&LGtd|Uv}ZUT5dA%JIh0X(tp;rXNho=*wjiFFUpo&tFG62P;!0G@pW@a!vqXFmZv zpAo>bzW|=k3g9_F0MF+H@EjuL$7zssNs21n?Xyfaf>?JjV;*IY9u=*97o#IC z0(ib5fajY6cuo?)bFu)QQv~pwDuCxS0X*Ll!1HYZJl_$(bGiVYGX(IQDS+oJ0X*Lo zz;m_$o^u57oGXCmdjfdQ6TtI*0X*jm;JH8m&xHbbE)u}=0|7i23*fm#0MDfYcrFvb z^FskVKN7%mxd5IY3*h;Q0G=xZ;^~K6#S_2#fhT_F15f;}2cGyH4?OX^9eCn*I`G8r za^Q*I;lLBWyMZTuXXD){*dW+My_xz;Vd$>}&|gz;q24MCy-fi94fVH1`$r2ye<%2t zU_12=>hFc2e-J?Lq~1mSqcHSt0rVc~y+-5vFE8|d!9KwO>Vwoj2}2(eKp&<)LVZ*i z`j`OvIQ7p)Z{b(grR>EKwqc+o%)6_^i6?ie;H0_e~;15_kGavg1=Yr0CgJbw8GHo1kmZJAEeG8 z44qK`oryX#bq8VSEP?<*R_bij*@dBV2%vLP=c3Ln44p>+otOF{>R4gue1eAs`Kb#~ z7ZiprB!DhV{RnjtVd$a)=s@aX)E$MPiwlATC8$eMmlB39Er2dVU6#6>Fm!nVbOq{) z)N#Vll?9aqRj8{{R}+S=E`Y8Ud%3x`Iaqin<W}S=OF<+4-4RVL;%mD0(c%1!1K5Oo<9rVc~St+Qv!IN7Qpk20G?+B@H{7g z=Xn7F*~j zo~Qxv#M*}^);>J3-roC>8yS6bk@6gI%{4$oi#6> z&N>%QXPt|uv*yLqS@YuQtaI^n)_F$ZJc3Muyn@VvhXh#!`2<-7`32bo1q7%a1qC?- zg#-xIe z_2GsJbLPKCHBm_1qnbHoi_@B`nrq#&-TYVj)^$m<>0c{b?lqDulISdx{g~FT~vQM$gMXa0~R%WzTb6i{hO9PRC@6G zi@HVFoZh{*H_%ay59f~`dDZo8w>;mWcb-YBJFIB;%B!VU>bPzJ-PBuYb-dZ9>4bx= zo-8!8p03>?=KME-dv(3-`L{nG9N_wgzxu$H@WKJQWuDOmXCHaY^=*H=@4@yDzo|Q} z7&L6x*{g2*5;I)+a{rQnI`LAU=hy$1q$}55KXt^`*1E=#E|sb*I;~Z&-_kAHf5G*S zII(2!k0X9{ePc7s&6fSM7n1!t)q6BY`UiBUPEj>ibSt8h@}>(P8&p*n?LXs0$2P-s z$;JEg|Mp3+t~ld|;g5Ao)WM~ug*Lg6!}Yi8(&pPKc)>IMW~|alP1k2>d10AOI(#9Z zLg+xudUVn6mzfrhgUtSFwK;=Y!&WP@Hdy^FeVw zxW1eZit{1a-^>Ta`Jl}Fy~g(auFU+spv?RYRc8KPaedAFO{X}273Z((Z{}|Z{cb9= z-u#tWZ{ro$o8o$NeYxJ0S#J{+*PG&cbNy}JW?kR?`$+Tsu>HQnkL^#x_D@J<`(ID7 z{pNdTfA;%zcN|$a*zXP4?^oUaVcqz1zni+DST|I)p;#@Rdp2Lp_vHSZ=dC%w70u@btcQbH538^q#<3n|)~qkut%nE9`>?*S9)9Rs54Cv?ag%jCigo-1>-c&4 z-q5Twu0QLHw)=4Q|DWnO=g&R+{4vi>?0pZv$F=uG z?)tFbtEBin%~b<|X+QPlPR7iu3xtmOUNrlXql4io8Ws1+`l8^biJ>On${i;Cf%U3(j_BddYc)`Himh51Her&gv-y>vW=D!BQ+MUL7mw}h z_I!K2@jI(3M3q0;a7&V^RMA`FkH=};*X{ZCdgE6{73-UR=e9mKRSCao-wrQ3LX|3fdhw*a5315zFNUiH zLsZ!`qti7@cv_WRUE`afJ5DJ+pLCDy>-Kzmz4gl#R^Yjq`Ee@Gt{+dmyWlbP@B`yw zW7K?=Z&l>8vm0+x`F{@#Xg7P4D)2@6YdJD)QKs&uagXim_Iz{w0_!)_saC14qj!3~ zHtlbxP5TqIdH>nkv}cVr?bF({e}h|h?Xi8`o^P(7nJ<4dlphB>FM zt(&#IYSd@t{t~;Ysm8s&dHlz$bybs0Bf>pv-*$hmXpimd_Iz`FjPmtsoESUmiRL#{ z(`NNgEKJCu!q;5)Zd!OzHT%Hx`PH~s_xFSL*uHMhcdn1{WBX#<_Sx5)eY>t(frJnh zvG3gC`ELzTEvAntkz?XW_xF_c*uHMhH`nK)Uv)QM`~LR)$cXiWtM>a{wQO6g!1b2Z z+}~%~WAnN^&*A%<>o3z!x&3GJv+c3hNA2}{v)kz?Wq%-1xJO7gBiyhxTt~ce*SJOV%PxE_RZNA5?ug&+cLE3yT zn^l|daTB%KH;mKf`)d!6$GflF^Ud|eT|eu~^{rViH2Yt3d^Owa{vO93+t=;+>|bsD zYxSmIYR((YdFg)NZjbHj_I!>T+Zp5bgMEK{9_xYT`qf--?)Uii*uHMh=lC-J z>g>M+w;ybK>~*Xon(NyA9g{ugJa^l{c|zefseXs4>)A?S}>R4!4*KJ32aMR5{ z1?@=El{U@&de^X?I%xFR(cZzY=zxHV4^A00M;V^3OnkKBd5YI5<8wq=-_Y3;GiD3f zq}AbHp4l`xN(VQp;0?a8P*>WJyVI{5^Xj0N21VpL_OK4fkgwdaqb#k4vUQ0mHtmvnH0{5$LAi`13Y{;=-Hn)!6li)%w3I^S9c zr0w0R=dsz!@HA!OEfmjFyiOUP5z6=m>d+aV_o%+&L9Gr>x)zvrh7Jx{cJau(CA!j@ zOjGMNAEAR@7?bf>*byDz-+$2B$-gSY=ah*bQ0Bbh%3QZd8J~BQ^$nf={;Hep7HM_h zt*@Ks8l;2kWlmS8%|2a8Z>hTG#tI$uyx-~cODgLCPwa-B?+sUm2P+e=sCb?-*X>cp z=Q(A4L#G$X)oVd}@h`M6V8SXLtg1EWnGhoWCC6SrnN|l4tx|4D?x%EsU&FvRD@7^8 z;mX9ji$Bgwqs(cD2ea82&&-h;8`2KYJ@xA5zZ0R#UTlvh-w|(a4L!6&2eCB6SZPx+U z1=rVt+pMp7w^?72$?NMc>qBp!`Y@CAVJ7Rt%d8K*eCoqdTOU-T=()ACAMUHd^M1Nw zQiX?9#EY4baQDr(W9fG-x8Q?192d1hIe94h+ho+HD*JEhu1MxIv@ z->R5OB`;Qs-=ku)U+6#TqqeH!#hFDbA3Lw&yXCI%Ti7AhsC~CfXI2HP@O%%Btlnjz zir9VZ#!n;WsmQGZx_SeGRn!Mr+Z3o@K>R-l8Z~;E__x^AuWz_&*W&EFpFTUJVk!=w z^!xb@;-ATH%x4Q!#|zKZIvhSv#XsITWL=A;s!@k`9!?6}tHSf2-;u87vnpb5&)4?% zYNH~zWeC{ZbA|YKee<)`-;4j(ojW|eR{SeZnKiby_)mJQ{-Y&TOohwmtBna$vDq3{ z%Nq8b>UjR8Tmw6WsQAZr*6i}jX4R-;y$PGbepTTGyQbNFHD2z!=A_MBx`g--+*P4W zocJ$#bXcB1@jqNU+o6i$pKtA%{9DC8a`nLDyTyN4(6;YpsMxFvu3zoeU3EP7^`Pwj z5#s;U)MjVut449HL;U8nRN;jZD=#_mqKer6?7)OppXuP^?E3(Uw}O#CZ1d-{t-;$Oesw$>kufAgcoGprK-QXdTY{t5Bld*aoo zx#EAI<@p|R-@5aNb5F-Ng!6Mx z3iEU2KcAm}SYL~{zUJS(_2txu-mDJ~`_zY`f3rSZbn8Px>z}thu%duU3@dl0OQy7{ zQ?(ImKP?uel7ddAP1-hIbttUTw~spn099kG8%EZKkZM z^+9v-Uz3=5*L?B6dh?SR@2jNZbt*rfu7LQDEFCaojQIcXTIl-r;ty`8O?<58dE)O} zC;pC)w!R6`#WzfTu)0cYSi5h%t+A?8^$tnD?wKh5!_y^wvPb-veYG$Cg!mt=w5Udc z_!~Cylj4u__G(_IjZa5yeG{U`B`wXiO8h6U?sucD_|JQOSd-1-|9SUGxyy~6ik19lK2~DT>NofdGW_}Uy8ruBmTxWA$muPp(Q7Z|ISxV4VW(e`{MGp4ix{R z?HW!mA^vC2m+x~*{I88X{8mTtH*Dgk#UJOD6n|V-O#I<9L;Q_zLiDc#X0`fR{IBHv zET)C{U#%Yb-4Eh_ZL446JK}$RRn9Y$#s9{k98Ke(D^T>Np~bn(Y^JH;P9k>YQB zE&ntBcmBfvZuC!yzv!QTAKz%{A7`ATfBt=Z$4meG-SNH0^YfmpuLa5L>#o#?@vIN6 zSRc~a`k=W_(PrOrQF9-oxv$aO=V-I;&UUQ$Mxo^^DAC*s=eN}JGeTp{w zmiglE>|-?dHJbYz@yEWWnfN>VAkBS|<~~WAebanx_EC$p*;m!n+^1->Zwb|AAG1Sq zUnBn5=adqE?0f2nzq1b#e`jB$xlht&-_%xfAEmjk5`Sl(qRqY~Qga_8{?5Ke{ISp3 zBmUU;Y!iQHA0+clJrz?3*TNvyU3Cxvvs`XP+Ye*tf)qzq5}Ke`jAK{?0x} z{ITzuApXuiNc^3Bk@!3NB=L9lP2!JzRDJQszG}`r@(=wt|J3wPPzwFCI~D!&PsTUU zXM9WCVtk!_w9owfE|v512l2-~eq{>tbI-kBU*chjV4}JK(xcq%s zo8zZPG&ri8N9g)9>mJjQl`jPqST4Uu58tq{WwVpIb&pFOq9X%!^n{GF-dnUsw_8@T z#=@mJbSOFORCdH?#e{wGNq=C;PK2A9lZgZ?duFtXIlc z&=DhYyjL*GbltMu?#U6IkLlKVf1ka)Y`Bg-=562jU(0m+Ie}dkPsyueYyVRE+?Db= zZd#i~HIH{m{(G?%$KV zKD=Fb%$s9%e9}bMH?drs0vV3()14l9@kF{|$91P&*K!2xE}~0L-n_oYxH-DQr14YM zJeH)ZUOP2m^~FH_XnaJP=O?sx^NBq7?t=5Vr|Ot2F;M|OcXIn7aoI10BDQ>_JL#D{ z=B}Qqle(Y&dhXJTI_YSqPV<6((b)>G3?6;@bDjI?V(-3Hy0I?Ue0uL+x^~pX_RgMu z?)&$3r8+&rYt4S$&By$G+6|plqh*`^FNf>SMT*TncVVLL{OaiI@!{)q=dTC7N8;`bU1(?(|P<`u?s=|4dP)e>%JG!~Rk1A7%RIk}~~sS())Yr8vHd<4fP0isP%y z_?A)}U&ZlFejhWwisP#|zKZixaelhKW`6cpoS%yGQ*nMO&QHbp>Anx=r{ernW_>;6 z`kM7sPH}xHt}n&)rOf*JP;q@Jt}n&)mHa-=`g%6m*QpPO73+gyeNe0qiuFO6`mkHE zJ}A})#rmLFAKdpb-&@Pyn>qeR?z+F}pZv;wA5(vB(?82n?jQSiXY3y{zEzUP*Ze|7 zvHqlTeC7Kd>uc%{$M*{7r~I9VsXw=wpQZ13ezN{>eI;>y732Eq;PxBq57$?c+umER zuZ!;bV*O!#Xw3Q$$NKO->%;5r`>_6~Kh}qdtPksa>jUfCO4hef*0*TZx7n<3uW8mF zZT}98{yz0>y>ESEeSVkqIg$0bDC@KR@9W*rtUs*Jo!$5OV||{+`h1D?`LfUF%jYS4 zzI@Bimr{59`C{g0#pKV&A?EL=SbzTU=cD`i?)cu&tUtH;eE%@z&-Vk)FT8XDKi|!` ziLa>-sobCJPVN3gsgJuBee2p96_VwHYi~vOQ1u`BV)p7?AF2Ag$7YWH{D2B=_e;N} z7ssm5Ni819)3*<~FXQ9g^UQV2T_5Wk{87e>WjvQuot(Xz?oU*fQ0nc=oi7K5DYbLw+j}MqA`fP~p?jXa&iYv2DsdBAPg`0;Rg3Jt=*1V#sp|W; z#tmzgOV!K}n6KrmeyZj-Gv6M&BR~aLUKziC;V73)Jd1mtz0UZYSH`!dDzoS%{qAGy zRr#^O1Bx!$rYf92HErE9;i}?yqi$R(-AGmHwkE^at*un0$uQ9J{ z>iSsUM>4#gWoE-ns>s&HA+48ws{-o=boWHgQN^Nn?Yr#Bu7Yws@StA4Mg{dLmp|wB zXOh{8ujP5!-0Q55^-VjiMaCgR9#!eD|M1nMNxfBuv$Nmb=zUpb>b`pVCm(KBnV&2@ zxKXxCD)ZTcMLebICo|*rJagSE^y#IHuhNEtwejzv&3VJLxo(X%{-?F^ubs?}|7rI; zbKP*)$NHK)GH8?67H#@xrZ)W(piTd1ZThEAGCTdV+C9%+XMDD51YcmfsYtB#dNH=cI z>*HQ$e9pMOW*wZ@W?gjDW}W<~&HBow&H4(}W_=AzX0z^iUUv67>tlQ`YO{{lYSstM zb*@c)IH*m17^h8r=$p(=-5AI74!GA@A6p+R-&y^UI>fqU>(rgqpWSX>bvh zfd6v+S*L8Buyy0!)}LOftUvYKx^!>r&&d?(&y#Ll`+N0Ao(tcy{>)+>`%l%MHEx}_ zyY=Us>-(RnKdb*?{W+M*`qSNK|8tOaW?b^V$L@nnedGS;Ag@bl|8vo2|MR0y{b`iE z?{W4)cK;*$BJPuJz5ltW>^{YeudP2h-MYfh7w&sTyKMJG=JTa5>sAhTA7y>*KE-@K zZt>awG``LLr&TKVKbdc{|5?j@Pyb}*zR2tYZnytY?!LwBGe-Z-{m;v;kJ+Epb?b!L z|8)Nk?SE!)Uz3G(<_qq7r0zKT#FXmK%v9E&rtZGxkNcmxKKq|2_q@N}|5W$c|77L< zrw{izncRJk*$3JEPbT*~yKge{{B#QSCzkt|o!r;>?tcdT&Hc}s6zb1`+w6ZPxcel# zZ~E)~&l4%spYeCO{`l^H@Vxjr4;HJx`>(%S zf5KC^|MIOr*;rTX{nzd4Pw!OTfBDv*tUmW&cf0=B`>zSf_g&8ZMDD|!{mJ;-)}Q*1 zwJg&$G+s5x8S;HiZ)p|Qx$c71YOiY8aod&R1D{ci{FlDC<76S#sP(dwvxY7rFL2}b zJbRt>F}`v1Eu|VZDSaU0`sJ$eBmKwC+|ph(8F#S!_OR8e>6n~bzkg$c3ePgR_SGu& zTsHAd?s?|A82WtT)80MwjZsZUe-YaFNPE?6)b{18JM~x1Z=8Ae`Q`Gvz6~w9jLiGE z%QkM$GuOq?Czk!NkNwb(?O5abw#Z#H)X0)mRd`H-J}d}cHhtDW&6+g$nWZW=EEQTANTPe?J4z?d$zUBD#|I_%|bz$ePoo9AFn0!XK^V0USjob6g zbsc=>=U%RZGF%rc_<9Go9d;erakFgWChs+_uUV%n-1X(Vj!iyxUD*1NJkQ*D!ErPF z+uvPJf2p*W~rFX8qC3TXSA%&R>^J zd?U|W&Ff;c@%hB{we7XO9AC|Oq&Z(T$JJ#U=lE)So$=|we%QzS`nm0}zMP+$^+$7F zCbOBJ+MZ|M$L4MNx1Za;wjXS}tS{@2=DH$}(KgQY!8}K>KR3I+cHC_L+J3O@wZ5!B zn)ShbKYO0Nj`KHp9+*1hj+;HtUT6HrxW0Gn&v|z1{weGBgU!P->kr4LtWW=Ja{I@O z!?W&uy!H5&O&(YCIpg~N_4q#Pt|!(Xcb?h#z&hj3OWS`oZqGCGGnVTh)}5bb-IjIN zg`K~4o|%5z#PJDn*~aa8=DJw=tl;`8`=@nm*SYPt)YS*u5Bq%TL%jRnQMCU((Jtos Rwf*lmDjqBQ-|O@_{yzW$Qgi?S diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 7a0a5914..6e72338c 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -1,13 +1,10 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -25,7 +22,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', 'm_cl','m_r','m_s', / &jedi_linear_model -incremental_wind_interpolation=.true., +incremental_wind_interpolation=.false., nl_time_step='P0DT1H0M0S', / &jedi_pseudo_model @@ -34,22 +31,19 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings -adjoint_test_tolerance=1.0e-4, +adjoint_test_tolerance=1.0e-3, forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -71,6 +65,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -80,7 +83,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -98,12 +101,14 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', -diag_stem_name='', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', +checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_jedi_lfric_tests_to_linear_model-jedi_lfric_tests_developer-with_core_3/run1/share/data/restart_jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit_tstep', +diag_stem_name='diagGungho', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +ls_filename='final_ls', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +start_dump_filename='final_pert', / &finite_element cellshape='quadrilateral', @@ -119,10 +124,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -130,29 +135,38 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -173,9 +187,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='analytic', +init_option='fd_start_dump', lbc_option='none', -ls_option='analytic', +ls_option='file', model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., @@ -187,10 +201,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -202,7 +216,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -211,22 +225,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -239,26 +256,30 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.true., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, +reference_reset_time=1800, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-3, split_w=.true., / &mixing @@ -267,6 +288,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -274,15 +303,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=1, +panel_xproc=6, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., limit_drag_incs=.false., sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -294,10 +326,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -310,24 +346,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -339,10 +378,10 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', -outer_iterations=2, +outer_iterations=1, runge_kutta_method='forward_euler', spinup_alpha=.false., tau_r=1.0, @@ -351,10 +390,11 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -364,28 +404,29 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', @@ -395,13 +436,13 @@ splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml deleted file mode 100644 index 4a5237da..00000000 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml +++ /dev/null @@ -1,405 +0,0 @@ -&jedi_lfric_tests -test_field='theta', -/ - -#### Configure JEDI-LFRIC - -&jedi_geometry -io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', -io_path_state_write='write_file', -io_setup_increment=.false., -io_time_step='P0DT1H0M0S', -/ -&jedi_state -state_time='2018-04-14 21:00:00', -use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', -/ -&jedi_increment -inc_time='2018-04-14 21:00:00', -initialise_via_read=.false., -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', -'m_cl','m_r','m_s', -/ -&jedi_linear_model -incremental_wind_interpolation=.true., -nl_time_step='P0DT1H0M0S', -/ -&jedi_pseudo_model -initial_time='2018-04-14T21:00:00', -number_of_steps=9, -time_step='P0DT1H0M0S', -/ -&jedi_lfric_settings -adjoint_test_tolerance=1.0e-4, -forecast_length='P0DT6H0M0S', -/ - -#### Configure LFRic - -&base_mesh -file_prefix='mesh_C12', -geometry='spherical', -prepartitioned=.false., -prime_mesh_name='C12', -topology='fully_periodic', -/ -&boundaries -limited_area=.false., -transport_overwrite_freq='final' -/ -&checks -limit_cfl=.false., -/ -§ion_choice -aerosol='none', -boundary_layer='none', -chemistry='none', -cloud='none', -dynamics='gungho', -external_forcing=.false., -iau=.false., -iau_sst=.false., -iau_surf=.false., -methane_oxidation=.false., -orographic_drag='none', -radiation='none', -spectral_gwd='none', -stochastic_physics='none', -surface='none', -/ -&damping_layer -dl_base=40000.0, -dl_str=0.05, -dl_type='standard', -/ -&departure_points -horizontal_limit='cap', -horizontal_method='ffsl', -n_dep_pt_iterations=1, -vertical_limit='exponential', -vertical_method='timeaverage', -vertical_sorting=.false., -/ -&energy_correction -encorr_usage='none', -integral_method='fd', -/ -&extrusion -domain_height=80000.0, -method='um_L70_50t_20s_80km', -number_of_layers=70, -planet_radius=6371229.0, -stretching_height=17507.0, -stretching_method='smooth', -/ -&files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', -diag_stem_name='', -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', -/ -&finite_element -cellshape='quadrilateral', -coord_order=1, -coord_system='native', -element_order_h=0, -element_order_v=0, -rehabilitate=.true., -vorticity_in_w1=.false., -/ -&formulation -dlayer_on=.true., -dry_static_adjust=.true., -eos_method='sampled', -exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. -init_exner_bt=.true., -l_multigrid=.false., -lagged_orog=.true., -moisture_formulation='dry', -moisture_in_solver=.false., -p2theta_vert=.true., -rotating=.true., -shallow=.true., -si_momentum_equation=.false., -use_multires_coupling=.false., -use_physics=.false., -use_wavedynamics=.true., -vector_invariant=.false., -/ -&helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., -normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, -/ -&idealised -f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', -/ -&ideal_surface -canopy_height=19.01,16.38,0.79,1.26,1.0, -leaf_area_index=5.0,4.0,1.5,1.5,1.5, -n_snow_layers=11*0, -snow_depth=11*0.0, -snow_layer_ice_mass=27*0.0, -snow_layer_temp=27*273.0, -snow_layer_thickness=27*0.0, -soil_moisture=15.86,98.861,274.35,862.27, -soil_temperature=284.508,286.537,289.512,293.066, -surf_tile_fracs=9*0.0,1.0,0.0, -surf_tile_temps=9*295.0,300.0,265.0, -tile_snow_mass=11*0.0, -/ -&initialization -ancil_option='none', -coarse_aerosol_ancil=.false., -coarse_orography_ancil=.false., -coarse_ozone_ancil=.false., -init_option='analytic', -lbc_option='none', -ls_option='analytic', -model_eos_height=100, -n_orog_smooth=0, -read_w2h_wind=.true., -sea_ice_source='ancillary', -snow_source='start_dump', -w0_orography_mapping=.false., -zero_w2v_wind=.false., -/ -&initial_density -density_background=0.1, -density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, -y1=0.0, -y2=0.0, -z1=0.0, -z2=0.0, -/ -&initial_pressure -method='balanced', -surface_pressure=1000.0e2, -/ -&initial_temperature -bvf_square=0.0001, -pert_centre=120.0, -pert_width_scaling=1.0, -perturb='none', -theta_surf=300.0, -/ -&initial_vapour -/ -&initial_wind -nl_constant=0.0, -profile='none', -sbr_angle_lat=0.0, -sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, -v0=0.0, -wind_time_period=0.0, -/ -&io -checkpoint_read=.false., -checkpoint_write=.false., -counter_output_suffix='counter.txt', -diag_active_files='lfric_diag', -diag_always_on_sampling=.false., -diagnostic_frequency=8, -file_convention='UGRID', -nodal_output_on_w3=.false., -subroutine_counters=.false., -subroutine_timers=.true., -timer_output_path='timer.txt', -use_xios_io=.true., -write_conservation_diag=.false., -write_diag=.true., -write_dump=.false., -write_fluxes=.false., -write_minmax_tseries=.false., -/ -&linear -fixed_ls=.true. -ls_read_w2h=.false., -pert_option='analytic', -/ -&logging -run_log_level='info', -/ -&mixed_solver -eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, -guess_np1=.false., -mixed_solver_a_tol=1.0e-21, -monitor_convergence=.true., -normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, -si_method='block_gcr', -si_preconditioner='pressure', -si_tolerance=1.0e-21, -split_w=.true., -/ -&mixing -leonard_term=.false., -smagorinsky=.false., -viscosity=.false., -viscosity_mu=0.0, -/ -&esm_couple -l_esm_couple_test=.false., -/ -&orography -orog_init_option='ancil', -/ -&partitioning -panel_decomposition='auto', -panel_xproc=1, -panel_yproc=1, -partitioner='cubedsphere', -/ -&physics -limit_drag_incs=.false., -sample_physics_scalars=.true., -sample_physics_winds=.true., -/ -&planet -cp=1005.0, -gravity=9.80665, -omega=7.292116E-5, -p_zero=100000.0, -rd=287.05, -scaling_factor=1.0, -/ -&radiative_gases -cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', -co_rad_opt='off', -cs_rad_opt='off', -h2_rad_opt='off', -h2o_rad_opt='prognostic', -hcfc22_rad_opt='off', -hcn_rad_opt='off', -he_rad_opt='off', -hfc134a_rad_opt='off', -k_rad_opt='off', -l_cts_fcg_rates=.false., -li_rad_opt='off', -n2_rad_opt='off', -n2o_rad_opt='off', -na_rad_opt='off', -nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', -rb_rad_opt='off', -so2_rad_opt='off', -tio_rad_opt='off', -vo_rad_opt='off', -/ -&solver -fail_on_non_converged=.false., -gcrk=18, -maximum_iterations=50, -method='chebyshev', -monitor_convergence=.false., -preconditioner='diagonal', -tolerance=1.0e-18, -/ -&time -calendar='timestep', -calendar_origin='2018-04-14 21:00:00', -calendar_start='2018-04-14 21:00:00', -calendar_type='gregorian', -timestep_end='13', -timestep_start='1', -/ -×tepping -alpha=0.55, -dt=3600, -inner_iterations=2, -method='semi_implicit', -outer_iterations=2, -runge_kutta_method='forward_euler', -spinup_alpha=.false., -tau_r=1.0, -tau_t=1.0, -tau_u=0.55, -/ -&transport -adjust_theta=.false., -adjust_vhv_wind=.false. -broken_w2_projection=.false., -calculate_detj='upwind', -cap_density_predictor=0.01, -cfl_mol_1d_stab=1.0, -cfl_mol_2d_stab=1.0, -cfl_mol_3d_stab=1.0, -cheap_update=.false., -consistent_metric=.false., -dep_pt_stencil_extent=3, -dry_field_name='density', -enforce_min_value=5*.false., -equation_form=1,2,2,2,2, -extended_mesh=.false., -ffsl_inner_order=2, -ffsl_outer_order=2, -ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', -fv_horizontal_order=2, -fv_vertical_order=2, -horizontal_method=5*1, -horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', -min_val_abs_tol=-1.0e-12, -min_val_max_iterations=10, -min_val_method='iterative', -min_value=0.0,0.0,-99999999.0,0.0,0.0, -oned_reconstruction=.false., -operators='fv', -profile_size=5, -reversible=5*.false., -runge_kutta_method='ssp3', -scheme=5*1, -si_outer_transport='none', -slice_order='parabola', -splitting=5*1, -substep_transport='off', -theta_dispersion_correction=.false., -theta_variable='dry', -use_density_predictor=.false., -vertical_method=5*1, -vertical_monotone=5*1, -vertical_monotone_order=5*1, -vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 -/ -&validity_test -number_gamma_values=2, -update_ls_frequency=1, -/ diff --git a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml index 1de565f8..7d20e408 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml @@ -47,7 +47,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -396,7 +396,7 @@ - + diff --git a/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc b/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc deleted file mode 100644 index f7ea6988e22a06194aac0d17b6e3be62cd539773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85708 zcmbr^2eh39y{-MV)=omN(u;-;Dhenn3P=}FM3mk_fB?~uAcSTG6)ULN3n&&;6uT&b z1?&xb!-@ra!`{&E`K|rp@tonk_l)s5?sMmV&G&^obMFmAj(hL3-()oVpOuSwF>~F{gL^ryO`TeV}oSmC5o7M!_k$@Gu%Yp-_tqO(q0uzcAW%a$xV_59hlS3Gsm zveOqWKhsC=taR2Hr!6{j@ktAp4A1}VbPGUVM^wPg=I@%##)!F>u;9G;|2l{7)0)2h|EE7@`fT=(nV!QRv)=T>@QW>7y6B|ki_clS z{J*~DtNTU%_0H_qdA;e^`2X?8{Og_JkD2~CX1_Vh{;$7|cmDm4nf`%&$Nz6`OBOGE z)a)O#^3r8z`i2ib($l}reBGx1+2imFhO6)I*-MrzSbWx!g-cJ?`Rnmt@7?iId8b8> zK6_z5XNwmuS+Hc`^2N)~p8YG)`*-}TczyMgmz}B$FJ6Au{8RcH)BKZ`ow;<;ne%=B&$>sy^k|i{mM=VW zd4DCIylDCt@*R78eY)@Co&K}3zv};M&wqWN|Mz?T^Uu$J+Oxy|e$Q0IkpJb5J^uTS z|N7bcpF4aV{`2?cKmSbs#~lYO?Qf+11~C8J(-xm}+Wh`@))(KO;H>#e7cD;Zv=e<# z7A@?N^8dACJb#Ki6%uWB8 z?*HS@-oO5s{$}(){<{578+ZD*@0CB)Pg^VJFF$wL>`z&r7B24xuphnYpKkWY?tlCJ zy4seN|MfS^*?-nd|C#%58&>OQc#zHb*PK2begD6^&i;M)f9ty9 zzx@sBKY4C+$MgTJIr^WTtKH!_{d?-H;J>-v{ZdpH`1M-gU1L{#l`O`_Ix6VC3cZxOt8?k$72&V5zbpxY|8 z4&Ju7w+Y@l_qM@X=iV-O>)dw@-a7Z)g163n_n03#_x8bi{&3%;ho=w#9u?@YcCc4&FNVqTsD_pAx)v z?o)%e&V5?&*0~o4Z=L&*!CU8kRPffhm&6I7bKe#=oDiqS(%@~2ds*<-xz7mRI`^Z4 zx6XZL@YcD{3f?;R^5Cs=pB=n)?sI~-&V6q1*169M-a7Z~VT11ccuerN#r@det#dyv zcbPYK?-?(s^c4Z4fsslnS8 z_tS#6&i(Y@t#dykctKx;B zbH6%X6gu~7;>DqJzcyYHI`@_F($KkI7cUE)`}Ohi(7E3bmxZo-ynSpobXS#c3>$25 zzbSa@+*ijHp>w}EcwaHxZz*}}+;0uuI``Xxx6b|c;H`7NBY5lF?+o5L_q)OdUH5pG z*$va~n!0xfZ(H2&3En#QwZU8Ges9>IbNBt6dh6WR2X9;4?+e~K_xppl&i#Slt#f}c zcKxIY}cb?%P@Z=L(2!CUA4Sn$@lKOVew?oR}7o%@r) zTj%~%@YcCM9lUk!&%_O(>mDC6yJ6bhRQK87ZHxPJ!CUA4eDKz}zYx52?k@&!o%>6{ zTj&0A@YcD%61;WpuLf_O`)k2l=l*)wpz9tVH@jil-CXyL;BAZho55S>{#NkTxxXE} zb?)y3Z=L(Q!CU9PC3x%H-wWP4_xFRh&i#Ynt#kh{Y|wR&7td~(cDL63D0tiA{&Dcu zxqlM8b?%=AZ=L&R!CUA4dGOY`e-XEY&i%{aeamqFs^qP6|2lZ<+`kDMblu~#XE#i{ z+v(-U=l)yp*17*4 zHt4#?7tU^&cDL94BY4~5{%7#kb&rdwcb$9e|Kr^j_juCHyUsnH>E>PM9?$9KUFROp z?dDzQ9?$FMUFROJ(9OHfJzlZfhC287lDKfT^LvT$%H6!%;vTQkZ9|=VylV7uy2ZU( z@UEKPtCzfW?lpq9&b?;v*16XT-a7Z%!CU9PQ}EWg*9qP__e;YD-MX<}@V3Rhe(=`0 zHwfN3_l9AE&b?9a*10zh-a7Xt!CU9vG)cm{4Rw?2;`(mh zZE;WD*Uh`mJ$ZjO?>hJ71Kqsq+>;M>^R9DGZs_J+=bqfy&AZM$`A|3SI``zm-Ms7E zlaF-su5(X5+C6`^bI%;!ZG-L}v3YD3+s8d)i_m$tLu?s3&vuNhLg(2|v32M?yH{)z zI?wJM+lJ1wonyPud3K+;Yv???Z`>_(p4~6*9y-r_E#DqG&+Z>Qx$hDW2%b96b`737 z&vpx*I?r|wo;uGS7(8{J?GZe6p6wYtb)M}NJawM!9XxfO?Grq8o_#WG(0R6B@Z`R4 zJSceTJlj8b>O4Cjco;uHt44yjAjtZVS&yEhBI?s*? zo;uHt4W2sBz85y=JUc#kaz8E>1W%o3Cj?KOXA6U;&a)GPr_QsJf~U^2lY^(uvqiyE z=h-R2Q|H;K!BgkiX~9$H*)PKeoo9~>p4=D5qk^Z-vn9b(=h^AOQ|H;z;HmR$S@6_( zc1G~jdG_ewsq^g2;HmTMtl+8hY$^F83a`4o7 z_LShM^X#JFsq^fq!Bgki(}JhYv!@47ooCMoo;uH-89a5KJu7U`d3JH|)b(t#*04e6 z*|UQu_ewQPn~Da51u;DUJyKWp1m-5>O6Z<@YH$s;;=#I z*-L__u4j`?XE#hc&t4WhxxX}C9z1oPT^2lbo?RY1b)LNTsr_Qst1W%o3Zw(uCp1m!2>UuWWd3M9J>)Ff^^*nR;`-+((yLr}m zHgi-r&pOX$j_&4J=h@6L-8}0&n>n_dXPsv=$940p^K9n$Zk~0X%`E8VS?Afz3Eei- zc{a1K+lD&NW=@>lpqoDXK+oP0Z;$uK2jiWg^X!IrSLi&uF|G-nXCI1pht9JP$9qEO z*+=5q(0TUJcyH)D`&e8TI?p~H*N4utPsIB|*R$#WjcYt~o_#8Ka{pv}I(X_l`%LiE zd3ICq)Oq&V;HmTMbHP*R+2@0&&a*EBPn~C944yjAz7#g-Jo|F+)b(uof8$zh=sf#s z@Z|oL_*(GPdG__-sq^gS;HmTM8^KfO**Aly&a-a?Pn~Dq4xT#Cz7srko_#lL(0O)C z@YMBewAJi}Y3JGZgD3az#Sem~&a)o|Pn~DC22Y)5KMI~Y&wd;{b)Nkscvan*>i?&qfPpH%vRv?i@V1ZyI+Ao;uIw z2Tz@6n*~puXPXC4oo8DFPn~C522Y)5TLn*@XIlqPooCyG4LZ-Z4W7E5jZTj?Ogqo+ z8a%mg7k3MuI?wJNJawLJA3SxQ-6MGFJiBM`)Oof;@YH#>WAM~@wo~xbd3LX`LFd`M zgQu=%qw}K;)6TQ|1W)ce$9;pR&a?XkPn~DG1W%o3_Ya;r&mIswb)M}SJawM!7Cd#H z?H)XJo;@&Z(0R5;@YMBebWyZn+VyPaux_5Y&zu;CcJr+BY~~T&JnKB0d3ZO^I?rYf z>E>DI+04VbdDeM0b8t7$I?rYv+Rd}hvzddsdDeM0^N?;E>O7lyaCe?M&t?uBO*iN~ zoBm6{NzeD}eBUhY$zI*p&*Gl!-F@9G?#Vvg@14ax*|+=JS=^KTy5BR4d-9;}chBOU z?B9LOEbhqx-S3*kJ;`(Wd#-oR-jiIXzbAV~pWS``{hn?5H?o<+Zr*VFy6}eE*Nr#a zzOKCC_I2kCx9(lr{r7Wi;69pLcVh5{ z`=sCv_sPK4fm3;0o~*6W;bvj&8s^- zc*DIkc*DIcc*A{0@P_-*!5i)~gE!n~1#h^Q2XDB~4&HE|6TIO*H*7%nc-z?x+(#?a zofo{}K0kQF{g~hl_hW-M+>Z<1a6dkH!~KNd4fhj+H{2HlZ@4cE-f%xDY(V#To7oNA zM=RDnIe5eUl;92bMZp{Hrv`7hpBB8~etPhR`x(I-?q>#XxStig;l4O{!+lBEfbQ|u zvm3aNR;qh;@P_+2!5i-925-184c>4+FL=ZK{NN4u3xYS?FAUyrzbJUa{o>#a_e;VC zbdR^1-N1dca@|XVH{34^-f+J>c*A{J@P_;H;0^aHf;Zf+4Bl{G5xn7kRq%%U)xjI? z*Mtq|9&b6jf%|Bcy4MD8xUUS}aKA2i!~Oc;4fh*@H{4eRZ@AwWyy1RR@P_;9;0^bi zgE!o72^-Ko-ePtG_tC0#Zw=mXzb$yf{r2Du_d9|&-0uwDaK9^f!+lNghWp*Y8}9c6 zZ@8}w-f+J+Y(V#T^VtpDr~kVd-*?_I{om5~zVnXh|8BxYJUo5{AHrV3+a`4u)hWC8+6?>N6v1TcHgP{Zt%9neM|7xxxW{@b?)y6Z=L%G z!CUA4Ver>Tj#z#c)bP|blXtpo>?_)u*JPv@V3Q$Y}lY%J=O@`wz$^}-a7YM!CU8EJ9z8dcM9G* z_d3B_=Uz8>>)h)FZ=HMn;H`6S5WIEn4THDNeO%a}+bA{;-nO_m3En#Qromh1zH{)_ zx$hFZb?*7WTj$;^c=WA$N*?7Dsl-ehx=FhaIw?yHP)DBRgb2 zXQO_$Ms~=4u15VVjqH&99F6-vj@mKmXK2*V&8VN1=?=L^>=|~*y`rCm=?>Y?!Km;3 zbcgKwKI(ft-68uvk9=?Kko}B~`njC$ko`=K`Z=8Lko^pf4h}nHKXW5~cF2ClM*Un( zcgTLG#*52#j1G&#@x-u0UJ(53kWY#yhaK`M`MX*dd=D z&j>r@GvirdhrBp02|MJo<2hl6d~RGCcF5<&^TQ7Lf_P!rAzu_P4m;#ag5L#0zN~zC z*dZ^=|LtWvMwiDc;+0{Cydqu|cF0%9Yr+os+PE_8kgto^haK__aaGtM-xzNSJLJ{z z=CDJ)CEgl#$hQSQJLEg!oneQ3SN@+Y+cCN(-W~4=JLI+T-ne4O>&olH4*9-#f7l^E z5FZRX8#yiWex^|>A6bz{9)zt8QE;|*fNsG8och7&%vK@XOF}`Q)7~2oIQ+e;$VaT1!`^LS7 zykB|$xX+LeD0hophTOf}BX%9queEnPaL9ei{bH{nA5g z#z|p^JUJGH9rBboHSCb5<^TAy9ey7%eq=lr8P5tk}?eP1E@jK$3VTXKIToZQ4cgK6e4tZ_7H|&tt#r0u_ zd|$jj?2sRb4~8A`hPW~8kROTC&0&Z9Mtn2uklzY^cF6CS zv02z5H;*mC4!LFIH{Bt(j%~sYxo!TtmF@8Rh{;{!ZefSKdu$(e$a};+!w$Ja>=<^) zo#I|$hrD;}9Cpb2#C^jKdB4~t?2z}52ZSAR*WhP|+&vx`cE~;QKdfwr-$zXLioL@Q zxlimHcF6tWL1Bm7KMn{xAinEvlAjw_FfqvQBEA&w3G!Z;}wg#P3>B~A?esj)Z~h5nJTBu)#xUuRi7 zD)eW>nXxqVXT{m^=+K`N=f(2SpC6Bnb3^~Q+@D%LCiG8;C&n@H__!c03_J8siYJF1 z`lrN2VTazI>uF(!{^{|IutWdMcvjel=fuD3 z_+;3j|5SWB?9hKEZVEf}pN-Fj9s1A57s3wx7voD|hyKg)m9Rtq)%aT2q5pdDvqS%l z_-5Fl|5pCDmF<}J-zmQvc6>W-iSLCS`tQdN!Vdip@=U z(C?c6A!R$J{qE%h!;alzkJvNp(C-y{haLKTV&AYszh68k?9lHY2ZSB^1LMJAhyEdP zP}re=XdE1N=pPpR?9e|v9uaov56ypZ*^X&{czHzFaabG~M}-~wqvM#cLw{@>7k226 zj|E|e{)AWhmcIeNG^TQ7PW8$%4hyHQ#_^?C&gm_}up}!#b*`a?@ zJUQ&pKPCT{mhG7KPb;4h7sXTKnQ?JEJ@l8vbK+T{e{MW4o*nw<#|z`q(7z~N5-$k7 zU+d-Z;?Q3fuZWk0{+02nxIFZ)j@QN&p}#U-AFm1h8%F)jqI_NG-xzNSJFbeW*=sy*o4m{b%EIVTbJ`qcIdyJ|88YFru{d{Z-yN=$G76!VTb-Z@!haPe@lEX z?9hKdeh_x(e;Buh9r_=|kHZfAPvWOxhyG{r^RPqzi}+>Oq5oCgV*!&lz{yQ9oxA zGu`db&*_CZbNk#5{hWERLZ92ApR;0rg46rl4*i^!W0gL)!|yBRtQxEJxgGjBtH&CB zZijx(nz2@&+o7MccHF7Y?a{!w&skv3J;^-zWABJM{a-gTfB|{&7Iqp+7Jl9Cqj*5(kAH`iI8BVTb-<`Cn7E zW7rBNE{l6g&q3C3Ae_T91?9e|Uo)~uMFBpwRx0dag_D?FG9Cln7Pl=1d z4*gT(X<>){>G6!PL;uWpR@kAxI4%i0^v{mxgdO_l#-(A0{(15IutWcXcwyL~e^IE89 z5LbmA`Zva#!Vdk_@#e5Y|CV@b*r9*hXf$58Y=_?OBSz!yw~t11ckXk)rkwMR@;-ge zSI&87dEY*_LC$$sdA~llU(UIv+@;TbP2`++m-p{;9&*lm$_Mnhud$qSZMkco+a>3` zx7@AIeb3~a>&o5x+}BCYxxRd0pZgh*bKci)gC0}n?Qh0&-e12*$yh& zFL}!^l#eKR%P*FPmb~Sc%EQXMr}^dlm-jjE(aPml>JKk@%deJ4l)UBF$|FnO^6TYM zC2x6id34EJexp35{J%VR>@NTi#kODtXHvm8X=v<&Vo#OWyJ)YS;<@8R-RGv zmcK21eR#{?m1mZ`A_pB8qbLFkgJu?4Bm3}cvkS1YsAHo_cYhce^IwT z;fCc}aY^u&Ysa&Lx9oc~_c_5^t`pA<-g4czG?aq7D zuQ~SXza@B=V}Jg)2Jdq0kAGY6F30yN-yZ(Ba=c6Vj^JI6cP-x;yvy+e%Xfu8Z#mwp zye4>;<9*9_2k&ycfBBy9>z3mOm)Az#a{SQzk1F}RcQl%}Tc7)L%DLB-yZ3pY*_?ZQ z*{?s@Z#L(?uiT^0{Tg!a`^!E1eBf-({Xp5DYx0oUocqCY?>_fy%DFd`{kbO(o6Wg5 zmibQ}KAUqtRQ7944xP=pA1)u%=fh`n?nnB4(9%91nZK|1N9*miLw>A0ptM7Nyv%L7 zLw=&qz8-eSPnNk(cgRom`JmDc`ROwE=??jsJ|A4#A#W<%GTk9R+vh_{JLKoewoP}) z&*y(e*^cqHey3be+9AJN zo>1B$Zz&g+cF6CQCzf`|@0TZ)cE}%;Czp1}AC`+sJLIk9DWx6qN9C!d9rDNJX{88@|Wf5r5*BD<HBYoysdn6X@~r6>FaBU{9SogX@~rM{^ykK7;j$wq23-l$r-|5~13+9Cf|KBlxo{=Ix`X@|VMd|YXV{73ot(hm90@(HCK<-Ae;ew}uV z=l6LWPwcZD<-AE;&}Tc!c{6cgpY15;&50-V*^YAF+<0=I?I`E<3(R{;pY15;tq>RW z*^YAFit*Gw+fmM2DW2A6JIZ-0$J6_4M>%hmct)S?DCe!3e_sbX#&<4Pi)V%%a`kvt zOom*eyg2NTYsMvEhg>V39d^jI<2hl6yi+_k?2zlkrD2C$H=Y-E$o1m+VTW8lUJ!Q3 z4f5~%WXE`ua>ICG*daHH7lj>i<9Kn{A^kBg2|MJb@zStE`kK5f?2vbfmxmqF_x!T3 zLv9wAhaGbBctzMDw}@AU9dgV3pHQ}A%yp}{BJ7Y`$E(6KxlOz}?2y~WYr+n>UA#8z zkavwM!wz}3cwN{b?;fuYJLLB9hOk54Bd!WNucTfz>xbG$X|koSqVg&p#~@%FGo-Y?z}cF0}goneQ(f4nQ~kPnD! z!VbA>{!c2~G46Zh->J-dci2(-cP{hZ6LysToy@#z!;aFwvzhnau%q1dTc_dVB-){j;D+}BD!+8{3N^GDPD zME8clnY%3;1?M(R`;AM^ZJPF*l$_f%?fbc(I=5-s_j5mWZqu~y=YHzkrfEOFbchr0?f`#MvhOw!zsZeLwdj z&Nk`q8k~I}^!?nA=7;ZtzMuOMXWxhUv3+p1Nq>*v%w6Bl{nVMeeuua!`aXRSe(KC!-_QNjnY%6h+)tgk+p=?T=5EVkkgj-1QF&&fN8f1ZVF0hX-fw`bPw3?)pRHrfAb-PI*{x=5EX3!I``Mh~Ug! ze`IjpBlJfFXYTr=gEM#iF~OO;{@CEmU4L9~=B__JICIx82+rK~C&bOsrpcP+!r;u^ zmJ@?Bcl}AhnY;ev;LKgWC^&Q1pAww8>rV~N-1VmgXYTsN!I``Mk-?d}{!wv4aMv%1 zTcb^rP0G`QGk05-250X2Wx<)d{*2(vUH|Cd%w2zGaOSQ*D>!r4FAvV#^=AiX?)r0r zGk5*D!I``Mytpk+$bZ}N{NT*pmd6BV?)t|DXYTsP1!wO1#|LNb`X>Zu?)oPNXYTq7 zf-`shg~6G-{z<`^yZ*_+nY;ceaeK6Ba_{n@;LP2Yrv_*4`lkhF?)s+(XYTrE1ZVF0 zX9j2P`e(%j!CilGaOQqNToRnQ>z^H*x$B=3oVn|t+uwIqD%&*KqkpU(*3FrFTV@U@ zIdiX{*{$Tvy?$oLk~8=EnXO9B-0NpHEID(ppINQs%)NeQTynl3>L-6FIdiX{{IulE zy?*lTGUus#{p1VzuiIyvR*lQ!dG#MHFO65k^ZWd<*?#oO@&$eV_-sGAqI_YWKQY^n zURA!R&!3#_N3Skl+~-ft_M_L7FX{8AXZz7>%a``~Gqe5Z%JOA>zG=1}y{>$DpFca> zk6vG1*5}X7_MPaN&mj!Y?J=|!PzGL2ZFOr`VU6VQ+NFh z`R`KNv_sq&oVnZbq2SD2|KZ@wUH_5b%w7M{;LKhBvEa;I@8^y)cfFrG&fN8W?l^PT ze=0b0*MB;02=4mN zcm0=xGk5)0f-`shSA#Qm{nsMrsk{E``5#i=5c|i?!I`@)-w4j!_1_H6-1XlI&fN9i z4$j>5-wDp#_1_K7-1WBvXYTs%1!wO1?+0h@`X5Bj(@pvx=6_si)1h%|aOQ5ykAgFI z{f~n)cl}R-Gk5(@gEM#i&w?{|{m&FVt+}kpql$^QOk7r8G z-0R14O3vKt$8$^0-0R2lO3vKt$19XMPdC+%SBwk$Y}0w&E0vtNw`II?$(eioc$Mg! zZmJ)z8Vc^kc(vfny<)t2aOPe=UL!bjuOF`&oVnMJ*9y+u>&I&cXYTdmJ4Mbm>BsBD zC4IK(Dc$P^XYOqouNOH_-RsBeN6t1)w`@>yu9|Myu;k2Lzfo}JuHQH~bJuSYoVn{a z4bI&4cMi_n^>+!*-1YP0rD4-^`{(c%x;b-i%jAnCXYTcrFO{5qAL=JxE;;)?)K9)r za^_w?`D)3Td;R2VC1>vSldqSYxz|r_E;)0rpM0a_%)Nf{&5|?s`pLJ-E5oMkWAnPt zx8<_#d&Cxf{z$o5+%vZ9^R;E~jdzHx`h0cSd*dBr>povm_TG4>*rv}fD0^>wuh_QF zPcM6KeDBz<&yOp6Z@hEdwa;giy*Iv3+^x?im%TT>Z`{4lN0z-ezF)k(&krek&p(H! z&bdy1Uv&RIbLMK>1A;SG+jb4kT)nqjaOUd0-Geh%?>#U$bM@XH!I`V~_6*Kky|-6z z=IXt@gELp}?Gx{hHcj8#x8$6we;$wb3(j0^dr)xZ>b?DgGgt2&5S+Ps@4(>9)q4*P z&Ro6c>&BU@_YMlqT)p?u;LO!~2M1@Hy!Wv9WZ2}rLxOXzqZ`VH2WPIfJt8=B_1>Yu znXC5>3(j1b)a^Ggt5VIpECIdq)LluHHL3ICJ&hF~OOu_l}LPgiYQ%E;#2p z{e98#-JH4Fwjelj_1+1=nXC5}24}9`J25zO_1;OrnXC6s4$fS?wcUpWeZ1UdX;GFC9_eGEF=FHW$M+IlD-dhr!xq9#P;LO!~OM^34?=1_?T)lTj zaOUd0M+axF-a9imbM@X?!I`V~md7u{ChwgcoO7N2zUZ88&RlIfH#l?k-g&{9tM|?i z&Ro6snBdISdyfsyT)p?W;LO!~j}OjVz4wIR%+-5O49;A=cR~CmZ1UcP!8zCI?~9() z&6%rhPY%vpz4w&h%+-4r1!u0_dunjz>b<80XRh9RdT{3Iy=MexuHJiQaOUd0X9Z`j z-n+QJcg`(s^4=xEIoIj$i=N%hnX7Hj3C>)-_uSyj)q9r)XRh9RUU25>z2^sKuHJh= zaOUd07Y1jp-g{AS=IXr{N6u4M@4Y1dwMv`3_tN0Zb;WpDaOP^;%Y!pl?_Cz0xq9#N z;LO!~uL#auz4yxC%+-5W1ZS?^dsT4e>b+M7XRh9RP2@av_1 zf-_g!ULTyfdhZRvnXC7%3eH@;_r~DN)q8IW&Ro5Bb#UhDy*CGEuHJh~aOUd0w?@uW zSMR+o|LsbfdT;uB3C>*S_xUF!XRd9V{J!MOwfAO5C1jCb|JJ zk$7*P_bq#G{L#3s&-;|UH~v^$-{-x{-Wz{B-q+{7%HEs)-@C?r-m|;+rvEJF%=Lcp zso>1jwoeCVuHO4haOUd0n}Rb}?|n8nbM@Zmf-_g|eLgsI_1+hPGgt3@F*tMe-k0JN z!PR?T9*st;m2H~7_mz?}S6_p#24}9HjIRY}uHO54aOUd0n}ah~?|maUbM@XggELp} zeJeO~_1?FGGgt3@CpdHU-ghJCsjK&H$$!JrChvVOICFhid_OpIwe1JNnXC7H7@WC! z@7CbV)q6h*&Ro6s7-Q}0by4bC?8-ek4l%(eF>s|RPUy*F7S za-O>O!eq@}I-t*O@}7SdPn~@qF6dr6ICGsFcM8s2+csGzICJg2$-2RrYwu0gi=3yf zy*F7ua-O>O-eiN|%+tM@h!&Ro5>MR4Zoy)A)_1Qd)q|LQ&;b8 zoBzVnChu(*oO7N2-srB~oVnU|x8Tgxdv_1cT)nq_aOUd0djw~$-n(aT=IXs2f-_g| z?HHW7dT*!T%+-7Mikzpe-n)1Hr-6_V_vz-$)wcTvXRhA6UvTE?ynH6oU7kw z%q-~U%(ZPZ$CsSB_TJ2KC1Dje~~shDE8{SzT7h&8hiKoy0U(9aO~6P z_m=gOhsC~qzIL{s98&Jr=l9I^lZTfN>hrs2`^h89{rh~)Y(F`)JfP3-n(Zftl?V3u zowNOf_k;WVj@f=<*F*aJ_St^YZogmS>Td=UUl-0?ZSi&E%vJB}%DD~G-q)RT8>YSQ z3+FaWd*3(CZJ74HubkU3?N2BS!?Zs+e?Jqsj%Lb5 z!I`Tqrvzsk^rr@A8}z3IXB+g3gR>3#M+Rpb^p6V8Ht3fGXB+gV2WK1fOM|lw`el*x zbc6nk{QZpQI+{~HIyiH+<;>vBRex4+=Bi&FoVn`H4$fTl=LBc2`g4ObSN(axnXCT% z;LKJ3nBdG+|JcZRxYo-lPdDhFp8vLGuA_P7GlDZ$Tb>!5x$2)4oVn^R z4$fTlmjq|7`ez4cuKMQ$XRi9^24}ANOM^34{quq|SN-!N=jjIh3-aHl%yqOv`NH7L z)s`0pXRi7e2WPJOmjq|7`j-Z0uKJe+XRi8}2WPJO%Yrjk{pG=#tNs=Bj^taOSFiM{wq< ze`j#!s()8-=BmFYICIs%J2-RIzbA5@ZqQ$w|CVL0qm|3|24}9eTo;_V>aP#ZT=nk@ z&Rq5H56)cm9|+D|^&bq*T=h2uXRi7igELqChk`R#{f8sx=?48r^53G&b+k(P(csM0 zmX8HzuKJG$XRi8B1ZS@LPX=eM`cDOCuKG_0XRi9s1ZS@Ln}Rb}{bz$SSN-QA=jjIh z=kwpZ%yqPCT-wc-wmA3eY1%(Z^>f|4`W`q2wZ&Rpw9FDf~6tslL(<;aBkDI|9N>! zv}xM^qU7ABY5&WTbDO69uS(8sn)bggIk#!r|EA>JrfGj$$+=C_{Hiv>ZPNcOINPNEdvLZ% ze|vDYN&k=FY?J<vSGb@#xx!2FETyo}KKeI}tI^9%1vugft=yRJ! z7x#I!;LN=(Gph$@?)5Wk1ZVE`GiwHC?)5Wk1!wN{GiwKD?)5Ww3eMc?XVwYM-0Nr7 z4bI%_XV#0Hr|$JL>qpKuO}A{2|5e@TkDgU-7@WD=vQcp6uHQH~bJuSYoVn{a4bI&4 zcMi_n^>+!*-1YN=Gk5)F!I`^$^We-~zeVIcb=Pm1{~OCTjh+)--1T=4&fN9e2WRg3djx0h`g=ys(@pvv@_$p=rqMIX z9fLD>TXqW0-1YYg&fN9)4$j>5I|pa(`uhZD?)v)%XYTs@1!wO1U4k=r{r!V8cl`q* z=jkT>uK8bGwrTYAa<|~j-Im>hGk5(1gEM#i9>JNre$U{{UB6dw=C0p6ICIzU6P&s0 z_YKb6_4@^9?)nEs&eKi${quiw*{0Fc$^(KkcUuk&&fN764$j>54++lP^#=uK?)rxY zXYTrggEM#i!-6w+{UO1byZ+(9nY;cGk@Iwu{?Pp2QnqRI)bg<4%-xp5gEM#i5y6?e z{>b3WU4K+?=B__FICIw@6P&s0j}6Y;^~VKg?)u|{Gk5)h$a%U+e?tCmE!#A@sJ}1m z(ao8ATP8d?bFZJ+!I^vg#7@rK>nFaqoVnLee2+PEub=oja^_w?{r5tgxz|tsy%A^b z_0xZ^#F=~j#P{)p;9fuJ`#k-3Rc#uLV-l+k_v*u~n+c!YYYew;&hXj2=5Xug4xim? z4YzLI@Y%igaO+kWKD+NU+`1Kq&+c`GTes5i*}d*?>sB58*m!Xq3^w;3DlQukH=%fw14xO~&#-ZD-;-GL#8y-5`(uRYFPTKIWp_4WoGIY|0hYy{!;Sob8Z8&u3qzyL@-C-r~!^16Y zIAXY^4Mz^0z&x4anb(uQ+~PTFwZ z&`I9658e5t4UY-8wBfPCEp2$*&`BE}KXlTDCk&mm;fX^hZMY!Z(uNC%TiWoXp_4W| zdFZ4KPZ>JdhVe>6cTvgvso|D3JZ-q84No6BX~Q#yPTKIyp_4W|Yv?5Ji-%5L5SN5o z+VJe*mNqD@w&5}-$U{K*Y5>)?{gde^?Tc$`rL+p{a$_RKDS|JqoFIO z{~cxZp)05Voomu(U1`f5|6Nz|zT>~UOB??6?;^g_=QjN7->rPH&uy4|Z0O4Azf-zy zwwwN*;(2wK$EER#;nqEW`0Re=aO++$e0Es~f|cE4`8buS-2yI()ty32;o?l%l~-FUO%vwQpDzN+-K zd1JVxuhE-^Tl(5uJ#_MlcyqX=ufmBz8$K{} z(uNNXowVVGaLYD~_Z{vVOWq#}x3uBI!!2$2$k0g}K00*LhK~)MwBh4JCvEt|&`BFU zIdsy7PYs>4;nPDWd4Fc;`N{4(6qhF=Z0wBgr7CvEu6(8)H8&mOwlO5VQ>x3uAR z!!2$2{m@Ap{xEdXhCdFSwBb)fCvEui&`I8Z89HghUx!ZG@VB9pHvE0)WE;j84&Ch~ z?|+0_+VKCia~AZqEsP--g^K!gb-RFga83TNFjhCs8kVYiXfoU6s4&Y z0g)m_QBd^IK?U>)3eu%YuL_9p?{&{QH_wqsP_uM-Zf{Rvgh2n6K_(3 zB?pfXVh&3V9ud%B{)`DD7taHX2_qLz8pec?izh8(!pOywjxk~6;z`e# zFmmy{%GiT)EbaDW5QqjN2Tw-Egq?P0Vhk)HPi6r$7`X&cgON)X#=yuWD`Q~fl8rGi za>>pZ7`fzN42)cIG6qI2lNrk;jCSW1K!cG>9%?Xh$;%iR?S6dK$oLNtSFD6%Tps3$YbaV)QA=1F?2<0#DaJXU5Og8;yi|~OpRCx z9z$25Myw={p{r6OR*J{a)u<6G&12~5)QFYgF?0=T#Fp?F8smi5Y6{Rd!PH>%Q7y*6 z=$qP%fzc;*7z3j(9%T%SKB&tW7`ZFPz{t5CV_@VO!WbAi)@KZi+(H=xqurYsYaomq z!UWJ@!U#4#TLy z$l*oCz{p`ZV_@Vkf-x|1c!@DEau~@N7&(k$42&E`GX_QuFEa*44zDl21X8( z7z0ZV-U5tG7Dl_L2%y2pVJbBkIZR^=j2zx#42&G!W(p%oi+>zr!p^hTc*caCXPF6djF_$W zdjT{UIs8BkMh-g}10#oBjDeBEkBotl!*0gF$YBp-VC1luF)(u2#~2tn>}L#&91buB zmK^X*(1{%sM!SC!K!cIPA!;ykILsIrIUHdOj2wCHj9Ii74Mh?F-21X7y z7y~1Rn~Z@a2d}&(Vh&3VUXRgWbVoR~0j@%l3+j9k1AFeZ$4nvCX8IX4>Bfbj!pOzHC1b+K#XpiUVdUc9f-zy_;vd17Fmmy4&X_QA z@o&bMFmmw^XG|Em_%~%t*ef~Uxh7)XdXkG*{ug4jw?1{KFmwX}bQpC*>PEuQjRnx+ z=V*9}#&<+sXnB7>e_^x>Z9#jXkq0#LgGS!a=nrW06Eyk{8vP30#%O#u<>+Yfe?W9w zfoN|#>h{zz!q6QA(6Q7VspEv9;|0(OM&mm%N6VP{r4ijpAljQm-I=5sGp|pDGc390NtCq4|QK*=zap|XN<;ofR64j z{^>+ND-i7+K>Zx`Kw;=X0_efiL#T%eLq9Koe!*x@aq3~>pI-Ef0@2>#)FY^05{4cr zfF4CXn)+p7=vM^LuNv(Mq8=mu4~iZu5bYgDJ)U}kF!XBz=+~(yQokV#{iXnVlF^=G z)RVKVe&GX>DIjP?XlzbpP3Mb8$9_RgW6OZ}cO z^gIFd`_%KP7YIWy6hJRB+EbMJ1M$x!da*#XcM0`U>Se;v9}1v9qFzq@u`u)}0_YV+ zdx{v1dlA$K+^e8Q;9drG0rxtn3%D0TjljJUY6R}3P#18og}Q)yG1LXzt2uQ6ZD}eH zPp2M;r&ABa)2RpI>C^-9bn1b4I`u$2oq8aiPCXD$ryevBZY_Xk8$q}rTF^|;R?u9~ zP7onL9cUql5kv|)2wDnI6QTsD1FZz81MrL&z%xMr&qM({I|<;KB!FjU0X(}1;Mr9G z&&LGtd|Uv}ZUT5dA%JIh0X(tp;rXNho=*wjiFFUpo&tFG62P;!0G@pW@a!vqXFmZv zpAo>bzW|=k3g9_F0MF+H@EjuL$7zssNs21n?Xyfaf>?JjV;*IY9u=*97o#IC z0(ib5fajY6cuo?)bFu)QQv~pwDuCxS0X*Ll!1HYZJl_$(bGiVYGX(IQDS+oJ0X*Lo zz;m_$o^u57oGXCmdjfdQ6TtI*0X*jm;JH8m&xHbbE)u}=0|7i23*fm#0MDfYcrFvb z^FskVKN7%mxd5IY3*h;Q0G=xZ;^~K6#S_2#fhT_F15f;}2cGyH4?OX^9eCn*I`G8r za^Q*I;lLBWyMZTuXXD){*dW+My_xz;Vd$>}&|gz;q24MCy-fi94fVH1`$r2ye<%2t zU_12=>hFc2e-J?Lq~1mSqcHSt0rVc~y+-5vFE8|d!9KwO>Vwoj2}2(eKp&<)LVZ*i z`j`OvIQ7p)Z{b(grR>EKwqc+o%)6_^i6?ie;H0_e~;15_kGavg1=Yr0CgJbw8GHo1kmZJAEeG8 z44qK`oryX#bq8VSEP?<*R_bij*@dBV2%vLP=c3Ln44p>+otOF{>R4gue1eAs`Kb#~ z7ZiprB!DhV{RnjtVd$a)=s@aX)E$MPiwlATC8$eMmlB39Er2dVU6#6>Fm!nVbOq{) z)N#Vll?9aqRj8{{R}+S=E`Y8Ud%3x`Iaqin<W}S=OF<+4-4RVL;%mD0(c%1!1K5Oo<9rVc~St+Qv!IN7Qpk20G?+B@H{7g z=Xn7F*~j zo~Qxv#M*}^);>J3-roC>8yS6bk@6gI%{4$oi#6> z&N>%QXPt|uv*yLqS@YuQtaI^n)_F$ZJc3Muyn@VvhXh#!`2<-7`32bo1q7%a1qC?- zg#-xIe z_2GsJbLPKCHBm_1qnbHoi_@B`nrq#&-TYVj)^$m<>0c{b?lqDulISdx{g~FT~vQM$gMXa0~R%WzTb6i{hO9PRC@6G zi@HVFoZh{*H_%ay59f~`dDZo8w>;mWcb-YBJFIB;%B!VU>bPzJ-PBuYb-dZ9>4bx= zo-8!8p03>?=KME-dv(3-`L{nG9N_wgzxu$H@WKJQWuDOmXCHaY^=*H=@4@yDzo|Q} z7&L6x*{g2*5;I)+a{rQnI`LAU=hy$1q$}55KXt^`*1E=#E|sb*I;~Z&-_kAHf5G*S zII(2!k0X9{ePc7s&6fSM7n1!t)q6BY`UiBUPEj>ibSt8h@}>(P8&p*n?LXs0$2P-s z$;JEg|Mp3+t~ld|;g5Ao)WM~ug*Lg6!}Yi8(&pPKc)>IMW~|alP1k2>d10AOI(#9Z zLg+xudUVn6mzfrhgUtSFwK;=Y!&WP@Hdy^FeVw zxW1eZit{1a-^>Ta`Jl}Fy~g(auFU+spv?RYRc8KPaedAFO{X}273Z((Z{}|Z{cb9= z-u#tWZ{ro$o8o$NeYxJ0S#J{+*PG&cbNy}JW?kR?`$+Tsu>HQnkL^#x_D@J<`(ID7 z{pNdTfA;%zcN|$a*zXP4?^oUaVcqz1zni+DST|I)p;#@Rdp2Lp_vHSZ=dC%w70u@btcQbH538^q#<3n|)~qkut%nE9`>?*S9)9Rs54Cv?ag%jCigo-1>-c&4 z-q5Twu0QLHw)=4Q|DWnO=g&R+{4vi>?0pZv$F=uG z?)tFbtEBin%~b<|X+QPlPR7iu3xtmOUNrlXql4io8Ws1+`l8^biJ>On${i;Cf%U3(j_BddYc)`Himh51Her&gv-y>vW=D!BQ+MUL7mw}h z_I!K2@jI(3M3q0;a7&V^RMA`FkH=};*X{ZCdgE6{73-UR=e9mKRSCao-wrQ3LX|3fdhw*a5315zFNUiH zLsZ!`qti7@cv_WRUE`afJ5DJ+pLCDy>-Kzmz4gl#R^Yjq`Ee@Gt{+dmyWlbP@B`yw zW7K?=Z&l>8vm0+x`F{@#Xg7P4D)2@6YdJD)QKs&uagXim_Iz{w0_!)_saC14qj!3~ zHtlbxP5TqIdH>nkv}cVr?bF({e}h|h?Xi8`o^P(7nJ<4dlphB>FM zt(&#IYSd@t{t~;Ysm8s&dHlz$bybs0Bf>pv-*$hmXpimd_Iz`FjPmtsoESUmiRL#{ z(`NNgEKJCu!q;5)Zd!OzHT%Hx`PH~s_xFSL*uHMhcdn1{WBX#<_Sx5)eY>t(frJnh zvG3gC`ELzTEvAntkz?XW_xF_c*uHMhH`nK)Uv)QM`~LR)$cXiWtM>a{wQO6g!1b2Z z+}~%~WAnN^&*A%<>o3z!x&3GJv+c3hNA2}{v)kz?Wq%-1xJO7gBiyhxTt~ce*SJOV%PxE_RZNA5?ug&+cLE3yT zn^l|daTB%KH;mKf`)d!6$GflF^Ud|eT|eu~^{rViH2Yt3d^Owa{vO93+t=;+>|bsD zYxSmIYR((YdFg)NZjbHj_I!>T+Zp5bgMEK{9_xYT`qf--?)Uii*uHMh=lC-J z>g>M+w;ybK>~*Xon(NyA9g{ugJa^l{c|zefseXs4>)A?S}>R4!4*KJ32aMR5{ z1?@=El{U@&de^X?I%xFR(cZzY=zxHV4^A00M;V^3OnkKBd5YI5<8wq=-_Y3;GiD3f zq}AbHp4l`xN(VQp;0?a8P*>WJyVI{5^Xj0N21VpL_OK4fkgwdaqb#k4vUQ0mHtmvnH0{5$LAi`13Y{;=-Hn)!6li)%w3I^S9c zr0w0R=dsz!@HA!OEfmjFyiOUP5z6=m>d+aV_o%+&L9Gr>x)zvrh7Jx{cJau(CA!j@ zOjGMNAEAR@7?bf>*byDz-+$2B$-gSY=ah*bQ0Bbh%3QZd8J~BQ^$nf={;Hep7HM_h zt*@Ks8l;2kWlmS8%|2a8Z>hTG#tI$uyx-~cODgLCPwa-B?+sUm2P+e=sCb?-*X>cp z=Q(A4L#G$X)oVd}@h`M6V8SXLtg1EWnGhoWCC6SrnN|l4tx|4D?x%EsU&FvRD@7^8 z;mX9ji$Bgwqs(cD2ea82&&-h;8`2KYJ@xA5zZ0R#UTlvh-w|(a4L!6&2eCB6SZPx+U z1=rVt+pMp7w^?72$?NMc>qBp!`Y@CAVJ7Rt%d8K*eCoqdTOU-T=()ACAMUHd^M1Nw zQiX?9#EY4baQDr(W9fG-x8Q?192d1hIe94h+ho+HD*JEhu1MxIv@ z->R5OB`;Qs-=ku)U+6#TqqeH!#hFDbA3Lw&yXCI%Ti7AhsC~CfXI2HP@O%%Btlnjz zir9VZ#!n;WsmQGZx_SeGRn!Mr+Z3o@K>R-l8Z~;E__x^AuWz_&*W&EFpFTUJVk!=w z^!xb@;-ATH%x4Q!#|zKZIvhSv#XsITWL=A;s!@k`9!?6}tHSf2-;u87vnpb5&)4?% zYNH~zWeC{ZbA|YKee<)`-;4j(ojW|eR{SeZnKiby_)mJQ{-Y&TOohwmtBna$vDq3{ z%Nq8b>UjR8Tmw6WsQAZr*6i}jX4R-;y$PGbepTTGyQbNFHD2z!=A_MBx`g--+*P4W zocJ$#bXcB1@jqNU+o6i$pKtA%{9DC8a`nLDyTyN4(6;YpsMxFvu3zoeU3EP7^`Pwj z5#s;U)MjVut449HL;U8nRN;jZD=#_mqKer6?7)OppXuP^?E3(Uw}O#CZ1d-{t-;$Oesw$>kufAgcoGprK-QXdTY{t5Bld*aoo zx#EAI<@p|R-@5aNb5F-Ng!6Mx z3iEU2KcAm}SYL~{zUJS(_2txu-mDJ~`_zY`f3rSZbn8Px>z}thu%duU3@dl0OQy7{ zQ?(ImKP?uel7ddAP1-hIbttUTw~spn099kG8%EZKkZM z^+9v-Uz3=5*L?B6dh?SR@2jNZbt*rfu7LQDEFCaojQIcXTIl-r;ty`8O?<58dE)O} zC;pC)w!R6`#WzfTu)0cYSi5h%t+A?8^$tnD?wKh5!_y^wvPb-veYG$Cg!mt=w5Udc z_!~Cylj4u__G(_IjZa5yeG{U`B`wXiO8h6U?sucD_|JQOSd-1-|9SUGxyy~6ik19lK2~DT>NofdGW_}Uy8ruBmTxWA$muPp(Q7Z|ISxV4VW(e`{MGp4ix{R z?HW!mA^vC2m+x~*{I88X{8mTtH*Dgk#UJOD6n|V-O#I<9L;Q_zLiDc#X0`fR{IBHv zET)C{U#%Yb-4Eh_ZL446JK}$RRn9Y$#s9{k98Ke(D^T>Np~bn(Y^JH;P9k>YQB zE&ntBcmBfvZuC!yzv!QTAKz%{A7`ATfBt=Z$4meG-SNH0^YfmpuLa5L>#o#?@vIN6 zSRc~a`k=W_(PrOrQF9-oxv$aO=V-I;&UUQ$Mxo^^DAC*s=eN}JGeTp{w zmiglE>|-?dHJbYz@yEWWnfN>VAkBS|<~~WAebanx_EC$p*;m!n+^1->Zwb|AAG1Sq zUnBn5=adqE?0f2nzq1b#e`jB$xlht&-_%xfAEmjk5`Sl(qRqY~Qga_8{?5Ke{ISp3 zBmUU;Y!iQHA0+clJrz?3*TNvyU3Cxvvs`XP+Ye*tf)qzq5}Ke`jAK{?0x} z{ITzuApXuiNc^3Bk@!3NB=L9lP2!JzRDJQszG}`r@(=wt|J3wPPzwFCI~D!&PsTUU zXM9WCVtk!_w9owfE|v512l2-~eq{>tbI-kBU*chjV4}JK(xcq%s zo8zZPG&ri8N9g)9>mJjQl`jPqST4Uu58tq{WwVpIb&pFOq9X%!^n{GF-dnUsw_8@T z#=@mJbSOFORCdH?#e{wGNq=C;PK2A9lZgZ?duFtXIlc z&=DhYyjL*GbltMu?#U6IkLlKVf1ka)Y`Bg-=562jU(0m+Ie}dkPsyueYyVRE+?Db= zZd#i~HIH{m{(G?%$KV zKD=Fb%$s9%e9}bMH?drs0vV3()14l9@kF{|$91P&*K!2xE}~0L-n_oYxH-DQr14YM zJeH)ZUOP2m^~FH_XnaJP=O?sx^NBq7?t=5Vr|Ot2F;M|OcXIn7aoI10BDQ>_JL#D{ z=B}Qqle(Y&dhXJTI_YSqPV<6((b)>G3?6;@bDjI?V(-3Hy0I?Ue0uL+x^~pX_RgMu z?)&$3r8+&rYt4S$&By$G+6|plqh*`^FNf>SMT*TncVVLL{OaiI@!{)q=dTC7N8;`bU1(?(|P<`u?s=|4dP)e>%JG!~Rk1A7%RIk}~~sS())Yr8vHd<4fP0isP%y z_?A)}U&ZlFejhWwisP#|zKZixaelhKW`6cpoS%yGQ*nMO&QHbp>Anx=r{ernW_>;6 z`kM7sPH}xHt}n&)rOf*JP;q@Jt}n&)mHa-=`g%6m*QpPO73+gyeNe0qiuFO6`mkHE zJ}A})#rmLFAKdpb-&@Pyn>qeR?z+F}pZv;wA5(vB(?82n?jQSiXY3y{zEzUP*Ze|7 zvHqlTeC7Kd>uc%{$M*{7r~I9VsXw=wpQZ13ezN{>eI;>y732Eq;PxBq57$?c+umER zuZ!;bV*O!#Xw3Q$$NKO->%;5r`>_6~Kh}qdtPksa>jUfCO4hef*0*TZx7n<3uW8mF zZT}98{yz0>y>ESEeSVkqIg$0bDC@KR@9W*rtUs*Jo!$5OV||{+`h1D?`LfUF%jYS4 zzI@Bimr{59`C{g0#pKV&A?EL=SbzTU=cD`i?)cu&tUtH;eE%@z&-Vk)FT8XDKi|!` ziLa>-sobCJPVN3gsgJuBee2p96_VwHYi~vOQ1u`BV)p7?AF2Ag$7YWH{D2B=_e;N} z7ssm5Ni819)3*<~FXQ9g^UQV2T_5Wk{87e>WjvQuot(Xz?oU*fQ0nc=oi7K5DYbLw+j}MqA`fP~p?jXa&iYv2DsdBAPg`0;Rg3Jt=*1V#sp|W; z#tmzgOV!K}n6KrmeyZj-Gv6M&BR~aLUKziC;V73)Jd1mtz0UZYSH`!dDzoS%{qAGy zRr#^O1Bx!$rYf92HErE9;i}?yqi$R(-AGmHwkE^at*un0$uQ9J{ z>iSsUM>4#gWoE-ns>s&HA+48ws{-o=boWHgQN^Nn?Yr#Bu7Yws@StA4Mg{dLmp|wB zXOh{8ujP5!-0Q55^-VjiMaCgR9#!eD|M1nMNxfBuv$Nmb=zUpb>b`pVCm(KBnV&2@ zxKXxCD)ZTcMLebICo|*rJagSE^y#IHuhNEtwejzv&3VJLxo(X%{-?F^ubs?}|7rI; zbKP*)$NHK)GH8?67H#@xrZ)W(piTd1ZThEAGCTdV+C9%+XMDD51YcmfsYtB#dNH=cI z>*HQ$e9pMOW*wZ@W?gjDW}W<~&HBow&H4(}W_=AzX0z^iUUv67>tlQ`YO{{lYSstM zb*@c)IH*m17^h8r=$p(=-5AI74!GA@A6p+R-&y^UI>fqU>(rgqpWSX>bvh zfd6v+S*L8Buyy0!)}LOftUvYKx^!>r&&d?(&y#Ll`+N0Ao(tcy{>)+>`%l%MHEx}_ zyY=Us>-(RnKdb*?{W+M*`qSNK|8tOaW?b^V$L@nnedGS;Ag@bl|8vo2|MR0y{b`iE z?{W4)cK;*$BJPuJz5ltW>^{YeudP2h-MYfh7w&sTyKMJG=JTa5>sAhTA7y>*KE-@K zZt>awG``LLr&TKVKbdc{|5?j@Pyb}*zR2tYZnytY?!LwBGe-Z-{m;v;kJ+Epb?b!L z|8)Nk?SE!)Uz3G(<_qq7r0zKT#FXmK%v9E&rtZGxkNcmxKKq|2_q@N}|5W$c|77L< zrw{izncRJk*$3JEPbT*~yKge{{B#QSCzkt|o!r;>?tcdT&Hc}s6zb1`+w6ZPxcel# zZ~E)~&l4%spYeCO{`l^H@Vxjr4;HJx`>(%S zf5KC^|MIOr*;rTX{nzd4Pw!OTfBDv*tUmW&cf0=B`>zSf_g&8ZMDD|!{mJ;-)}Q*1 zwJg&$G+s5x8S;HiZ)p|Qx$c71YOiY8aod&R1D{ci{FlDC<76S#sP(dwvxY7rFL2}b zJbRt>F}`v1Eu|VZDSaU0`sJ$eBmKwC+|ph(8F#S!_OR8e>6n~bzkg$c3ePgR_SGu& zTsHAd?s?|A82WtT)80MwjZsZUe-YaFNPE?6)b{18JM~x1Z=8Ae`Q`Gvz6~w9jLiGE z%QkM$GuOq?Czk!NkNwb(?O5abw#Z#H)X0)mRd`H-J}d}cHhtDW&6+g$nWZW=EEQTANTPe?J4z?d$zUBD#|I_%|bz$ePoo9AFn0!XK^V0USjob6g zbsc=>=U%RZGF%rc_<9Go9d;erakFgWChs+_uUV%n-1X(Vj!iyxUD*1NJkQ*D!ErPF z+uvPJf2p*W~rFX8qC3TXSA%&R>^J zd?U|W&Ff;c@%hB{we7XO9AC|Oq&Z(T$JJ#U=lE)So$=|we%QzS`nm0}zMP+$^+$7F zCbOBJ+MZ|M$L4MNx1Za;wjXS}tS{@2=DH$}(KgQY!8}K>KR3I+cHC_L+J3O@wZ5!B zn)ShbKYO0Nj`KHp9+*1hj+;HtUT6HrxW0Gn&v|z1{weGBgU!P->kr4LtWW=Ja{I@O z!?W&uy!H5&O&(YCIpg~N_4q#Pt|!(Xcb?h#z&hj3OWS`oZqGCGGnVTh)}5bb-IjIN zg`K~4o|%5z#PJDn*~aa8=DJw=tl;`8`=@nm*SYPt)YS*u5Bq%TL%jRnQMCU((Jtos Rwf*lmDjqBQ-|O@_{yzW$Qgi?S From 3979361c92b1f9f5c2127e879120125f2a9f1ed1 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 13:50:20 +0000 Subject: [PATCH 16/68] Added real increment test --- .../jedi_lfric_tests/source/jedi_tlm_tests.f90 | 14 +++++++++----- .../opt/rose-app-real_increment.conf | 5 +++++ .../jedi_lfric_tests/tasks_jedi_lfric_tests.cylc | 14 ++++++++++++++ .../site/meto/groups/groups_jedi_lfric_tests.cylc | 2 ++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf diff --git a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 index bd1d338d..a5f452f7 100644 --- a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 +++ b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 @@ -35,7 +35,7 @@ program jedi_tlm_tests use cli_mod, only : parse_command_line - use constants_mod, only : PRECISION_REAL, i_def, str_def, r_def + use constants_mod, only : PRECISION_REAL, i_def, str_def, r_def, l_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & LOG_LEVEL_ALWAYS, LOG_LEVEL_ERROR, & @@ -71,6 +71,8 @@ program jedi_tlm_tests integer( kind=i_def ) :: model_communicator type( jedi_duration_type ) :: forecast_length type( namelist_type ), pointer :: jedi_lfric_settings_config + type( namelist_type ), pointer :: jedi_increment_config + logical( kind=l_def ) :: real_increment character( str_def ) :: forecast_length_str real( kind=r_def ) :: dot_product_1 real( kind=r_def ) :: dot_product_2 @@ -110,6 +112,12 @@ program jedi_tlm_tests ! Create geometry call geometry%initialise( model_communicator, configuration ) + ! Create inc_initial, either from file or random + call inc_initial%initialise( geometry, configuration ) + jedi_increment_config => configuration%get_namelist('jedi_increment') + call jedi_increment_config%get_value( 'initialise_via_read', real_increment ) + if (.not. real_increment) call inc_initial%random() + ! Create state call state%initialise( geometry, configuration ) @@ -127,10 +135,6 @@ program jedi_tlm_tests ! ---- Perform the adjoint test - ! Create inc_initial and randomise - call inc_initial%initialise( geometry, configuration ) - call inc_initial%random() - ! Check the norm is not zero if (inc_initial%norm() <= 0.0_r_def) then call log_event("inc_initial norm not > 0.0", LOG_LEVEL_ERROR) diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf new file mode 100644 index 00000000..aea74c8f --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf @@ -0,0 +1,5 @@ +[namelist:jedi_geometry] +io_setup_increment=.true. + +[namelist:jedi_increment] +initialise_via_read=.true. diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index 8b9d6809..f2365c63 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -133,6 +133,19 @@ "threads": 4, }) %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "real_increment"], + "resolution": "C12_MG", + "ancil_resolution": "C12", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 6, + "threads": 4, + }) %} + {% elif task_ns.conf_name == "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG" %} {% do task_dict.update({ @@ -261,6 +274,7 @@ "tlm_tests_nwp_gal9-C12_op", "tlm_tests_nwp_gal9-1PE-C12_MG", "tlm_tests_nwp_gal9-4OMP-C12_MG", + "tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG", "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG", "tlm_tests_nwp_gal9-dry-C12_MG", "tlm_tests_nwp_gal9-dry-4OMP-C12_MG", diff --git a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc index ce208279..97d37306 100644 --- a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc +++ b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc @@ -22,6 +22,7 @@ "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_azspice_gnu_fast-debug-64bit", @@ -63,6 +64,7 @@ "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_ex1a_cce_fast-debug-64bit", From 6c3059dbcc12f738f5a085f4895bd9fb7357c1d8 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 14:44:09 +0000 Subject: [PATCH 17/68] Tolerance was a bit tight before --- .../app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf index d9c5499f..6a4202a6 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf @@ -1,5 +1,5 @@ [namelist:jedi_lfric_settings] -adjoint_test_tolerance=1.0e-3 +adjoint_test_tolerance=2.0e-3 [namelist:mixed_solver] mixed_solver_a_tol=1.0e-21 From 41e2de7a361a74a7af62c48d230b9c1eaf1f345d Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 15:04:26 +0000 Subject: [PATCH 18/68] Empty commit to test signing From ae5415eba8514a8cab653a15b7b5cf3b176f59d0 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 15:27:35 +0000 Subject: [PATCH 19/68] Majority of changes --- .../C224_create_traj_file.sh | 19 +++++++ .../jedi_tlm_tests/opt/rose-app-C224_MG.conf | 8 +++ .../opt/rose-app-nwp_gal9_c224.conf | 3 ++ .../tasks_jedi_lfric_tests.cylc | 53 ++++++++++++++++++- .../common/lfric_atm/tasks_lfric_atm.cylc | 13 +++++ .../meto/groups/groups_jedi_lfric_tests.cylc | 3 ++ .../site/meto/groups/groups_lfric_atm.cylc | 1 + 7 files changed, 99 insertions(+), 1 deletion(-) create mode 100755 applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf create mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf diff --git a/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh b/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh new file mode 100755 index 00000000..22ba5032 --- /dev/null +++ b/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh @@ -0,0 +1,19 @@ +# This input file can be generated by running the lfric_atm nightly test suite +# It is generated by the nwp_gal9_ls_and_jedi-C224_MG test +INPUT=ls_and_jedi_trajectory_2021060200-2021060207.nc +OUTPUT=C224_jedi_trajectory.nc + +TIMESTEP=$(ncks -d time,0 -v time ${INPUT} | grep "time =" | sed -e "s/.*= //;s/ .*//" | tr -d -c 0-9) + +echo Altering variable names to match JEDI/MONIO +# Change the file so that the time starts at 0, not 3600 +ncrename -d time,time_counter ${INPUT} ${INPUT}_tmp +ncrename -O -v time,time_instant ${INPUT}_tmp ${INPUT}_tmp +ncrename -O -v time_bounds,time_instant_bounds ${INPUT}_tmp ${INPUT}_tmp + +echo Shifting time back by ${TIMESTEP} +# Change the file so that the time starts at 0 +ncap2 -O -s time_instant-=${TIMESTEP} ${INPUT}_tmp ${INPUT}_tmp +ncap2 -O -s time_instant_bounds-=${TIMESTEP} ${INPUT}_tmp ${OUTPUT} +rm *tmp* +echo Output ${OUTPUT} diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf new file mode 100644 index 00000000..1814a470 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C224_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C224_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C224_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf new file mode 100644 index 00000000..dfe2b916 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf @@ -0,0 +1,3 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index f2365c63..2665f83c 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -244,6 +244,54 @@ "threads": 4, }) %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-4OMP-C224_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 1176, + "threads": 4, + "xios_nodes": 4, + "mpi_parts_xios" : 16, + "wallclock": 10, + }) %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 1176, + "threads": 4, + "xios_nodes": 4, + "mpi_parts_xios" : 16, + "wallclock": 10, + }) %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 1176, + "threads": 4, + "xios_nodes": 4, + "mpi_parts_xios" : 16, + "wallclock": 10, + }) %} + {% elif task_ns.conf_name == "integration_tests" %} {% do task_dict.update({ @@ -280,7 +328,10 @@ "tlm_tests_nwp_gal9-dry-4OMP-C12_MG", "tlm_tests_nwp_gal9-dry-1PE-C12_MG", "tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG", - "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG" + "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG", + "tlm_tests_nwp_gal9-4OMP-C224_MG", + "tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG", + "tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG" ] %} {% if task_ns.conf_name not in no_kgo %} diff --git a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc index b7e58ca4..ff7f5f9b 100644 --- a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc @@ -245,6 +245,19 @@ "log_level": "error", }) %} +{% elif task_ns.conf_name == "nwp_gal9_ls_and_jedi-C224_MG" %} + + {% do task_dict.update({ + "opt_confs": ["um_dump","ls_and_jedi","june_case"], + "resolution": "C224_MG", + "DT": 720, + "tsteps": 35, + "mpi_parts": 1176, + "wallclock": 10, + "xios_nodes": 4, + "mpi_parts_xios" : 16, + }) %} + {% elif task_ns.conf_name == "nwp_gal9-C896_MG" %} {% do task_dict.update({ diff --git a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc index 97d37306..12128c65 100644 --- a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc +++ b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc @@ -71,6 +71,9 @@ "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG_ex1a_cce_fast-debug-64bit-rsolver64", + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C224_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG_ex1a_cce_fast-debug-64bit-rsolver64", "jedi_lfric_tests_ex1a_integration_tests", ], "jedi_lfric_tests_op_ex1a_developer": [ diff --git a/rose-stem/site/meto/groups/groups_lfric_atm.cylc b/rose-stem/site/meto/groups/groups_lfric_atm.cylc index 44467096..3e6176df 100644 --- a/rose-stem/site/meto/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/meto/groups/groups_lfric_atm.cylc @@ -120,6 +120,7 @@ "lfric_atm_nwp_gal9_eda-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9_eda_jada-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9_ls_and_jedi-C12_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_ls_and_jedi-C224_MG_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9-pert-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_casim-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_coma9-C12_ex1a_cce_fast-debug-32bit", From 054f999315b8761a4a4cf0339bcd23d8a30c22ad Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 15:30:39 +0000 Subject: [PATCH 20/68] Removing change that's meant for a later PR --- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 4 ++-- rose-stem/app/jedi_tlm_tests/rose-app.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 82baa804..6eb46dde 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -602,8 +602,8 @@ write_minmax_tseries=.false. [namelist:jedi_geometry] io_calender_start='2021-06-02T00:00:00' -io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' -io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 99c205f8..d6de641c 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -602,8 +602,8 @@ write_minmax_tseries=.false. [namelist:jedi_geometry] io_calender_start='2021-06-02T00:00:00' -io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' -io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' From 02438dd07a4e2aea1590b7112067f3d451b0e716 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 15:32:04 +0000 Subject: [PATCH 21/68] Link to new files --- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 4 ++-- rose-stem/app/jedi_tlm_tests/rose-app.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 6eb46dde..82baa804 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -602,8 +602,8 @@ write_minmax_tseries=.false. [namelist:jedi_geometry] io_calender_start='2021-06-02T00:00:00' -io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' -io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' +io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' +io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index d6de641c..99c205f8 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -602,8 +602,8 @@ write_minmax_tseries=.false. [namelist:jedi_geometry] io_calender_start='2021-06-02T00:00:00' -io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' -io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' +io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' +io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' From 5c36313722681730f6934230d805ba5f7445625f Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 20 Jan 2026 15:33:36 +0000 Subject: [PATCH 22/68] opt conf corrections --- .../site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index 2665f83c..e7b3bb62 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -248,7 +248,7 @@ {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "semi_strict_solver"], "resolution": "C224_MG", "ancil_resolution": "C224", "DT": 1800, @@ -264,7 +264,7 @@ {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "real_increment", "semi_strict_solver"], "resolution": "C224_MG", "ancil_resolution": "C224", "DT": 1800, From 33b96bc210e687974db36055d19ae4f66e55dba5 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 09:00:07 +0000 Subject: [PATCH 23/68] Turn off XIOS server mode --- .../jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf | 2 +- .../common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf index 6a4202a6..4af6d3cf 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf @@ -1,5 +1,5 @@ [namelist:jedi_lfric_settings] -adjoint_test_tolerance=2.0e-3 +adjoint_test_tolerance=1.0e-2 [namelist:mixed_solver] mixed_solver_a_tol=1.0e-21 diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index e7b3bb62..432c1b86 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -255,9 +255,6 @@ "tsteps": 13, "mpi_parts": 1176, "threads": 4, - "xios_nodes": 4, - "mpi_parts_xios" : 16, - "wallclock": 10, }) %} {% elif task_ns.conf_name == "tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG" %} @@ -271,9 +268,6 @@ "tsteps": 13, "mpi_parts": 1176, "threads": 4, - "xios_nodes": 4, - "mpi_parts_xios" : 16, - "wallclock": 10, }) %} {% elif task_ns.conf_name == "tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG" %} @@ -287,9 +281,6 @@ "tsteps": 13, "mpi_parts": 1176, "threads": 4, - "xios_nodes": 4, - "mpi_parts_xios" : 16, - "wallclock": 10, }) %} {% elif task_ns.conf_name == "integration_tests" %} From b1d0eb7dab4f1a2a6742f95aa3849785e17d2389 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 11:13:07 +0000 Subject: [PATCH 24/68] Initial commit - transfer of changes from Tim's branch --- .../linear_physics/atlt_bdy_lyr_alg_mod.x90 | 194 ++++++++++++ .../linear_physics/atlt_bl_inc_alg_mod.x90 | 189 ++++++++++++ .../timestepping/atlt_si_timestep_alg_mod.x90 | 2 +- .../source/driver/adjoint_test_driver_mod.f90 | 12 + .../example_tlm_tests/iodef.xml | 2 + .../jedi_id_linear_model_mod.f90 | 3 +- .../jedi-interface/jedi_linear_model_mod.f90 | 3 +- .../jedi_setup_field_meta_data_mod.F90 | 3 + applications/linear_model/example/iodef.xml | 6 + .../jedi_lfric_linear_modeldb_driver_mod.f90 | 2 +- .../field/jedi_lfric_linear_fields_mod.f90 | 25 ++ rose-stem/app/linear_model/file/iodef.xml | 6 + .../opt/rose-app-nwp_gal9_c12.conf | 4 +- rose-stem/app/linear_model/rose-app.conf | 13 +- .../linear_physics/atl_bdy_lyr_alg.x90 | 283 ++++++++++++++++++ .../timestepping/atl_si_timestep_alg_mod.x90 | 137 ++++++++- .../linear_physics/atl_bl_inc_kernel_mod.F90 | 184 ++++++++++++ .../lfric-linear/HEAD/rose-meta.conf | 88 ++++++ .../algorithm/linear_data_algorithm_mod.x90 | 7 +- .../linear_physics/tl_bdy_lyr_alg.x90 | 279 +++++++++++++++++ .../timestepping/tl_si_timestep_alg_mod.x90 | 117 +++++++- .../source/driver/linear_driver_mod.f90 | 2 +- .../source/driver/linear_model_data_mod.f90 | 20 +- .../linear_physics/tl_bl_inc_kernel_mod.F90 | 164 ++++++++++ .../tl_compute_aubu_kernel_mod.F90 | 123 ++++++++ .../tl_compute_qe_kernel_mod.F90 | 176 +++++++++++ 26 files changed, 2002 insertions(+), 42 deletions(-) create mode 100644 applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 create mode 100644 applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 create mode 100644 science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 create mode 100644 science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 create mode 100644 science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 create mode 100644 science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 create mode 100644 science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 create mode 100644 science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 new file mode 100644 index 00000000..09b8944c --- /dev/null +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 @@ -0,0 +1,194 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Module containing adjoint test for atl_bdy_lyr_alg +module atlt_bdy_lyr_alg_mod + + use sci_assign_field_random_range_alg_mod, & + only : assign_field_random_range + use field_mod, only : field_type + use function_space_mod, only : function_space_type + use constants_mod, only : r_def, i_def, l_def + use field_indices_mod, only : igh_u, igh_t, & + igh_d, igh_p + use log_mod, only : log_event, & + log_scratch_space, & + LOG_LEVEL_INFO, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_ERROR + use mesh_mod, only : mesh_type + use derived_config_mod, only : bundle_size + use driver_modeldb_mod, only : modeldb_type + use finite_element_config_mod, only : element_order_h, element_order_v + use fs_continuity_mod, only : W2, W3, Wtheta + use function_space_collection_mod, only : function_space_collection + use adjoint_test_parameters_mod, only : ls_u_range, ls_theta_range, & + ls_rho_range, ls_exner_range + + implicit none + + public + + contains + + !============================================================================= + !> @brief Adjoint test for atl_bdy_lyr_alg. + !> @details Passes if adjoint is transpose of tangent linear. + !> Determined by testing the equality of inner products and , + !> where M is the tangent linear and A is the adjoint. + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + subroutine atlt_bdy_lyr_alg( modeldb, mesh ) + + use tl_bdy_lyr_alg_mod, only : tl_bdy_lyr_alg + use atl_bdy_lyr_alg_mod, only : atl_bdy_lyr_alg + + implicit none + + ! Arguments + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + + ! Arguments for tl and atl calls + ! Form of state is [u,theta,rho,exner] + type(field_type) :: state(bundle_size) + type(field_type) :: u_bl_inc + type(field_type) :: ls_state(bundle_size) + + ! Copies of input fields used in inner products + type(field_type) :: state_input(bundle_size) + type(field_type) :: u_bl_inc_input + + ! Pointers for initialising fields + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! Inner products + real(kind=r_def) :: inner1 + real(kind=r_def) :: inner2 + real(kind=r_def) :: ip1(2),ip2(2) + real(kind=r_def) :: sf(2) + + + ! Test parameters and variables + real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def) :: machine_tol + real(kind=r_def) :: relative_diff + real(kind=r_def), parameter :: eps = 1e-30_r_def + + ! Misc + real(kind=r_def) :: dt + + + ! Determining time constants + dt = real(modeldb%clock%get_seconds_per_step(), r_def) + if ( dt <= 0.0_r_def ) then + write( log_scratch_space, * ) "dt cannot be leq 0, found dt = ", dt + call log_event( log_scratch_space, log_level_error ) + end if + + + ! Initialising fields + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) + vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) + vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) + + call state(igh_u) % initialise( vector_space = vector_space_w2_ptr ) + call state(igh_t) % initialise( vector_space = vector_space_wtheta_ptr ) + call state(igh_d) % initialise( vector_space = vector_space_w3_ptr ) + call state(igh_p) % initialise( vector_space = vector_space_w3_ptr ) + call u_bl_inc % initialise( vector_space = vector_space_w2_ptr ) + + call state(igh_u) % copy_field_properties( state_input(igh_u) ) + call state(igh_t) % copy_field_properties( state_input(igh_t) ) + call state(igh_d) % copy_field_properties( state_input(igh_d) ) + call state(igh_p) % copy_field_properties( state_input(igh_p) ) + call state(igh_u) % copy_field_properties( u_bl_inc_input ) + + call state(igh_u) % copy_field_properties( ls_state(igh_u) ) + call state(igh_t) % copy_field_properties( ls_state(igh_t) ) + call state(igh_d) % copy_field_properties( ls_state(igh_d) ) + call state(igh_p) % copy_field_properties( ls_state(igh_p) ) + + + ! Initialise values and call the tangent-linear alg. + call invoke( setval_random( u_bl_inc ), & + setval_x(u_bl_inc_input, u_bl_inc ), & + setval_random( state(igh_u) ), & + setval_x( state_input(igh_u), state(igh_u) ), & + setval_random( state(igh_t) ), & + setval_x( state_input(igh_t), state(igh_t) ), & + setval_random( state(igh_d) ), & + setval_x( state_input(igh_d), state(igh_d) ), & + setval_random( state(igh_p) ), & + setval_x( state_input(igh_p), state(igh_p) ) ) + + + ! LS init + call assign_field_random_range( ls_state(igh_u), ls_u_range(1), ls_u_range(2) ) + call assign_field_random_range( ls_state(igh_t), ls_theta_range(1), ls_theta_range(2) ) + call invoke( setval_random( ls_state(igh_d) ), & + setval_random( ls_state(igh_p) ) ) + + + ! Tangent linear + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + + ! < Mx, Mx > + call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & + x_innerproduct_x( ip1(2), u_bl_inc ) ) + + + sf(1) = 1.0_r_def / (ip1(1) + eps) + sf(2) = 1.0_r_def / (ip1(2) + eps) + + inner1 = 0.0_r_def + inner1 = inner1 + ip1(1) * sf(1) + inner1 = inner1 + ip1(2) * sf(2) + + ! Scaling fields + call invoke( inc_a_times_X( sf(1), state(igh_u) ), & + inc_a_times_X( sf(2), u_bl_inc ) ) + + ! Adjoint alg call and inner products + + ! Adjoint + call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + + ! < AMx, x > + call invoke( x_innerproduct_y( ip2(1), & + state(igh_u), & + state_input(igh_u) ), & + x_innerproduct_y( ip2(2), & + u_bl_inc, & + u_bl_inc_input ) ) + + + inner2 = 0.0_r_def + inner2 = inner2 + ip2(1) + inner2 = inner2 + ip2(2) + + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip1=',ip1(1)*sf(1),ip1(2)*sf(2) + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip2=',ip2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: s(ip1),s(ip2)=',inner1,inner2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + ! Test the inner-product values for equality, allowing for the precision of the active variables + machine_tol = spacing( max( abs( inner1 ), abs( inner2 ) ) ) + relative_diff = abs( inner1 - inner2 ) / machine_tol + if ( relative_diff < overall_tolerance ) then + write( log_scratch_space, * ) "PASSED tl_bdy_lyr_alg:", inner1, inner2, relative_diff + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + else + write( log_scratch_space, * ) "FAILED tl_bdy_lyr_alg:", inner1, inner2, relative_diff + call log_event( log_scratch_space, LOG_LEVEL_ERROR ) + end if + + end subroutine atlt_bdy_lyr_alg + +end module atlt_bdy_lyr_alg_mod diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 new file mode 100644 index 00000000..b4de5d92 --- /dev/null +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 @@ -0,0 +1,189 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Module containing adjoint test for atl_bl_inc_kernel +module atlt_bl_inc_alg_mod + + use sci_assign_field_random_range_alg_mod, & + only : assign_field_random_range + use sci_geometric_constants_mod, only: get_face_selector_ew, & + get_face_selector_ns + use integer_field_mod, only: integer_field_type + use field_mod, only : field_type + use function_space_mod, only : function_space_type + use log_mod, only : log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_INFO + use mesh_mod, only : mesh_type + use function_space_collection_mod, only : function_space_collection + use finite_element_config_mod, only : element_order_h, element_order_v + use fs_continuity_mod, only : W2, W3, Wtheta + use constants_mod, only : i_def, r_def + use quadrature_face_mod, only : quadrature_face_type + use quadrature_rule_gaussian_mod, only : quadrature_rule_gaussian_type + use reference_element_mod, only : reference_element_type + use planet_config_mod, only : cp + use adjoint_test_parameters_mod, only : ls_theta_range, & + ls_exner_range, & + ls_md1_range, & + ls_md2_range, & + ls_md3_range + + implicit none + + public + + contains + + !============================================================================= + !> @brief Adjoint test for atl_bl_inc. + !> @details Passes if adjoint is transpose of tangent linear. + !> Determined by testing the equality of inner products and , + !> where M is the tangent linear and A is the adjoint. + !> @param[in] mesh Mesh object + subroutine atlt_bl_inc_alg( mesh ) + + use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type + use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type + + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + + implicit none + + ! Arguments + type(mesh_type), pointer, intent(in) :: mesh + + ! Arguments for tl and adj calls + type( field_type) :: u_inc + type( field_type) :: u + type( field_type) :: auv + type( field_type) :: buv_inv + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + ! Copies of input fields used in inner products + type( field_type) :: u_inc_input + type( field_type) :: u_input + + ! Pointers for initialising fields + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! Inner products + real(kind=r_def) :: ip1(2) + real(kind=r_def) :: ip2(2) + real(kind=r_def) :: sf(2) + real(kind=r_def) :: inner1 + real(kind=r_def) :: inner2 + + ! Test parameters and variables + real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def) :: machine_tol + real(kind=r_def) :: relative_diff + real(kind=r_def), parameter :: eps = 1e-30_r_def + + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) + vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) + vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) + + call auv % initialise( vector_space = vector_space_w2_ptr, name = 'auv' ) + call buv_inv % initialise( vector_space = vector_space_w2_ptr, name = 'buv_inv' ) + + call u_inc % initialise( vector_space = vector_space_w2_ptr, name = 'u_inc' ) + call u % initialise( vector_space = vector_space_w2_ptr, name = 'u' ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + + call u_inc % copy_field_properties( u_inc_input ) + call u % copy_field_properties( u_input ) + + + ! Initialise arguments and call the tangent-linear kernel. + call invoke( setval_random( u ), & + setval_x( u_input, u ), & + setval_random( u_inc ), & + setval_x( u_inc_input, u_inc ) ) + + + ! LS init + call assign_field_random_range( auv, -1.0_r_def, 1.0_r_def ) + call assign_field_random_range( buv_inv, 1.0_r_def, 2.0_r_def ) ! must avoid 0 + + + ! < Mx, Mx > + call invoke ( tl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + call invoke ( & + x_innerproduct_x( ip1(1), u_inc ), & + x_innerproduct_x( ip1(2), u ) ) + + + sf(1) = 1.0_r_def / (ip1(1) + eps) + sf(2) = 1.0_r_def / (ip1(2) + eps) + + inner1 = 0.0_r_def + inner1 = inner1 + ip1(1) * sf(1) + inner1 = inner1 + ip1(2) * sf(2) + + + ! Scaling fields + call invoke( inc_a_times_X( sf(1),u_inc ), & + inc_a_times_X( sf(2),u ) ) + + ! < AMx, x > + call invoke ( atl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + + call invoke ( & + x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & + x_innerproduct_y( ip2(2), u, u_input ) ) + + inner2 = 0.0_r_def + inner2 = inner2 + ip2(1) + inner2 = inner2 + ip2(2) + + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & + ip1(1)*sf(1),ip1(2)*sf(2) + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=',ip2 + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & + inner1,inner2 + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + + ! Test the inner-product values for equality, allowing for the precision of the active variables + machine_tol = spacing( max( abs(inner1), abs(inner2) ) ) + relative_diff = abs(inner1 - inner2) / machine_tol + if (relative_diff < overall_tolerance) then + write(log_scratch_space, *) "PASSED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_INFO) + else + write(log_scratch_space, *) "FAILED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end if + + end subroutine atlt_bl_inc_alg + +end module atlt_bl_inc_alg_mod diff --git a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 index 10022e7b..b552e0e4 100644 --- a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 @@ -95,7 +95,7 @@ contains real(kind=r_def) :: u_u_inp_inner_prod, rho_rho_inp_inner_prod, theta_theta_inp_inner_prod, exner_exner_inp_inner_prod, & mr_mr_inp_inner_prod(nummr), moist_dyn_moist_dyn_inp_inner_prod(num_moist_factors) real(kind=r_def) :: inner1, inner2 - real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 5000.0_r_def real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver real(kind=r_def), parameter :: eps = 1e-30_r_def diff --git a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 index 9ebee3a4..8db25218 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 @@ -54,6 +54,9 @@ subroutine run( modeldb ) use adjt_poly_adv_upd_lookup_alg_mod, only : adjt_poly_adv_upd_lookup_alg use adjt_w3h_adv_upd_lookup_alg_mod, only : adjt_w3h_adv_upd_lookup_alg + ! ./linear_physics + use atlt_bl_inc_alg_mod, only : atlt_bl_inc_alg + ! Handwritten algorithm tests ! ./interpolation use adjt_interpolation_alg_mod, only : adjt_interp_w3wth_to_w2_alg, & @@ -103,6 +106,9 @@ subroutine run( modeldb ) use adjt_mixed_solver_alg_mod, only : adjt_mixed_solver_alg use adjt_semi_implicit_solver_step_alg_mod, only : adjt_semi_implicit_solver_step_alg + ! ./linear_physics + use atlt_bdy_lyr_alg_mod, only : atlt_bdy_lyr_alg + ! ./timestepping use atlt_si_timestep_alg_mod, only : atlt_si_timestep_alg @@ -141,6 +147,9 @@ subroutine run( modeldb ) ! ./core_dynamics call atlt_pressure_gradient_bd_alg( mesh ) + ! ./linear_physics + call atlt_bl_inc_alg( mesh ) + ! ./inter_function_space call adjt_sci_convert_hdiv_field_alg( mesh, chi, panel_id ) @@ -188,6 +197,9 @@ subroutine run( modeldb ) call adjt_compute_vorticity_alg( mesh ) call atlt_derive_exner_from_eos_alg( mesh ) call atlt_moist_dyn_factors_alg( mesh ) + + ! ./linear_physics + call atlt_bdy_lyr_alg( modeldb, mesh ) ! ./solver call adjt_pressure_precon_alg( modeldb, mesh, modeldb%clock ) diff --git a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml index 7d20e408..1d5caf93 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 index 4cf75379..991c69c7 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 @@ -34,6 +34,7 @@ module jedi_id_linear_model_mod use jedi_base_linear_model_mod, only : jedi_base_linear_model_type use jedi_lfric_duration_mod, only : jedi_duration_type use jedi_lfric_linear_fields_mod, only : variable_names, & + ls_variable_names, & create_linear_fields use jedi_lfric_wind_fields_mod, only : create_scalar_winds, & setup_vector_wind @@ -187,7 +188,7 @@ subroutine set_trajectory( self, jedi_state ) call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state - call jedi_state%get_to_field_collection( variable_names, & + call jedi_state%get_to_field_collection( ls_variable_names, & next_linear_state ) ! Create W2 wind, interpolate from scaler winds (W3/Wtheta) then diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 index 6be77032..364ee384 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 @@ -39,6 +39,7 @@ module jedi_linear_model_mod zero_moist_fields use jedi_lfric_duration_mod, only : jedi_duration_type use jedi_lfric_linear_fields_mod, only : variable_names, & + ls_variable_names, & create_linear_fields use jedi_lfric_wind_fields_mod, only : create_scalar_winds, & setup_vector_wind @@ -185,7 +186,7 @@ subroutine set_trajectory( self, jedi_state ) call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state - call jedi_state%get_to_field_collection( variable_names, & + call jedi_state%get_to_field_collection( ls_variable_names, & next_linear_state ) ! Create W2 wind, interpolate from scaler winds (W3/Wtheta) then diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 index c8d0c0f0..34dd084d 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 @@ -108,6 +108,9 @@ subroutine get_field_info(function_space, is_2d, variable_name) case ( "u10m" ) function_space = W3 is_2d = .true. + case ( "land_fraction" ) + function_space = W3 + is_2d = .true. case default write ( log_scratch_space, '(4A)' ) & "jedi_setup_field_meta_data_mod::get_field_info:: ", & diff --git a/applications/linear_model/example/iodef.xml b/applications/linear_model/example/iodef.xml index 65df40e1..f5100492 100644 --- a/applications/linear_model/example/iodef.xml +++ b/applications/linear_model/example/iodef.xml @@ -52,6 +52,11 @@ + + + + + @@ -361,6 +366,7 @@ + diff --git a/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 b/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 index c7d2bb14..5a665c30 100644 --- a/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 @@ -191,7 +191,7 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ aerosol_twod_mesh ) ! Instantiate the linearisation state - call linear_create_ls_analytic( modeldb, mesh ) + call linear_create_ls_analytic( modeldb, mesh, twod_mesh ) ! 4. Initialise the model diff --git a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 index b1ab2359..83e67fda 100644 --- a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 @@ -35,6 +35,7 @@ module jedi_lfric_linear_fields_mod integer( kind=i_def ), parameter :: element_order_h = 0 integer( kind=i_def ), parameter :: element_order_v = 0 integer( kind=i_def ), parameter :: nvars = 10 + integer( kind=i_def ), parameter :: ls_nvars = 11 character( len=str_def ), parameter, public :: & variable_names(nvars) = (/'theta ', & 'exner ', & @@ -46,6 +47,18 @@ module jedi_lfric_linear_fields_mod 'm_cl ', & 'm_r ', & 'm_s '/) + character( len=str_def ), parameter, public :: & + ls_variable_names(nvars) = (/'theta ', & + 'exner ', & + 'rho ', & + 'u_in_w3 ', & + 'v_in_w3 ', & + 'w_in_wth ', & + 'm_v ', & + 'm_cl ', & + 'm_r ', & + 'm_s ', & + 'land_fraction'/) integer( kind=i_def ), parameter, public :: & variable_function_spaces(nvars) = (/Wtheta, & @@ -58,6 +71,18 @@ module jedi_lfric_linear_fields_mod Wtheta, & Wtheta, & Wtheta/) + integer( kind=i_def ), parameter, public :: & + ls_variable_function_spaces(nvars) = (/Wtheta, & + W3, & + W3, & + W3, & + W3, & + Wtheta, & + Wtheta, & + Wtheta, & + Wtheta, & + Wtheta, & + W3/) public :: create_linear_fields diff --git a/rose-stem/app/linear_model/file/iodef.xml b/rose-stem/app/linear_model/file/iodef.xml index 8591084d..8a13fa6f 100644 --- a/rose-stem/app/linear_model/file/iodef.xml +++ b/rose-stem/app/linear_model/file/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -327,6 +332,7 @@ + diff --git a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf index 4b375741..6bc37fdb 100644 --- a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' diff --git a/rose-stem/app/linear_model/rose-app.conf b/rose-stem/app/linear_model/rose-app.conf index 1c83c663..e46d9877 100644 --- a/rose-stem/app/linear_model/rose-app.conf +++ b/rose-stem/app/linear_model/rose-app.conf @@ -376,7 +376,7 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_directory='/data/users/tim.payne/lfric_apps/files' ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' @@ -720,11 +720,20 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.true. +l_stabilise_bl=.false. ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +l_boundary_layer=.true. +Log_layer=2 +Blevs_m=15 +e_folding_levs_m=10 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 +L_0_m=80.0 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 new file mode 100644 index 00000000..b60f408c --- /dev/null +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -0,0 +1,283 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief (Adjoint of) given TL state(igh_u) compute boundary layer increment u_bl_inc +module atl_bdy_lyr_alg_mod + + use constants_mod, only: r_def, i_def, l_def + use field_collection_mod, only: field_collection_type + use integer_field_mod, only: integer_field_type + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_DEBUG + use driver_modeldb_mod, only: modeldb_type + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use sci_geometric_constants_mod, only: get_height_fe, get_coordinates, & + get_panel_id, & + get_face_selector_ew, & + get_face_selector_ns + use sci_fem_constants_mod, only: get_mass_matrix_fe, & + get_inverse_mass_matrix_fe, & + get_rmultiplicity_fe + use dycore_constants_mod, only: get_coriolis, & + get_w2_mass_matrix, & + w2_damping_layer_matrix + use sci_field_bundle_builtins_mod, only: clone_bundle, & + bundle_axpy, & + add_bundle, & + copy_bundle, & + set_bundle_scalar, & + bundle_is_zero + use field_mod, only: field_type + + use formulation_config_mod, only: rotating, & + si_momentum_equation, & + vector_invariant, & + eos_method, & + eos_method_sampled, & + eos_method_projected + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + + use planet_config_mod, only: cp, kappa, rd, p_zero + use tl_kinetic_energy_gradient_kernel_mod, & + only: tl_kinetic_energy_gradient_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use operator_mod, only: operator_type + use tl_hydrostatic_kernel_mod, only: tl_hydrostatic_kernel_type + use tl_pressure_gradient_bd_kernel_mod, only: tl_pressure_gradient_bd_kernel_type + use quadrature_xyoz_mod, only: quadrature_xyoz_type + use quadrature_face_mod, only: quadrature_face_type + use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + use io_config_mod, only: subroutine_timers + use timer_mod, only: timer + use tl_rhs_project_eos_kernel_mod, only: tl_rhs_project_eos_kernel_type + use tl_rhs_sample_eos_kernel_mod, only: tl_rhs_sample_eos_kernel_type + use moist_dyn_mod, only: num_moist_factors, gas_law + use dg_matrix_vector_kernel_mod, only: dg_matrix_vector_kernel_type + use reference_element_mod, only: reference_element_type + use mesh_mod, only: mesh_type + use tl_vorticity_advection_kernel_mod, only: tl_vorticity_advection_kernel_type + use compute_vorticity_alg_mod, only: compute_vorticity_alg + use fs_continuity_mod, only: W1, W2, W3, Wtheta + use function_space_collection_mod, only: function_space_collection + use sci_field_minmax_alg_mod, only: get_field_minmax + + use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type + use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type + use atl_bl_inc_kernel_mod, only: atl_bl_inc_kernel_type + + implicit none + + private + public :: atl_bdy_lyr_alg + +contains + +!>@brief (Adjoint of) given TL state(igh_u) compute boundary layer increment u_bl_inc +!>@param[in,out] modeldb The modeldb instance +!>@param[in,out] u_bl_inc Increment to be computed +!>@param[in,out] state The current TL model prognostic state +!>@param[in] ls_state The current linearisation state +!>@param[in] dt The TL model timestep length +subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) + + implicit none + + + type(modeldb_type), target, intent(inout) :: modeldb + + ! Form of state and rhs is [u,theta,rho,exner] + type(field_type), target, intent(inout) :: state(bundle_size) + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt + + type( field_type ), intent(inout) :: u_bl_inc + + + real(kind=r_def) :: alpha_dt + logical(kind=l_def) :: dlayer_rhs + logical(kind=l_def) :: compute_eos + + type(operator_type), pointer :: mm_vel => null(), & + mm_wtheta => null(), & + mm_w3_inv => null() + type(field_type), pointer :: chi(:) => null(), & + panel_id => null(), & + geopotential => null(), & + u => null(), & + theta => null(), & + rho => null(), & + u_base => null(), & + theta_base => null(), & + rho_base => null(), & + exner => null(), & + ls_u => null(), & + ls_theta => null(), & + ls_rho => null(), & + ls_exner => null() + + + class(reference_element_type), pointer :: reference_element => null() + type (mesh_type), pointer :: mesh => null() + + type( field_type ), pointer :: height_w1 => null() + type( field_type ), pointer :: height_w2 => null() + type( field_type ), pointer :: height_w3 => null() + type( field_type ), pointer :: height_wth => null() + type( field_type ), pointer :: w2_rmultiplicity => null() + + type( field_type ) :: state_initial(bundle_size) + + type( field_collection_type ), pointer :: ls_fields + type( field_type), pointer :: ls_land_fraction => null() + + type( field_type) :: Q + type( field_type) :: E + type( field_type) :: auv + type( field_type) :: buv_inv + + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + integer(kind=i_def), parameter :: exner_stencil_depth = 1 + real(kind=r_def) :: fmin + real(kind=r_def) :: fmax + real(kind=r_def) :: ip + + if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') + + ls_fields => modeldb%fields%get_field_collection("ls_fields") + + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => state(igh_u)%get_mesh() + + mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) + chi => get_coordinates(mesh%get_id()) + panel_id => get_panel_id(mesh%get_id()) + + + height_w1 => get_height_fe(W1, mesh%get_id()) + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta,mesh%get_id() ) + + w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + dlayer_rhs = .false. + alpha_dt = 0.5_r_def * dt + compute_eos = .false. + + u => state(igh_u) + theta => state(igh_t) + rho => state(igh_d) + exner => state(igh_p) + + u_base => state(igh_u) + theta_base => state(igh_t) + rho_base => state(igh_d) + + ls_u => ls_state(igh_u) + ls_theta => ls_state(igh_t) + ls_rho => ls_state(igh_d) + ls_exner => ls_state(igh_p) + + call clone_bundle(state,state_initial , bundle_size) + call copy_bundle(state, state_initial, bundle_size) + + call rho%copy_field_properties( Q ) + call rho%copy_field_properties( E ) + + call invoke(setval_c(Q,0.0_r_def),& + setval_c(E,0.0_r_def) ) + + call u%copy_field_properties( auv ) + call u%copy_field_properties( buv_inv ) + + call invoke(setval_c(auv,0.0_r_def),& + setval_c(buv_inv,0.0_r_def) ) + + call get_field_minmax(ls_land_fraction, fmin, fmax ) + write( log_scratch_space, '(a,1x,3(e12.5,1x))') 'atl_bdy_lyr_alg, ms,min,max ls_land_fraction=',ip,fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call invoke ( tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, height_wth,& + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m ) ) + + call get_field_minmax( Q, fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Q=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call get_field_minmax( E, fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max E=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call invoke ( tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m ) ) + + call get_field_minmax( Auv, fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Auv=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call get_field_minmax( buv_inv, fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max buv_inv=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call get_field_minmax( state(igh_u), fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max state(igh_u) before atl_bl_inc=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call invoke ( atl_bl_inc_kernel_type( u_bl_inc, & + state(igh_u), & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + + call get_field_minmax( state(igh_u), fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max state(igh_u) after atl_bl_inc=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + nullify( mm_vel, mm_wtheta, mm_w3_inv, & + chi, panel_id, & + geopotential, u, theta, rho, exner, & + mesh, reference_element ) + + if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') + + end subroutine atl_bdy_lyr_alg + +end module atl_bdy_lyr_alg_mod diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index 04c46674..94024961 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -24,7 +24,8 @@ module atl_si_timestep_alg_mod use linear_config_mod, only: fixed_ls, & l_stabilise_bl, & n_bl_levels_to_stabilise, & - max_bl_stabilisation + max_bl_stabilisation, & + l_boundary_layer use derived_config_mod, only: bundle_size use boundaries_config_mod, only: limited_area use sci_fem_constants_mod, only: get_mass_matrix_fe, get_qr_fe @@ -35,6 +36,7 @@ module atl_si_timestep_alg_mod use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type use adj_dg_inc_matrix_vector_kernel_mod, only: adj_dg_inc_matrix_vector_kernel_type + use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type use adj_stabilise_bl_u_kernel_mod, only: adj_stabilise_bl_u_kernel_type use field_mod, only: field_type use mesh_collection_mod, only: mesh_collection @@ -52,11 +54,13 @@ module atl_si_timestep_alg_mod use derive_exner_from_eos_alg_mod, only: derive_exner_from_eos use atl_derive_exner_from_eos_alg_mod, only: atl_derive_exner_from_eos use update_prognostic_scalars_alg_mod, only: update_prognostic_scalars_alg + use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg use mr_indices_mod, only: nummr use moist_dyn_mod, only: num_moist_factors, gas_law use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p use mixing_config_mod, only: smagorinsky use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use sci_geometric_constants_mod, only: get_da_at_w2 use timer_mod, only: timer use transport_enumerated_types_mod, only: direction_3d, direction_h, direction_v @@ -75,6 +79,7 @@ module atl_si_timestep_alg_mod type(field_type), allocatable :: state2(:) type(field_type), allocatable :: state_copy(:) type(field_type), allocatable :: state_n(:) + type(field_type), allocatable :: state_star(:) type(field_type), allocatable :: state_after_slow(:) type(field_type), allocatable :: advected_state(:) type(field_type), allocatable :: mr_n(:) @@ -86,6 +91,7 @@ module atl_si_timestep_alg_mod type(field_type), allocatable :: state_test(:) type(field_type), allocatable :: rhs_np1_test(:) type(field_type), allocatable :: rhs_np1_in(:) + type(field_type), allocatable :: rhs_phys(:) ! Linearisation state type(field_type), allocatable :: ls_state(:) @@ -173,6 +179,7 @@ contains allocate(self%state_copy(bundle_size)) allocate(self%state_n(bundle_size)) allocate(self%state_after_slow(bundle_size)) + allocate(self%state_star(bundle_size)) allocate(self%advected_state(bundle_size)) allocate(self%rhs_n(bundle_size)) allocate(self%rhs_np1(bundle_size)) @@ -183,6 +190,7 @@ contains allocate(self%state_test(bundle_size)) allocate(self%rhs_np1_test(bundle_size)) allocate(self%rhs_np1_in(bundle_size)) + allocate(self%rhs_phys(bundle_size)) allocate(self%ls_state(bundle_size)) allocate(self%ls_state_n(bundle_size)) @@ -225,6 +233,7 @@ contains call clone_bundle( self%state, self%state_test, bundle_size ) call clone_bundle( self%state, self%rhs_np1_test, bundle_size ) call clone_bundle( self%state, self%rhs_np1_in, bundle_size ) + call clone_bundle( self%state, self%rhs_phys, bundle_size ) call clone_bundle( self%state, self%ls_state, bundle_size ) call clone_bundle( self%state, self%ls_state_n, bundle_size ) @@ -322,6 +331,15 @@ contains type(mesh_type), pointer :: mesh character(len=str_def) :: prime_mesh_name + ! Local variables for boundary layer + type( field_type ) :: u_bl_inc + type( field_type ) :: u_bl_inc_flux + type( field_type ) :: du + type( field_type ) :: u_star + type( field_type ) :: u_star_physical + type( field_type ) :: rhsu_np1 + type( field_type ), pointer :: dA => null() + if (subroutine_timers) call timer('atl_si_timestep_type::step') cast_dt = real( modeldb%clock%get_seconds_per_step(), r_def ) @@ -554,6 +572,7 @@ contains call set_bundle_scalar( 0.0_r_def, self%state_initial, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%rhs_n, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%rhs_np1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%rhs_phys, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) @@ -643,31 +662,121 @@ contains setval_c( self%rhs_np1(igh_t), 0.0_r_def ) ) end if + if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) call add_bundle( self%rhs_adv, self%rhs_np1, self%rhs_adv, bundle_size ) call add_bundle( self%rhs_n, self%rhs_np1, self%rhs_n, bundle_size ) call bundle_ax( -1.0_r_def, self%rhs_np1, self%rhs_np1, bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + if (inner > 1) then + + call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) + call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,ls_inner), & + self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state,self%state2 ,self%state, bundle_size ) + call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + + end if - call atl_rhs_alg( self%rhs_np1, & + end do inner_dynamics_loop + !------------------------------------------------------------------------- + ! End of inner (nonlinear, Coriolis) loop + !------------------------------------------------------------------------- + + if (l_boundary_layer) then + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call self%rhs_adv(igh_u)%copy_field_properties(rhsu_np1 ) + + call du%initialise( self%rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( self%rhs_adv(igh_u)%get_function_space() ) + + call clone_bundle(self%state,self%state_star, bundle_size) + call copy_bundle(self%state, self%state_star, bundle_size) ! Only state_star(igh_u) is used + call set_bundle_scalar(0.0_r_def,self%state_star, bundle_size) + + dA => get_da_at_w2(mesh%get_id()) + + call invoke( setval_c(u_bl_inc_flux, 0.0_r_def), & + setval_c(u_bl_inc, 0.0_r_def), & + setval_c(u_star, 0.0_r_def), & + setval_c(u_star_physical, 0.0_r_def), & + setval_c(du, 0.0_r_def), & + setval_c(rhsu_np1, 0.0_r_def) ) + + call invoke( enforce_bc_kernel_type(self%rhs_phys(igh_u)), & + adj_matrix_vector_kernel_type(self%rhs_phys(igh_u),u_bl_inc_flux, mm_vel ) ) + + call set_bundle_scalar(0.0_r_def,self%rhs_phys, bundle_size) + + ! Adj of u_bl_inc_flux = u_bl_inc * dA + call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & + inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & + setval_c(u_bl_inc_flux, 0.0_r_def) ) + + call atl_bdy_lyr_alg(modeldb, u_bl_inc, self%state_star, & + self%ls_state_itns(:,ls_outer,1), cast_dt ) + + ! Adj of state_star(igh_u) <- u_star_physical + call invoke( inc_x_plus_y(u_star_physical , self%state_star(igh_u) ), & + setval_c( self%state_star(igh_u), 0.0_r_def) ) + + ! Adj of u_star_physical = u_star / dA + call invoke( inc_x_divideby_y( u_star_physical, dA ), & + inc_x_plus_y( u_star, u_star_physical ), & + setval_c(u_star_physical, 0.0_r_def) ) + + ! Adj of u_star = du + state(igh_u) + call invoke( inc_X_plus_Y( du, u_star ), & + inc_X_plus_Y( self%state(igh_u), u_star ), & + setval_c(u_star, 0.0_r_def) ) + + ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) + call mass_matrix_solver_alg( rhsu_np1, du) + + ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) + call invoke( inc_X_plus_Y( self%rhs_adv(igh_u),rhsu_np1) ) + + ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) + call invoke( inc_X_plus_bY(self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1), & + inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & + setval_c( rhsu_np1, 0.0_r_def) ) + + ! Adj of du <- 0 + call invoke( setval_c(du, 0.0_r_def)) + + end if ! l_boundary_layer + + call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) + call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & -varalpha*cast_dt, & self%state1, & self%state2, & moist_dyn, & - self%ls_state_itns(:,ls_outer,ls_inner), & - self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & + self%ls_state_itns(:,ls_outer,1), & + self%ls_moist_dyn_itns(:,ls_outer,1), & .true., & dlayer_on, & modeldb%clock ) - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) - - end do inner_dynamics_loop - !------------------------------------------------------------------------- - ! End of inner (nonlinear, Coriolis) loop - !------------------------------------------------------------------------- + call add_bundle( self%state,self%state2 ,self%state, bundle_size ) + call add_bundle( self%state,self%state1 ,self%state, bundle_size ) call invoke( setval_c( self%theta_fv_inc, 0.0_r_def ), & adj_dg_inc_matrix_vector_kernel_type( self%rhs_adv(igh_t), & @@ -758,6 +867,7 @@ contains if (allocated(self%state_n)) deallocate(self%state_n) if (allocated(self%state_initial)) deallocate(self%state_initial) if (allocated(self%state_after_slow)) deallocate(self%state_after_slow) + if (allocated(self%state_star)) deallocate(self%state_star) if (allocated(self%advected_state)) deallocate(self%advected_state) if (allocated(self%rhs_n)) deallocate(self%rhs_n) if (allocated(self%rhs_np1)) deallocate(self%rhs_np1) @@ -768,6 +878,7 @@ contains if (allocated(self%state_test)) deallocate(self%state_test) if (allocated(self%rhs_np1_test)) deallocate(self%rhs_np1_test) if (allocated(self%rhs_np1_in)) deallocate(self%rhs_np1_in) + if (allocated(self%rhs_phys)) deallocate(self%rhs_phys) if (allocated(self%ls_state)) deallocate(self%ls_state) if (allocated(self%ls_state_itns)) deallocate(self%ls_state_itns) diff --git a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 new file mode 100644 index 00000000..c632526b --- /dev/null +++ b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 @@ -0,0 +1,184 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +module atl_bl_inc_kernel_mod + + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only: N + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: atl_bl_inc_kernel_type + PRIVATE + TYPE(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & + arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & + /) + INTEGER :: operates_on = CELL_COLUMN + CONTAINS + PROCEDURE, NOPASS :: atl_bl_inc_code + END TYPE + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: atl_bl_inc_code + + contains + + !> @brief (Adjoint of) computes boundary layer u inc + !! @param[in] nlayers Number of layers + !! @param[in,out] u_inc Output + !! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field + !! @param[in] undf_w2 Unique number of degrees of freedom for the output field + !! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field + subroutine atl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w2 + integer(kind=i_def), intent(in) :: ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(inout) :: u + real(kind=r_def), dimension(undf_w2), intent(in) :: auv + real(kind=r_def), dimension(undf_w2), intent(in) :: buv_inv + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + integer(kind=i_def), intent(in) :: ndf_w3_2d + integer(kind=i_def), intent(in) :: undf_w3_2d + integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns + integer(kind=i_def), intent(in) :: blevs_m + + ! Internal variables + integer(kind=i_def) :: df + integer(kind=i_def) :: k + integer(kind=i_def) :: j + real(kind=r_def), dimension(blevs_m) :: a0 + real(kind=r_def), dimension(blevs_m) :: a1 + real(kind=r_def), dimension(blevs_m) :: a2 + real(kind=r_def), dimension(blevs_m) :: u_rhs + real(kind=r_def), dimension(blevs_m) :: u_out + real(kind=r_def), dimension(blevs_m) :: factor_u + integer :: idx + integer :: idx_1 + + do j = face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)), 1, -1 + df = j + if (j == 3 .AND. face_selector_ns(map_w3_2d(1)) == 2 .AND. face_selector_ew(map_w3_2d(1)) == 1) then + df = n + end if + + u_out = 0.0_r_def + u_rhs = 0.0_r_def + a0(:) = 0.0_r_def + a1(:) = 0.0_r_def + a2(:) = 0.0_r_def + factor_u(:) = 0.0_r_def + +! ===================== set up coeffs a0,a1,a2,factor_u ===================== + + a0(1) = 1.0_r_def+(Auv(map_w2(df)+1)+Auv(map_w2(df)+0))/Buv_inv(map_w2(df)+1) + a1(1) = -Auv(map_w2(df)+1)/Buv_inv(map_w2(df)+1) + + DO k=2,BLevs_m-1 + a0(k) = 1.0_r_def+(Auv(map_w2(df)+k)+Auv(map_w2(df)+k-1))/Buv_inv(map_w2(df)+k) + a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) + a1(k) = -Auv(map_w2(df)+k)/Buv_inv(map_w2(df)+k) + end do + + a0(BLevs_m) = 1.0_r_def+Auv(map_w2(df)+BLevs_m-1)/Buv_inv(map_w2(df)+BLevs_m) + a2(BLevs_m) = -Auv(map_w2(df)+BLevs_m-1)/Buv_inv(map_w2(df)+BLevs_m) + + a0(1) = 1.0_r_def/a0(1) + + do k=2,BLevs_m + factor_u(k) = a2(k)*a0(k-1) + a0(k) = 1.0_r_def/(a0(k)-factor_u(k)*a1(k-1)) + END DO + +! ================ Adj of Solve for u_inc and transform to upper triangular form ============= + + do k = 1, blevs_m - 1 + + u_out(k) = u_out(k) + u_inc(map_w2(df) + k - 1) + u_inc(map_w2(df) + k - 1) = 0.0_r_def + + u_out(k + 1) = u_out(k + 1) + (-a0(k) * a1(k) * u_out(k)) + u_rhs(k) = u_rhs(k) + a0(k) * u_out(k) + u_out(k) = 0.0_r_def + enddo + + u_out(blevs_m) = u_out(blevs_m) + u_inc(map_w2(df) + blevs_m - 1) + u_inc(map_w2(df) + blevs_m - 1) = 0.0_r_def + + u_rhs(blevs_m) = u_rhs(blevs_m) + a0(blevs_m) * u_out(blevs_m) + u_out(blevs_m) = 0.0_r_def + + do k = blevs_m, 2, -1 + u_rhs(k - 1) = u_rhs(k - 1) + (-factor_u(k) * u_rhs(k)) + enddo + + u(blevs_m + map_w2(df) - 2) = u(blevs_m + map_w2(df) - 2) + & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + u(blevs_m + map_w2(df) - 1) = u(blevs_m + map_w2(df) - 1) - & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + u_rhs(blevs_m) = 0.0_r_def + + do k = blevs_m - 1, 2, -1 + u(k + map_w2(df)) = u(k + map_w2(df)) + auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 2) = u(k + map_w2(df) - 2) + auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + u_rhs(k) = 0.0_r_def + enddo + + u(map_w2(df) + 1) = u(map_w2(df) + 1) + auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df)) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u_rhs(1) = 0.0_r_def + + do idx_1 = blevs_m, 1, -1 + u_out(idx_1) = 0.0_r_def + enddo + do idx = blevs_m, 1, -1 + u_rhs(idx) = 0.0_r_def + enddo + + enddo + + end subroutine atl_bl_inc_code + +end module atl_bl_inc_kernel_mod diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index 98a373e4..b45a8835 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -53,6 +53,94 @@ ns=namelist/Job/Timestepping/semi-implicit range=1: type=integer +[namelist:linear=l_boundary_layer] +compulsory=false +description=?????? +help=If true then turn on boundary layer in linear model +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +type=logical + +[namelist:linear=log_layer] +compulsory=false +description=?????? +fail-if=this < 1 ; +help=Number of boundary layers levels in log layer in linear model +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=1: +type=integer + +[namelist:linear=Blevs_m] +compulsory=false +description=?????? +fail-if=this < 1 ; +help=Number of boundary layers levels in linear model +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=1: +type=integer + +[namelist:linear=e_folding_levs_m] +compulsory=false +description=?????? +fail-if=this < 1 ; +help=Number of e-folding boundary layers levels in linear model +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=1: +type=integer + +[namelist:linear=u_land_m] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=friction velocity over land +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +type=real + +[namelist:linear=u_sea_m] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=friction velocity over sea +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +type=real + +[namelist:linear=z_land_m] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=friction height over land +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +type=real + +[namelist:linear=z_sea_m] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=friction height over sea +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +type=real + +[namelist:linear=L_0_m] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=height parameter for BL in TLM +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +type=real + [namelist:linear=pert_option] compulsory=true description=Method to generate the perturbation. diff --git a/science/linear/source/algorithm/linear_data_algorithm_mod.x90 b/science/linear/source/algorithm/linear_data_algorithm_mod.x90 index 400293b4..46927bd2 100644 --- a/science/linear/source/algorithm/linear_data_algorithm_mod.x90 +++ b/science/linear/source/algorithm/linear_data_algorithm_mod.x90 @@ -590,6 +590,7 @@ module linear_data_algorithm_mod init_mr_fields use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type use idealised_config_mod, only: test + use sci_assign_field_random_kernel_mod, only: assign_field_random_kernel_type implicit none @@ -602,6 +603,7 @@ module linear_data_algorithm_mod type( field_type ), pointer :: ls_mr(:) => null() type( field_type ), pointer :: ls_moist_dyn(:) => null() + type( field_type ), pointer :: ls_land_fraction => null() type( field_collection_type ), pointer :: ls_fields @@ -621,6 +623,7 @@ module linear_data_algorithm_mod call ls_fields%get_field('ls_u', ls_u) call ls_fields%get_field('ls_rho', ls_rho) call ls_fields%get_field('ls_exner', ls_exner) + call ls_fields%get_field('ls_land_fraction', ls_land_fraction ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") call moisture_fields%get_field("ls_mr",ls_mr_array) @@ -645,7 +648,9 @@ module linear_data_algorithm_mod call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - nullify( ls_theta, ls_rho, ls_u, ls_exner, ls_moist_dyn, ls_mr ) + call invoke( assign_field_random_kernel_type( ls_land_fraction, 1.0_r_def )) + + nullify( ls_theta, ls_rho, ls_u, ls_exner, ls_moist_dyn, ls_mr, ls_land_fraction ) nullify( chi, panel_id ) end subroutine linear_init_reference_ls diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 new file mode 100644 index 00000000..8feb17b8 --- /dev/null +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -0,0 +1,279 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Given TL state(igh_u) compute boundary layer increment u_bl_inc +module tl_bdy_lyr_alg_mod + + use constants_mod, only: r_def, i_def, l_def + use field_collection_mod, only: field_collection_type + use integer_field_mod, only: integer_field_type + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_INFO + use driver_modeldb_mod, only: modeldb_type + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use sci_geometric_constants_mod, only: get_height_fe, get_coordinates, & + get_panel_id, & + get_face_selector_ew, & + get_face_selector_ns + use sci_fem_constants_mod, only: get_mass_matrix_fe, & + get_inverse_mass_matrix_fe, & + get_rmultiplicity_fe + use dycore_constants_mod, only: get_coriolis, & + get_w2_mass_matrix, & + w2_damping_layer_matrix + use sci_field_bundle_builtins_mod, only: clone_bundle, & + bundle_axpy, & + add_bundle, & + copy_bundle, & + set_bundle_scalar, & + bundle_is_zero + use field_mod, only: field_type + + use formulation_config_mod, only: rotating, & + si_momentum_equation, & + vector_invariant, & + eos_method, & + eos_method_sampled, & + eos_method_projected + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + + use planet_config_mod, only: cp, kappa, rd, p_zero + use tl_kinetic_energy_gradient_kernel_mod, & + only: tl_kinetic_energy_gradient_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use operator_mod, only: operator_type + use tl_hydrostatic_kernel_mod, only: tl_hydrostatic_kernel_type + use tl_pressure_gradient_bd_kernel_mod, only: tl_pressure_gradient_bd_kernel_type + use quadrature_xyoz_mod, only: quadrature_xyoz_type + use quadrature_face_mod, only: quadrature_face_type + use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + use io_config_mod, only: subroutine_timers + use timer_mod, only: timer + use tl_rhs_project_eos_kernel_mod, only: tl_rhs_project_eos_kernel_type + use tl_rhs_sample_eos_kernel_mod, only: tl_rhs_sample_eos_kernel_type + use moist_dyn_mod, only: num_moist_factors, gas_law + use dg_matrix_vector_kernel_mod, only: dg_matrix_vector_kernel_type + use reference_element_mod, only: reference_element_type + use mesh_mod, only: mesh_type + use tl_vorticity_advection_kernel_mod, only: tl_vorticity_advection_kernel_type + use compute_vorticity_alg_mod, only: compute_vorticity_alg + use fs_continuity_mod, only: W1, W2, W3, Wtheta + use function_space_collection_mod, only: function_space_collection + use sci_field_minmax_alg_mod, only: get_field_minmax + + use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type + use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type + use tl_bl_inc_kernel_mod, only: tl_bl_inc_kernel_type + + + implicit none + + private + public :: tl_bdy_lyr_alg + +! Typical namelist parameters: +! INTEGER :: Log_layer = 2 +! INTEGER :: Blevs_m = 8 +! INTEGER :: BL_levels = 13 +! INTEGER :: e_folding_levs_m =5 +! REAL :: u_land_m =0.4 +! REAL :: u_sea_m =0.4 +! REAL :: z_land_m =0.05 +! REAL :: z_sea_m =0.0005 +! REAL :: L_0_m =80.0 + +contains + +!>@brief Given TL state(igh_u) compute boundary layer increment u_bl_inc +!>@param[in,out] modeldb The modeldb instance +!>@param[in,out] u_bl_inc Increment to be computed +!>@param[in,out] state The current TL model prognostic state +!>@param[in] ls_state The current linearisation state +!>@param[in] dt The TL model timestep length +subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + + ! Form of state and rhs is [u,theta,rho,exner] + type(field_type), target, intent(inout) :: state(bundle_size) + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt + + type( field_type ), intent(inout) :: u_bl_inc + + real(kind=r_def) :: alpha_dt + logical(kind=l_def) :: dlayer_rhs + logical(kind=l_def) :: compute_eos + + type(operator_type), pointer :: mm_vel => null(), & + mm_wtheta => null(), & + mm_w3_inv => null() + type(field_type), pointer :: chi(:) => null(), & + panel_id => null(), & + geopotential => null(), & + u => null(), & + theta => null(), & + rho => null(), & + u_base => null(), & + theta_base => null(), & + rho_base => null(), & + exner => null(), & + ls_u => null(), & + ls_theta => null(), & + ls_rho => null(), & + ls_exner => null() + + class(reference_element_type), pointer :: reference_element => null() + type (mesh_type), pointer :: mesh => null() + + type( field_type ), pointer :: height_w1 => null() + type( field_type ), pointer :: height_w2 => null() + type( field_type ), pointer :: height_w3 => null() + type( field_type ), pointer :: height_wth => null() + type( field_type ), pointer :: w2_rmultiplicity => null() + + type( field_type ) :: state_initial(bundle_size) + + type( field_collection_type ), pointer :: ls_fields + type( field_type), pointer :: ls_land_fraction => null() + + type( field_type) :: Q + type( field_type) :: E + type( field_type) :: auv + type( field_type) :: buv_inv + + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + integer(kind=i_def), parameter :: exner_stencil_depth = 1 + real(kind=r_def) :: fmin + real(kind=r_def) :: fmax + real(kind=r_def) :: ip + + if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') + + ls_fields => modeldb%fields%get_field_collection("ls_fields") + + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => state(igh_u)%get_mesh() + + mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) + chi => get_coordinates(mesh%get_id()) + panel_id => get_panel_id(mesh%get_id()) + + height_w1 => get_height_fe(W1, mesh%get_id()) + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta,mesh%get_id() ) + + w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + dlayer_rhs = .false. + alpha_dt = 0.5_r_def * dt + compute_eos = .false. + + u => state(igh_u) + theta => state(igh_t) + rho => state(igh_d) + exner => state(igh_p) + + u_base => state(igh_u) + theta_base => state(igh_t) + rho_base => state(igh_d) + + ls_u => ls_state(igh_u) + ls_theta => ls_state(igh_t) + ls_rho => ls_state(igh_d) + ls_exner => ls_state(igh_p) + + call clone_bundle(state,state_initial , bundle_size) + call copy_bundle(state, state_initial, bundle_size) + call u%copy_field_properties( u_bl_inc ) + call invoke(setval_c(u_bl_inc,0.0_r_def)) + + call rho%copy_field_properties( Q ) + call rho%copy_field_properties( E ) + + call invoke(setval_c(Q,0.0_r_def),& + setval_c(E,0.0_r_def) ) + + call u%copy_field_properties( auv ) + call u%copy_field_properties( buv_inv ) + + call invoke(setval_c(auv,0.0_r_def),& + setval_c(buv_inv,0.0_r_def) ) + + call invoke (x_innerproduct_x(ip,ls_land_fraction)) + call get_field_minmax(ls_land_fraction, fmin, fmax ) + write( log_scratch_space, '(a,1x,3(e12.5,1x))') 'tl_bdy_lyr_alg, ms,min,max ls_land_fraction=',ip,fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call invoke ( tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, height_wth,& + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m ) ) + + call invoke ( tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m ) ) + + call get_field_minmax( state(igh_u), fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'tl_bdy_lyr_alg, min,max state(igh_u) before tl_bl_inc=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + call invoke ( tl_bl_inc_kernel_type( u_bl_inc, & + state(igh_u), & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + + call get_field_minmax(u_bl_inc , fmin, fmax ) + write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'tl_bdy_lyr_alg, min,max u_bl_inc=',fmin, fmax + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + nullify( mm_vel, mm_wtheta, mm_w3_inv, & + chi, panel_id, & + geopotential, u, theta, rho, exner, & + mesh, reference_element ) + + if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') + + end subroutine tl_bdy_lyr_alg + +end module tl_bdy_lyr_alg_mod diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index c4bfedbd..bfd7bb8d 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -31,7 +31,8 @@ module tl_si_timestep_alg_mod use linear_config_mod, only: fixed_ls, & l_stabilise_bl, & n_bl_levels_to_stabilise, & - max_bl_stabilisation + max_bl_stabilisation, & + l_boundary_layer use mixed_solver_config_mod, only: guess_np1, & reference_reset_time use timestepping_config_mod, only: alpha, & @@ -50,6 +51,7 @@ module tl_si_timestep_alg_mod copy_bundle, & set_bundle_scalar, & bundle_is_zero + use sci_geometric_constants_mod, only: get_da_at_w2 use fs_continuity_mod, only: Wtheta, W2 ! PsyKAl PSYClone kernels @@ -57,6 +59,8 @@ module tl_si_timestep_alg_mod use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg use sci_set_any_dof_kernel_mod, only: set_any_dof_kernel_type use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use stabilise_bl_u_kernel_mod, only: stabilise_bl_u_kernel_type ! Derived Types @@ -97,6 +101,8 @@ module tl_si_timestep_alg_mod use map_physics_fields_alg_mod, only: map_physics_fields_alg + use tl_bdy_lyr_alg_mod, only: tl_bdy_lyr_alg + ! Moisture species use mr_indices_mod, only: nummr, imr_v, imr_cl use moist_dyn_mod, only: num_moist_factors, gas_law @@ -109,6 +115,7 @@ module tl_si_timestep_alg_mod use timer_mod, only: timer + implicit none private @@ -123,6 +130,7 @@ module tl_si_timestep_alg_mod type( field_type ), allocatable :: state_initial(:) type( field_type ), allocatable :: state_n(:) type( field_type ), allocatable :: state_after_slow(:) + type( field_type ), allocatable :: state_star(:) type( field_type ), allocatable :: advected_state(:) type( field_type ), allocatable :: mr_n(:) type( field_type ), allocatable :: mr_inc(:) @@ -130,6 +138,7 @@ module tl_si_timestep_alg_mod type( field_type ), allocatable :: rhs_n(:) type( field_type ), allocatable :: rhs_np1(:) type( field_type ), allocatable :: rhs_adv(:) + type( field_type ), allocatable :: rhs_phys(:) ! Linearisation state type( field_type ), allocatable :: ls_state(:) @@ -220,10 +229,12 @@ contains allocate(state_initial(bundle_size)) allocate(state_n(bundle_size)) allocate(state_after_slow(bundle_size)) + allocate(state_star(bundle_size)) allocate(advected_state(bundle_size)) allocate(rhs_n(bundle_size)) allocate(rhs_np1(bundle_size)) allocate(rhs_adv(bundle_size)) + allocate(rhs_phys(bundle_size)) allocate(mr_n(nummr)) allocate(mr_after_slow(nummr)) allocate(mr_inc(nummr)) @@ -273,6 +284,7 @@ contains call clone_bundle(state, rhs_n, bundle_size) call clone_bundle(state, rhs_np1, bundle_size) call clone_bundle(state, rhs_adv, bundle_size) + call clone_bundle(state, rhs_phys, bundle_size) call clone_bundle(state, ls_state, bundle_size) call clone_bundle(state, ls_state_n, bundle_size) @@ -371,6 +383,14 @@ contains type( field_type ), intent( in ) :: ls_moist_dyn(num_moist_factors) ! field groups type( field_collection_type ), intent( inout ) :: derived_fields + ! Linear boundary layer scheme + type( field_type ) :: u_bl_inc + type( field_type ) :: u_bl_inc_flux + type( field_type ) :: du + type( field_type ) :: u_star + type( field_type ) :: u_star_physical + type( field_type ) :: rhsu_np1 + type( field_type ), pointer :: dA => null() type( mesh_type ), intent( in ), pointer :: mesh type( mesh_type ), intent( in ), pointer :: twod_mesh @@ -397,7 +417,7 @@ contains type( namelist_type ), pointer :: mixed_solver_nml real( kind=r_def ) :: mixed_solver_a_tol - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( subroutine_timers ) call timer('tl_semi_implicit_timestep_alg') cast_dt = real(modeldb%clock%get_seconds_per_step(), r_def) @@ -697,6 +717,8 @@ contains moist_dyn, ls_state_n, ls_moist_dyn_itns(:, 1,1), & .false., .false., model_clock=modeldb%clock ) + call invoke(setval_c( rhs_np1(igh_u), 0.0_r_def )) + call copy_bundle(state_after_slow, advected_state, bundle_size) if ( .not. si_momentum_equation ) then ! Predictor of the wind field (u-beta*dt*rhs) to be advected if using @@ -739,6 +761,69 @@ contains dg_inc_matrix_vector_kernel_type(rhs_adv(igh_t), & theta_fv_inc, mm_wt) ) + ! Previously tl_rhs_alg was called within each inner loop. + ! It still is called there for inner_iterations > 1. + ! For the first inner loop, it needs to be called before entering. + ! This is because rhs_np1 is used to calculate u_star in tl_bdy_lyr_alg. + call tl_rhs_alg( rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns( :, ls_outer, 1 ), & + ls_moist_dyn_itns( :, ls_outer, 1 ), & + .true., & + dlayer_on, & + modeldb%clock ) + + + if (l_boundary_layer) then + ! Run linear boundary layer scheme to compute increment to u perturbation + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + ! Compute u_star = u_np1 + M^-1(-rhs_np1 + rhs_n + rhs_a) + ! du = M^-1(-rhs_np1 + rhs_n + rhs_a + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + call invoke( setval_c(du, 0.0_r_def), & + aX_plus_Y(rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u)), & + inc_X_plus_Y(rhsu_np1, rhs_adv(igh_u)) ) + + call mass_matrix_solver_alg(du, rhsu_np1 ) + + call invoke( X_plus_Y(u_star, du, state(igh_u)) ) + + ! u_star_physical = u_star / dA + ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity + dA => get_da_at_w2(mesh%get_id()) + call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) + + ! For convenience place u_star_physical as igh_u component of state_star + call clone_bundle(state,state_star, bundle_size) + call copy_bundle(state, state_star, bundle_size) + call invoke( setval_x(state_star(igh_u),u_star_physical ) ) + + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) + ! u_bl_inc computed from state_star(igh_u) + ! NB use state_star + + ! u_bl_inc_flux = u_bl_inc * dA + ! i.e., multiply by dA to transform from velocity to flux + call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) + + call set_bundle_scalar(0.0_r_def,rhs_phys, bundle_size) + call invoke(name="update_rhs_phys_from_fast_physics", & + matrix_vector_kernel_type(rhs_phys(igh_u) ,u_bl_inc_flux, mm_vel ), & + enforce_bc_kernel_type(rhs_phys(igh_u)) ) + + end if ! l_boundary_layer + if (use_wavedynamics) then ! Use advective update to guess n+1 level scalar fieldsgv . @@ -762,16 +847,19 @@ contains !-------------------------------------------------------------------- ! Compute the time-level n+1 dynamics terms !-------------------------------------------------------------------- - call tl_rhs_alg(rhs_np1, & - -varalpha*cast_dt, & - state, & - state, & - moist_dyn, & - ls_state_itns(:, ls_outer, ls_inner), & - ls_moist_dyn_itns(:, ls_outer, ls_inner), & - .true., & - dlayer_on, & - modeldb%clock) + ! Only call tl_rhs_alg if inner > 1 as for inner===1 it is already called early (see comment above) + if (inner > 1) then + call tl_rhs_alg(rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns(:, ls_outer, ls_inner), & + ls_moist_dyn_itns(:, ls_outer, ls_inner), & + .true., & + dlayer_on, & + modeldb%clock) + end if !-------------------------------------------------------------------- ! Compute the LAM LBCs and RHS @@ -788,6 +876,7 @@ contains !-------------------------------------------------------------------- call bundle_axpy(-1.0_r_def, rhs_np1, rhs_n, rhs_np1, bundle_size) call add_bundle(rhs_np1, rhs_adv, rhs_np1, bundle_size) + if (l_boundary_layer) call add_bundle(rhs_np1, rhs_phys, rhs_np1, bundle_size) if ( limited_area ) then call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) @@ -891,7 +980,7 @@ contains nullify( mm_wt, mm_vel, qr ) - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( subroutine_timers ) call timer('tl_semi_implicit_timestep_alg') end subroutine tl_semi_implicit_alg_step @@ -910,10 +999,12 @@ contains if (allocated(state_initial)) deallocate(state_initial) if (allocated(state_n)) deallocate(state_n) if (allocated(state_after_slow)) deallocate(state_after_slow) + if (allocated(state_star)) deallocate(state_star) if (allocated(advected_state)) deallocate(advected_state) if (allocated(rhs_n)) deallocate(rhs_n) if (allocated(rhs_np1)) deallocate(rhs_np1) if (allocated(rhs_adv)) deallocate(rhs_adv) + if (allocated(rhs_phys)) deallocate(rhs_phys) if (allocated(mr_n)) deallocate(mr_n) if (allocated(mr_after_slow)) deallocate(mr_after_slow) if (allocated(mr_inc)) deallocate(mr_inc) diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index 662faea6..c7ac5631 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -174,7 +174,7 @@ subroutine initialise( program_name, modeldb ) end if ! Instantiate the linearisation state - call linear_create_ls( modeldb, mesh ) + call linear_create_ls( modeldb, mesh, twod_mesh) ! Initialise the fields stored in the model_data if ( init_option == init_option_fd_start_dump ) then diff --git a/science/linear/source/driver/linear_model_data_mod.f90 b/science/linear/source/driver/linear_model_data_mod.f90 index 95befc39..11f80b13 100644 --- a/science/linear/source/driver/linear_model_data_mod.f90 +++ b/science/linear/source/driver/linear_model_data_mod.f90 @@ -71,23 +71,24 @@ module linear_model_data_mod !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls( modeldb, mesh ) + subroutine linear_create_ls( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh select case( ls_option ) case( ls_option_analytic ) - call linear_create_ls_analytic( modeldb, mesh ) + call linear_create_ls_analytic( modeldb, mesh, twod_mesh ) case( ls_option_file ) - call linear_create_ls_file( modeldb, mesh ) + call linear_create_ls_file( modeldb, mesh, twod_mesh ) case default @@ -106,13 +107,14 @@ end subroutine linear_create_ls !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls_analytic( modeldb, mesh ) + subroutine linear_create_ls_analytic( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), pointer :: depository type( field_collection_type ), pointer :: prognostics @@ -170,6 +172,9 @@ subroutine linear_create_ls_analytic( modeldb, mesh ) imr=imr ) end do + call setup_field( ls_fields, depository, prognostics, "ls_land_fraction", W3, & + twod_mesh, checkpoint_restart_flag ) + end subroutine linear_create_ls_analytic !> @brief Create the fields in the ls fields field collection to be setup @@ -180,13 +185,14 @@ end subroutine linear_create_ls_analytic !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls_file( modeldb, mesh ) + subroutine linear_create_ls_file( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), pointer :: depository type( field_collection_type ), pointer :: prognostics @@ -242,6 +248,8 @@ subroutine linear_create_ls_file( modeldb, mesh ) mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) call setup_field( ls_fields, depository, prognostics, "ls_theta", Wtheta, & mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) + call setup_field( ls_fields, depository, prognostics, "ls_land_fraction", W3, & + twod_mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) if ( ls_read_w2h ) then call setup_field( ls_fields, depository, prognostics, "ls_h_u", W2h, & @@ -454,4 +462,4 @@ subroutine linear_init_pert( mesh, twod_mesh, modeldb ) end subroutine linear_init_pert -end module linear_model_data_mod \ No newline at end of file +end module linear_model_data_mod diff --git a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 new file mode 100644 index 00000000..5549b030 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 @@ -0,0 +1,164 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +module tl_bl_inc_kernel_mod + + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only: N + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: tl_bl_inc_kernel_type + private + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ns + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_bl_inc_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_bl_inc_code + +contains + +!> @brief Computes boundary layer u inc +!! @param[in] nlayers Number of layers +!! @param[in,out] u_inc Output +!! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field +!! @param[in] undf_w2 Unique number of degrees of freedom for the output field +!! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field +subroutine tl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) + + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + + real(kind=r_def), dimension(undf_w2), intent(in) :: u + REAL(kind=r_def), dimension(undf_w2), intent(in) :: Auv + REAL(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv + + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + + integer(kind=i_def), intent(in) :: ndf_w3_2d, undf_w3_2d + integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d + + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns + + integer(kind=i_def), intent(in) :: Blevs_m + + ! Internal variables + integer(kind=i_def) :: df, k, j + + real(kind=r_def) :: a0(1:BLevs_m) + real(kind=r_def) :: a1(1:BLevs_m) + real(kind=r_def) :: a2(1:BLevs_m) + real(kind=r_def) :: u_rhs(1:BLevs_m) + real(kind=r_def) :: u_out(1:BLevs_m) + real(kind=r_def) :: factor_u(1:BLevs_m) + + ! Loop over horizontal W2 DoFs + do j = 1, face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)) + + df = j + if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 & + .and. face_selector_ew(map_w3_2d(1)) == 1) df = N + + a0=0.0_r_def + a1=0.0_r_def + a2=0.0_r_def + u_rhs=0.0_r_def + u_out=0.0_r_def + factor_u=0.0_r_def + +! ===================== set up coeffs a0,a1,a2,u_rhs ===================== + + DO k=1,BLevs_m + IF (k == 1) THEN + a0(1) = 1.0_r_def+(Auv(map_w2(df)+1)+Auv(map_w2(df)+0))/Buv_inv(map_w2(df)+1) + a1(k) = -Auv(map_w2(df)+1)/Buv_inv(map_w2(df)+1) + u_rhs(1) = (Auv(map_w2(df)+1) & + * (u(map_w2(df)+1)-u(map_w2(df)+0))-Auv(map_w2(df)+0)*u(map_w2(df)+0))/Buv_inv(map_w2(df)+1) + ELSE IF (k > 1 .AND. k < BLevs_m) THEN + a0(k) = 1.0_r_def+(Auv(map_w2(df)+k)+Auv(map_w2(df)+k-1))/Buv_inv(map_w2(df)+k) + a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) + a1(k) = -Auv(map_w2(df)+k)/Buv_inv(map_w2(df)+k) + u_rhs(k) = (Auv(map_w2(df)+k) & + * (u(map_w2(df)+k)-u(map_w2(df)+k-1)) & + - Auv(map_w2(df)+k-1)*(u(map_w2(df)+k-1)-u(map_w2(df)+k-2)))/Buv_inv(map_w2(df)+k) + ELSE + a0(k) = 1.0_r_def+Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) + a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) + u_rhs(k) = & + -(Auv(map_w2(df)+k-1)*(u(map_w2(df)+k-1)-u(map_w2(df)+k-2)))/Buv_inv(map_w2(df)+k) + END IF + END DO + +! ====================== transform to upper triangular form ====================== + + DO k=1,BLevs_m + IF (k == 1) THEN + a0(1) = 1.0_r_def/a0(1) + ELSE + factor_u(k) = a2(k)*a0(k-1) + a0(k) = 1.0_r_def/(a0(k)-factor_u(k)*a1(k-1)) + u_rhs(k) = u_rhs(k)-factor_u(k)*u_rhs(k-1) + END IF + END DO + +! ============================== Solve for u_inc ============================== + + u_out(BLevs_m) = a0(BLevs_m)*u_rhs(BLevs_m) + u_inc(map_w2(df)+BLevs_m-1) = u_out(BLevs_m) + + DO k=BLevs_m-1,1,-1 + u_out(k) = a0(k)*(u_rhs(k)-a1(k)*u_out(k+1)) + u_inc(map_w2(df)+k-1) = u_out(k) + END DO + + end do ! Loop over horizontal W2 DoFs + +end subroutine tl_bl_inc_code + +end module tl_bl_inc_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 new file mode 100644 index 00000000..fad73df9 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 @@ -0,0 +1,123 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +module tl_compute_aubu_kernel_mod + + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & + GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: tl_compute_aubu_kernel_type + private + type(arg_type) :: meta_args(8) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! Q + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! E + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! height_w2 + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! w2_rmultiplicity + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! dt + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m + /) + + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_compute_aubu_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_compute_aubu_code + +contains + +!> @brief Computes coefficients Auv and Buv_inv +!! @param[in] nlayers Number of layers +!! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field +!! @param[in] undf_w2 Unique number of degrees of freedom for the output field +!! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field +subroutine tl_compute_aubu_code(nlayers, & + Auv, & + Buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3, undf_w3, map_w3) + + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + + real(kind=r_def), dimension(undf_w2), intent(in) :: w2_rmultiplicity + + REAL(kind=r_def), dimension(undf_w2), intent(inout) :: Auv !! (0:BLevs_m) + REAL(kind=r_def), dimension(undf_w2), intent(inout) :: Buv_inv !! Use inverse of Buv as this is what is averaged + + REAL(kind=r_def), dimension(undf_w3), intent(in) :: Q !! (0:BLevs_m) + REAL(kind=r_def), dimension(undf_w3), intent(in) :: E !! (BLevs_m) + + real(kind=r_def), dimension(undf_w2), intent(in) :: height_w2 + + real(kind=r_def), intent(in) :: dt + integer(kind=i_def), intent(in) :: Blevs_m + + ! Internal variables + integer(kind=i_def) :: df, df3, k + +df3=1 + + do df = 1,4 + do k = 0, BLevs_m + + IF (k == 0) THEN + Auv(map_w2(df)+k) = Auv(map_w2(df)+k)+ & + w2_rmultiplicity(map_w2(df) ) * & + Q(map_w3(df3) ) + + ELSE ! 1 <= k <= BLevs_m + + Auv(map_w2(df)+k) = Auv(map_w2(df)+k)+ & + w2_rmultiplicity(map_w2(df)+k ) * & + Q(map_w3(df3) + k ) / ( height_w2(map_w2(df)+k) - height_w2(map_w2(df)+k-1) ) + + Buv_inv(map_w2(df)+k) = Buv_inv(map_w2(df)+k)+ & + ( w2_rmultiplicity(map_w2(df)+k ) * E( map_w3(df3) + k) ) / dt + + END IF + + end do ! k = 0, BLevs_m + end do ! df = 1,4 + +end subroutine tl_compute_aubu_code + +end module tl_compute_aubu_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 new file mode 100644 index 00000000..7cace4a0 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -0,0 +1,176 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +module tl_compute_qe_kernel_mod + + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & + GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3, Wtheta + use kernel_mod, only : kernel_type + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: tl_compute_qe_kernel_type + private + type(arg_type) :: meta_args(14) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! Q + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! E + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! ls_rho + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! height_w3 + arg_type(GH_FIELD, GH_REAL, GH_READ, Wtheta), & ! height_wth + arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1 ), & ! ls_land_fraction + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! log_layer + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! Blevs_m + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! e_folding_levs_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ) & ! L_0_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_compute_qe_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_compute_qe_code + +contains + +!> @brief Computes coefficients Q and E +!! @param[in] nlayers Number of layers +!! @param[in] ndf_w3 Number of degrees of freedom per cell for the output field +!! @param[in] undf_w3 Unique number of degrees of freedom for the output field +!! @param[in] map_w3 Dofmap for the cell at the base of the column for the output field +subroutine tl_compute_qe_code( nlayers, & + Q, & + E, & + ls_rho, & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m, & + ndf_w3, undf_w3, map_w3, & + ndf_wtheta, undf_wtheta, map_wtheta, & + ndf_2d, undf_2d, map_2d ) + + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + + integer(kind=i_def), intent(in) :: undf_wtheta, ndf_wtheta + integer(kind=i_def), dimension(ndf_wtheta),intent(in) :: map_wtheta + + integer(kind=i_def), intent(in) :: undf_2d, ndf_2d + integer(kind=i_def), dimension(ndf_2d), intent(in) :: map_2d + + REAL(kind=r_def), dimension(undf_w3), intent(inout) :: Q !! (0:BLevs_m) + REAL(kind=r_def), dimension(undf_w3), intent(inout) :: E !! (BLevs_m) + + real(kind=r_def), dimension(undf_w3), intent(in) :: ls_rho + + real(kind=r_def), dimension(undf_w3), intent(in) :: height_w3 + real(kind=r_def), dimension(undf_wtheta), intent(in) :: height_wth + real(kind=r_def), dimension(undf_2d), intent(in) :: ls_land_fraction + + integer(kind=i_def), intent(in) :: log_layer,Blevs_m,e_folding_levs_m + real(kind=r_def), intent(in) :: u_land_m, u_sea_m, z_land_m, & + z_sea_m, L_0_m + + ! Internal variables + integer(kind=i_def) :: df, k + real(kind=r_def) :: roughness_length_m + + REAL(kind=r_def), PARAMETER :: Von_Karman=0.4_r_def + REAL(kind=r_def) :: L_diff_m(1:BLevs_m) + + real(kind=r_def) :: u1 + +! ============================== setup roughness_length_m ============================== + + df = 1 + roughness_length_m = z_land_m*ls_land_fraction(map_2d(df)) + & + z_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) + +! ============================== setup L_diff ============================== +! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above + +! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 +! L_diff_m(k) defined for 1 <= k <= BLevs_m + +df=1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell + +DO k = 1, BLevs_m + IF (k <= Log_layer) THEN + L_diff_m(k)=Von_Karman * ( height_w3(map_w3(df)+k) - height_w3(map_w3(df)+k-1)) & + / (LOG((height_w3(map_w3(df)+k)- height_wth(map_wtheta(df)) & + + roughness_length_m)/(height_w3(map_w3(df)+k-1) & + - height_wth(map_wtheta(df)) + roughness_length_m) )+Von_Karman & + * (height_w3(map_w3(df)+k)-height_w3(map_w3(df)+k-1))/L_0_m) + ELSE + L_diff_m(k)=Von_Karman * (( height_wth(map_wtheta(df)+k)- height_wth(map_wtheta(df)) & + + roughness_length_m)/(1.0_r_def +( height_wth(map_wtheta(df)+k) & + - height_wth(map_wtheta(df))+roughness_length_m)/L_0_m)) + END IF +END DO + +! ============================== Define Q and E ============================== +! E is on cell centres +! Q is on centre of horizontal faces - for convenience indexed by centre of cell above + +! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 +! Q(k) defined for 0 <= k <= BLevs_m +! E(k) defined for 1 <= k <= BLevs_m + +df=1 +u1=u_land_m*ls_land_fraction(map_2d(df)) + & + u_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) + +DO k=0,BLevs_m + IF (k == 0) THEN + Q( map_w3(df) + k)=Von_Karman * u1 & + / LOG(((height_w3(map_w3(df)+0) - height_wth(map_wtheta(df)+0) & ! + + roughness_length_m)/(roughness_length_m))) + ELSE ! ie k >= 1 + Q( map_w3(df) + k)=L_diff_m(k) * u1 & + * EXP( (height_wth(map_wtheta(df))-height_wth(map_wtheta(df)+k)) & + / (height_wth(map_wtheta(df)+e_folding_levs_m)-height_wth(map_wtheta(df)))) + + + E(map_w3(df) + k) = ls_rho( map_w3(df) + k-1 )*(height_wth(map_wtheta(df)+k)-height_wth(map_wtheta(df)+k-1)) + + END IF +END DO + +end subroutine tl_compute_qe_code + +end module tl_compute_qe_kernel_mod From d5248c222dd0ddb1c548aa293c3d160c2e58a9bf Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 12:02:35 +0000 Subject: [PATCH 25/68] config_dump_checker and style_checker --- .../linear_physics/atlt_bdy_lyr_alg_mod.x90 | 4 +- .../linear_physics/atlt_bl_inc_alg_mod.x90 | 6 +- .../atlt_bl_inc_alg_mod.x90.bak | 189 +++ .../source/driver/adjoint_test_driver_mod.f90 | 2 +- rose-stem/app/linear_model/rose-app.conf | 10 +- .../linear_physics/atl_bdy_lyr_alg.x90 | 20 +- .../timestepping/atl_si_timestep_alg_mod.x90 | 34 +- .../atl_si_timestep_alg_mod.x90.bak | 902 +++++++++++++++ .../linear_physics/atl_bl_inc_kernel_mod.F90 | 4 +- .../lfric-linear/HEAD/rose-meta.conf | 116 +- .../linear_physics/tl_bdy_lyr_alg.x90 | 20 +- .../timestepping/tl_si_timestep_alg_mod.x90 | 8 +- .../tl_si_timestep_alg_mod.x90.bak | 1030 +++++++++++++++++ .../linear_physics/tl_bl_inc_kernel_mod.F90 | 12 +- .../tl_compute_aubu_kernel_mod.F90 | 12 +- .../tl_compute_qe_kernel_mod.F90 | 18 +- 16 files changed, 2254 insertions(+), 133 deletions(-) create mode 100644 applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak create mode 100644 science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak create mode 100644 science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90.bak diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 index 09b8944c..28e0d3be 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 @@ -135,7 +135,7 @@ module atlt_bdy_lyr_alg_mod ! Tangent linear - call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) ! < Mx, Mx > call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & @@ -156,7 +156,7 @@ module atlt_bdy_lyr_alg_mod ! Adjoint alg call and inner products ! Adjoint - call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) ! < AMx, x > call invoke( x_innerproduct_y( ip2(1), & diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 index b4de5d92..043485b6 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 @@ -67,7 +67,7 @@ module atlt_bl_inc_alg_mod ! Arguments for tl and adj calls type( field_type) :: u_inc type( field_type) :: u - type( field_type) :: auv + type( field_type) :: auv type( field_type) :: buv_inv type(integer_field_type), pointer :: face_selector_ew => null() type(integer_field_type), pointer :: face_selector_ns => null() @@ -131,7 +131,7 @@ module atlt_bl_inc_alg_mod face_selector_ew, & face_selector_ns, & Blevs_m ) ) - call invoke ( & + call invoke ( & x_innerproduct_x( ip1(1), u_inc ), & x_innerproduct_x( ip1(2), u ) ) @@ -156,7 +156,7 @@ module atlt_bl_inc_alg_mod face_selector_ns, & Blevs_m ) ) - call invoke ( & + call invoke ( & x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & x_innerproduct_y( ip2(2), u, u_input ) ) diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak new file mode 100644 index 00000000..b23dfcbe --- /dev/null +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak @@ -0,0 +1,189 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Module containing adjoint test for atl_bl_inc_kernel +module atlt_bl_inc_alg_mod + + use sci_assign_field_random_range_alg_mod, & + only : assign_field_random_range + use sci_geometric_constants_mod, only: get_face_selector_ew, & + get_face_selector_ns + use integer_field_mod, only: integer_field_type + use field_mod, only : field_type + use function_space_mod, only : function_space_type + use log_mod, only : log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_INFO + use mesh_mod, only : mesh_type + use function_space_collection_mod, only : function_space_collection + use finite_element_config_mod, only : element_order_h, element_order_v + use fs_continuity_mod, only : W2, W3, Wtheta + use constants_mod, only : i_def, r_def + use quadrature_face_mod, only : quadrature_face_type + use quadrature_rule_gaussian_mod, only : quadrature_rule_gaussian_type + use reference_element_mod, only : reference_element_type + use planet_config_mod, only : cp + use adjoint_test_parameters_mod, only : ls_theta_range, & + ls_exner_range, & + ls_md1_range, & + ls_md2_range, & + ls_md3_range + + implicit none + + public + + contains + + !============================================================================= + !> @brief Adjoint test for atl_bl_inc. + !> @details Passes if adjoint is transpose of tangent linear. + !> Determined by testing the equality of inner products and , + !> where M is the tangent linear and A is the adjoint. + !> @param[in] mesh Mesh object + subroutine atlt_bl_inc_alg( mesh ) + + use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type + use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type + + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + + implicit none + + ! Arguments + type(mesh_type), pointer, intent(in) :: mesh + + ! Arguments for tl and adj calls + type( field_type) :: u_inc + type( field_type) :: u + type( field_type) :: auv + type( field_type) :: buv_inv + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + ! Copies of input fields used in inner products + type( field_type) :: u_inc_input + type( field_type) :: u_input + + ! Pointers for initialising fields + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! Inner products + real(kind=r_def) :: ip1(2) + real(kind=r_def) :: ip2(2) + real(kind=r_def) :: sf(2) + real(kind=r_def) :: inner1 + real(kind=r_def) :: inner2 + + ! Test parameters and variables + real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def) :: machine_tol + real(kind=r_def) :: relative_diff + real(kind=r_def), parameter :: eps = 1e-30_r_def + + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) + vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) + vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) + + call auv % initialise( vector_space = vector_space_w2_ptr, name = 'auv' ) + call buv_inv % initialise( vector_space = vector_space_w2_ptr, name = 'buv_inv' ) + + call u_inc % initialise( vector_space = vector_space_w2_ptr, name = 'u_inc' ) + call u % initialise( vector_space = vector_space_w2_ptr, name = 'u' ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + + call u_inc % copy_field_properties( u_inc_input ) + call u % copy_field_properties( u_input ) + + + ! Initialise arguments and call the tangent-linear kernel. + call invoke( setval_random( u ), & + setval_x( u_input, u ), & + setval_random( u_inc ), & + setval_x( u_inc_input, u_inc ) ) + + + ! LS init + call assign_field_random_range( auv, -1.0_r_def, 1.0_r_def ) + call assign_field_random_range( buv_inv, 1.0_r_def, 2.0_r_def ) ! must avoid 0 + + + ! < Mx, Mx > + call invoke ( tl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + call invoke ( & + x_innerproduct_x( ip1(1), u_inc ), & + x_innerproduct_x( ip1(2), u ) ) + + + sf(1) = 1.0_r_def / (ip1(1) + eps) + sf(2) = 1.0_r_def / (ip1(2) + eps) + + inner1 = 0.0_r_def + inner1 = inner1 + ip1(1) * sf(1) + inner1 = inner1 + ip1(2) * sf(2) + + + ! Scaling fields + call invoke( inc_a_times_X( sf(1),u_inc ), & + inc_a_times_X( sf(2),u ) ) + + ! < AMx, x > + call invoke ( atl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + + call invoke ( & + x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & + x_innerproduct_y( ip2(2), u, u_input ) ) + + inner2 = 0.0_r_def + inner2 = inner2 + ip2(1) + inner2 = inner2 + ip2(2) + + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & + ip1(1)*sf(1),ip1(2)*sf(2) + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=',ip2 + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & + inner1,inner2 + call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + + ! Test the inner-product values for equality, allowing for the precision of the active variables + machine_tol = spacing( max( abs(inner1), abs(inner2) ) ) + relative_diff = abs(inner1 - inner2) / machine_tol + if (relative_diff < overall_tolerance) then + write(log_scratch_space, *) "PASSED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_INFO) + else + write(log_scratch_space, *) "FAILED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end if + + end subroutine atlt_bl_inc_alg + +end module atlt_bl_inc_alg_mod diff --git a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 index 8db25218..e32cb183 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 @@ -197,7 +197,7 @@ subroutine run( modeldb ) call adjt_compute_vorticity_alg( mesh ) call atlt_derive_exner_from_eos_alg( mesh ) call atlt_moist_dyn_factors_alg( mesh ) - + ! ./linear_physics call atlt_bdy_lyr_alg( modeldb, mesh ) diff --git a/rose-stem/app/linear_model/rose-app.conf b/rose-stem/app/linear_model/rose-app.conf index e46d9877..deda3fd2 100644 --- a/rose-stem/app/linear_model/rose-app.conf +++ b/rose-stem/app/linear_model/rose-app.conf @@ -719,21 +719,21 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] +blevs_m=15 +e_folding_levs_m=10 fixed_ls=.true. +l_0_m=80.0 +l_boundary_layer=.true. l_stabilise_bl=.false. +log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' -l_boundary_layer=.true. -Log_layer=2 -Blevs_m=15 -e_folding_levs_m=10 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 z_sea_m=0.0005 -L_0_m=80.0 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index b60f408c..ba98a76c 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -47,7 +47,7 @@ module atl_bdy_lyr_alg_mod z_land_m, & z_sea_m, & L_0_m - + use planet_config_mod, only: cp, kappa, rd, p_zero use tl_kinetic_energy_gradient_kernel_mod, & only: tl_kinetic_energy_gradient_kernel_type @@ -144,9 +144,9 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) type( field_collection_type ), pointer :: ls_fields type( field_type), pointer :: ls_land_fraction => null() - type( field_type) :: Q + type( field_type) :: Q type( field_type) :: E - type( field_type) :: auv + type( field_type) :: auv type( field_type) :: buv_inv type(integer_field_type), pointer :: face_selector_ew => null() @@ -156,9 +156,9 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) real(kind=r_def) :: fmin real(kind=r_def) :: fmax real(kind=r_def) :: ip - + if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') - + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field('ls_land_fraction', ls_land_fraction) @@ -209,7 +209,7 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) call u%copy_field_properties( auv ) call u%copy_field_properties( buv_inv ) - + call invoke(setval_c(auv,0.0_r_def),& setval_c(buv_inv,0.0_r_def) ) @@ -229,8 +229,8 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) u_sea_m, & z_land_m, & z_sea_m, & - L_0_m ) ) - + L_0_m ) ) + call get_field_minmax( Q, fmin, fmax ) write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Q=',fmin, fmax call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) @@ -246,8 +246,8 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) height_w2, & w2_rmultiplicity, & dt, & - Blevs_m ) ) - + Blevs_m ) ) + call get_field_minmax( Auv, fmin, fmax ) write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Auv=',fmin, fmax call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index 94024961..0d4aab4c 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -662,13 +662,13 @@ contains setval_c( self%rhs_np1(igh_t), 0.0_r_def ) ) end if - if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) + if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) call add_bundle( self%rhs_adv, self%rhs_np1, self%rhs_adv, bundle_size ) call add_bundle( self%rhs_n, self%rhs_np1, self%rhs_n, bundle_size ) call bundle_ax( -1.0_r_def, self%rhs_np1, self%rhs_np1, bundle_size ) if (inner > 1) then - + call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) @@ -685,14 +685,14 @@ contains call add_bundle( self%state,self%state2 ,self%state, bundle_size ) call add_bundle( self%state,self%state1 ,self%state, bundle_size ) - - end if + + end if end do inner_dynamics_loop !------------------------------------------------------------------------- ! End of inner (nonlinear, Coriolis) loop !------------------------------------------------------------------------- - + if (l_boundary_layer) then call u%copy_field_properties( u_bl_inc ) @@ -725,45 +725,45 @@ contains ! Adj of u_bl_inc_flux = u_bl_inc * dA call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & - inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & + inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & setval_c(u_bl_inc_flux, 0.0_r_def) ) call atl_bdy_lyr_alg(modeldb, u_bl_inc, self%state_star, & self%ls_state_itns(:,ls_outer,1), cast_dt ) - + ! Adj of state_star(igh_u) <- u_star_physical call invoke( inc_x_plus_y(u_star_physical , self%state_star(igh_u) ), & setval_c( self%state_star(igh_u), 0.0_r_def) ) ! Adj of u_star_physical = u_star / dA call invoke( inc_x_divideby_y( u_star_physical, dA ), & - inc_x_plus_y( u_star, u_star_physical ), & - setval_c(u_star_physical, 0.0_r_def) ) + inc_x_plus_y( u_star, u_star_physical ), & + setval_c(u_star_physical, 0.0_r_def) ) ! Adj of u_star = du + state(igh_u) call invoke( inc_X_plus_Y( du, u_star ), & inc_X_plus_Y( self%state(igh_u), u_star ), & - setval_c(u_star, 0.0_r_def) ) + setval_c(u_star, 0.0_r_def) ) - ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) + ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) call mass_matrix_solver_alg( rhsu_np1, du) ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) call invoke( inc_X_plus_Y( self%rhs_adv(igh_u),rhsu_np1) ) - + ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) call invoke( inc_X_plus_bY(self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1), & - inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & - setval_c( rhsu_np1, 0.0_r_def) ) + inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & + setval_c( rhsu_np1, 0.0_r_def) ) - ! Adj of du <- 0 + ! Adj of du <- 0 call invoke( setval_c(du, 0.0_r_def)) - + end if ! l_boundary_layer call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) - + call atl_rhs_alg( self%rhs_np1, & -varalpha*cast_dt, & self%state1, & diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak new file mode 100644 index 00000000..94024961 --- /dev/null +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak @@ -0,0 +1,902 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2025 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 Adjoint of tl_si_timestep_alg_mod + +module atl_si_timestep_alg_mod + + use atl_moist_dyn_factors_alg_mod, only: atl_moist_dyn_factors_alg + use constants_mod, only: i_def, r_def, l_def, str_def + use log_mod, only: log_event, log_scratch_space, & + LOG_LEVEL_INFO, LOG_LEVEL_ERROR + use driver_modeldb_mod, only: modeldb_type + use namelist_mod, only: namelist_type + use reference_element_mod, only: T + use formulation_config_mod, only: dlayer_on, exner_from_eos, si_momentum_equation, & + moisture_formulation, moisture_formulation_dry, & + use_physics, use_wavedynamics + use io_config_mod, only: subroutine_timers + use mixed_solver_config_mod, only: guess_np1, reference_reset_time + use timestepping_config_mod, only: alpha, spinup_alpha, & + outer_iterations, inner_iterations + use linear_config_mod, only: fixed_ls, & + l_stabilise_bl, & + n_bl_levels_to_stabilise, & + max_bl_stabilisation, & + l_boundary_layer + use derived_config_mod, only: bundle_size + use boundaries_config_mod, only: limited_area + use sci_fem_constants_mod, only: get_mass_matrix_fe, get_qr_fe + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, & + set_bundle_scalar, add_bundle, & + bundle_axpy, bundle_ax, bundle_is_zero + use fs_continuity_mod, only: Wtheta, W2 + use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg + use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use adj_dg_inc_matrix_vector_kernel_mod, only: adj_dg_inc_matrix_vector_kernel_type + use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type + use adj_stabilise_bl_u_kernel_mod, only: adj_stabilise_bl_u_kernel_type + use field_mod, only: field_type + use mesh_collection_mod, only: mesh_collection + use mesh_mod, only: mesh_type + use quadrature_xyoz_mod, only: quadrature_xyoz_type + use operator_mod, only: operator_type + use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg + use rhs_alg_mod, only: rhs_alg + use atl_rhs_alg_mod, only: atl_rhs_alg + use gungho_transport_control_alg_mod, only: gungho_transport_control_alg + use atl_transport_control_alg_mod, only: atl_transport_control_alg + use si_operators_alg_mod, only: compute_si_operators + use semi_implicit_solver_alg_mod, only: semi_implicit_solver_alg_step + use adj_semi_implicit_solver_alg_mod, only: adj_semi_implicit_solver_type + use derive_exner_from_eos_alg_mod, only: derive_exner_from_eos + use atl_derive_exner_from_eos_alg_mod, only: atl_derive_exner_from_eos + use update_prognostic_scalars_alg_mod, only: update_prognostic_scalars_alg + use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg + use mr_indices_mod, only: nummr + use moist_dyn_mod, only: num_moist_factors, gas_law + use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + use mixing_config_mod, only: smagorinsky + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use sci_geometric_constants_mod, only: get_da_at_w2 + use timer_mod, only: timer + use transport_enumerated_types_mod, only: direction_3d, direction_h, direction_v + + implicit none + + private + + type, public :: atl_si_timestep_type + + private + + ! Perturbation + type(field_type), allocatable :: state(:) + type(field_type), allocatable :: state_initial(:) + type(field_type), allocatable :: state1(:) + type(field_type), allocatable :: state2(:) + type(field_type), allocatable :: state_copy(:) + type(field_type), allocatable :: state_n(:) + type(field_type), allocatable :: state_star(:) + type(field_type), allocatable :: state_after_slow(:) + type(field_type), allocatable :: advected_state(:) + type(field_type), allocatable :: mr_n(:) + type(field_type), allocatable :: mr_inc(:) + type(field_type), allocatable :: mr_after_slow(:) + type(field_type), allocatable :: rhs_n(:) + type(field_type), allocatable :: rhs_np1(:) + type(field_type), allocatable :: rhs_adv(:) + type(field_type), allocatable :: state_test(:) + type(field_type), allocatable :: rhs_np1_test(:) + type(field_type), allocatable :: rhs_np1_in(:) + type(field_type), allocatable :: rhs_phys(:) + + ! Linearisation state + type(field_type), allocatable :: ls_state(:) + type(field_type), allocatable :: ls_state_itns(:,:,:) + type(field_type), allocatable :: ls_state_n(:) + type(field_type), allocatable :: ls_state_after_slow(:) + type(field_type), allocatable :: ls_advected_state(:) + type(field_type), allocatable :: ls_mr_n(:) + type(field_type), allocatable :: ls_mr_inc(:,:,:) + type(field_type), allocatable :: ls_mr_after_slow(:) + type(field_type), allocatable :: ls_rhs_n(:) + type(field_type), allocatable :: ls_rhs_np1(:,:,:) + type(field_type), allocatable :: ls_rhs_adv(:,:,:) + type(field_type), allocatable :: ls_rhs_phys(:,:,:) + type(field_type), allocatable :: ls_mr_itns(:,:,:) + type(field_type), allocatable :: ls_moist_dyn_itns(:,:,:) + integer( i_def ) :: ls_outer_iterations, ls_inner_iterations + + ! theta_fv transport increment to change to weak form + type(field_type) :: theta_fv_inc + + ! Solver + type(adj_semi_implicit_solver_type) :: adj_semi_implicit_solver + + ! Moisture flag + logical(l_def) :: use_moisture + + contains + + procedure, public :: initialise + procedure, public :: step + procedure, public :: finalise + + end type atl_si_timestep_type + +contains + + !> @brief Initialisation procedure for the adjoint timestepping algorithm + !> @param[in,out] u Change in 3D wind field + !> @param[in,out] rho Change in Density + !> @param[in,out] theta Change in Potential temperature + !> @param[in,out] exner Change in Exner pressure + !> @param[in,out] mr Change in Mixing ratios + !> @param[in] ls_theta Lin. state for Potential temperature + !> @param[in] ls_exner Lin. state for Exner pressure + !> @param[in] ls_mr Lin. state for Mixing ratios + !> @param[in] ls_moist_dyn Lin. state for moist dynamical factors + subroutine initialise( self, u, rho, theta, exner, mr, & + ls_theta, ls_exner, ls_mr, ls_moist_dyn ) + + implicit none + + ! Arguments + class(atl_si_timestep_type), intent(inout) :: self + type(field_type), intent(inout) :: u, rho, theta, exner + type(field_type), intent(inout) :: mr(nummr) + type(field_type), intent(inout) :: ls_theta, ls_exner + type(field_type), intent(inout) :: ls_mr(nummr) + type(field_type), intent(inout) :: ls_moist_dyn(num_moist_factors) + + ! Local variables + integer(kind=i_def) :: outer, inner + + self%use_moisture = (moisture_formulation /= moisture_formulation_dry) + + ! Allocate internal state field arrays + + if (fixed_ls) then + ! The linearisation state is not evolved (a 0x0 looping) + ! but ls_outer_iterations and ls_inner_iterations are set to + ! 1 so that the arrays are defined. + self%ls_outer_iterations = 1_i_def + self%ls_inner_iterations = 1_i_def + else + ! The linearisation state is evolved, and the intermediate iterations + ! are used to calculate the evolution of the perturbation. + self%ls_outer_iterations = outer_iterations + self%ls_inner_iterations = inner_iterations + end if + + allocate(self%state(bundle_size)) + allocate(self%state_initial(bundle_size)) + allocate(self%state1(bundle_size)) + allocate(self%state2(bundle_size)) + allocate(self%state_copy(bundle_size)) + allocate(self%state_n(bundle_size)) + allocate(self%state_after_slow(bundle_size)) + allocate(self%state_star(bundle_size)) + allocate(self%advected_state(bundle_size)) + allocate(self%rhs_n(bundle_size)) + allocate(self%rhs_np1(bundle_size)) + allocate(self%rhs_adv(bundle_size)) + allocate(self%mr_n(nummr)) + allocate(self%mr_after_slow(nummr)) + allocate(self%mr_inc(nummr)) + allocate(self%state_test(bundle_size)) + allocate(self%rhs_np1_test(bundle_size)) + allocate(self%rhs_np1_in(bundle_size)) + allocate(self%rhs_phys(bundle_size)) + + allocate(self%ls_state(bundle_size)) + allocate(self%ls_state_n(bundle_size)) + allocate(self%ls_state_after_slow(bundle_size)) + allocate(self%ls_advected_state(bundle_size)) + allocate(self%ls_rhs_n(bundle_size)) + allocate(self%ls_mr_n(nummr)) + allocate(self%ls_mr_after_slow(nummr)) + + allocate(self%ls_state_itns( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_rhs_np1( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_rhs_adv( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_rhs_phys( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_mr_inc( nummr, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_mr_itns( nummr, self%ls_outer_iterations, self%ls_inner_iterations )) + allocate(self%ls_moist_dyn_itns( num_moist_factors, self%ls_outer_iterations, self%ls_inner_iterations )) + + ! Initialise internal state field objects + + call u%copy_field_properties(self%state(igh_u)) + call theta%copy_field_properties(self%state(igh_t)) + call rho%copy_field_properties(self%state(igh_d)) + call exner%copy_field_properties(self%state(igh_p)) + + call invoke( setval_X( self%state(igh_u), u ), & + setval_X( self%state(igh_t), theta ), & + setval_X( self%state(igh_d), rho ), & + setval_X( self%state(igh_p), exner ) ) + + call clone_bundle( self%state, self%state_n, bundle_size ) + call clone_bundle( self%state, self%state_initial, bundle_size ) + call clone_bundle( self%state, self%state1, bundle_size ) + call clone_bundle( self%state, self%state2, bundle_size ) + call clone_bundle( self%state, self%state_copy, bundle_size ) + call clone_bundle( self%state, self%state_after_slow, bundle_size ) + call clone_bundle( self%state, self%advected_state, bundle_size ) + call clone_bundle( self%state, self%rhs_n, bundle_size ) + call clone_bundle( self%state, self%rhs_np1, bundle_size ) + call clone_bundle( self%state, self%rhs_adv, bundle_size ) + call clone_bundle( self%state, self%state_test, bundle_size ) + call clone_bundle( self%state, self%rhs_np1_test, bundle_size ) + call clone_bundle( self%state, self%rhs_np1_in, bundle_size ) + call clone_bundle( self%state, self%rhs_phys, bundle_size ) + + call clone_bundle( self%state, self%ls_state, bundle_size ) + call clone_bundle( self%state, self%ls_state_n, bundle_size ) + call clone_bundle( self%state, self%ls_state_after_slow, bundle_size ) + call clone_bundle( self%state, self%ls_advected_state, bundle_size ) + call clone_bundle( self%state, self%ls_rhs_n, bundle_size ) + + do outer = 1, self%ls_outer_iterations + do inner = 1, self%ls_inner_iterations + call clone_bundle( self%state, self%ls_state_itns(:,outer,inner), bundle_size ) + call clone_bundle( self%state, self%ls_rhs_np1(:,outer,inner), bundle_size ) + call clone_bundle( self%state, self%ls_rhs_adv(:,outer,inner), bundle_size ) + call clone_bundle( self%state, self%ls_rhs_phys(:,outer,inner), bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%ls_rhs_phys(:,outer,inner), bundle_size ) + end do + end do + + call ls_theta%copy_field_properties(self%theta_fv_inc) + + call clone_bundle( mr, self%mr_n, nummr ) + call clone_bundle( mr, self%mr_after_slow, nummr ) + + if (self%use_moisture) then + call clone_bundle( mr, self%mr_inc, nummr ) + else + call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) + call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) + end if + + call clone_bundle( ls_mr, self%ls_mr_n, nummr ) + call clone_bundle( ls_mr, self%ls_mr_after_slow, nummr ) + + do outer = 1, self%ls_outer_iterations + do inner = 1, self%ls_inner_iterations + call clone_bundle( ls_moist_dyn, self%ls_moist_dyn_itns(:,outer,inner), num_moist_factors ) + call clone_bundle( ls_mr, self%ls_mr_itns(:,outer,inner), nummr ) + if (self%use_moisture) call clone_bundle( ls_mr, self%ls_mr_inc(:,outer,inner), nummr ) + end do + end do + + if (.not. self%use_moisture) then + call set_bundle_scalar( 0.0_r_def, self%ls_mr_n, nummr ) + call set_bundle_scalar( 0.0_r_def, self%ls_mr_after_slow, nummr ) + end if + + call self%adj_semi_implicit_solver%initialise(self%state) + + call log_event( "atl_si_timestep_type%init: initialised timestepping algorithm", LOG_LEVEL_INFO ) + + end subroutine initialise + + !> @brief The adjoint for the timestepping of the 3D nonlinear equations + !> @param[in,out] modeldb Structure containing the model state + !> @param[in,out] u 3D wind field + !> @param[in,out] rho Density + !> @param[in,out] theta Potential temperature + !> @param[in,out] exner Exner pressure + !> @param[in,out] mr Mixing ratios + !> @param[in,out] moist_dyn Factors for moist dynamics + !> @param[in] ls_u 3D wind field + !> @param[in] ls_rho Density + !> @param[in] ls_theta Potential temperature + !> @param[in] ls_exner Exner pressure + !> @param[in] ls_mr Mixing ratios + !> @param[in] ls_moist_dyn Factors for moist dynamics + subroutine step( self, modeldb, u, rho, theta, exner, mr, moist_dyn, & + ls_u, ls_rho, ls_theta, ls_exner, ls_mr, ls_moist_dyn ) + + implicit none + + ! Arguments + class(atl_si_timestep_type), intent(inout) :: self + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u, rho, theta, exner + type(field_type), intent(inout) :: mr(nummr) + type(field_type), intent(inout) :: moist_dyn(num_moist_factors) + type(field_type), intent(in) :: ls_u, ls_rho, ls_theta, ls_exner + type(field_type), intent(in) :: ls_mr(nummr) + type(field_type), intent(in) :: ls_moist_dyn(num_moist_factors) + + ! Local variables + real(kind=r_def) :: cast_dt + type(quadrature_xyoz_type), pointer :: qr + type(operator_type), pointer :: mm_wt + type(operator_type), pointer :: mm_vel + integer(kind=i_def) :: outer, inner, reference_reset_freq + integer(kind=i_def) :: ls_outer, ls_inner + integer(kind=i_def) :: next_outer, next_inner + real(kind=r_def) :: varalpha, varbeta + type(namelist_type), pointer :: mixed_solver_nml + type(namelist_type), pointer :: base_mesh_nml + real(kind=r_def) :: mixed_solver_a_tol + type(field_type) :: rhs_n_igh_u + type(field_type) :: advected_u + type(mesh_type), pointer :: mesh + character(len=str_def) :: prime_mesh_name + + ! Local variables for boundary layer + type( field_type ) :: u_bl_inc + type( field_type ) :: u_bl_inc_flux + type( field_type ) :: du + type( field_type ) :: u_star + type( field_type ) :: u_star_physical + type( field_type ) :: rhsu_np1 + type( field_type ), pointer :: dA => null() + + if (subroutine_timers) call timer('atl_si_timestep_type::step') + + cast_dt = real( modeldb%clock%get_seconds_per_step(), r_def ) + + qr => get_qr_fe() + + ! Get mesh + base_mesh_nml => modeldb%configuration%get_namelist('base_mesh') + call base_mesh_nml%get_value( 'prime_mesh_name', prime_mesh_name ) + mesh => mesh_collection%get_mesh(prime_mesh_name) + + mm_wt => get_mass_matrix_fe( Wtheta, mesh%get_id() ) + mm_vel => get_mass_matrix_fe( W2, mesh%get_id() ) + + ! If off-centring is being spun up then modify the alpha value + if (spinup_alpha .and. modeldb%clock%is_spinning_up()) then + varalpha = 1.0_r_def + else + varalpha = alpha + end if + varbeta = 1.0_r_def - varalpha + + ! Copy prognostic field data to state arrays + call invoke( name="copy_init_fields_to_state", & + setval_X( self%state(igh_u), u ), & + setval_X( self%state(igh_t), theta ), & + setval_X( self%state(igh_d), rho ), & + setval_X( self%state(igh_p), exner ) ) + + !--------------------------------------------------------------------------- + ! Linearisation state + !--------------------------------------------------------------------------- + + ! Copy ls data to self%ls_state arrays + call invoke( name="copy_lin_fields_to_ls_state", & + setval_X( self%ls_state(igh_u), ls_u ), & + setval_X( self%ls_state(igh_t), ls_theta ), & + setval_X( self%ls_state(igh_d), ls_rho ), & + setval_X( self%ls_state(igh_p), ls_exner ) ) + + ! Update state_n and mr_n with start of timestep values + call copy_bundle( ls_mr, self%ls_mr_itns(:,1,1), nummr ) + call copy_bundle( ls_moist_dyn, self%ls_moist_dyn_itns(:,1,1), num_moist_factors ) + if (self%use_moisture) then + call copy_bundle( ls_mr, self%ls_mr_n(:), nummr ) + call copy_bundle( ls_mr, self%ls_mr_after_slow(:), nummr ) + call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,1,1), self%ls_mr_n(:) ) + end if + call copy_bundle( self%ls_state, self%ls_state_itns(:,1,1), bundle_size ) + call copy_bundle( self%ls_state, self%ls_state_n(:), bundle_size ) + call copy_bundle( self%ls_state, self%ls_state_after_slow(:), bundle_size ) + + ! Compute the semi-implicit operators + + ! Reset the reference state in the semi-implicit operators using the latest state guess. + ! This occurs every n timesteps, where n is calculated as reference_reset_time divided by dt. + ! The reference_reset_time is specified in the configuration namelist. + ! Note that this reset can only occur at most once per timestep. + reference_reset_freq = nint( reference_reset_time / cast_dt, i_def ) + if (mod( modeldb%clock%get_step() - 1_i_def, reference_reset_freq ) == 0_i_def) & + call compute_si_operators( self%ls_state(igh_t), self%ls_state(igh_d), self%ls_state(igh_p), & + modeldb%clock, self%ls_moist_dyn_itns(:,1,1) ) + + ! Compute the time-level n dynamics terms + + call copy_bundle( self%ls_state_after_slow, self%ls_advected_state, bundle_size ) + + if ( .not. fixed_ls ) then + call rhs_alg( self%ls_rhs_n, varbeta*cast_dt, & + self%ls_state_after_slow, self%ls_state_n, self%ls_moist_dyn_itns(:,1,1), & + compute_eos=.false., compute_rhs_t_d=.true., dlayer_rhs=.false., model_clock=modeldb%clock ) + + + if (.not. si_momentum_equation) call mass_matrix_solver_alg( self%ls_advected_state(igh_u), self%ls_rhs_n(igh_u) ) + ! Predictor of the wind field (u - beta * dt * rhs) to be advected if using explicit advection + + !--------------------------------------------------------------------------- + ! Start the outer (advection) loop + !--------------------------------------------------------------------------- + ls_outer_dynamics_loop: do outer = 1, self%ls_outer_iterations + + call gungho_transport_control_alg( self%ls_rhs_adv(:,outer,1), & + self%ls_advected_state, & + self%ls_state_itns(igh_u,outer,1), & + self%ls_state_n(igh_u), & + self%ls_mr_itns(:,outer,1), & + self%ls_mr_after_slow(:), & + modeldb%clock, outer, & + cheap_update=.false. ) + + ! Convert theta increment to weak form + call invoke( setval_X( self%theta_fv_inc, self%ls_rhs_adv(igh_t,outer,1) ), & + setval_c( self%ls_rhs_adv(igh_t,outer,1), 0.0_r_def ), & + dg_inc_matrix_vector_kernel_type( self%ls_rhs_adv(igh_t,outer,1), self%theta_fv_inc, mm_wt ) ) + + if (use_wavedynamics) then + ! Use advective update to guess n + 1 level scalar fields. + if (guess_np1) then + ! Update factors for moist dynamics + if (self%use_moisture) call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,outer,1), self%ls_mr_itns(:,outer,1) ) + call update_prognostic_scalars_alg( self%ls_state_itns(:,outer,1), & + self%ls_rhs_n, & + self%ls_rhs_adv(:,outer,1), & + self%ls_rhs_phys(:,outer,1), & + self%ls_moist_dyn_itns(gas_law,outer,1) ) + end if + + !----------------------------------------------------------------------- + ! Start the inner (nonlinear, Coriolis) loop + !----------------------------------------------------------------------- + ls_inner_dynamics_loop: do inner = 1,self%ls_inner_iterations + + ! Calculate the counters for the next iteration + if (inner == inner_iterations) then + next_inner = 1 + next_outer = outer + 1 + else + next_inner = inner + 1 + next_outer = outer + end if + + ! Only intermediate iterations are required for the adjoint and not + ! the final iteration so the final loop of the nonlinear isn't required + if (next_outer <= outer_iterations .and. next_inner <= inner_iterations) then + + ! Compute the time-level n + 1 dynamics terms + call rhs_alg( self%ls_rhs_np1(:,outer,inner), & + -varalpha*cast_dt, & + self%ls_state_itns(:,outer,inner), & + self%ls_state_itns(:,outer,inner), & + self%ls_moist_dyn_itns(:,outer,inner), & + compute_eos=.true., & + compute_rhs_t_d=.true., & + dlayer_rhs=dlayer_on, & + model_clock=modeldb%clock ) + + ! Compute the LAM LBCs and RHS + if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) + + ! Compute the residuals + + ! Add on advective terms: rhs = rhs_n - rhs_np1 + rhs_adv + ! (reuse rhs_np1 for rhs) + call bundle_axpy( -1.0_r_def, & + self%ls_rhs_np1(:,outer,inner), & + self%ls_rhs_n, & + self%ls_rhs_np1(:,outer,inner), & + bundle_size ) + call add_bundle( self%ls_rhs_np1(:,outer,inner), & + self%ls_rhs_adv(:,outer,inner), & + self%ls_rhs_np1(:,outer,inner), & + bundle_size ) + + if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) + + ! Accelerators for inner loop convergence + if (inner > 1) then + call invoke( setval_c(self%ls_rhs_np1(igh_d,outer,inner), 0.0_r_def ), & + setval_c(self%ls_rhs_np1(igh_t,outer,inner), 0.0_r_def ) ) + end if + !------------------------------------------------------------------- + ! Solve semi-implicit system: A * inc = rhs, + ! and increment state by inc + !------------------------------------------------------------------- + + ! First copy the intermediate self%ls_state values to the next iteration + call copy_bundle( self%ls_state_itns(:,outer,inner), & + self%ls_state_itns(:,next_outer,next_inner), & + bundle_size ) + call copy_bundle( self%ls_rhs_np1(:,outer,inner), & + self%ls_rhs_np1(:,next_outer,next_inner), & + bundle_size ) + call copy_bundle( self%ls_rhs_adv(:,outer,inner), & + self%ls_rhs_adv(:,next_outer,next_inner), & + bundle_size ) + call copy_bundle( self%ls_moist_dyn_itns(:,outer,inner), & + self%ls_moist_dyn_itns(:,next_outer,next_inner), & + num_moist_factors ) + call copy_bundle( self%ls_mr_itns(:,outer,inner), & + self%ls_mr_itns(:,next_outer,next_inner), & + nummr ) + if (self%use_moisture) then + call copy_bundle( self%ls_mr_inc(:,outer,inner), & + self%ls_mr_inc(:,next_outer,next_inner), & + nummr ) + end if + + call semi_implicit_solver_alg_step( self%ls_state_itns(:,next_outer,next_inner), & + self%ls_rhs_np1(:,outer,inner), & + self%ls_moist_dyn_itns(gas_law, next_outer, next_inner), & + self%ls_mr_itns(:,next_outer,next_inner), & + .false., first_iteration=(inner==1) ) + ! If not already done, update factors for moist dynamics + if (.not. guess_np1 .and. self%use_moisture) then + call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,next_outer,next_inner), & + self%ls_mr_itns(:,next_outer,next_inner) ) + end if + if (exner_from_eos) then + call derive_exner_from_eos( self%ls_state_itns(:,next_outer,next_inner), & + self%ls_moist_dyn_itns(gas_law, next_outer, next_inner) ) + end if + + ! LAM overwrite and blend LBCs + if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) + + end if + + end do ls_inner_dynamics_loop + !----------------------------------------------------------------------- + ! End of inner (nonlinear, Coriolis) loop + !----------------------------------------------------------------------- + + end if ! use_wavedynamics + + end do ls_outer_dynamics_loop + !--------------------------------------------------------------------------- + ! End of outer (advection) loop + !--------------------------------------------------------------------------- + end if + + !--------------------------------------------------------------------------- + ! Perturbation + !--------------------------------------------------------------------------- + + ! All except state zeroed out (adjoint) + call set_bundle_scalar( 0.0_r_def, self%rhs_adv, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state_n, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%advected_state, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state_after_slow, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state_initial, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%rhs_n, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%rhs_np1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%rhs_phys, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) + call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) + + call self%rhs_n(igh_u)%copy_field_properties(rhs_n_igh_u) + call invoke( setval_c( rhs_n_igh_u, 0.0_r_def ), & + setval_c( self%state(igh_p), 0.0_r_def ), & + setval_c( self%state(igh_d), 0.0_r_def ), & + setval_c( self%state(igh_t), 0.0_r_def ), & + setval_c( self%state(igh_u), 0.0_r_def ), & + inc_X_plus_Y( self%state(igh_p), exner ), & + inc_X_plus_Y( self%state(igh_d), rho ), & + inc_X_plus_Y( self%state(igh_t), theta ), & + inc_X_plus_Y( self%state(igh_u), u ) ) + + if (self%use_moisture) call atl_moist_dyn_factors_alg( moist_dyn, mr ) + + if (smagorinsky) call log_event( "atl_si_timestep_type%step: smagorinsky (in call to mixing_alg) not coded", LOG_LEVEL_ERROR ) + + ! Adjoint of boundary layer stabilisation + if (l_stabilise_bl) then + call invoke( setval_c( u, 0.0_r_def ), & + inc_X_plus_Y( u, self%state(igh_u) ), & + setval_c( self%state_initial(igh_u), 0.0_r_def ), & + setval_c( self%state(igh_u), 0.0_r_def ), & + adj_stabilise_bl_u_kernel_type( u, self%state_initial(igh_u), & + self%state(igh_u), & + n_bl_levels_to_stabilise, & + max_bl_stabilisation ), & + inc_X_plus_Y( self%state(igh_u), u ), & + setval_c( u, 0.0_r_def ) ) + end if + + !--------------------------------------------------------------------------- + ! Start the outer (advection) loop + !--------------------------------------------------------------------------- + outer_dynamics_loop: do outer = outer_iterations, 1, -1 + + if (fixed_ls) then + ls_outer = 1 + else + ls_outer = outer + end if + + !------------------------------------------------------------------------- + ! Start the inner (nonlinear, Coriolis) loop + !------------------------------------------------------------------------- + inner_dynamics_loop: do inner = inner_iterations, 1, -1 + + if (fixed_ls) then + ls_inner = 1 + else + ls_inner = inner + end if + + write( log_scratch_space, '(A,2I3)' ) 'atl_si_timestep_type%step: TL loop indices (o, i): ', outer, inner + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + ! LAM overwrite and blend LBCs + if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) + + if (exner_from_eos) then + call atl_derive_exner_from_eos(self%state, & ! (p,d,t) out,in,in + moist_dyn(gas_law), & ! in + self%ls_state, & + ls_moist_dyn(gas_law)) + end if + + if (self%use_moisture) call atl_moist_dyn_factors_alg( moist_dyn, mr ) + + !----------------------------------------------------------------------- + ! Solve adjoint of semi-implicit system: A * inc = rhs + !----------------------------------------------------------------------- + + mixed_solver_nml => modeldb%configuration%get_namelist('mixed_solver') + call mixed_solver_nml%get_value( 'mixed_solver_a_tol', mixed_solver_a_tol ) + + ! If self%state is zero, there is no need to call the SI solver + if (.not. bundle_is_zero( mixed_solver_a_tol, self%state, bundle_size )) then + call self%adj_semi_implicit_solver%step( self%state, self%rhs_np1, & + moist_dyn(gas_law), mr, & + .false., first_iteration=(inner==1) ) + end if + + ! Accelerators for inner loop convergence + if (inner > 1) then + call invoke( setval_c( self%rhs_np1(igh_d), 0.0_r_def ), & + setval_c( self%rhs_np1(igh_t), 0.0_r_def ) ) + end if + + if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) + call add_bundle( self%rhs_adv, self%rhs_np1, self%rhs_adv, bundle_size ) + call add_bundle( self%rhs_n, self%rhs_np1, self%rhs_n, bundle_size ) + call bundle_ax( -1.0_r_def, self%rhs_np1, self%rhs_np1, bundle_size ) + + if (inner > 1) then + + call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) + call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,ls_inner), & + self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state,self%state2 ,self%state, bundle_size ) + call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + + end if + + end do inner_dynamics_loop + !------------------------------------------------------------------------- + ! End of inner (nonlinear, Coriolis) loop + !------------------------------------------------------------------------- + + if (l_boundary_layer) then + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call self%rhs_adv(igh_u)%copy_field_properties(rhsu_np1 ) + + call du%initialise( self%rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( self%rhs_adv(igh_u)%get_function_space() ) + + call clone_bundle(self%state,self%state_star, bundle_size) + call copy_bundle(self%state, self%state_star, bundle_size) ! Only state_star(igh_u) is used + call set_bundle_scalar(0.0_r_def,self%state_star, bundle_size) + + dA => get_da_at_w2(mesh%get_id()) + + call invoke( setval_c(u_bl_inc_flux, 0.0_r_def), & + setval_c(u_bl_inc, 0.0_r_def), & + setval_c(u_star, 0.0_r_def), & + setval_c(u_star_physical, 0.0_r_def), & + setval_c(du, 0.0_r_def), & + setval_c(rhsu_np1, 0.0_r_def) ) + + call invoke( enforce_bc_kernel_type(self%rhs_phys(igh_u)), & + adj_matrix_vector_kernel_type(self%rhs_phys(igh_u),u_bl_inc_flux, mm_vel ) ) + + call set_bundle_scalar(0.0_r_def,self%rhs_phys, bundle_size) + + ! Adj of u_bl_inc_flux = u_bl_inc * dA + call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & + inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & + setval_c(u_bl_inc_flux, 0.0_r_def) ) + + call atl_bdy_lyr_alg(modeldb, u_bl_inc, self%state_star, & + self%ls_state_itns(:,ls_outer,1), cast_dt ) + + ! Adj of state_star(igh_u) <- u_star_physical + call invoke( inc_x_plus_y(u_star_physical , self%state_star(igh_u) ), & + setval_c( self%state_star(igh_u), 0.0_r_def) ) + + ! Adj of u_star_physical = u_star / dA + call invoke( inc_x_divideby_y( u_star_physical, dA ), & + inc_x_plus_y( u_star, u_star_physical ), & + setval_c(u_star_physical, 0.0_r_def) ) + + ! Adj of u_star = du + state(igh_u) + call invoke( inc_X_plus_Y( du, u_star ), & + inc_X_plus_Y( self%state(igh_u), u_star ), & + setval_c(u_star, 0.0_r_def) ) + + ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) + call mass_matrix_solver_alg( rhsu_np1, du) + + ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) + call invoke( inc_X_plus_Y( self%rhs_adv(igh_u),rhsu_np1) ) + + ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) + call invoke( inc_X_plus_bY(self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1), & + inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & + setval_c( rhsu_np1, 0.0_r_def) ) + + ! Adj of du <- 0 + call invoke( setval_c(du, 0.0_r_def)) + + end if ! l_boundary_layer + + call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) + call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,1), & + self%ls_moist_dyn_itns(:,ls_outer,1), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state,self%state2 ,self%state, bundle_size ) + call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + + call invoke( setval_c( self%theta_fv_inc, 0.0_r_def ), & + adj_dg_inc_matrix_vector_kernel_type( self%rhs_adv(igh_t), & + self%theta_fv_inc, mm_wt ), & + setval_X( self%rhs_adv(igh_t), self%theta_fv_inc ) ) + + call atl_transport_control_alg( self%rhs_adv, & + self%advected_state, & ! rhs_adv is INOUT, + self%state(igh_u), & + self%state_n(igh_u), & ! advected_state, state(igh_u), state_n(igh_u) are OUT + mr, & + self%mr_after_slow, & + self%ls_advected_state, & + self%ls_state_itns(igh_u,ls_outer,1), & + self%ls_state_n(igh_u), & + self%ls_mr_after_slow, & + modeldb%clock, & + outer ) ! advected_state finished with + + end do outer_dynamics_loop + !--------------------------------------------------------------------------- + ! End of outer (advection) loop + !--------------------------------------------------------------------------- + + call advected_u%initialise(vector_space=self%rhs_n(igh_u)%get_function_space()) + + if (.not. si_momentum_equation) then + call invoke(enforce_bc_kernel_type(self%advected_state(igh_u))) ! bc enforcement + call mass_matrix_solver_alg( rhs_n_igh_u, self%advected_state(igh_u) ) + call invoke(inc_x_plus_y( self%rhs_n(igh_u), rhs_n_igh_u )) + call invoke(setval_c( self%advected_state(igh_u), 0.0_r_def )) + else + call log_event( "atl_si_timestep_type%step: si_momentum_equation not coded", LOG_LEVEL_ERROR ) + endif + + call add_bundle( self%state_after_slow, self%advected_state, self%state_after_slow, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%advected_state, bundle_size ) + + call atl_rhs_alg( self%rhs_n, varbeta * cast_dt, self%state_after_slow, & + self%state_n, moist_dyn, self%ls_state_n, & + self%ls_moist_dyn_itns(:, 1,1), .false., .false., modeldb%clock ) + + call copy_bundle( self%state, self%state_copy, bundle_size ) + call add_bundle( self%state_copy, self%state_after_slow, self%state, bundle_size ) + call set_bundle_scalar (0.0_r_def, self%state_after_slow, bundle_size ) + + call copy_bundle( self%state, self%state_copy, bundle_size ) + call add_bundle( self%state_copy, self%state_n, self%state, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state_n, bundle_size ) + + if (l_stabilise_bl) then + call copy_bundle( self%state, self%state_copy, bundle_size ) + call add_bundle( self%state_copy, self%state_initial, self%state, bundle_size ) + call set_bundle_scalar (0.0_r_def, self%state_initial, bundle_size ) + end if + + if (self%use_moisture) then + call atl_moist_dyn_factors_alg( moist_dyn, self%mr_n ) + call add_bundle( mr, self%mr_after_slow, mr, nummr ) + call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) + call add_bundle( mr, self%mr_n, mr, nummr ) + call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) + end if + + call invoke( setval_X( u, self%state(igh_u) ), & + setval_X( theta, self%state(igh_t) ), & + setval_X( rho, self%state(igh_d) ), & + setval_X( exner, self%state(igh_p) ) ) + + if (subroutine_timers) call timer('atl_si_timestep_type::step') + + end subroutine step + + !> @brief Release all claimed resources once completed + subroutine finalise(self) + + implicit none + + ! Arguments + class(atl_si_timestep_type), intent(inout) :: self + + call self%adj_semi_implicit_solver%finalise() + + if (allocated(self%state)) deallocate(self%state) + if (allocated(self%state1)) deallocate(self%state1) + if (allocated(self%state2)) deallocate(self%state2) + if (allocated(self%state_copy)) deallocate(self%state_copy) + if (allocated(self%state_n)) deallocate(self%state_n) + if (allocated(self%state_initial)) deallocate(self%state_initial) + if (allocated(self%state_after_slow)) deallocate(self%state_after_slow) + if (allocated(self%state_star)) deallocate(self%state_star) + if (allocated(self%advected_state)) deallocate(self%advected_state) + if (allocated(self%rhs_n)) deallocate(self%rhs_n) + if (allocated(self%rhs_np1)) deallocate(self%rhs_np1) + if (allocated(self%rhs_adv)) deallocate(self%rhs_adv) + if (allocated(self%mr_n)) deallocate(self%mr_n) + if (allocated(self%mr_after_slow)) deallocate(self%mr_after_slow) + if (allocated(self%mr_inc)) deallocate(self%mr_inc) + if (allocated(self%state_test)) deallocate(self%state_test) + if (allocated(self%rhs_np1_test)) deallocate(self%rhs_np1_test) + if (allocated(self%rhs_np1_in)) deallocate(self%rhs_np1_in) + if (allocated(self%rhs_phys)) deallocate(self%rhs_phys) + + if (allocated(self%ls_state)) deallocate(self%ls_state) + if (allocated(self%ls_state_itns)) deallocate(self%ls_state_itns) + if (allocated(self%ls_state_n)) deallocate(self%ls_state_n) + if (allocated(self%ls_state_after_slow)) deallocate(self%ls_state_after_slow) + if (allocated(self%ls_advected_state)) deallocate(self%ls_advected_state) + if (allocated(self%ls_rhs_n)) deallocate(self%ls_rhs_n) + if (allocated(self%ls_rhs_np1)) deallocate(self%ls_rhs_np1) + if (allocated(self%ls_rhs_adv)) deallocate(self%ls_rhs_adv) + if (allocated(self%ls_rhs_phys)) deallocate(self%ls_rhs_phys) + if (allocated(self%ls_mr_n)) deallocate(self%ls_mr_n) + if (allocated(self%ls_mr_after_slow)) deallocate(self%ls_mr_after_slow) + if (allocated(self%ls_mr_inc)) deallocate(self%ls_mr_inc) + if (allocated(self%ls_mr_itns)) deallocate(self%ls_mr_itns) + if (allocated(self%ls_moist_dyn_itns)) deallocate(self%ls_moist_dyn_itns) + + return + + end subroutine finalise + +end module atl_si_timestep_alg_mod diff --git a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 index c632526b..efbd602d 100644 --- a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 +++ b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 @@ -6,7 +6,7 @@ module atl_bl_inc_kernel_mod use argument_mod, only : arg_type, & - GH_FIELD, GH_OPERATOR, & + GH_FIELD, GH_OPERATOR, & GH_SCALAR, GH_INTEGER, & GH_READ, GH_INC, & GH_REAL, CELL_COLUMN, & @@ -49,7 +49,7 @@ module atl_bl_inc_kernel_mod !> @brief (Adjoint of) computes boundary layer u inc !! @param[in] nlayers Number of layers - !! @param[in,out] u_inc Output + !! @param[in,out] u_inc Output !! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field !! @param[in] undf_w2 Unique number of degrees of freedom for the output field !! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index b45a8835..770a9290 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -8,51 +8,43 @@ ns=namelist/Linear/Initial sort-key=Section-A07 title=Linear -[namelist:linear=fixed_ls] -compulsory=true -description=Do not update the linearisation state during the timestep. -help=The linearisation state is the same for every outer and inner loop. -!kind=default -type=logical - -[namelist:linear=l_stabilise_bl] -compulsory=true +[namelist:linear=Blevs_m] +compulsory=false description=?????? -help=If true then turn on boundary layer stabilisation in linear model +fail-if=this < 1 ; +help=Number of boundary layers levels in linear model !kind=default ns=namelist/Job/Timestepping/semi-implicit -type=logical - -[namelist:linear=ls_read_w2h] -compulsory=true -!default=kind -description=For the linearisation state, read winds on a W2h space - =from a file. -help=Horizontal winds are read in on a W2h space from the ls file. If - =false, then cell-centres (W3), co-located winds are assumed. -sort-key=Panel-A07a -type=logical +range=1: +type=integer -[namelist:linear=max_bl_stabilisation] +[namelist:linear=L_0_m] compulsory=false description=?????? fail-if=this < 0.0 -help=Maximum boundary layer stabilisation scalar in linear model +help=height parameter for BL in TLM !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: type=real -[namelist:linear=n_bl_levels_to_stabilise] +[namelist:linear=e_folding_levs_m] compulsory=false description=?????? fail-if=this < 1 ; -help=Number of boundary layers levels to stabilise in linear model +help=Number of e-folding boundary layers levels in linear model !kind=default ns=namelist/Job/Timestepping/semi-implicit range=1: type=integer +[namelist:linear=fixed_ls] +compulsory=true +description=Do not update the linearisation state during the timestep. +help=The linearisation state is the same for every outer and inner loop. +!kind=default +type=logical + [namelist:linear=l_boundary_layer] compulsory=false description=?????? @@ -61,6 +53,14 @@ help=If true then turn on boundary layer in linear model ns=namelist/Job/Timestepping/semi-implicit type=logical +[namelist:linear=l_stabilise_bl] +compulsory=true +description=?????? +help=If true then turn on boundary layer stabilisation in linear model +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +type=logical + [namelist:linear=log_layer] compulsory=false description=?????? @@ -71,26 +71,52 @@ ns=namelist/Job/Timestepping/semi-implicit range=1: type=integer -[namelist:linear=Blevs_m] +[namelist:linear=ls_read_w2h] +compulsory=true +!default=kind +description=For the linearisation state, read winds on a W2h space + =from a file. +help=Horizontal winds are read in on a W2h space from the ls file. If + =false, then cell-centres (W3), co-located winds are assumed. +sort-key=Panel-A07a +type=logical + +[namelist:linear=max_bl_stabilisation] compulsory=false description=?????? -fail-if=this < 1 ; -help=Number of boundary layers levels in linear model +fail-if=this < 0.0 +help=Maximum boundary layer stabilisation scalar in linear model !kind=default ns=namelist/Job/Timestepping/semi-implicit -range=1: -type=integer +range=0.0: +type=real -[namelist:linear=e_folding_levs_m] +[namelist:linear=n_bl_levels_to_stabilise] compulsory=false description=?????? fail-if=this < 1 ; -help=Number of e-folding boundary layers levels in linear model +help=Number of boundary layers levels to stabilise in linear model !kind=default ns=namelist/Job/Timestepping/semi-implicit range=1: type=integer +[namelist:linear=pert_option] +compulsory=true +description=Method to generate the perturbation. +!enumeration=true +help=This can be an analytical perturbation, random data or from a file. + =The analytical perturbation is based on the DCMIP gravity wave test. + =The random data is generated with the Fortran intrinsic function 'random_number'. + =The file contains data produced from LFRic with horizontal winds in W2. +ns=namelist/Linear/Initial +sort-key=Panel-A07a +value-titles=analytic, + =random, + =file, + =zero +values='analytic', 'random', 'file', 'zero' + [namelist:linear=u_land_m] compulsory=false description=?????? @@ -131,32 +157,6 @@ ns=namelist/Job/Timestepping/semi-implicit range=0.0: type=real -[namelist:linear=L_0_m] -compulsory=false -description=?????? -fail-if=this < 0.0 -help=height parameter for BL in TLM -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -range=0.0: -type=real - -[namelist:linear=pert_option] -compulsory=true -description=Method to generate the perturbation. -!enumeration=true -help=This can be an analytical perturbation, random data or from a file. - =The analytical perturbation is based on the DCMIP gravity wave test. - =The random data is generated with the Fortran intrinsic function 'random_number'. - =The file contains data produced from LFRic with horizontal winds in W2. -ns=namelist/Linear/Initial -sort-key=Panel-A07a -value-titles=analytic, - =random, - =file, - =zero -values='analytic', 'random', 'file', 'zero' - [namelist:validity_test] compulsory=true description=Provides settings for the tangent linear validity tests. diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index 8feb17b8..36ad759e 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -48,7 +48,7 @@ module tl_bdy_lyr_alg_mod z_land_m, & z_sea_m, & L_0_m - + use planet_config_mod, only: cp, kappa, rd, p_zero use tl_kinetic_energy_gradient_kernel_mod, & only: tl_kinetic_energy_gradient_kernel_type @@ -154,9 +154,9 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) type( field_collection_type ), pointer :: ls_fields type( field_type), pointer :: ls_land_fraction => null() - type( field_type) :: Q + type( field_type) :: Q type( field_type) :: E - type( field_type) :: auv + type( field_type) :: auv type( field_type) :: buv_inv type(integer_field_type), pointer :: face_selector_ew => null() @@ -166,9 +166,9 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) real(kind=r_def) :: fmin real(kind=r_def) :: fmax real(kind=r_def) :: ip - + if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') - + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field('ls_land_fraction', ls_land_fraction) @@ -214,13 +214,13 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) call rho%copy_field_properties( Q ) call rho%copy_field_properties( E ) - + call invoke(setval_c(Q,0.0_r_def),& setval_c(E,0.0_r_def) ) - + call u%copy_field_properties( auv ) call u%copy_field_properties( buv_inv ) - + call invoke(setval_c(auv,0.0_r_def),& setval_c(buv_inv,0.0_r_def) ) @@ -241,7 +241,7 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) u_sea_m, & z_land_m, & z_sea_m, & - L_0_m ) ) + L_0_m ) ) call invoke ( tl_compute_aubu_kernel_type(auv, & buv_inv, & @@ -250,7 +250,7 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) height_w2, & w2_rmultiplicity, & dt, & - Blevs_m ) ) + Blevs_m ) ) call get_field_minmax( state(igh_u), fmin, fmax ) write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'tl_bdy_lyr_alg, min,max state(igh_u) before tl_bl_inc=',fmin, fmax diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index bfd7bb8d..931e3b37 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -776,7 +776,7 @@ contains dlayer_on, & modeldb%clock ) - + if (l_boundary_layer) then ! Run linear boundary layer scheme to compute increment to u perturbation @@ -798,18 +798,18 @@ contains call mass_matrix_solver_alg(du, rhsu_np1 ) call invoke( X_plus_Y(u_star, du, state(igh_u)) ) - + ! u_star_physical = u_star / dA ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity dA => get_da_at_w2(mesh%get_id()) call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) - + ! For convenience place u_star_physical as igh_u component of state_star call clone_bundle(state,state_star, bundle_size) call copy_bundle(state, state_star, bundle_size) call invoke( setval_x(state_star(igh_u),u_star_physical ) ) - call tl_bdy_lyr_alg(modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) ! u_bl_inc computed from state_star(igh_u) ! NB use state_star diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90.bak b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90.bak new file mode 100644 index 00000000..931e3b37 --- /dev/null +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90.bak @@ -0,0 +1,1030 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2021 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 The tangent linear for the two time-level iterative +!! time-discretisation of the nonlinear 3D equations. +module tl_si_timestep_alg_mod + + use constants_mod, only: i_def, r_def, l_def + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_INFO, & + LOG_LEVEL_ERROR + use driver_modeldb_mod, only: modeldb_type + use namelist_mod, only: namelist_type + use reference_element_mod, only: T + + ! Configuration options + use formulation_config_mod, only: dlayer_on, & + moisture_formulation, & + moisture_formulation_dry, & + use_physics, & + use_wavedynamics, & + si_momentum_equation, & + exner_from_eos + + use io_config_mod, only: subroutine_timers, & + write_conservation_diag + use linear_config_mod, only: fixed_ls, & + l_stabilise_bl, & + n_bl_levels_to_stabilise, & + max_bl_stabilisation, & + l_boundary_layer + use mixed_solver_config_mod, only: guess_np1, & + reference_reset_time + use timestepping_config_mod, only: alpha, & + outer_iterations, inner_iterations, & + spinup_alpha + use transport_config_mod, only: use_density_predictor + use derived_config_mod, only: bundle_size + use boundaries_config_mod, only: limited_area + use sci_fem_constants_mod, only: get_mass_matrix_fe, & + get_qr_fe + + use sci_field_bundle_builtins_mod, & + only: clone_bundle, & + bundle_axpy, & + add_bundle, & + copy_bundle, & + set_bundle_scalar, & + bundle_is_zero + use sci_geometric_constants_mod, only: get_da_at_w2 + use fs_continuity_mod, only: Wtheta, W2 + + ! PsyKAl PSYClone kernels + use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg + use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg + use sci_set_any_dof_kernel_mod, only: set_any_dof_kernel_type + use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use stabilise_bl_u_kernel_mod, only: stabilise_bl_u_kernel_type + + ! Derived Types + use field_mod, only: field_type + use field_collection_mod, only: field_collection_type + use mesh_mod, only: mesh_type + use quadrature_xyoz_mod, only: quadrature_xyoz_type + use operator_mod, only: operator_type + + ! Algorithms + use sci_mass_matrix_solver_alg_mod, & + only: mass_matrix_solver_alg + use rhs_alg_mod, only: rhs_alg + use tl_rhs_alg_mod, only: tl_rhs_alg + use gungho_transport_control_alg_mod, & + only: gungho_transport_control_alg_init, & + gungho_transport_control_alg + + use tl_transport_control_alg_mod, & + only: tl_transport_control_alg + + use si_operators_alg_mod, only: create_si_operators, & + compute_si_operators, & + final_si_operators + use checks_and_balances_alg_mod, only: check_fields + + use semi_implicit_solver_alg_mod,only: semi_implicit_solver_alg_init, & + semi_implicit_solver_alg_step, & + semi_implicit_solver_alg_final + use derive_exner_from_eos_alg_mod, & + only: derive_exner_from_eos + use tl_derive_exner_from_eos_alg_mod, & + only: tl_derive_exner_from_eos + + use update_prognostic_scalars_alg_mod, & + only: update_prognostic_scalars_alg + use mixing_alg_mod, only: mixing_alg + + use map_physics_fields_alg_mod, only: map_physics_fields_alg + + use tl_bdy_lyr_alg_mod, only: tl_bdy_lyr_alg + + ! Moisture species + use mr_indices_mod, only: nummr, imr_v, imr_cl + use moist_dyn_mod, only: num_moist_factors, gas_law + + ! Field indices + use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + + ! Mixing settings + use mixing_config_mod, only: smagorinsky + + use timer_mod, only: timer + + + implicit none + + private + + logical(l_def) :: use_moisture + + ! 'State' items private to the algorithm that need to be + ! created once but used every step + + ! Perturbation + type( field_type ), allocatable :: state(:) + type( field_type ), allocatable :: state_initial(:) + type( field_type ), allocatable :: state_n(:) + type( field_type ), allocatable :: state_after_slow(:) + type( field_type ), allocatable :: state_star(:) + type( field_type ), allocatable :: advected_state(:) + type( field_type ), allocatable :: mr_n(:) + type( field_type ), allocatable :: mr_inc(:) + type( field_type ), allocatable :: mr_after_slow(:) + type( field_type ), allocatable :: rhs_n(:) + type( field_type ), allocatable :: rhs_np1(:) + type( field_type ), allocatable :: rhs_adv(:) + type( field_type ), allocatable :: rhs_phys(:) + + ! Linearisation state + type( field_type ), allocatable :: ls_state(:) + type( field_type ), allocatable :: ls_state_itns(:,:,:) + type( field_type ), allocatable :: ls_state_n(:) + type( field_type ), allocatable :: ls_state_after_slow(:) + type( field_type ), allocatable :: ls_advected_state(:) + type( field_type ), allocatable :: ls_mr_n(:) + type( field_type ), allocatable :: ls_mr_inc(:,:,:) + type( field_type ), allocatable :: ls_mr_after_slow(:) + type( field_type ), allocatable :: ls_rhs_n(:) + type( field_type ), allocatable :: ls_rhs_np1(:,:,:) + type( field_type ), allocatable :: ls_rhs_adv(:,:,:) + type( field_type ), allocatable :: ls_rhs_phys(:,:,:) + type( field_type ), allocatable :: ls_mr_itns(:,:,:) + type( field_type ), allocatable :: ls_moist_dyn_itns(:,:,:) + integer( i_def ) :: ls_outer_iterations, ls_inner_iterations + + type( field_type ) :: theta_fv_inc ! theta fv transport increment to change to weak form + + public :: tl_semi_implicit_alg_init + public :: tl_semi_implicit_alg_step + public :: tl_semi_implicit_alg_final +contains + + !> @brief Initialisation procedure for the tangent linear timestepping + !> algorithm + !> @param[in] mesh Mesh object on which the model runs + !> @param[in,out] u Change in 3D wind field + !> @param[in,out] rho Change in Density + !> @param[in,out] theta Change in Potential temperature + !> @param[in,out] exner Change in Exner pressure + !> @param[in,out] mr Change in Mixing ratios + !> @param[in] ls_u Lin. state for 3D wind field + !> @param[in] ls_rho Lin. state for Density + !> @param[in] ls_theta Lin. state for Potential temperature + !> @param[in] ls_exner Lin. state for Exner pressure + !> @param[in] ls_mr Lin. state for Mixing ratios + !> @param[in] ls_moist_dyn Lin. state for moist dynamical factors + subroutine tl_semi_implicit_alg_init( mesh, u, rho, theta, exner, mr, & + ls_u, ls_rho, ls_theta, ls_exner, & + ls_mr, ls_moist_dyn, partial_init ) + + implicit none + + ! Mesh + type(mesh_type), intent( in ), pointer :: mesh + + ! Prognostic fields + type( field_type ), intent( inout ) :: u, rho, theta, exner + type( field_type ), intent( inout ) :: mr(nummr) + type( field_type ), intent( inout ) :: ls_u, ls_rho, ls_theta, ls_exner + type( field_type ), intent( inout ) :: ls_mr(nummr) + type( field_type ), intent( inout ) :: ls_moist_dyn(num_moist_factors) + + ! When atlt_si_timestep_alg_mod in adjoint_tests is run, this routine is called + ! but it has been already. Hence we have a switch to turn off aspects of the + ! initialisation that would result in attempts to allocate where memory is already + ! allocated, but leave on aspects that are still required + logical(kind=l_def), optional, intent ( in ) :: partial_init + logical(kind=l_def) :: full_init + + integer(kind=i_def) :: outer, inner + + use_moisture = ( moisture_formulation /= moisture_formulation_dry ) + full_init = .true. + if (present(partial_init)) full_init = (.not. partial_init) + + !-------------------------------------------------------------------- + ! Allocate internal state field arrays + !-------------------------------------------------------------------- + + if (fixed_ls) then + ! The linearisation state is not evolved (a 0x0 looping) + ! but ls_outer_iterations and ls_inner_iterations are set to + ! 1 so that the arrays are defined. + ls_outer_iterations = 1_i_def + ls_inner_iterations = 1_i_def + else + ! The linearisation state is evolved, and the intermediate iterations + ! are used to calculate the evolution of the perturbation. + ls_outer_iterations = outer_iterations + ls_inner_iterations = inner_iterations + end if + + if (full_init) then + allocate(state(bundle_size)) + allocate(state_initial(bundle_size)) + allocate(state_n(bundle_size)) + allocate(state_after_slow(bundle_size)) + allocate(state_star(bundle_size)) + allocate(advected_state(bundle_size)) + allocate(rhs_n(bundle_size)) + allocate(rhs_np1(bundle_size)) + allocate(rhs_adv(bundle_size)) + allocate(rhs_phys(bundle_size)) + allocate(mr_n(nummr)) + allocate(mr_after_slow(nummr)) + allocate(mr_inc(nummr)) + + allocate(ls_state(bundle_size)) + allocate(ls_state_n(bundle_size)) + allocate(ls_state_after_slow(bundle_size)) + allocate(ls_advected_state(bundle_size)) + allocate(ls_rhs_n(bundle_size)) + allocate(ls_mr_n(nummr)) + allocate(ls_mr_after_slow(nummr)) + + allocate(ls_state_itns(bundle_size, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_rhs_np1(bundle_size, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_rhs_adv(bundle_size, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_rhs_phys(bundle_size, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_mr_inc(nummr, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_mr_itns(nummr, & + ls_outer_iterations, ls_inner_iterations )) + allocate(ls_moist_dyn_itns(num_moist_factors, & + ls_outer_iterations, ls_inner_iterations )) + end if + + !-------------------------------------------------------------------- + ! Initialise internal state field objects + !-------------------------------------------------------------------- + + call u%copy_field_properties( state(igh_u) ) + call theta%copy_field_properties( state(igh_t) ) + call rho%copy_field_properties( state(igh_d) ) + call exner%copy_field_properties( state(igh_p) ) + + call invoke( setval_X(state(igh_u), u), & + setval_X(state(igh_t), theta), & + setval_X(state(igh_d), rho), & + setval_X(state(igh_p), exner) ) + + call clone_bundle(state, state_initial, bundle_size) + call clone_bundle(state, state_n, bundle_size) + call clone_bundle(state, state_after_slow, bundle_size) + call clone_bundle(state, advected_state, bundle_size) + call clone_bundle(state, rhs_n, bundle_size) + call clone_bundle(state, rhs_np1, bundle_size) + call clone_bundle(state, rhs_adv, bundle_size) + call clone_bundle(state, rhs_phys, bundle_size) + + call clone_bundle(state, ls_state, bundle_size) + call clone_bundle(state, ls_state_n, bundle_size) + call clone_bundle(state, ls_state_after_slow, bundle_size) + call clone_bundle(state, ls_advected_state, bundle_size) + call clone_bundle(state, ls_rhs_n, bundle_size) + + do outer = 1, ls_outer_iterations + do inner = 1, ls_inner_iterations + call clone_bundle(state, ls_state_itns(:, outer, inner), bundle_size) + call clone_bundle(state, ls_rhs_np1(:, outer, inner), bundle_size) + call clone_bundle(state, ls_rhs_adv(:, outer, inner), bundle_size) + call clone_bundle(state, ls_rhs_phys(:, outer, inner), bundle_size) + call set_bundle_scalar(0.0_r_def, ls_rhs_phys(:, outer, inner), bundle_size) + end do + end do + + call ls_theta%copy_field_properties(theta_fv_inc) + + call clone_bundle(mr, mr_n, nummr) + call clone_bundle(mr, mr_after_slow, nummr) + + if (use_moisture) then + call clone_bundle(mr, mr_inc, nummr) + else + call set_bundle_scalar(0.0_r_def, mr_n, nummr) + call set_bundle_scalar(0.0_r_def, mr_after_slow, nummr) + end if + + call clone_bundle(ls_mr, ls_mr_n, nummr) + call clone_bundle(ls_mr, ls_mr_after_slow, nummr) + + do outer = 1,ls_outer_iterations + do inner = 1, ls_inner_iterations + call clone_bundle(ls_moist_dyn, ls_moist_dyn_itns(:, outer, inner), & + num_moist_factors) + call clone_bundle(ls_mr, ls_mr_itns(:, outer, inner), nummr) + if (use_moisture) then + call clone_bundle(ls_mr, ls_mr_inc(:, outer, inner), nummr) + else + end if + end do + end do + + if (.not. use_moisture) then + call set_bundle_scalar(0.0_r_def, ls_mr_n, nummr) + call set_bundle_scalar(0.0_r_def, ls_mr_after_slow, nummr) + end if + + !-------------------------------------------------------------------- + ! Operators for si solves + !-------------------------------------------------------------------- + if (full_init) then + call create_si_operators( mesh ) + call gungho_transport_control_alg_init( mesh ) + call semi_implicit_solver_alg_init( state ) + end if + + call log_event( "semi_implicit_timestep: initialised timestepping algorithm", LOG_LEVEL_INFO ) + + end subroutine tl_semi_implicit_alg_init + + !> @brief The tangent linear for the timestepping of the 3D nonlinear + !> equations using an iterative process with inner and outer loops. + !> @param[in,out] modeldb Structure containing the model state + !> @param[in,out] u 3D wind field + !> @param[in,out] rho Density + !> @param[in,out] theta Potential temperature + !> @param[in,out] exner Exner pressure + !> @param[in,out] mr Mixing ratios + !> @param[in,out] moist_dyn Factors for moist dynamics + !> @param[in] ls_u 3D wind field + !> @param[in] ls_rho Density + !> @param[in] ls_theta Potential temperature + !> @param[in] ls_exner Exner pressure + !> @param[in] ls_mr Mixing ratios + !> @param[in] ls_moist_dyn Factors for moist dynamics + !> @param[in] derived_fields Group of derived fields + !> @param[in] mesh The current mesh + !> @param[in] twod_mesh The current 2d mesh + subroutine tl_semi_implicit_alg_step( modeldb, u, rho, theta, exner, mr, moist_dyn, & + ls_u, ls_rho, ls_theta, ls_exner, ls_mr, ls_moist_dyn, & + derived_fields, mesh, twod_mesh ) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + + ! Prognostic fields + type( field_type ), intent( inout ) :: u, rho, theta, exner + type( field_type ), intent( inout ) :: mr(nummr) + type( field_type ), intent( inout ) :: moist_dyn(num_moist_factors) + ! Linearisation state + type( field_type ), intent( in ) :: ls_u, ls_rho, ls_theta, ls_exner + type( field_type ), intent( in ) :: ls_mr(nummr) + type( field_type ), intent( in ) :: ls_moist_dyn(num_moist_factors) + ! field groups + type( field_collection_type ), intent( inout ) :: derived_fields + ! Linear boundary layer scheme + type( field_type ) :: u_bl_inc + type( field_type ) :: u_bl_inc_flux + type( field_type ) :: du + type( field_type ) :: u_star + type( field_type ) :: u_star_physical + type( field_type ) :: rhsu_np1 + type( field_type ), pointer :: dA => null() + + type( mesh_type ), intent( in ), pointer :: mesh + type( mesh_type ), intent( in ), pointer :: twod_mesh + + real( kind=r_def ) :: cast_dt + + ! Quadrature object + type( quadrature_xyoz_type ), pointer :: qr => null() + + type( operator_type ), pointer :: mm_wt => null() + type( operator_type ), pointer :: mm_vel => null() + + integer( kind=i_def ) :: outer, inner, reference_reset_freq + integer( kind=i_def ) :: ls_outer, ls_inner + integer( kind=i_def ) :: next_outer, next_inner + real( kind=r_def ) :: varalpha, varbeta ! alpha, beta weight to use + ! these may differ from input + ! values during the spinup period + + ! Don't write moisture diagnostics in linear app + logical( kind=l_def ) :: write_moisture_diag = .false. + + ! Configuration + type( namelist_type ), pointer :: mixed_solver_nml + real( kind=r_def ) :: mixed_solver_a_tol + + if ( subroutine_timers ) call timer('tl_semi_implicit_timestep_alg') + + cast_dt = real(modeldb%clock%get_seconds_per_step(), r_def) + + call log_event( "Tangent linear: semi implicit timestep", LOG_LEVEL_INFO ) + + qr => get_qr_fe() + + mm_wt => get_mass_matrix_fe(Wtheta, mesh%get_id()) + mm_vel => get_mass_matrix_fe(W2, mesh%get_id()) + + !-------------------------------------------------------------------- + ! If off-centring is being spun up then modify the alpha value + !-------------------------------------------------------------------- + if (spinup_alpha .and. modeldb%clock%is_spinning_up()) then + varalpha = 1.0_r_def + else + varalpha = alpha + end if + varbeta = 1.0_r_def - varalpha + + !-------------------------------------------------------------------- + ! Copy prognostic field data to state arrays + !-------------------------------------------------------------------- + call invoke( name = "copy_init_fields_to_state", & + setval_X(state(igh_u), u ), & + setval_X(state(igh_t), theta), & + setval_X(state(igh_d), rho ), & + setval_X(state(igh_p), exner) ) + +!-------------------------------------------------------------------- +! Linearisation state +!-------------------------------------------------------------------- + + !-------------------------------------------------------------------- + ! Copy ls data to ls_state arrays + !-------------------------------------------------------------------- + + call invoke( name = "copy_lin_fields_to_ls_state", & + setval_X(ls_state(igh_u), ls_u ), & + setval_X(ls_state(igh_t), ls_theta), & + setval_X(ls_state(igh_d), ls_rho ), & + setval_X(ls_state(igh_p), ls_exner) ) + + !-------------------------------------------------------------------- + ! Update state_n and mr_n with start of timestep values + !-------------------------------------------------------------------- + + call copy_bundle(ls_mr, ls_mr_itns(:,1,1), nummr) + + call copy_bundle(ls_moist_dyn, ls_moist_dyn_itns(:,1,1), num_moist_factors) + + if (use_moisture) then + call copy_bundle(ls_mr, ls_mr_n(:), nummr) + call copy_bundle(ls_mr, ls_mr_after_slow(:), nummr) + + call moist_dyn_factors_alg(ls_moist_dyn_itns(:, 1, 1), ls_mr_n(:) ) + end if + + call copy_bundle(ls_state, ls_state_itns(:, 1, 1), bundle_size) + + call copy_bundle(ls_state, ls_state_n(:), bundle_size) + + call copy_bundle(ls_state, ls_state_after_slow(:), bundle_size) + + !-------------------------------------------------------------------- + ! Compute the semi-implicit operators + !-------------------------------------------------------------------- + ! Reset the reference state in the semi-implicit operators using the latest state guess. + ! This occurs every n timesteps, where n is calculated as reference_reset_time divided by dt. + ! The reference_reset_time is specified in the configuration namelist. + ! Note that this reset can only occur at most once per timestep. + reference_reset_freq = nint(reference_reset_time / cast_dt, i_def) + if ( mod(modeldb%clock%get_step() - 1_i_def, reference_reset_freq) == 0_i_def ) & + call compute_si_operators(ls_state(igh_t), & + ls_state(igh_d), & + ls_state(igh_p), & + modeldb%clock, & + ls_moist_dyn_itns(:,1,1)) + + + !-------------------------------------------------------------------- + ! Compute the time-level n dynamics terms + !-------------------------------------------------------------------- + call copy_bundle(ls_state_after_slow, ls_advected_state, bundle_size) + + if ( .not. fixed_ls ) then + + call rhs_alg( ls_rhs_n, varbeta*cast_dt, ls_state_after_slow, & + ls_state_n, ls_moist_dyn_itns(:,1,1), & + compute_eos=.false., compute_rhs_t_d=.true., & + dlayer_rhs=.false., model_clock=modeldb%clock ) + + if ( .not. si_momentum_equation ) then + ! Predictor of the wind field (u-beta*dt*rhs) to be advected if using + ! explicit advection + call mass_matrix_solver_alg(ls_advected_state(igh_u), ls_rhs_n(igh_u)) + end if + + !========================================================================== + ! Start the Outer (advection) loop + !========================================================================== + ls_outer_dynamics_loop: do outer = 1,ls_outer_iterations + + call gungho_transport_control_alg(ls_rhs_adv(:, outer, 1), & + ls_advected_state, & + ls_state_itns(igh_u, outer, 1), & + ls_state_n(igh_u), & + ls_mr_itns(:, outer, 1), & + ls_mr_after_slow(:), & + modeldb%clock, outer, & + cheap_update = .false. ) + + ! Convert theta increment to weak form + call invoke( setval_X(theta_fv_inc, ls_rhs_adv(igh_t, outer, 1)), & + setval_c(ls_rhs_adv(igh_t, outer, 1), 0.0_r_def), & + dg_inc_matrix_vector_kernel_type(ls_rhs_adv(igh_t, outer, 1), & + theta_fv_inc, mm_wt) ) + + if (use_wavedynamics) then + + ! Use advective update to guess n+1 level scalar fields. + if ( guess_np1 ) then + ! Update factors for moist dynamics + if (use_moisture) then + call moist_dyn_factors_alg( ls_moist_dyn_itns(:, outer, 1), & + ls_mr_itns(:, outer, 1) ) + end if + call update_prognostic_scalars_alg( & + ls_state_itns(:, outer, 1), & + ls_rhs_n, & + ls_rhs_adv(:, outer, 1), & + ls_rhs_phys(:, outer, 1), & + ls_moist_dyn_itns(gas_law, outer, 1) ) + end if + + !===================================================================== + ! Start the Inner (nonlinear, coriolis) loop + !===================================================================== + ls_inner_dynamics_loop: do inner = 1,ls_inner_iterations + + write( log_scratch_space, '(A,2I3)' ) 'loop indices (o, i): ', & + outer, inner + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + ! Calculate the counters for the next iteration + if ( inner == inner_iterations ) then + next_inner = 1 + next_outer = outer + 1 + else + next_inner = inner + 1 + next_outer = outer + end if + + ! Only the intermediate iterations are required for the tangent linear + ! - and not the final iteration. So the final loop of the nonlinear is + ! not required. + if ( next_outer <= outer_iterations .and. & + next_inner <= inner_iterations ) then + + !-------------------------------------------------------------------- + ! Compute the time-level n+1 dynamics terms + !-------------------------------------------------------------------- + call rhs_alg( ls_rhs_np1(:, outer, inner), & + -varalpha*cast_dt, & + ls_state_itns(:, outer, inner), & + ls_state_itns(:, outer, inner), & + ls_moist_dyn_itns(:, outer, inner), & + compute_eos=.true., & + compute_rhs_t_d=.true., & + dlayer_rhs=dlayer_on, & + model_clock=modeldb%clock ) + + !-------------------------------------------------------------------- + ! Compute the LAM LBCs and RHS + !-------------------------------------------------------------------- + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + end if + + !-------------------------------------------------------------------- + ! Compute the residuals + ! + ! Add on advective terms: rhs = rhs_n - rhs_np1 + rhs_adv + ! (reuse rhs_np1 for rhs) + !-------------------------------------------------------------------- + call bundle_axpy(-1.0_r_def, & + ls_rhs_np1(:, outer, inner), & + ls_rhs_n, & + ls_rhs_np1(:, outer, inner), & + bundle_size) + call add_bundle(ls_rhs_np1(:, outer, inner), & + ls_rhs_adv(:, outer, inner), & + ls_rhs_np1(:, outer, inner), & + bundle_size) + + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + end if + + ! Accelerators for inner loop convergence + if ( inner > 1 ) then + call invoke( setval_c(ls_rhs_np1(igh_d, outer, inner), 0.0_r_def), & + setval_c(ls_rhs_np1(igh_t, outer, inner), 0.0_r_def) ) + end if + + !-------------------------------------------------------------------- + ! Solve semi-implicit system: A*inc = rhs, and increment state by inc + !-------------------------------------------------------------------- + + ! First copy the intermediate ls_state values to the next iteration + + call copy_bundle( ls_state_itns(:, outer, inner), & + ls_state_itns(:, next_outer, next_inner), & + bundle_size ) + call copy_bundle( ls_rhs_np1(:, outer, inner), & + ls_rhs_np1(:, next_outer, next_inner), & + bundle_size ) + call copy_bundle( ls_rhs_adv(:, outer, inner), & + ls_rhs_adv(:, next_outer, next_inner), & + bundle_size ) + + call copy_bundle( ls_moist_dyn_itns(:, outer, inner), & + ls_moist_dyn_itns(:, next_outer, next_inner), & + num_moist_factors ) + call copy_bundle( ls_mr_itns(:, outer, inner), & + ls_mr_itns(:, next_outer, next_inner), & + nummr ) + if (use_moisture) then + call copy_bundle( ls_mr_inc(:, outer, inner), & + ls_mr_inc(:, next_outer, next_inner), & + nummr ) + end if + + call semi_implicit_solver_alg_step( & + ls_state_itns(:, next_outer, next_inner), & + ls_rhs_np1(:, outer, inner), & + ls_moist_dyn_itns(gas_law, next_outer, next_inner), & + ls_mr_itns(:, next_outer, next_inner), & + write_moisture_diag, first_iteration=(inner==1) ) + ! If not already done update factors for moist dynamics + if ( .not. guess_np1 .and. use_moisture) then + call moist_dyn_factors_alg( & + ls_moist_dyn_itns(:, next_outer, next_inner), & + ls_mr_itns(:, next_outer, next_inner) ) + end if + if (exner_from_eos) then + call derive_exner_from_eos( & + ls_state_itns(:, next_outer, next_inner), & + ls_moist_dyn_itns(gas_law, next_outer, next_inner) ) + end if + + !---------------------------------------------------------------- + ! LAM Overwrite and Blend LBCs + !---------------------------------------------------------------- + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + endif + + end if + + end do ls_inner_dynamics_loop + !-------------------------------------------------------------------- + ! End of Inner (nonlinear, coriolis) loop + !-------------------------------------------------------------------- + + end if ! use_wavedynamics + + end do ls_outer_dynamics_loop + !-------------------------------------------------------------------- + ! End of Outer (advection) loop + !-------------------------------------------------------------------- + end if + +!-------------------------------------------------------------------- +! Perturbation +!-------------------------------------------------------------------- + + ! Perform some checking on the fields. + call check_fields(state, cast_dt) + + !-------------------------------------------------------------------- + ! Update state_n and mr_n with start of timestep values + !-------------------------------------------------------------------- + if (use_moisture) then + call copy_bundle(mr, mr_n, nummr) + call copy_bundle(mr, mr_after_slow, nummr) + call tl_moist_dyn_factors_alg(moist_dyn, mr_n) + end if + if (l_stabilise_bl) call copy_bundle(state, state_initial, bundle_size) + call copy_bundle(state, state_n, bundle_size) + call copy_bundle(state, state_after_slow, bundle_size) + + !-------------------------------------------------------------------- + ! Compute the time-level n dynamics terms + !-------------------------------------------------------------------- + call tl_rhs_alg( rhs_n, varbeta*cast_dt, state_after_slow, state_n, & + moist_dyn, ls_state_n, ls_moist_dyn_itns(:, 1,1), & + .false., .false., model_clock=modeldb%clock ) + + call invoke(setval_c( rhs_np1(igh_u), 0.0_r_def )) + + call copy_bundle(state_after_slow, advected_state, bundle_size) + if ( .not. si_momentum_equation ) then + ! Predictor of the wind field (u-beta*dt*rhs) to be advected if using + ! explicit advection + call mass_matrix_solver_alg(advected_state(igh_u), rhs_n(igh_u)) + if ( use_density_predictor ) then + call log_event('T.L. si timestep: transport with density predictor not yet implemented', & + LOG_LEVEL_ERROR) + end if + end if + + !========================================================================== + ! Start the Outer (advection) loop + !========================================================================== + + outer_dynamics_loop: do outer = 1,outer_iterations + + if (fixed_ls) then + ls_outer = 1 + else + ls_outer = outer + end if + + call tl_transport_control_alg(rhs_adv, & + advected_state, & + state(igh_u), & + state_n(igh_u), & + mr, & + mr_after_slow, & + ls_advected_state, & + ls_state_itns(igh_u, ls_outer, 1), & + ls_state_n(igh_u), & + ls_mr_after_slow, & + modeldb%clock, & + outer ) + + ! Convert theta increment to weak form + call invoke( setval_X(theta_fv_inc, rhs_adv(igh_t)), & + setval_c(rhs_adv(igh_t), 0.0_r_def), & + dg_inc_matrix_vector_kernel_type(rhs_adv(igh_t), & + theta_fv_inc, mm_wt) ) + + ! Previously tl_rhs_alg was called within each inner loop. + ! It still is called there for inner_iterations > 1. + ! For the first inner loop, it needs to be called before entering. + ! This is because rhs_np1 is used to calculate u_star in tl_bdy_lyr_alg. + call tl_rhs_alg( rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns( :, ls_outer, 1 ), & + ls_moist_dyn_itns( :, ls_outer, 1 ), & + .true., & + dlayer_on, & + modeldb%clock ) + + + if (l_boundary_layer) then + ! Run linear boundary layer scheme to compute increment to u perturbation + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + ! Compute u_star = u_np1 + M^-1(-rhs_np1 + rhs_n + rhs_a) + ! du = M^-1(-rhs_np1 + rhs_n + rhs_a + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + call invoke( setval_c(du, 0.0_r_def), & + aX_plus_Y(rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u)), & + inc_X_plus_Y(rhsu_np1, rhs_adv(igh_u)) ) + + call mass_matrix_solver_alg(du, rhsu_np1 ) + + call invoke( X_plus_Y(u_star, du, state(igh_u)) ) + + ! u_star_physical = u_star / dA + ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity + dA => get_da_at_w2(mesh%get_id()) + call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) + + ! For convenience place u_star_physical as igh_u component of state_star + call clone_bundle(state,state_star, bundle_size) + call copy_bundle(state, state_star, bundle_size) + call invoke( setval_x(state_star(igh_u),u_star_physical ) ) + + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) + ! u_bl_inc computed from state_star(igh_u) + ! NB use state_star + + ! u_bl_inc_flux = u_bl_inc * dA + ! i.e., multiply by dA to transform from velocity to flux + call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) + + call set_bundle_scalar(0.0_r_def,rhs_phys, bundle_size) + call invoke(name="update_rhs_phys_from_fast_physics", & + matrix_vector_kernel_type(rhs_phys(igh_u) ,u_bl_inc_flux, mm_vel ), & + enforce_bc_kernel_type(rhs_phys(igh_u)) ) + + end if ! l_boundary_layer + + if (use_wavedynamics) then + + ! Use advective update to guess n+1 level scalar fieldsgv . + if ( guess_np1 ) & + call log_event( 'guess_np1 not available for tangent linear', LOG_LEVEL_ERROR ) + + !======================================================================= + ! Start the Inner (nonlinear, coriolis) loop + !======================================================================= + inner_dynamics_loop: do inner = 1,inner_iterations + write( log_scratch_space, '(A,2I3)' ) 'loop indices (o, i): ', & + outer, inner + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + if (fixed_ls) then + ls_inner = 1 + else + ls_inner = inner + end if + + !-------------------------------------------------------------------- + ! Compute the time-level n+1 dynamics terms + !-------------------------------------------------------------------- + ! Only call tl_rhs_alg if inner > 1 as for inner===1 it is already called early (see comment above) + if (inner > 1) then + call tl_rhs_alg(rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns(:, ls_outer, ls_inner), & + ls_moist_dyn_itns(:, ls_outer, ls_inner), & + .true., & + dlayer_on, & + modeldb%clock) + end if + + !-------------------------------------------------------------------- + ! Compute the LAM LBCs and RHS + !-------------------------------------------------------------------- + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + end if + + !-------------------------------------------------------------------- + ! Compute the residuals + ! + ! Add on advective terms: rhs = rhs_n - rhs_np1 + rhs_adv + ! (reuse rhs_np1 for rhs) + !-------------------------------------------------------------------- + call bundle_axpy(-1.0_r_def, rhs_np1, rhs_n, rhs_np1, bundle_size) + call add_bundle(rhs_np1, rhs_adv, rhs_np1, bundle_size) + if (l_boundary_layer) call add_bundle(rhs_np1, rhs_phys, rhs_np1, bundle_size) + + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + end if + + ! Accelerators for inner loop convergence + if ( inner > 1 ) then + call invoke( setval_c(rhs_np1(igh_d), 0.0_r_def), & + setval_c(rhs_np1(igh_t), 0.0_r_def) ) + end if + + !-------------------------------------------------------------------- + ! Solve semi-implicit system: A*inc = rhs, and increment state by inc + !-------------------------------------------------------------------- + + mixed_solver_nml => modeldb%configuration%get_namelist('mixed_solver') + call mixed_solver_nml%get_value( 'mixed_solver_a_tol', & + mixed_solver_a_tol ) + + ! If rhs_np1 is zero, there is no need to call the SI solver + if ( .not. & + bundle_is_zero(mixed_solver_a_tol, rhs_np1, bundle_size) ) then + call semi_implicit_solver_alg_step( state, rhs_np1, & + moist_dyn(gas_law), & + mr, & + write_moisture_diag, & + first_iteration=(inner==1) ) + end if + + ! Update factors for moist dynamics + if (use_moisture) then + call tl_moist_dyn_factors_alg(moist_dyn, mr ) + end if + + if (exner_from_eos) then + call tl_derive_exner_from_eos( state, & + moist_dyn(gas_law), & + ls_state, & + ls_moist_dyn(gas_law) ) + end if + + !-------------------------------------------------------------------- + ! LAM Overwrite and Blend LBCs + !-------------------------------------------------------------------- + if ( limited_area ) then + call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) + endif + + end do inner_dynamics_loop + !-------------------------------------------------------------------- + ! End of Inner (nonlinear, coriolis) loop + !-------------------------------------------------------------------- + + end if ! use_wavedynamics + + end do outer_dynamics_loop + !-------------------------------------------------------------------- + ! End of Outer (advection) loop + !-------------------------------------------------------------------- + + !-------------------------------------------------------------------- + ! Apply boundary layer (BL) stabilisation if required + !-------------------------------------------------------------------- + if (l_stabilise_bl) then + ! Set u inside boundary layer to: + ! alpha * state_initial(igh_u) + (1 - alpha) * state(igh_u) + ! where alpha is a maximum of 1 at the model base and decreases + ! linearly to 0 at top of boundary layer + call invoke( setval_X( u, state(igh_u) ), & + stabilise_bl_u_kernel_type( u, state_initial(igh_u), & + state(igh_u), & + n_bl_levels_to_stabilise, & + max_bl_stabilisation ), & + setval_X( state(igh_u), u ) ) + end if + + !-------------------------------------------------------------------- + ! Apply mixing + !-------------------------------------------------------------------- + call mixing_alg(mr, state(igh_t), & + state(igh_u), derived_fields, & + state(igh_d), cast_dt ) + + ! Update derived variables for time level n+1 + if (use_moisture) then + call tl_moist_dyn_factors_alg(moist_dyn, mr) + end if + if (use_physics) then + call map_physics_fields_alg(state(igh_u), state(igh_p), & + state(igh_d), state(igh_t), & + moist_dyn, derived_fields) + end if + + !-------------------------------------------------------------------- + ! Update fields held in the driver layer + !-------------------------------------------------------------------- + call invoke( setval_X(u, state(igh_u)), & + setval_X(theta, state(igh_t)), & + setval_X(rho, state(igh_d)), & + setval_X(exner, state(igh_p)) ) + + nullify( mm_wt, mm_vel, qr ) + + if ( subroutine_timers ) call timer('tl_semi_implicit_timestep_alg') + + end subroutine tl_semi_implicit_alg_step + + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !> @brief Release all claimed resources once completed. + subroutine tl_semi_implicit_alg_final() + + implicit none + + call semi_implicit_solver_alg_final() + + call final_si_operators() + + if (allocated(state)) deallocate(state) + if (allocated(state_initial)) deallocate(state_initial) + if (allocated(state_n)) deallocate(state_n) + if (allocated(state_after_slow)) deallocate(state_after_slow) + if (allocated(state_star)) deallocate(state_star) + if (allocated(advected_state)) deallocate(advected_state) + if (allocated(rhs_n)) deallocate(rhs_n) + if (allocated(rhs_np1)) deallocate(rhs_np1) + if (allocated(rhs_adv)) deallocate(rhs_adv) + if (allocated(rhs_phys)) deallocate(rhs_phys) + if (allocated(mr_n)) deallocate(mr_n) + if (allocated(mr_after_slow)) deallocate(mr_after_slow) + if (allocated(mr_inc)) deallocate(mr_inc) + + if (allocated(ls_state)) deallocate(ls_state) + if (allocated(ls_state_itns)) deallocate(ls_state_itns) + if (allocated(ls_state_n)) deallocate(ls_state_n) + if (allocated(ls_state_after_slow)) deallocate(ls_state_after_slow) + if (allocated(ls_advected_state)) deallocate(ls_advected_state) + if (allocated(ls_rhs_n)) deallocate(ls_rhs_n) + if (allocated(ls_rhs_np1)) deallocate(ls_rhs_np1) + if (allocated(ls_rhs_adv)) deallocate(ls_rhs_adv) + if (allocated(ls_rhs_phys)) deallocate(ls_rhs_phys) + if (allocated(ls_mr_n)) deallocate(ls_mr_n) + if (allocated(ls_mr_after_slow)) deallocate(ls_mr_after_slow) + if (allocated(ls_mr_inc)) deallocate(ls_mr_inc) + if (allocated(ls_mr_itns)) deallocate(ls_mr_itns) + if (allocated(ls_moist_dyn_itns)) deallocate(ls_moist_dyn_itns) + + return + end subroutine tl_semi_implicit_alg_final + +end module tl_si_timestep_alg_mod diff --git a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 index 5549b030..45c2cd5f 100644 --- a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 @@ -7,7 +7,7 @@ module tl_bl_inc_kernel_mod use argument_mod, only : arg_type, & - GH_FIELD, GH_OPERATOR, & + GH_FIELD, GH_OPERATOR, & GH_SCALAR, GH_INTEGER, & GH_READ, GH_INC, & GH_REAL, CELL_COLUMN, & @@ -50,7 +50,7 @@ module tl_bl_inc_kernel_mod !> @brief Computes boundary layer u inc !! @param[in] nlayers Number of layers -!! @param[in,out] u_inc Output +!! @param[in,out] u_inc Output !! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field !! @param[in] undf_w2 Unique number of degrees of freedom for the output field !! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field @@ -75,8 +75,8 @@ subroutine tl_bl_inc_code( nlayers, & integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 real(kind=r_def), dimension(undf_w2), intent(in) :: u - REAL(kind=r_def), dimension(undf_w2), intent(in) :: Auv - REAL(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv + REAL(kind=r_def), dimension(undf_w2), intent(in) :: Auv + REAL(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc @@ -100,7 +100,7 @@ subroutine tl_bl_inc_code( nlayers, & ! Loop over horizontal W2 DoFs do j = 1, face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)) - + df = j if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 & .and. face_selector_ew(map_w3_2d(1)) == 1) df = N @@ -136,7 +136,7 @@ subroutine tl_bl_inc_code( nlayers, & END DO ! ====================== transform to upper triangular form ====================== - + DO k=1,BLevs_m IF (k == 1) THEN a0(1) = 1.0_r_def/a0(1) diff --git a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 index fad73df9..3a34b1d9 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 @@ -7,7 +7,7 @@ module tl_compute_aubu_kernel_mod use argument_mod, only : arg_type, func_type, & - GH_FIELD, GH_OPERATOR, & + GH_FIELD, GH_OPERATOR, & GH_SCALAR, GH_INTEGER, & GH_READ, GH_INC, GH_READWRITE, & GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & @@ -63,7 +63,7 @@ subroutine tl_compute_aubu_code(nlayers, & w2_rmultiplicity, & dt, & Blevs_m, & - ndf_w2, undf_w2, map_w2, & + ndf_w2, undf_w2, map_w2, & ndf_w3, undf_w3, map_w3) @@ -98,7 +98,7 @@ subroutine tl_compute_aubu_code(nlayers, & do df = 1,4 do k = 0, BLevs_m - + IF (k == 0) THEN Auv(map_w2(df)+k) = Auv(map_w2(df)+k)+ & w2_rmultiplicity(map_w2(df) ) * & @@ -114,9 +114,9 @@ subroutine tl_compute_aubu_code(nlayers, & ( w2_rmultiplicity(map_w2(df)+k ) * E( map_w3(df3) + k) ) / dt END IF - - end do ! k = 0, BLevs_m - end do ! df = 1,4 + + end do ! k = 0, BLevs_m + end do ! df = 1,4 end subroutine tl_compute_aubu_code diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 index 7cace4a0..ca6acf12 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -7,7 +7,7 @@ module tl_compute_qe_kernel_mod use argument_mod, only : arg_type, func_type, & - GH_FIELD, GH_OPERATOR, & + GH_FIELD, GH_OPERATOR, & GH_SCALAR, GH_INTEGER, & GH_READ, GH_INC, GH_READWRITE, & GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & @@ -74,7 +74,7 @@ subroutine tl_compute_qe_code( nlayers, & z_land_m, & z_sea_m, & L_0_m, & - ndf_w3, undf_w3, map_w3, & + ndf_w3, undf_w3, map_w3, & ndf_wtheta, undf_wtheta, map_wtheta, & ndf_2d, undf_2d, map_2d ) @@ -86,7 +86,7 @@ subroutine tl_compute_qe_code( nlayers, & integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 - + integer(kind=i_def), intent(in) :: undf_wtheta, ndf_wtheta integer(kind=i_def), dimension(ndf_wtheta),intent(in) :: map_wtheta @@ -111,18 +111,18 @@ subroutine tl_compute_qe_code( nlayers, & real(kind=r_def) :: roughness_length_m REAL(kind=r_def), PARAMETER :: Von_Karman=0.4_r_def - REAL(kind=r_def) :: L_diff_m(1:BLevs_m) + REAL(kind=r_def) :: L_diff_m(1:BLevs_m) real(kind=r_def) :: u1 ! ============================== setup roughness_length_m ============================== - + df = 1 roughness_length_m = z_land_m*ls_land_fraction(map_2d(df)) + & z_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) ! ============================== setup L_diff ============================== -! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above +! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above ! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 ! L_diff_m(k) defined for 1 <= k <= BLevs_m @@ -145,7 +145,7 @@ subroutine tl_compute_qe_code( nlayers, & ! ============================== Define Q and E ============================== ! E is on cell centres -! Q is on centre of horizontal faces - for convenience indexed by centre of cell above +! Q is on centre of horizontal faces - for convenience indexed by centre of cell above ! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 ! Q(k) defined for 0 <= k <= BLevs_m @@ -154,11 +154,11 @@ subroutine tl_compute_qe_code( nlayers, & df=1 u1=u_land_m*ls_land_fraction(map_2d(df)) + & u_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) - + DO k=0,BLevs_m IF (k == 0) THEN Q( map_w3(df) + k)=Von_Karman * u1 & - / LOG(((height_w3(map_w3(df)+0) - height_wth(map_wtheta(df)+0) & ! + / LOG(((height_w3(map_w3(df)+0) - height_wth(map_wtheta(df)+0) & ! + roughness_length_m)/(roughness_length_m))) ELSE ! ie k >= 1 Q( map_w3(df) + k)=L_diff_m(k) * u1 & From 0cd0a26b82ebc8df753ccec86cdd5c848b694973 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 12:07:08 +0000 Subject: [PATCH 26/68] jedi_lfric build errors --- .../source/field/jedi_lfric_linear_fields_mod.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 index 83e67fda..2378b991 100644 --- a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 @@ -48,7 +48,7 @@ module jedi_lfric_linear_fields_mod 'm_r ', & 'm_s '/) character( len=str_def ), parameter, public :: & - ls_variable_names(nvars) = (/'theta ', & + ls_variable_names(ls_nvars) = (/'theta ', & 'exner ', & 'rho ', & 'u_in_w3 ', & @@ -72,7 +72,7 @@ module jedi_lfric_linear_fields_mod Wtheta, & Wtheta/) integer( kind=i_def ), parameter, public :: & - ls_variable_function_spaces(nvars) = (/Wtheta, & + ls_variable_function_spaces(ls_nvars) = (/Wtheta, & W3, & W3, & W3, & @@ -109,12 +109,12 @@ subroutine create_linear_fields( mesh, linear_fields ) integer :: i ! Setup the field_collection - call linear_fields%initialise(name = 'linear_state_trajectory', table_len = nvars) + call linear_fields%initialise(name = 'linear_state_trajectory', table_len = ls_nvars) ! Create and add the fields defined in the list of variable names - do i = 1, nvars + do i = 1, ls_nvars - variable_name = trim(variable_names(i)) + variable_name = trim(ls_variable_names(i)) call field%initialise( & vector_space = function_space_collection%get_fs(mesh, & From a4345367a68c6df1ab7753cca1dc3e144acc32c6 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 12:19:33 +0000 Subject: [PATCH 27/68] Other minor fixes --- .../adjoint_tests/opt/rose-app-nwp_gal9_c12.conf | 4 ++-- rose-stem/app/adjoint_tests/rose-app.conf | 13 +++++++++++-- rose-stem/app/jedi_tlm_tests/rose-app.conf | 11 ++++++++++- .../app/linear_model/opt/rose-app-dcmip301.conf | 2 ++ .../linear_model/opt/rose-app-semi-implicit.conf | 2 ++ .../integration-test/tl_test/tl_test_driver_mod.f90 | 2 +- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf index 4b375741..6bc37fdb 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' diff --git a/rose-stem/app/adjoint_tests/rose-app.conf b/rose-stem/app/adjoint_tests/rose-app.conf index 881bff89..a02da048 100644 --- a/rose-stem/app/adjoint_tests/rose-app.conf +++ b/rose-stem/app/adjoint_tests/rose-app.conf @@ -376,7 +376,7 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_directory='/data/users/tim.payne/lfric_apps/files' ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' @@ -719,12 +719,21 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] +blevs_m=15 +e_folding_levs_m=10 fixed_ls=.true. -l_stabilise_bl=.true. +l_0_m=80.0 +l_boundary_layer=.true. +l_stabilise_bl=.false. +log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 99c205f8..9b269ed0 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -762,12 +762,21 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] +blevs_m=15 +e_folding_levs_m=10 fixed_ls=.true. -l_stabilise_bl=.true. +l_0_m=80.0 +l_boundary_layer=.true. +l_stabilise_bl=.false. +log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf index 01576bf1..9ad5d50e 100644 --- a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf +++ b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf @@ -58,6 +58,8 @@ ls_option='analytic' diagnostic_frequency=36 [namelist:linear] +Blevs_m=4 +e_folding_levs_m=3 fixed_ls=.false. l_stabilise_bl=.false. pert_option='analytic' diff --git a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf index be23c9c8..5a822d83 100644 --- a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf +++ b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf @@ -58,6 +58,8 @@ ls_option='analytic' diagnostic_frequency=20 [namelist:linear] +Blevs_m=4 +e_folding_levs_m=3 l_stabilise_bl=.false. pert_option='analytic' diff --git a/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 b/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 index b93d850d..efdec0b8 100644 --- a/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 +++ b/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 @@ -142,7 +142,7 @@ subroutine initialise( program_name, modeldb, calendar ) aerosol_twod_mesh ) ! Instantiate the linearisation state - call linear_create_ls( modeldb, mesh ) + call linear_create_ls( modeldb, mesh, twod_mesh ) ! Initialise the fields stored in the model_data prognostics. This needs ! to be done before initialise_model. From 2fea9a9c4d8ea3d711c2564cc66e043813adf760 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 14:14:38 +0000 Subject: [PATCH 28/68] rose config-dump --- rose-stem/app/linear_model/opt/rose-app-dcmip301.conf | 2 +- rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf index 9ad5d50e..07cb3c61 100644 --- a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf +++ b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf @@ -58,7 +58,7 @@ ls_option='analytic' diagnostic_frequency=36 [namelist:linear] -Blevs_m=4 +blevs_m=4 e_folding_levs_m=3 fixed_ls=.false. l_stabilise_bl=.false. diff --git a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf index 5a822d83..b32e014c 100644 --- a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf +++ b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf @@ -58,7 +58,7 @@ ls_option='analytic' diagnostic_frequency=20 [namelist:linear] -Blevs_m=4 +blevs_m=4 e_folding_levs_m=3 l_stabilise_bl=.false. pert_option='analytic' From 6b108db947692df271848690d907c9afce0c7a5c Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 14:49:36 +0000 Subject: [PATCH 29/68] minor fixes --- .../source/field/jedi_lfric_linear_fields_mod.f90 | 2 +- rose-stem/app/adjoint_tests/file/iodef.xml | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 index 2378b991..267a85c3 100644 --- a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 @@ -120,7 +120,7 @@ subroutine create_linear_fields( mesh, linear_fields ) vector_space = function_space_collection%get_fs(mesh, & element_order_h, & element_order_v, & - variable_function_spaces(i)), & + ls_variable_function_spaces(i)), & name = variable_name ) call linear_fields%add_field( field ) diff --git a/rose-stem/app/adjoint_tests/file/iodef.xml b/rose-stem/app/adjoint_tests/file/iodef.xml index 8591084d..8a13fa6f 100644 --- a/rose-stem/app/adjoint_tests/file/iodef.xml +++ b/rose-stem/app/adjoint_tests/file/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -327,6 +332,7 @@ + From c57429a5a17ab64e711d3493ef43ee2ad666ffe9 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 15:37:10 +0000 Subject: [PATCH 30/68] Minor fixes --- .../adjoint_tests/example/configuration.nml | 17 +++++++--- .../linear_physics/atl_bdy_lyr_alg.x90 | 33 ------------------- .../linear_physics/tl_bdy_lyr_alg.x90 | 23 ------------- 3 files changed, 13 insertions(+), 60 deletions(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 812a000e..0f7e8e20 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -66,10 +66,10 @@ stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_adjoint_tests_to_linear_model-2/run1/share/data/restart_adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64_tstep', +checkpoint_stem_name='', diag_stem_name='diagGungho', -ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -ls_filename='final_ls', +ls_directory='/data/users/tim.payne/lfric_apps/files', +ls_filename='final_ls_with_land', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', @@ -220,12 +220,21 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear +blevs_m=15, +e_folding_levs_m=10, fixed_ls=.true., -l_stabilise_bl=.true., +l_0_m=80.0, +l_boundary_layer=.true., +l_stabilise_bl=.false., +log_layer=2, ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, / &logging log_to_rank_zero_only=.false., diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index ba98a76c..8a2b45b6 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -73,8 +73,6 @@ module atl_bdy_lyr_alg_mod use compute_vorticity_alg_mod, only: compute_vorticity_alg use fs_continuity_mod, only: W1, W2, W3, Wtheta use function_space_collection_mod, only: function_space_collection - use sci_field_minmax_alg_mod, only: get_field_minmax - use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use atl_bl_inc_kernel_mod, only: atl_bl_inc_kernel_type @@ -153,9 +151,6 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) type(integer_field_type), pointer :: face_selector_ns => null() integer(kind=i_def), parameter :: exner_stencil_depth = 1 - real(kind=r_def) :: fmin - real(kind=r_def) :: fmax - real(kind=r_def) :: ip if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') @@ -213,10 +208,6 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) call invoke(setval_c(auv,0.0_r_def),& setval_c(buv_inv,0.0_r_def) ) - call get_field_minmax(ls_land_fraction, fmin, fmax ) - write( log_scratch_space, '(a,1x,3(e12.5,1x))') 'atl_bdy_lyr_alg, ms,min,max ls_land_fraction=',ip,fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - call invoke ( tl_compute_qe_kernel_type(Q, & E, & ls_state(igh_d), & @@ -231,14 +222,6 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) z_sea_m, & L_0_m ) ) - call get_field_minmax( Q, fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Q=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - - call get_field_minmax( E, fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max E=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - call invoke ( tl_compute_aubu_kernel_type(auv, & buv_inv, & Q, & @@ -248,18 +231,6 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) dt, & Blevs_m ) ) - call get_field_minmax( Auv, fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max Auv=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - - call get_field_minmax( buv_inv, fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max buv_inv=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - - call get_field_minmax( state(igh_u), fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max state(igh_u) before atl_bl_inc=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - call invoke ( atl_bl_inc_kernel_type( u_bl_inc, & state(igh_u), & auv,buv_inv, & @@ -267,10 +238,6 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) face_selector_ns, & Blevs_m ) ) - call get_field_minmax( state(igh_u), fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'atl_bdy_lyr_alg, min,max state(igh_u) after atl_bl_inc=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - nullify( mm_vel, mm_wtheta, mm_w3_inv, & chi, panel_id, & geopotential, u, theta, rho, exner, & diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index 36ad759e..b176345e 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -9,11 +9,6 @@ module tl_bdy_lyr_alg_mod use constants_mod, only: r_def, i_def, l_def use field_collection_mod, only: field_collection_type use integer_field_mod, only: integer_field_type - use log_mod, only: log_event, & - log_scratch_space, & - LOG_LEVEL_ERROR, & - LOG_LEVEL_DEBUG, & - LOG_LEVEL_INFO use driver_modeldb_mod, only: modeldb_type use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use sci_geometric_constants_mod, only: get_height_fe, get_coordinates, & @@ -74,8 +69,6 @@ module tl_bdy_lyr_alg_mod use compute_vorticity_alg_mod, only: compute_vorticity_alg use fs_continuity_mod, only: W1, W2, W3, Wtheta use function_space_collection_mod, only: function_space_collection - use sci_field_minmax_alg_mod, only: get_field_minmax - use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use tl_bl_inc_kernel_mod, only: tl_bl_inc_kernel_type @@ -163,9 +156,6 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) type(integer_field_type), pointer :: face_selector_ns => null() integer(kind=i_def), parameter :: exner_stencil_depth = 1 - real(kind=r_def) :: fmin - real(kind=r_def) :: fmax - real(kind=r_def) :: ip if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') @@ -224,11 +214,6 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) call invoke(setval_c(auv,0.0_r_def),& setval_c(buv_inv,0.0_r_def) ) - call invoke (x_innerproduct_x(ip,ls_land_fraction)) - call get_field_minmax(ls_land_fraction, fmin, fmax ) - write( log_scratch_space, '(a,1x,3(e12.5,1x))') 'tl_bdy_lyr_alg, ms,min,max ls_land_fraction=',ip,fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - call invoke ( tl_compute_qe_kernel_type(Q, & E, & ls_state(igh_d), & @@ -252,10 +237,6 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) dt, & Blevs_m ) ) - call get_field_minmax( state(igh_u), fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'tl_bdy_lyr_alg, min,max state(igh_u) before tl_bl_inc=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - call invoke ( tl_bl_inc_kernel_type( u_bl_inc, & state(igh_u), & auv,buv_inv, & @@ -263,10 +244,6 @@ subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) face_selector_ns, & Blevs_m ) ) - call get_field_minmax(u_bl_inc , fmin, fmax ) - write( log_scratch_space, '(a,1x,2(e12.5,1x))') 'tl_bdy_lyr_alg, min,max u_bl_inc=',fmin, fmax - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - nullify( mm_vel, mm_wtheta, mm_w3_inv, & chi, panel_id, & geopotential, u, theta, rho, exner, & From 8e97dc3581e69a4b572bd418ce327284ccd34e8a Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 22 Jan 2026 16:02:26 +0000 Subject: [PATCH 31/68] iodef updates --- applications/jedi_lfric_tests/example/iodef.xml | 6 ++++++ .../jedi_lfric_tests/example_id_tlm_tests/iodef.xml | 8 ++++++++ applications/jedi_lfric_tests/example_tlm_tests/iodef.xml | 6 ++++++ rose-stem/app/jedi_id_tlm_tests/file/iodef.xml | 8 ++++++++ rose-stem/app/jedi_lfric_tests/file/iodef.xml | 6 ++++++ rose-stem/app/jedi_tlm_tests/file/iodef.xml | 8 ++++++++ 6 files changed, 42 insertions(+) diff --git a/applications/jedi_lfric_tests/example/iodef.xml b/applications/jedi_lfric_tests/example/iodef.xml index 368ff562..07393ded 100644 --- a/applications/jedi_lfric_tests/example/iodef.xml +++ b/applications/jedi_lfric_tests/example/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -327,6 +332,7 @@ + diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml index 7d20e408..a820d177 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -421,6 +428,7 @@ + diff --git a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml index 1d5caf93..a820d177 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml @@ -146,6 +146,11 @@ + + + + + @@ -423,6 +428,7 @@ + diff --git a/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml b/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml index 7d20e408..a820d177 100644 --- a/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml +++ b/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -421,6 +428,7 @@ + diff --git a/rose-stem/app/jedi_lfric_tests/file/iodef.xml b/rose-stem/app/jedi_lfric_tests/file/iodef.xml index 07b94bab..9514932a 100644 --- a/rose-stem/app/jedi_lfric_tests/file/iodef.xml +++ b/rose-stem/app/jedi_lfric_tests/file/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -327,6 +332,7 @@ + diff --git a/rose-stem/app/jedi_tlm_tests/file/iodef.xml b/rose-stem/app/jedi_tlm_tests/file/iodef.xml index 7d20e408..a820d177 100644 --- a/rose-stem/app/jedi_tlm_tests/file/iodef.xml +++ b/rose-stem/app/jedi_tlm_tests/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -421,6 +428,7 @@ + From 5ff06b459fdf9578e8f87c614f32757f76a6886a Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 09:13:31 +0000 Subject: [PATCH 32/68] Test config fixes --- .../adjoint_tests/example/configuration.nml | 4 ++-- applications/adjoint_tests/example/iodef.xml | 6 ++++++ rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 13 +++++++++++-- rose-stem/app/jedi_lfric_tests/rose-app.conf | 4 ++-- rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml | 8 ++++++++ .../jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf | 4 ++-- rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 0f7e8e20..5c4d3173 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -68,8 +68,8 @@ stretching_method='smooth', ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='diagGungho', -ls_directory='/data/users/tim.payne/lfric_apps/files', -ls_filename='final_ls_with_land', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +ls_filename='final_ls', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', diff --git a/applications/adjoint_tests/example/iodef.xml b/applications/adjoint_tests/example/iodef.xml index 8591084d..8a13fa6f 100644 --- a/applications/adjoint_tests/example/iodef.xml +++ b/applications/adjoint_tests/example/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -327,6 +332,7 @@ + diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 82baa804..4937c7b4 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -383,7 +383,7 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_directory='/data/users/tim.payne/lfric_apps/files' ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' @@ -761,12 +761,21 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] +blevs_m=15 +e_folding_levs_m=10 fixed_ls=.true. -l_stabilise_bl=.true. +l_0_m=80.0 +l_boundary_layer=.true. +l_stabilise_bl=.false. +log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index a683eda8..f82e630b 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -372,8 +372,8 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' diff --git a/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml b/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml index 7d20e408..a820d177 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml +++ b/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -421,6 +428,7 @@ + diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf index 958b917d..ea0467ea 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 9b269ed0..162cfa7c 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -383,7 +383,7 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_directory='/data/users/tim.payne/lfric_apps/files' ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' From a9672df36c07e971f7f4bbaed38381d3b84c960a Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 10:00:18 +0000 Subject: [PATCH 33/68] Config updates --- applications/adjoint_tests/example/configuration.nml | 4 ++-- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 2 +- rose-stem/app/jedi_lfric_tests/rose-app.conf | 2 +- rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf | 2 +- rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 5c4d3173..0f7e8e20 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -68,8 +68,8 @@ stretching_method='smooth', ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='diagGungho', -ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -ls_filename='final_ls', +ls_directory='/data/users/tim.payne/lfric_apps/files', +ls_filename='final_ls_with_land', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 4937c7b4..3d5b42ab 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -633,7 +633,7 @@ time_step='P0DT1H0M0S' state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' + ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index f82e630b..7f78a335 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -625,7 +625,7 @@ time_step='P0DT1H0M0S' state_time='2018-04-14 21:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' + ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index ba5167ca..121ddfeb 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -599,7 +599,7 @@ io_time_step='P0DT1H0M0S' inc_time='2018-04-14 21:00:00' initialise_via_read=.true. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', - ='m_cl','m_r','m_s' + ='m_cl','m_r','m_s','land_fraction' [namelist:jedi_lfric_settings] forecast_length='P0DT6H0M0S' diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 162cfa7c..418709a9 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -634,7 +634,7 @@ time_step='P0DT1H0M0S' state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' + ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. From 404e36bc18b89aa8fff454085f5695b1b51efba4 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 11:11:38 +0000 Subject: [PATCH 34/68] bugfix --- .../source/jedi-interface/jedi_state_mod.f90 | 5 ++++- .../source/field/atlas_field_interface_mod.F90 | 12 +++++++++++- .../jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 index 4b464f16..8c4b8168 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 @@ -382,6 +382,7 @@ subroutine setup_interface_to_modeldb( self ) real(real64), pointer :: atlas_data_ptr(:,:) integer(i_def), pointer :: horizontal_map_ptr(:) integer(i_def) :: n_variables + logical(l_def) :: is_2d type( field_collection_type ), pointer :: depository @@ -406,9 +407,11 @@ subroutine setup_interface_to_modeldb( self ) atlas_data_ptr => self%fields(ivar)%get_data() + is_2d = self%field_meta_data%get_variable_is_2d(ivar) + call self%fields_to_modeldb(ivar)%initialise( atlas_data_ptr, & horizontal_map_ptr, & - lfric_field_ptr ) + lfric_field_ptr, is_2d=is2d ) end do diff --git a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 index c630b998..b3cfb502 100644 --- a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 @@ -134,9 +134,10 @@ module atlas_field_interface_mod !> @param [in] atlas_name Optional name of the atlas field !> @param [in] fill_direction_up Optional logical set false if the atlas field !> data is orientated from top-bottom +!> @param [in] is_2d Optional logical set true if the field is 2D subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & lfric_field_ptr, surface_level_type, & - atlas_name, fill_direction_up ) + atlas_name, fill_direction_up, is_2d ) implicit none @@ -147,6 +148,7 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & integer(i_def), optional, intent(in) :: surface_level_type character( len=* ), optional, intent(in) :: atlas_name logical( kind=l_def ), optional, intent(in) :: fill_direction_up + logical( kind=l_def ), optional, intent(in) :: is_2d ! locals logical( kind=l_def ), allocatable :: check_map(:) @@ -157,6 +159,7 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & type( field_proxy_type ) :: field_proxy class(field_parent_type), pointer :: cast_field logical( kind=l_def ) :: fill_direction_up_local + logical( kind=l_def ) :: is_2d_local ! Initialise the abstract parent ! @@ -198,6 +201,12 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & fill_direction_up_local = .true. end if + if (present(is_2d)) then + is_2d_local = is_2d + else + is_2d_local = .false. + end if + ! Setup data sizes and indices self%n_horizontal = size(atlas_data_ptr,dim=2) self%n_vertical = size(atlas_data_ptr,dim=1) @@ -240,6 +249,7 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & " function space is not supported by the atlas_field_interface class." call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end select + if (is_2d_local) n_vertical_lfric = 1 ! Override if 2D field n_horizontal_lfric = field_proxy%vspace%get_last_dof_owned()/n_vertical_lfric ! 1. Vertical points diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf index 958b917d..ea0467ea 100644 --- a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' From 90f224986658c02c7863e5de64a184ad309bb0cb Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 13:29:41 +0000 Subject: [PATCH 35/68] Bugfix --- .../jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 index 8c4b8168..ead62f6c 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 @@ -411,7 +411,7 @@ subroutine setup_interface_to_modeldb( self ) call self%fields_to_modeldb(ivar)%initialise( atlas_data_ptr, & horizontal_map_ptr, & - lfric_field_ptr, is_2d=is2d ) + lfric_field_ptr, is_2d=is_2d ) end do From df880a67f92f14abef5b4d3d57988b73a7276acb Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 14:45:15 +0000 Subject: [PATCH 36/68] Debugging code --- .../source/jedi-interface/jedi_state_mod.f90 | 4 +++- .../source/field/atlas_field_interface_mod.F90 | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 index ead62f6c..4464fadf 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 @@ -469,6 +469,7 @@ subroutine setup_interface_to_field_collection( self, & integer(i_def), pointer :: horizontal_map_ptr(:) integer(i_def) :: n_variables logical :: all_variables_exists + logical(l_def) :: is_2d ! Check that the state contains all the required fields all_variables_exists = & @@ -488,9 +489,10 @@ subroutine setup_interface_to_field_collection( self, & call get_model_field( variable_names(ivar), & field_collection, lfric_field_ptr ) call self%get_field_data(variable_names(ivar), atlas_data_ptr) + is_2d = self%field_meta_data%get_variable_is_2d(ivar) call interface_fields(ivar)%initialise( atlas_data_ptr, & horizontal_map_ptr, & - lfric_field_ptr ) + lfric_field_ptr, is_2d=is_2d ) end do end subroutine setup_interface_to_field_collection diff --git a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 index b3cfb502..9c663a94 100644 --- a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 @@ -243,6 +243,10 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & n_vertical_lfric = field_proxy%vspace%get_nlayers() + 1 case ( W3 ) n_vertical_lfric = field_proxy%vspace%get_nlayers() + !TDB + if (self%atlas_name=='land_fraction' .or. self%atlas_name=='land_area_fraction') then + n_vertical_lfric = 1 + end if case default write(log_scratch_space, '(3A)') "The ", & trim(name_from_functionspace(fs_enumerator)) , & @@ -250,8 +254,14 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end select if (is_2d_local) n_vertical_lfric = 1 ! Override if 2D field + n_horizontal_lfric = field_proxy%vspace%get_last_dof_owned()/n_vertical_lfric + !TDB + if (self%atlas_name=='land_fraction' .or. self%atlas_name=='land_area_fraction') then + n_horizontal_lfric = self%n_horizontal + end if + ! 1. Vertical points if ( n_vertical_lfric /= self%n_vertical_lfric ) then write(log_scratch_space, '(A,I0,A,I0,A)') & From 945525d0a187d6b7904354f3ec4794846c0f21e8 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 23 Jan 2026 15:33:28 +0000 Subject: [PATCH 37/68] Alternate name for land fraction --- .../source/jedi-interface/jedi_setup_field_meta_data_mod.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 index 34dd084d..a7df2411 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 @@ -111,6 +111,9 @@ subroutine get_field_info(function_space, is_2d, variable_name) case ( "land_fraction" ) function_space = W3 is_2d = .true. + case ( "land_area_fraction" ) + function_space = W3 + is_2d = .true. case default write ( log_scratch_space, '(4A)' ) & "jedi_setup_field_meta_data_mod::get_field_info:: ", & From 73651cb47adbd52392b20e57fd1c3b3616c36a0b Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 11:13:51 +0000 Subject: [PATCH 38/68] Fixed dimension assignment --- .../jedi_setup_field_meta_data_mod.F90 | 3 --- .../source/field/atlas_field_interface_mod.F90 | 15 ++++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 index a7df2411..34dd084d 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 @@ -111,9 +111,6 @@ subroutine get_field_info(function_space, is_2d, variable_name) case ( "land_fraction" ) function_space = W3 is_2d = .true. - case ( "land_area_fraction" ) - function_space = W3 - is_2d = .true. case default write ( log_scratch_space, '(4A)' ) & "jedi_setup_field_meta_data_mod::get_field_info:: ", & diff --git a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 index 9c663a94..a5472835 100644 --- a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 @@ -243,24 +243,21 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & n_vertical_lfric = field_proxy%vspace%get_nlayers() + 1 case ( W3 ) n_vertical_lfric = field_proxy%vspace%get_nlayers() - !TDB - if (self%atlas_name=='land_fraction' .or. self%atlas_name=='land_area_fraction') then - n_vertical_lfric = 1 - end if case default write(log_scratch_space, '(3A)') "The ", & trim(name_from_functionspace(fs_enumerator)) , & " function space is not supported by the atlas_field_interface class." call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end select - if (is_2d_local) n_vertical_lfric = 1 ! Override if 2D field n_horizontal_lfric = field_proxy%vspace%get_last_dof_owned()/n_vertical_lfric - !TDB - if (self%atlas_name=='land_fraction' .or. self%atlas_name=='land_area_fraction') then - n_horizontal_lfric = self%n_horizontal - end if + ! n_vertical_lfric is set above based on function space and assuming a 3D field + ! This is then used to correctly calculate n_horizontal_lfric + ! However, this does not take into account 2D fields + ! Here we override n_vertical_lfric to 1 in the case of 2D fields + ! n_horizontal_lfric remains correct + if (is_2d_local) n_vertical_lfric = 1 ! 1. Vertical points if ( n_vertical_lfric /= self%n_vertical_lfric ) then From 1c03fac8fd96d72deeed7971d86be32324251471 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 11:25:00 +0000 Subject: [PATCH 39/68] Fix variables in rose-stem configs --- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 2 +- rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 3d5b42ab..63d1facd 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -632,7 +632,7 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 418709a9..edff4d87 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -633,7 +633,7 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] From 9d18e2469588346a0280f9ea93a79cb8f54fad63 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 11:36:41 +0000 Subject: [PATCH 40/68] rose config-dump, removing unnecessary changes --- applications/jedi_lfric_tests/example/iodef.xml | 6 ------ .../jedi_lfric_tests/example_id_tlm_tests/iodef.xml | 8 -------- applications/jedi_lfric_tests/example_tlm_tests/iodef.xml | 8 -------- applications/linear_model/example/iodef.xml | 6 ------ rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 4 ++-- rose-stem/app/jedi_tlm_tests/rose-app.conf | 4 ++-- 6 files changed, 4 insertions(+), 32 deletions(-) diff --git a/applications/jedi_lfric_tests/example/iodef.xml b/applications/jedi_lfric_tests/example/iodef.xml index 07393ded..368ff562 100644 --- a/applications/jedi_lfric_tests/example/iodef.xml +++ b/applications/jedi_lfric_tests/example/iodef.xml @@ -50,11 +50,6 @@ - - - - - @@ -332,7 +327,6 @@ - diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml index a820d177..7d20e408 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml @@ -41,7 +41,6 @@ - @@ -56,7 +55,6 @@ - @@ -146,11 +144,6 @@ - - - - - @@ -428,7 +421,6 @@ - diff --git a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml index a820d177..7d20e408 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml @@ -41,7 +41,6 @@ - @@ -56,7 +55,6 @@ - @@ -146,11 +144,6 @@ - - - - - @@ -428,7 +421,6 @@ - diff --git a/applications/linear_model/example/iodef.xml b/applications/linear_model/example/iodef.xml index f5100492..65df40e1 100644 --- a/applications/linear_model/example/iodef.xml +++ b/applications/linear_model/example/iodef.xml @@ -52,11 +52,6 @@ - - - - - @@ -366,7 +361,6 @@ - diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 63d1facd..73a91af6 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -632,8 +632,8 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s','land_fraction' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index edff4d87..d3a271ee 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -633,8 +633,8 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s','land_fraction' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. From 4b8b73d6efe94549c0e1a1431d5765810ed68f41 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 11:44:34 +0000 Subject: [PATCH 41/68] Deleted duplicate file --- .../atl_si_timestep_alg_mod.x90.bak | 902 ------------------ 1 file changed, 902 deletions(-) delete mode 100644 science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak deleted file mode 100644 index 94024961..00000000 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90.bak +++ /dev/null @@ -1,902 +0,0 @@ -!----------------------------------------------------------------------------- -! (C) Crown copyright 2025 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 Adjoint of tl_si_timestep_alg_mod - -module atl_si_timestep_alg_mod - - use atl_moist_dyn_factors_alg_mod, only: atl_moist_dyn_factors_alg - use constants_mod, only: i_def, r_def, l_def, str_def - use log_mod, only: log_event, log_scratch_space, & - LOG_LEVEL_INFO, LOG_LEVEL_ERROR - use driver_modeldb_mod, only: modeldb_type - use namelist_mod, only: namelist_type - use reference_element_mod, only: T - use formulation_config_mod, only: dlayer_on, exner_from_eos, si_momentum_equation, & - moisture_formulation, moisture_formulation_dry, & - use_physics, use_wavedynamics - use io_config_mod, only: subroutine_timers - use mixed_solver_config_mod, only: guess_np1, reference_reset_time - use timestepping_config_mod, only: alpha, spinup_alpha, & - outer_iterations, inner_iterations - use linear_config_mod, only: fixed_ls, & - l_stabilise_bl, & - n_bl_levels_to_stabilise, & - max_bl_stabilisation, & - l_boundary_layer - use derived_config_mod, only: bundle_size - use boundaries_config_mod, only: limited_area - use sci_fem_constants_mod, only: get_mass_matrix_fe, get_qr_fe - use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, & - set_bundle_scalar, add_bundle, & - bundle_axpy, bundle_ax, bundle_is_zero - use fs_continuity_mod, only: Wtheta, W2 - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg - use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type - use adj_dg_inc_matrix_vector_kernel_mod, only: adj_dg_inc_matrix_vector_kernel_type - use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type - use adj_stabilise_bl_u_kernel_mod, only: adj_stabilise_bl_u_kernel_type - use field_mod, only: field_type - use mesh_collection_mod, only: mesh_collection - use mesh_mod, only: mesh_type - use quadrature_xyoz_mod, only: quadrature_xyoz_type - use operator_mod, only: operator_type - use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg - use rhs_alg_mod, only: rhs_alg - use atl_rhs_alg_mod, only: atl_rhs_alg - use gungho_transport_control_alg_mod, only: gungho_transport_control_alg - use atl_transport_control_alg_mod, only: atl_transport_control_alg - use si_operators_alg_mod, only: compute_si_operators - use semi_implicit_solver_alg_mod, only: semi_implicit_solver_alg_step - use adj_semi_implicit_solver_alg_mod, only: adj_semi_implicit_solver_type - use derive_exner_from_eos_alg_mod, only: derive_exner_from_eos - use atl_derive_exner_from_eos_alg_mod, only: atl_derive_exner_from_eos - use update_prognostic_scalars_alg_mod, only: update_prognostic_scalars_alg - use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg - use mr_indices_mod, only: nummr - use moist_dyn_mod, only: num_moist_factors, gas_law - use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use mixing_config_mod, only: smagorinsky - use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use sci_geometric_constants_mod, only: get_da_at_w2 - use timer_mod, only: timer - use transport_enumerated_types_mod, only: direction_3d, direction_h, direction_v - - implicit none - - private - - type, public :: atl_si_timestep_type - - private - - ! Perturbation - type(field_type), allocatable :: state(:) - type(field_type), allocatable :: state_initial(:) - type(field_type), allocatable :: state1(:) - type(field_type), allocatable :: state2(:) - type(field_type), allocatable :: state_copy(:) - type(field_type), allocatable :: state_n(:) - type(field_type), allocatable :: state_star(:) - type(field_type), allocatable :: state_after_slow(:) - type(field_type), allocatable :: advected_state(:) - type(field_type), allocatable :: mr_n(:) - type(field_type), allocatable :: mr_inc(:) - type(field_type), allocatable :: mr_after_slow(:) - type(field_type), allocatable :: rhs_n(:) - type(field_type), allocatable :: rhs_np1(:) - type(field_type), allocatable :: rhs_adv(:) - type(field_type), allocatable :: state_test(:) - type(field_type), allocatable :: rhs_np1_test(:) - type(field_type), allocatable :: rhs_np1_in(:) - type(field_type), allocatable :: rhs_phys(:) - - ! Linearisation state - type(field_type), allocatable :: ls_state(:) - type(field_type), allocatable :: ls_state_itns(:,:,:) - type(field_type), allocatable :: ls_state_n(:) - type(field_type), allocatable :: ls_state_after_slow(:) - type(field_type), allocatable :: ls_advected_state(:) - type(field_type), allocatable :: ls_mr_n(:) - type(field_type), allocatable :: ls_mr_inc(:,:,:) - type(field_type), allocatable :: ls_mr_after_slow(:) - type(field_type), allocatable :: ls_rhs_n(:) - type(field_type), allocatable :: ls_rhs_np1(:,:,:) - type(field_type), allocatable :: ls_rhs_adv(:,:,:) - type(field_type), allocatable :: ls_rhs_phys(:,:,:) - type(field_type), allocatable :: ls_mr_itns(:,:,:) - type(field_type), allocatable :: ls_moist_dyn_itns(:,:,:) - integer( i_def ) :: ls_outer_iterations, ls_inner_iterations - - ! theta_fv transport increment to change to weak form - type(field_type) :: theta_fv_inc - - ! Solver - type(adj_semi_implicit_solver_type) :: adj_semi_implicit_solver - - ! Moisture flag - logical(l_def) :: use_moisture - - contains - - procedure, public :: initialise - procedure, public :: step - procedure, public :: finalise - - end type atl_si_timestep_type - -contains - - !> @brief Initialisation procedure for the adjoint timestepping algorithm - !> @param[in,out] u Change in 3D wind field - !> @param[in,out] rho Change in Density - !> @param[in,out] theta Change in Potential temperature - !> @param[in,out] exner Change in Exner pressure - !> @param[in,out] mr Change in Mixing ratios - !> @param[in] ls_theta Lin. state for Potential temperature - !> @param[in] ls_exner Lin. state for Exner pressure - !> @param[in] ls_mr Lin. state for Mixing ratios - !> @param[in] ls_moist_dyn Lin. state for moist dynamical factors - subroutine initialise( self, u, rho, theta, exner, mr, & - ls_theta, ls_exner, ls_mr, ls_moist_dyn ) - - implicit none - - ! Arguments - class(atl_si_timestep_type), intent(inout) :: self - type(field_type), intent(inout) :: u, rho, theta, exner - type(field_type), intent(inout) :: mr(nummr) - type(field_type), intent(inout) :: ls_theta, ls_exner - type(field_type), intent(inout) :: ls_mr(nummr) - type(field_type), intent(inout) :: ls_moist_dyn(num_moist_factors) - - ! Local variables - integer(kind=i_def) :: outer, inner - - self%use_moisture = (moisture_formulation /= moisture_formulation_dry) - - ! Allocate internal state field arrays - - if (fixed_ls) then - ! The linearisation state is not evolved (a 0x0 looping) - ! but ls_outer_iterations and ls_inner_iterations are set to - ! 1 so that the arrays are defined. - self%ls_outer_iterations = 1_i_def - self%ls_inner_iterations = 1_i_def - else - ! The linearisation state is evolved, and the intermediate iterations - ! are used to calculate the evolution of the perturbation. - self%ls_outer_iterations = outer_iterations - self%ls_inner_iterations = inner_iterations - end if - - allocate(self%state(bundle_size)) - allocate(self%state_initial(bundle_size)) - allocate(self%state1(bundle_size)) - allocate(self%state2(bundle_size)) - allocate(self%state_copy(bundle_size)) - allocate(self%state_n(bundle_size)) - allocate(self%state_after_slow(bundle_size)) - allocate(self%state_star(bundle_size)) - allocate(self%advected_state(bundle_size)) - allocate(self%rhs_n(bundle_size)) - allocate(self%rhs_np1(bundle_size)) - allocate(self%rhs_adv(bundle_size)) - allocate(self%mr_n(nummr)) - allocate(self%mr_after_slow(nummr)) - allocate(self%mr_inc(nummr)) - allocate(self%state_test(bundle_size)) - allocate(self%rhs_np1_test(bundle_size)) - allocate(self%rhs_np1_in(bundle_size)) - allocate(self%rhs_phys(bundle_size)) - - allocate(self%ls_state(bundle_size)) - allocate(self%ls_state_n(bundle_size)) - allocate(self%ls_state_after_slow(bundle_size)) - allocate(self%ls_advected_state(bundle_size)) - allocate(self%ls_rhs_n(bundle_size)) - allocate(self%ls_mr_n(nummr)) - allocate(self%ls_mr_after_slow(nummr)) - - allocate(self%ls_state_itns( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_rhs_np1( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_rhs_adv( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_rhs_phys( bundle_size, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_mr_inc( nummr, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_mr_itns( nummr, self%ls_outer_iterations, self%ls_inner_iterations )) - allocate(self%ls_moist_dyn_itns( num_moist_factors, self%ls_outer_iterations, self%ls_inner_iterations )) - - ! Initialise internal state field objects - - call u%copy_field_properties(self%state(igh_u)) - call theta%copy_field_properties(self%state(igh_t)) - call rho%copy_field_properties(self%state(igh_d)) - call exner%copy_field_properties(self%state(igh_p)) - - call invoke( setval_X( self%state(igh_u), u ), & - setval_X( self%state(igh_t), theta ), & - setval_X( self%state(igh_d), rho ), & - setval_X( self%state(igh_p), exner ) ) - - call clone_bundle( self%state, self%state_n, bundle_size ) - call clone_bundle( self%state, self%state_initial, bundle_size ) - call clone_bundle( self%state, self%state1, bundle_size ) - call clone_bundle( self%state, self%state2, bundle_size ) - call clone_bundle( self%state, self%state_copy, bundle_size ) - call clone_bundle( self%state, self%state_after_slow, bundle_size ) - call clone_bundle( self%state, self%advected_state, bundle_size ) - call clone_bundle( self%state, self%rhs_n, bundle_size ) - call clone_bundle( self%state, self%rhs_np1, bundle_size ) - call clone_bundle( self%state, self%rhs_adv, bundle_size ) - call clone_bundle( self%state, self%state_test, bundle_size ) - call clone_bundle( self%state, self%rhs_np1_test, bundle_size ) - call clone_bundle( self%state, self%rhs_np1_in, bundle_size ) - call clone_bundle( self%state, self%rhs_phys, bundle_size ) - - call clone_bundle( self%state, self%ls_state, bundle_size ) - call clone_bundle( self%state, self%ls_state_n, bundle_size ) - call clone_bundle( self%state, self%ls_state_after_slow, bundle_size ) - call clone_bundle( self%state, self%ls_advected_state, bundle_size ) - call clone_bundle( self%state, self%ls_rhs_n, bundle_size ) - - do outer = 1, self%ls_outer_iterations - do inner = 1, self%ls_inner_iterations - call clone_bundle( self%state, self%ls_state_itns(:,outer,inner), bundle_size ) - call clone_bundle( self%state, self%ls_rhs_np1(:,outer,inner), bundle_size ) - call clone_bundle( self%state, self%ls_rhs_adv(:,outer,inner), bundle_size ) - call clone_bundle( self%state, self%ls_rhs_phys(:,outer,inner), bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%ls_rhs_phys(:,outer,inner), bundle_size ) - end do - end do - - call ls_theta%copy_field_properties(self%theta_fv_inc) - - call clone_bundle( mr, self%mr_n, nummr ) - call clone_bundle( mr, self%mr_after_slow, nummr ) - - if (self%use_moisture) then - call clone_bundle( mr, self%mr_inc, nummr ) - else - call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) - call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) - end if - - call clone_bundle( ls_mr, self%ls_mr_n, nummr ) - call clone_bundle( ls_mr, self%ls_mr_after_slow, nummr ) - - do outer = 1, self%ls_outer_iterations - do inner = 1, self%ls_inner_iterations - call clone_bundle( ls_moist_dyn, self%ls_moist_dyn_itns(:,outer,inner), num_moist_factors ) - call clone_bundle( ls_mr, self%ls_mr_itns(:,outer,inner), nummr ) - if (self%use_moisture) call clone_bundle( ls_mr, self%ls_mr_inc(:,outer,inner), nummr ) - end do - end do - - if (.not. self%use_moisture) then - call set_bundle_scalar( 0.0_r_def, self%ls_mr_n, nummr ) - call set_bundle_scalar( 0.0_r_def, self%ls_mr_after_slow, nummr ) - end if - - call self%adj_semi_implicit_solver%initialise(self%state) - - call log_event( "atl_si_timestep_type%init: initialised timestepping algorithm", LOG_LEVEL_INFO ) - - end subroutine initialise - - !> @brief The adjoint for the timestepping of the 3D nonlinear equations - !> @param[in,out] modeldb Structure containing the model state - !> @param[in,out] u 3D wind field - !> @param[in,out] rho Density - !> @param[in,out] theta Potential temperature - !> @param[in,out] exner Exner pressure - !> @param[in,out] mr Mixing ratios - !> @param[in,out] moist_dyn Factors for moist dynamics - !> @param[in] ls_u 3D wind field - !> @param[in] ls_rho Density - !> @param[in] ls_theta Potential temperature - !> @param[in] ls_exner Exner pressure - !> @param[in] ls_mr Mixing ratios - !> @param[in] ls_moist_dyn Factors for moist dynamics - subroutine step( self, modeldb, u, rho, theta, exner, mr, moist_dyn, & - ls_u, ls_rho, ls_theta, ls_exner, ls_mr, ls_moist_dyn ) - - implicit none - - ! Arguments - class(atl_si_timestep_type), intent(inout) :: self - type(modeldb_type), target, intent(inout) :: modeldb - type(field_type), intent(inout) :: u, rho, theta, exner - type(field_type), intent(inout) :: mr(nummr) - type(field_type), intent(inout) :: moist_dyn(num_moist_factors) - type(field_type), intent(in) :: ls_u, ls_rho, ls_theta, ls_exner - type(field_type), intent(in) :: ls_mr(nummr) - type(field_type), intent(in) :: ls_moist_dyn(num_moist_factors) - - ! Local variables - real(kind=r_def) :: cast_dt - type(quadrature_xyoz_type), pointer :: qr - type(operator_type), pointer :: mm_wt - type(operator_type), pointer :: mm_vel - integer(kind=i_def) :: outer, inner, reference_reset_freq - integer(kind=i_def) :: ls_outer, ls_inner - integer(kind=i_def) :: next_outer, next_inner - real(kind=r_def) :: varalpha, varbeta - type(namelist_type), pointer :: mixed_solver_nml - type(namelist_type), pointer :: base_mesh_nml - real(kind=r_def) :: mixed_solver_a_tol - type(field_type) :: rhs_n_igh_u - type(field_type) :: advected_u - type(mesh_type), pointer :: mesh - character(len=str_def) :: prime_mesh_name - - ! Local variables for boundary layer - type( field_type ) :: u_bl_inc - type( field_type ) :: u_bl_inc_flux - type( field_type ) :: du - type( field_type ) :: u_star - type( field_type ) :: u_star_physical - type( field_type ) :: rhsu_np1 - type( field_type ), pointer :: dA => null() - - if (subroutine_timers) call timer('atl_si_timestep_type::step') - - cast_dt = real( modeldb%clock%get_seconds_per_step(), r_def ) - - qr => get_qr_fe() - - ! Get mesh - base_mesh_nml => modeldb%configuration%get_namelist('base_mesh') - call base_mesh_nml%get_value( 'prime_mesh_name', prime_mesh_name ) - mesh => mesh_collection%get_mesh(prime_mesh_name) - - mm_wt => get_mass_matrix_fe( Wtheta, mesh%get_id() ) - mm_vel => get_mass_matrix_fe( W2, mesh%get_id() ) - - ! If off-centring is being spun up then modify the alpha value - if (spinup_alpha .and. modeldb%clock%is_spinning_up()) then - varalpha = 1.0_r_def - else - varalpha = alpha - end if - varbeta = 1.0_r_def - varalpha - - ! Copy prognostic field data to state arrays - call invoke( name="copy_init_fields_to_state", & - setval_X( self%state(igh_u), u ), & - setval_X( self%state(igh_t), theta ), & - setval_X( self%state(igh_d), rho ), & - setval_X( self%state(igh_p), exner ) ) - - !--------------------------------------------------------------------------- - ! Linearisation state - !--------------------------------------------------------------------------- - - ! Copy ls data to self%ls_state arrays - call invoke( name="copy_lin_fields_to_ls_state", & - setval_X( self%ls_state(igh_u), ls_u ), & - setval_X( self%ls_state(igh_t), ls_theta ), & - setval_X( self%ls_state(igh_d), ls_rho ), & - setval_X( self%ls_state(igh_p), ls_exner ) ) - - ! Update state_n and mr_n with start of timestep values - call copy_bundle( ls_mr, self%ls_mr_itns(:,1,1), nummr ) - call copy_bundle( ls_moist_dyn, self%ls_moist_dyn_itns(:,1,1), num_moist_factors ) - if (self%use_moisture) then - call copy_bundle( ls_mr, self%ls_mr_n(:), nummr ) - call copy_bundle( ls_mr, self%ls_mr_after_slow(:), nummr ) - call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,1,1), self%ls_mr_n(:) ) - end if - call copy_bundle( self%ls_state, self%ls_state_itns(:,1,1), bundle_size ) - call copy_bundle( self%ls_state, self%ls_state_n(:), bundle_size ) - call copy_bundle( self%ls_state, self%ls_state_after_slow(:), bundle_size ) - - ! Compute the semi-implicit operators - - ! Reset the reference state in the semi-implicit operators using the latest state guess. - ! This occurs every n timesteps, where n is calculated as reference_reset_time divided by dt. - ! The reference_reset_time is specified in the configuration namelist. - ! Note that this reset can only occur at most once per timestep. - reference_reset_freq = nint( reference_reset_time / cast_dt, i_def ) - if (mod( modeldb%clock%get_step() - 1_i_def, reference_reset_freq ) == 0_i_def) & - call compute_si_operators( self%ls_state(igh_t), self%ls_state(igh_d), self%ls_state(igh_p), & - modeldb%clock, self%ls_moist_dyn_itns(:,1,1) ) - - ! Compute the time-level n dynamics terms - - call copy_bundle( self%ls_state_after_slow, self%ls_advected_state, bundle_size ) - - if ( .not. fixed_ls ) then - call rhs_alg( self%ls_rhs_n, varbeta*cast_dt, & - self%ls_state_after_slow, self%ls_state_n, self%ls_moist_dyn_itns(:,1,1), & - compute_eos=.false., compute_rhs_t_d=.true., dlayer_rhs=.false., model_clock=modeldb%clock ) - - - if (.not. si_momentum_equation) call mass_matrix_solver_alg( self%ls_advected_state(igh_u), self%ls_rhs_n(igh_u) ) - ! Predictor of the wind field (u - beta * dt * rhs) to be advected if using explicit advection - - !--------------------------------------------------------------------------- - ! Start the outer (advection) loop - !--------------------------------------------------------------------------- - ls_outer_dynamics_loop: do outer = 1, self%ls_outer_iterations - - call gungho_transport_control_alg( self%ls_rhs_adv(:,outer,1), & - self%ls_advected_state, & - self%ls_state_itns(igh_u,outer,1), & - self%ls_state_n(igh_u), & - self%ls_mr_itns(:,outer,1), & - self%ls_mr_after_slow(:), & - modeldb%clock, outer, & - cheap_update=.false. ) - - ! Convert theta increment to weak form - call invoke( setval_X( self%theta_fv_inc, self%ls_rhs_adv(igh_t,outer,1) ), & - setval_c( self%ls_rhs_adv(igh_t,outer,1), 0.0_r_def ), & - dg_inc_matrix_vector_kernel_type( self%ls_rhs_adv(igh_t,outer,1), self%theta_fv_inc, mm_wt ) ) - - if (use_wavedynamics) then - ! Use advective update to guess n + 1 level scalar fields. - if (guess_np1) then - ! Update factors for moist dynamics - if (self%use_moisture) call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,outer,1), self%ls_mr_itns(:,outer,1) ) - call update_prognostic_scalars_alg( self%ls_state_itns(:,outer,1), & - self%ls_rhs_n, & - self%ls_rhs_adv(:,outer,1), & - self%ls_rhs_phys(:,outer,1), & - self%ls_moist_dyn_itns(gas_law,outer,1) ) - end if - - !----------------------------------------------------------------------- - ! Start the inner (nonlinear, Coriolis) loop - !----------------------------------------------------------------------- - ls_inner_dynamics_loop: do inner = 1,self%ls_inner_iterations - - ! Calculate the counters for the next iteration - if (inner == inner_iterations) then - next_inner = 1 - next_outer = outer + 1 - else - next_inner = inner + 1 - next_outer = outer - end if - - ! Only intermediate iterations are required for the adjoint and not - ! the final iteration so the final loop of the nonlinear isn't required - if (next_outer <= outer_iterations .and. next_inner <= inner_iterations) then - - ! Compute the time-level n + 1 dynamics terms - call rhs_alg( self%ls_rhs_np1(:,outer,inner), & - -varalpha*cast_dt, & - self%ls_state_itns(:,outer,inner), & - self%ls_state_itns(:,outer,inner), & - self%ls_moist_dyn_itns(:,outer,inner), & - compute_eos=.true., & - compute_rhs_t_d=.true., & - dlayer_rhs=dlayer_on, & - model_clock=modeldb%clock ) - - ! Compute the LAM LBCs and RHS - if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) - - ! Compute the residuals - - ! Add on advective terms: rhs = rhs_n - rhs_np1 + rhs_adv - ! (reuse rhs_np1 for rhs) - call bundle_axpy( -1.0_r_def, & - self%ls_rhs_np1(:,outer,inner), & - self%ls_rhs_n, & - self%ls_rhs_np1(:,outer,inner), & - bundle_size ) - call add_bundle( self%ls_rhs_np1(:,outer,inner), & - self%ls_rhs_adv(:,outer,inner), & - self%ls_rhs_np1(:,outer,inner), & - bundle_size ) - - if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) - - ! Accelerators for inner loop convergence - if (inner > 1) then - call invoke( setval_c(self%ls_rhs_np1(igh_d,outer,inner), 0.0_r_def ), & - setval_c(self%ls_rhs_np1(igh_t,outer,inner), 0.0_r_def ) ) - end if - !------------------------------------------------------------------- - ! Solve semi-implicit system: A * inc = rhs, - ! and increment state by inc - !------------------------------------------------------------------- - - ! First copy the intermediate self%ls_state values to the next iteration - call copy_bundle( self%ls_state_itns(:,outer,inner), & - self%ls_state_itns(:,next_outer,next_inner), & - bundle_size ) - call copy_bundle( self%ls_rhs_np1(:,outer,inner), & - self%ls_rhs_np1(:,next_outer,next_inner), & - bundle_size ) - call copy_bundle( self%ls_rhs_adv(:,outer,inner), & - self%ls_rhs_adv(:,next_outer,next_inner), & - bundle_size ) - call copy_bundle( self%ls_moist_dyn_itns(:,outer,inner), & - self%ls_moist_dyn_itns(:,next_outer,next_inner), & - num_moist_factors ) - call copy_bundle( self%ls_mr_itns(:,outer,inner), & - self%ls_mr_itns(:,next_outer,next_inner), & - nummr ) - if (self%use_moisture) then - call copy_bundle( self%ls_mr_inc(:,outer,inner), & - self%ls_mr_inc(:,next_outer,next_inner), & - nummr ) - end if - - call semi_implicit_solver_alg_step( self%ls_state_itns(:,next_outer,next_inner), & - self%ls_rhs_np1(:,outer,inner), & - self%ls_moist_dyn_itns(gas_law, next_outer, next_inner), & - self%ls_mr_itns(:,next_outer,next_inner), & - .false., first_iteration=(inner==1) ) - ! If not already done, update factors for moist dynamics - if (.not. guess_np1 .and. self%use_moisture) then - call moist_dyn_factors_alg( self%ls_moist_dyn_itns(:,next_outer,next_inner), & - self%ls_mr_itns(:,next_outer,next_inner) ) - end if - if (exner_from_eos) then - call derive_exner_from_eos( self%ls_state_itns(:,next_outer,next_inner), & - self%ls_moist_dyn_itns(gas_law, next_outer, next_inner) ) - end if - - ! LAM overwrite and blend LBCs - if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) - - end if - - end do ls_inner_dynamics_loop - !----------------------------------------------------------------------- - ! End of inner (nonlinear, Coriolis) loop - !----------------------------------------------------------------------- - - end if ! use_wavedynamics - - end do ls_outer_dynamics_loop - !--------------------------------------------------------------------------- - ! End of outer (advection) loop - !--------------------------------------------------------------------------- - end if - - !--------------------------------------------------------------------------- - ! Perturbation - !--------------------------------------------------------------------------- - - ! All except state zeroed out (adjoint) - call set_bundle_scalar( 0.0_r_def, self%rhs_adv, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%state_n, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%advected_state, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%state_after_slow, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%state_initial, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%rhs_n, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%rhs_np1, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%rhs_phys, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) - call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) - - call self%rhs_n(igh_u)%copy_field_properties(rhs_n_igh_u) - call invoke( setval_c( rhs_n_igh_u, 0.0_r_def ), & - setval_c( self%state(igh_p), 0.0_r_def ), & - setval_c( self%state(igh_d), 0.0_r_def ), & - setval_c( self%state(igh_t), 0.0_r_def ), & - setval_c( self%state(igh_u), 0.0_r_def ), & - inc_X_plus_Y( self%state(igh_p), exner ), & - inc_X_plus_Y( self%state(igh_d), rho ), & - inc_X_plus_Y( self%state(igh_t), theta ), & - inc_X_plus_Y( self%state(igh_u), u ) ) - - if (self%use_moisture) call atl_moist_dyn_factors_alg( moist_dyn, mr ) - - if (smagorinsky) call log_event( "atl_si_timestep_type%step: smagorinsky (in call to mixing_alg) not coded", LOG_LEVEL_ERROR ) - - ! Adjoint of boundary layer stabilisation - if (l_stabilise_bl) then - call invoke( setval_c( u, 0.0_r_def ), & - inc_X_plus_Y( u, self%state(igh_u) ), & - setval_c( self%state_initial(igh_u), 0.0_r_def ), & - setval_c( self%state(igh_u), 0.0_r_def ), & - adj_stabilise_bl_u_kernel_type( u, self%state_initial(igh_u), & - self%state(igh_u), & - n_bl_levels_to_stabilise, & - max_bl_stabilisation ), & - inc_X_plus_Y( self%state(igh_u), u ), & - setval_c( u, 0.0_r_def ) ) - end if - - !--------------------------------------------------------------------------- - ! Start the outer (advection) loop - !--------------------------------------------------------------------------- - outer_dynamics_loop: do outer = outer_iterations, 1, -1 - - if (fixed_ls) then - ls_outer = 1 - else - ls_outer = outer - end if - - !------------------------------------------------------------------------- - ! Start the inner (nonlinear, Coriolis) loop - !------------------------------------------------------------------------- - inner_dynamics_loop: do inner = inner_iterations, 1, -1 - - if (fixed_ls) then - ls_inner = 1 - else - ls_inner = inner - end if - - write( log_scratch_space, '(A,2I3)' ) 'atl_si_timestep_type%step: TL loop indices (o, i): ', outer, inner - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - ! LAM overwrite and blend LBCs - if (limited_area) call log_event( "atl_si_timestep_type%step: No limited area for adjoint", LOG_LEVEL_ERROR ) - - if (exner_from_eos) then - call atl_derive_exner_from_eos(self%state, & ! (p,d,t) out,in,in - moist_dyn(gas_law), & ! in - self%ls_state, & - ls_moist_dyn(gas_law)) - end if - - if (self%use_moisture) call atl_moist_dyn_factors_alg( moist_dyn, mr ) - - !----------------------------------------------------------------------- - ! Solve adjoint of semi-implicit system: A * inc = rhs - !----------------------------------------------------------------------- - - mixed_solver_nml => modeldb%configuration%get_namelist('mixed_solver') - call mixed_solver_nml%get_value( 'mixed_solver_a_tol', mixed_solver_a_tol ) - - ! If self%state is zero, there is no need to call the SI solver - if (.not. bundle_is_zero( mixed_solver_a_tol, self%state, bundle_size )) then - call self%adj_semi_implicit_solver%step( self%state, self%rhs_np1, & - moist_dyn(gas_law), mr, & - .false., first_iteration=(inner==1) ) - end if - - ! Accelerators for inner loop convergence - if (inner > 1) then - call invoke( setval_c( self%rhs_np1(igh_d), 0.0_r_def ), & - setval_c( self%rhs_np1(igh_t), 0.0_r_def ) ) - end if - - if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) - call add_bundle( self%rhs_adv, self%rhs_np1, self%rhs_adv, bundle_size ) - call add_bundle( self%rhs_n, self%rhs_np1, self%rhs_n, bundle_size ) - call bundle_ax( -1.0_r_def, self%rhs_np1, self%rhs_np1, bundle_size ) - - if (inner > 1) then - - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) - - call atl_rhs_alg( self%rhs_np1, & - -varalpha*cast_dt, & - self%state1, & - self%state2, & - moist_dyn, & - self%ls_state_itns(:,ls_outer,ls_inner), & - self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & - .true., & - dlayer_on, & - modeldb%clock ) - - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) - - end if - - end do inner_dynamics_loop - !------------------------------------------------------------------------- - ! End of inner (nonlinear, Coriolis) loop - !------------------------------------------------------------------------- - - if (l_boundary_layer) then - - call u%copy_field_properties( u_bl_inc ) - call u%copy_field_properties( u_bl_inc_flux ) - call u%copy_field_properties( du ) - call u%copy_field_properties( u_star ) - call u%copy_field_properties( u_star_physical ) - call self%rhs_adv(igh_u)%copy_field_properties(rhsu_np1 ) - - call du%initialise( self%rhs_adv(igh_u)%get_function_space() ) - call rhsu_np1%initialise( self%rhs_adv(igh_u)%get_function_space() ) - - call clone_bundle(self%state,self%state_star, bundle_size) - call copy_bundle(self%state, self%state_star, bundle_size) ! Only state_star(igh_u) is used - call set_bundle_scalar(0.0_r_def,self%state_star, bundle_size) - - dA => get_da_at_w2(mesh%get_id()) - - call invoke( setval_c(u_bl_inc_flux, 0.0_r_def), & - setval_c(u_bl_inc, 0.0_r_def), & - setval_c(u_star, 0.0_r_def), & - setval_c(u_star_physical, 0.0_r_def), & - setval_c(du, 0.0_r_def), & - setval_c(rhsu_np1, 0.0_r_def) ) - - call invoke( enforce_bc_kernel_type(self%rhs_phys(igh_u)), & - adj_matrix_vector_kernel_type(self%rhs_phys(igh_u),u_bl_inc_flux, mm_vel ) ) - - call set_bundle_scalar(0.0_r_def,self%rhs_phys, bundle_size) - - ! Adj of u_bl_inc_flux = u_bl_inc * dA - call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & - inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & - setval_c(u_bl_inc_flux, 0.0_r_def) ) - - call atl_bdy_lyr_alg(modeldb, u_bl_inc, self%state_star, & - self%ls_state_itns(:,ls_outer,1), cast_dt ) - - ! Adj of state_star(igh_u) <- u_star_physical - call invoke( inc_x_plus_y(u_star_physical , self%state_star(igh_u) ), & - setval_c( self%state_star(igh_u), 0.0_r_def) ) - - ! Adj of u_star_physical = u_star / dA - call invoke( inc_x_divideby_y( u_star_physical, dA ), & - inc_x_plus_y( u_star, u_star_physical ), & - setval_c(u_star_physical, 0.0_r_def) ) - - ! Adj of u_star = du + state(igh_u) - call invoke( inc_X_plus_Y( du, u_star ), & - inc_X_plus_Y( self%state(igh_u), u_star ), & - setval_c(u_star, 0.0_r_def) ) - - ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) - call mass_matrix_solver_alg( rhsu_np1, du) - - ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) - call invoke( inc_X_plus_Y( self%rhs_adv(igh_u),rhsu_np1) ) - - ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) - call invoke( inc_X_plus_bY(self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1), & - inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & - setval_c( rhsu_np1, 0.0_r_def) ) - - ! Adj of du <- 0 - call invoke( setval_c(du, 0.0_r_def)) - - end if ! l_boundary_layer - - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) - - call atl_rhs_alg( self%rhs_np1, & - -varalpha*cast_dt, & - self%state1, & - self%state2, & - moist_dyn, & - self%ls_state_itns(:,ls_outer,1), & - self%ls_moist_dyn_itns(:,ls_outer,1), & - .true., & - dlayer_on, & - modeldb%clock ) - - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) - - call invoke( setval_c( self%theta_fv_inc, 0.0_r_def ), & - adj_dg_inc_matrix_vector_kernel_type( self%rhs_adv(igh_t), & - self%theta_fv_inc, mm_wt ), & - setval_X( self%rhs_adv(igh_t), self%theta_fv_inc ) ) - - call atl_transport_control_alg( self%rhs_adv, & - self%advected_state, & ! rhs_adv is INOUT, - self%state(igh_u), & - self%state_n(igh_u), & ! advected_state, state(igh_u), state_n(igh_u) are OUT - mr, & - self%mr_after_slow, & - self%ls_advected_state, & - self%ls_state_itns(igh_u,ls_outer,1), & - self%ls_state_n(igh_u), & - self%ls_mr_after_slow, & - modeldb%clock, & - outer ) ! advected_state finished with - - end do outer_dynamics_loop - !--------------------------------------------------------------------------- - ! End of outer (advection) loop - !--------------------------------------------------------------------------- - - call advected_u%initialise(vector_space=self%rhs_n(igh_u)%get_function_space()) - - if (.not. si_momentum_equation) then - call invoke(enforce_bc_kernel_type(self%advected_state(igh_u))) ! bc enforcement - call mass_matrix_solver_alg( rhs_n_igh_u, self%advected_state(igh_u) ) - call invoke(inc_x_plus_y( self%rhs_n(igh_u), rhs_n_igh_u )) - call invoke(setval_c( self%advected_state(igh_u), 0.0_r_def )) - else - call log_event( "atl_si_timestep_type%step: si_momentum_equation not coded", LOG_LEVEL_ERROR ) - endif - - call add_bundle( self%state_after_slow, self%advected_state, self%state_after_slow, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%advected_state, bundle_size ) - - call atl_rhs_alg( self%rhs_n, varbeta * cast_dt, self%state_after_slow, & - self%state_n, moist_dyn, self%ls_state_n, & - self%ls_moist_dyn_itns(:, 1,1), .false., .false., modeldb%clock ) - - call copy_bundle( self%state, self%state_copy, bundle_size ) - call add_bundle( self%state_copy, self%state_after_slow, self%state, bundle_size ) - call set_bundle_scalar (0.0_r_def, self%state_after_slow, bundle_size ) - - call copy_bundle( self%state, self%state_copy, bundle_size ) - call add_bundle( self%state_copy, self%state_n, self%state, bundle_size ) - call set_bundle_scalar( 0.0_r_def, self%state_n, bundle_size ) - - if (l_stabilise_bl) then - call copy_bundle( self%state, self%state_copy, bundle_size ) - call add_bundle( self%state_copy, self%state_initial, self%state, bundle_size ) - call set_bundle_scalar (0.0_r_def, self%state_initial, bundle_size ) - end if - - if (self%use_moisture) then - call atl_moist_dyn_factors_alg( moist_dyn, self%mr_n ) - call add_bundle( mr, self%mr_after_slow, mr, nummr ) - call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) - call add_bundle( mr, self%mr_n, mr, nummr ) - call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) - end if - - call invoke( setval_X( u, self%state(igh_u) ), & - setval_X( theta, self%state(igh_t) ), & - setval_X( rho, self%state(igh_d) ), & - setval_X( exner, self%state(igh_p) ) ) - - if (subroutine_timers) call timer('atl_si_timestep_type::step') - - end subroutine step - - !> @brief Release all claimed resources once completed - subroutine finalise(self) - - implicit none - - ! Arguments - class(atl_si_timestep_type), intent(inout) :: self - - call self%adj_semi_implicit_solver%finalise() - - if (allocated(self%state)) deallocate(self%state) - if (allocated(self%state1)) deallocate(self%state1) - if (allocated(self%state2)) deallocate(self%state2) - if (allocated(self%state_copy)) deallocate(self%state_copy) - if (allocated(self%state_n)) deallocate(self%state_n) - if (allocated(self%state_initial)) deallocate(self%state_initial) - if (allocated(self%state_after_slow)) deallocate(self%state_after_slow) - if (allocated(self%state_star)) deallocate(self%state_star) - if (allocated(self%advected_state)) deallocate(self%advected_state) - if (allocated(self%rhs_n)) deallocate(self%rhs_n) - if (allocated(self%rhs_np1)) deallocate(self%rhs_np1) - if (allocated(self%rhs_adv)) deallocate(self%rhs_adv) - if (allocated(self%mr_n)) deallocate(self%mr_n) - if (allocated(self%mr_after_slow)) deallocate(self%mr_after_slow) - if (allocated(self%mr_inc)) deallocate(self%mr_inc) - if (allocated(self%state_test)) deallocate(self%state_test) - if (allocated(self%rhs_np1_test)) deallocate(self%rhs_np1_test) - if (allocated(self%rhs_np1_in)) deallocate(self%rhs_np1_in) - if (allocated(self%rhs_phys)) deallocate(self%rhs_phys) - - if (allocated(self%ls_state)) deallocate(self%ls_state) - if (allocated(self%ls_state_itns)) deallocate(self%ls_state_itns) - if (allocated(self%ls_state_n)) deallocate(self%ls_state_n) - if (allocated(self%ls_state_after_slow)) deallocate(self%ls_state_after_slow) - if (allocated(self%ls_advected_state)) deallocate(self%ls_advected_state) - if (allocated(self%ls_rhs_n)) deallocate(self%ls_rhs_n) - if (allocated(self%ls_rhs_np1)) deallocate(self%ls_rhs_np1) - if (allocated(self%ls_rhs_adv)) deallocate(self%ls_rhs_adv) - if (allocated(self%ls_rhs_phys)) deallocate(self%ls_rhs_phys) - if (allocated(self%ls_mr_n)) deallocate(self%ls_mr_n) - if (allocated(self%ls_mr_after_slow)) deallocate(self%ls_mr_after_slow) - if (allocated(self%ls_mr_inc)) deallocate(self%ls_mr_inc) - if (allocated(self%ls_mr_itns)) deallocate(self%ls_mr_itns) - if (allocated(self%ls_moist_dyn_itns)) deallocate(self%ls_moist_dyn_itns) - - return - - end subroutine finalise - -end module atl_si_timestep_alg_mod From ba7904a0e1b80fe727da7bf057cd8cbfb902941c Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 12:00:09 +0000 Subject: [PATCH 42/68] Accidentally put land_fraction in increment rather than state variables --- rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index 121ddfeb..841ee628 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -599,7 +599,7 @@ io_time_step='P0DT1H0M0S' inc_time='2018-04-14 21:00:00' initialise_via_read=.true. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', - ='m_cl','m_r','m_s','land_fraction' + ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] forecast_length='P0DT6H0M0S' @@ -618,8 +618,8 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2018-04-14 21:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', + ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. From 0539f5b13526b64b33529597f8446b35e050f029 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 12:06:36 +0000 Subject: [PATCH 43/68] rose config-dump --- rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index 841ee628..777bc1c0 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -618,8 +618,8 @@ time_step='P0DT1H0M0S' [namelist:jedi_state] state_time='2018-04-14 21:00:00' use_pseudo_model=.true. -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s','land_fraction' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. From beeb3d5d6f45a74eabc0bcce676bbb3d677091e5 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 13:35:16 +0000 Subject: [PATCH 44/68] upgrade macro --- .../linear/rose-meta/lfric-linear/versions.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/science/linear/rose-meta/lfric-linear/versions.py b/science/linear/rose-meta/lfric-linear/versions.py index 152c043d..bad20f0e 100644 --- a/science/linear/rose-meta/lfric-linear/versions.py +++ b/science/linear/rose-meta/lfric-linear/versions.py @@ -31,3 +31,23 @@ def upgrade(self, config, meta_config=None): # Add settings return config, self.reports """ + + +class vn30_t129(MacroUpgrade): + # Upgrade macro for #129 by Tom Hill + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t129" + + def upgrade(self, config, meta_config=None): + """Add linear boundary layer physics scheme""" + self.add_setting(config, ["namelist:linear", "Blevs_m"], "15") + self.add_setting(config, ["namelist:linear", "e_folding_levs_m"], "10") + self.add_setting(config, ["namelist:linear", "l_0_m"], "80.0") + self.add_setting(config, ["namelist:linear", "l_boundary_layer"], ".true.") + self.add_setting(config, ["namelist:linear", "log_layer"], "2") + self.add_setting(config, ["namelist:linear", "u_land_m"], "0.4") + self.add_setting(config, ["namelist:linear", "u_sea_m"], "0.4") + self.add_setting(config, ["namelist:linear", "z_land_m"], "0.05") + self.add_setting(config, ["namelist:linear", "z_sea_m"], "0.0005") + return config, self.reports From 905c760b1516316da130a354801f5cc47ee38dd8 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Mon, 26 Jan 2026 14:06:52 +0000 Subject: [PATCH 45/68] upgrade macro --- .../rose-meta/jedi_common/versions.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py index 152c043d..bb31749b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py @@ -31,3 +31,14 @@ def upgrade(self, config, meta_config=None): # Add settings return config, self.reports """ + + +class vn30_t132(MacroUpgrade): + # Upgrade macro for #132 by Tom Hill + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + self.add_setting(config, ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], "1.0e-4") + return config, self.reports From 1000322f11ecc28885168bf66d42d0e4d5729554 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 27 Jan 2026 13:13:46 +0000 Subject: [PATCH 46/68] Reverted erroneous change --- applications/adjoint_tests/example/configuration.nml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 812a000e..c3ff431f 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -66,7 +66,7 @@ stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_adjoint_tests_to_linear_model-2/run1/share/data/restart_adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64_tstep', +checkpoint_stem_name='', diag_stem_name='diagGungho', ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', ls_filename='final_ls', From c01e1854616fb2a308191f93c1be705b321b82ec Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 27 Jan 2026 15:37:40 +0000 Subject: [PATCH 47/68] Responding to CR --- applications/adjoint_tests/example/iodef.xml | 9 --------- rose-stem/app/adjoint_tests/file/iodef.xml | 9 --------- rose-stem/app/adjoint_tests/rose-app.conf | 2 +- .../solver/adj_semi_implicit_solver_alg_mod.x90 | 12 ++++++------ 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/applications/adjoint_tests/example/iodef.xml b/applications/adjoint_tests/example/iodef.xml index 8591084d..a87414c9 100644 --- a/applications/adjoint_tests/example/iodef.xml +++ b/applications/adjoint_tests/example/iodef.xml @@ -108,13 +108,6 @@ - - - - - - - @@ -322,8 +315,6 @@ - - diff --git a/rose-stem/app/adjoint_tests/file/iodef.xml b/rose-stem/app/adjoint_tests/file/iodef.xml index 8591084d..a87414c9 100644 --- a/rose-stem/app/adjoint_tests/file/iodef.xml +++ b/rose-stem/app/adjoint_tests/file/iodef.xml @@ -108,13 +108,6 @@ - - - - - - - @@ -322,8 +315,6 @@ - - diff --git a/rose-stem/app/adjoint_tests/rose-app.conf b/rose-stem/app/adjoint_tests/rose-app.conf index 881bff89..f56126cf 100644 --- a/rose-stem/app/adjoint_tests/rose-app.conf +++ b/rose-stem/app/adjoint_tests/rose-app.conf @@ -322,7 +322,7 @@ stretching_method='smooth' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' -checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' +checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' diag_stem_name='diagGungho' diff --git a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 index ba8f3844..6388bc88 100644 --- a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 @@ -88,9 +88,9 @@ contains !> @brief Create adjoint operator and preconditioner for (Helmholtz) pressure problem !> @details Called by init method of this module, but also by !! adjt_mixed_schur_preconditioner_alg_mod and adjt_mixed_solver_alg_mod - !> @param[in] state Prognostic state for the adjoint pressure preconditioner - !> @param[out] pressure_operator_out Output (Helmholtz) pressure operator - !> @param[out] pressure_preconditioner_out Output (Helmholtz) pressure preconditioner + !> @param[in] state Prognostic state for the adjoint pressure preconditioner + !> @param[out] adj_pressure_operator_out Output adjoint (Helmholtz) pressure operator + !> @param[out] adj_pressure_preconditioner_out Output adjoint (Helmholtz) pressure preconditioner subroutine create_adj_pressure_preconditioner( state, adj_pressure_operator_out, adj_pressure_preconditioner_out ) use helmholtz_solver_config_mod, only: helmholtz_preconditioner => preconditioner, & @@ -108,7 +108,7 @@ contains class(abstract_preconditioner_type), allocatable, intent(out) :: adj_pressure_preconditioner_out ! Vertical pressure preconditioner - type(adj_pressure_preconditioner_type) :: adj_Hz_preconditioner + type(adj_pressure_preconditioner_type) :: adj_helmholtz_preconditioner adj_pressure_operator_out = adj_pressure_operator_type(level=1_i_def) @@ -123,11 +123,11 @@ contains allocate( adj_pressure_preconditioner_out, & source = adj_pressure_preconditioner_type(level=1_i_def) ) case(PRECONDITIONER_MULTIGRID) - adj_Hz_preconditioner = adj_pressure_preconditioner_type(level=1_i_def) + adj_helmholtz_preconditioner = adj_pressure_preconditioner_type(level=1_i_def) allocate( adj_pressure_preconditioner_out, & source = multigrid_preconditioner_type( state(igh_p)%get_function_space(), & adj_pressure_operator_out, & - adj_Hz_preconditioner ) ) + adj_helmholtz_preconditioner ) ) case default call log_event( "Invalid pressure preconditioner specified for adjoint", LOG_LEVEL_ERROR ) end select From 258c38637fbcff301d79062277598d8cdf030d7b Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 27 Jan 2026 16:24:49 +0000 Subject: [PATCH 48/68] Responding to SR --- .../opt/rose-app-nwp_gal9_c12.conf | 6 ------ rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 14 +++++++------- .../jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf | 6 ------ rose-stem/app/jedi_tlm_tests/rose-app.conf | 14 +++++++------- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf index 958b917d..ccd55de3 100644 --- a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -2,12 +2,6 @@ mode=auto source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml -[namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -start_dump_filename='final_pert' - [namelist:io] diagnostic_frequency=8 diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 570a628e..478d6931 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -329,10 +329,10 @@ stretching_method='smooth' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' -checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' +checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -diag_stem_name='diagGungho' +diag_stem_name='' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -383,8 +383,8 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' -ls_filename='final_2021060200-2021060207' +!!ls_directory='' +!!ls_filename='' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' @@ -399,8 +399,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' -start_dump_filename='final_2021060200-2021060207.pert' +start_dump_directory='' +start_dump_filename='' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -566,7 +566,7 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='fd_start_dump' +init_option='analytic' lbc_option='none' ls_option='file' model_eos_height=100 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf index 958b917d..ccd55de3 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -2,12 +2,6 @@ mode=auto source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml -[namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -start_dump_filename='final_pert' - [namelist:io] diagnostic_frequency=8 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 0b962228..1b704701 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -329,10 +329,10 @@ stretching_method='smooth' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' -checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' +checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -diag_stem_name='diagGungho' +diag_stem_name='' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -383,8 +383,8 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' -ls_filename='final_2021060200-2021060207' +!!ls_directory='' +!!ls_filename='' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' @@ -399,8 +399,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' -start_dump_filename='final_2021060200-2021060207.pert' +start_dump_directory='' +start_dump_filename='' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -566,7 +566,7 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='fd_start_dump' +init_option='analytic' lbc_option='none' ls_option='file' model_eos_height=100 From f99c5856d643c65f346523bc25c1eb9a3c84f500 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Tue, 27 Jan 2026 17:13:55 +0000 Subject: [PATCH 49/68] Corrected merge --- applications/adjoint_tests/source/adjoint_tests.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/applications/adjoint_tests/source/adjoint_tests.f90 b/applications/adjoint_tests/source/adjoint_tests.f90 index 28baf554..b24cf880 100644 --- a/applications/adjoint_tests/source/adjoint_tests.f90 +++ b/applications/adjoint_tests/source/adjoint_tests.f90 @@ -15,7 +15,6 @@ program adjoint_tests use driver_comm_mod, only : init_comm, final_comm use driver_config_mod, only : init_config, final_config use driver_log_mod, only : init_logger, final_logger - use driver_timer_mod, only : init_timers, final_timers use driver_time_mod, only : init_time, final_time use gungho_mod, only : gungho_required_namelists use driver_modeldb_mod, only : modeldb_type @@ -93,7 +92,6 @@ program adjoint_tests call final_collections() call final_timing( application_name ) call final_logger( application_name ) - call final_timers( application_name ) call final_config() call final_comm( modeldb ) From d01551cbf5a54c86100fd63a7e6a2360452fe128 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 09:20:32 +0000 Subject: [PATCH 50/68] Responding to SR --- .../example_id_tlm_tests/configuration.nml | 20 +- .../example_tlm_tests/configuration.nml | 18 +- .../configuration_dry_relaxed.nml | 398 ------------------ .../opt/rose-app-default.conf | 0 rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 2 +- .../jedi_tlm_tests/opt/rose-app-default.conf | 0 rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- 7 files changed, 21 insertions(+), 419 deletions(-) delete mode 100644 applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml delete mode 100644 rose-stem/app/jedi_id_tlm_tests/opt/rose-app-default.conf delete mode 100644 rose-stem/app/jedi_tlm_tests/opt/rose-app-default.conf diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml index 16e0fbb7..e2b6ea8b 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml @@ -101,13 +101,13 @@ stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_jedi_lfric_tests_to_linear_model-jedi_lfric_tests_developer-with_core_3/run1/share/data/restart_jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit_tstep', -diag_stem_name='diagGungho', -ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -ls_filename='final_ls', +checkpoint_stem_name='', +diag_stem_name='', +ls_directory='', +ls_filename='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -start_dump_filename='final_pert', +start_dump_directory='', +start_dump_filename='', / &finite_element cellshape='quadrilateral', @@ -186,9 +186,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='fd_start_dump', +init_option='', lbc_option='none', -ls_option='file', +ls_option='', model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., @@ -274,7 +274,7 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, +reference_reset_time=1800, si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', @@ -304,7 +304,7 @@ orog_init_option='ancil', &partitioning generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=6, +panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 6e72338c..8085cc47 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -102,13 +102,13 @@ stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='/home/users/tom.hill/cylc-run/align_jedi_lfric_tests_to_linear_model-jedi_lfric_tests_developer-with_core_3/run1/share/data/restart_jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit_tstep', -diag_stem_name='diagGungho', -ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -ls_filename='final_ls', +checkpoint_stem_name='', +diag_stem_name='', +ls_directory='', +ls_filename='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -start_dump_filename='final_pert', +start_dump_directory='', +start_dump_filename='', / &finite_element cellshape='quadrilateral', @@ -187,9 +187,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='fd_start_dump', +init_option='', lbc_option='none', -ls_option='file', +ls_option='', model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., @@ -305,7 +305,7 @@ orog_init_option='ancil', &partitioning generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=6, +panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml deleted file mode 100644 index e574ef7a..00000000 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml +++ /dev/null @@ -1,398 +0,0 @@ -&jedi_lfric_tests -test_field='theta', -/ - -#### Configure JEDI-LFRIC - -&jedi_geometry -io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', -io_path_state_write='write_file', -io_setup_increment=.false., -io_time_step='P0DT1H0M0S', -/ -&jedi_state -state_time='2018-04-14 21:00:00', -use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', -/ -&jedi_increment -inc_time='2018-04-14 21:00:00', -initialise_via_read=.false., -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', -'m_cl','m_r','m_s', -/ -&jedi_linear_model -nl_time_step='P0DT1H0M0S', -/ -&jedi_pseudo_model -initial_time='2018-04-14T21:00:00', -number_of_steps=9, -time_step='P0DT1H0M0S', -/ -&jedi_lfric_settings -adjoint_test_tolerance=1.0e-4, -forecast_length='P0DT6H0M0S', -/ - -#### Configure LFRic - -&base_mesh -file_prefix='mesh_C12', -geometry='spherical', -prepartitioned=.false., -prime_mesh_name='C12', -topology='fully_periodic', -/ -&boundaries -limited_area=.false., -transport_overwrite_freq='final' -/ -&checks -limit_cfl=.false., -/ -§ion_choice -aerosol='none', -boundary_layer='none', -chemistry='none', -cloud='none', -dynamics='gungho', -external_forcing=.false., -iau=.false., -iau_surf=.false., -methane_oxidation=.false., -orographic_drag='none', -radiation='none', -spectral_gwd='none', -stochastic_physics='none', -surface='none', -/ -&damping_layer -dl_base=40000.0, -dl_str=0.05, -dl_type='standard', -/ -&departure_points -horizontal_limit='cap', -horizontal_method='ffsl', -n_dep_pt_iterations=1, -vertical_limit='exponential', -vertical_method='timeaverage', -vertical_sorting=.false., -/ -&energy_correction -encorr_usage='none', -integral_method='fd', -/ -&extrusion -domain_height=80000.0, -method='um_L70_50t_20s_80km', -number_of_layers=70, -planet_radius=6371229.0, -stretching_height=17507.0, -stretching_method='smooth', -/ -&files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', -diag_stem_name='', -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', -/ -&finite_element -cellshape='quadrilateral', -coord_order=1, -coord_system='native', -element_order_h=0, -element_order_v=0, -rehabilitate=.true., -vorticity_in_w1=.false., -/ -&formulation -dlayer_on=.true., -dry_static_adjust=.true., -eos_method='sampled', -exner_from_eos=.false., -init_exner_bt=.true., -l_multigrid=.false., -lagged_orog=.true., -moisture_formulation='dry', -moisture_in_solver=.false., -p2theta_vert=.true., -rotating=.true., -shallow=.true., -si_momentum_equation=.false., -use_multires_coupling=.false., -use_physics=.false., -use_wavedynamics=.true., -vector_invariant=.false., -/ -&helmholtz_solver -fail_on_non_converged=.false., -gcrk=8, -method='bicgstab', -monitor_convergence=.true., -normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=1.0e-8, -si_pressure_maximum_iterations=400, -si_pressure_tolerance=1.0e-4, -/ -&idealised -f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', -/ -&ideal_surface -canopy_height=19.01,16.38,0.79,1.26,1.0, -leaf_area_index=5.0,4.0,1.5,1.5,1.5, -n_snow_layers=11*0, -snow_depth=11*0.0, -snow_layer_ice_mass=27*0.0, -snow_layer_temp=27*273.0, -snow_layer_thickness=27*0.0, -soil_moisture=15.86,98.861,274.35,862.27, -soil_temperature=284.508,286.537,289.512,293.066, -surf_tile_fracs=9*0.0,1.0,0.0, -surf_tile_temps=9*295.0,300.0,265.0, -tile_snow_mass=11*0.0, -/ -&initialization -ancil_option='none', -coarse_aerosol_ancil=.false., -coarse_orography_ancil=.false., -coarse_ozone_ancil=.false., -init_option='analytic', -lbc_option='none', -ls_option='analytic', -model_eos_height=100, -n_orog_smooth=0, -read_w2h_wind=.true., -sea_ice_source='ancillary', -snow_source='start_dump', -w0_orography_mapping=.false., -zero_w2v_wind=.false., -/ -&initial_density -density_background=0.1, -density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, -y1=0.0, -y2=0.0, -z1=0.0, -z2=0.0, -/ -&initial_pressure -method='balanced', -surface_pressure=1000.0e2, -/ -&initial_temperature -bvf_square=0.0001, -pert_centre=120.0, -pert_width_scaling=1.0, -perturb='none', -theta_surf=300.0, -/ -&initial_vapour -/ -&initial_wind -nl_constant=0.0, -profile='none', -sbr_angle_lat=0.0, -sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, -v0=0.0, -wind_time_period=0.0, -/ -&io -checkpoint_read=.false., -checkpoint_write=.false., -counter_output_suffix='counter.txt', -diag_active_files='lfric_diag', -diag_always_on_sampling=.false., -diagnostic_frequency=8, -file_convention='UGRID', -nodal_output_on_w3=.false., -subroutine_counters=.false., -subroutine_timers=.true., -timer_output_path='timer.txt', -use_xios_io=.true., -write_conservation_diag=.false., -write_diag=.true., -write_dump=.false., -write_fluxes=.false., -write_minmax_tseries=.false., -/ -&linear -ls_read_w2h=.false., -pert_option='analytic', -/ -&logging -run_log_level='info', -/ -&mixed_solver -eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=6, -guess_np1=.false., -mixed_solver_a_tol=0.0, -monitor_convergence=.true., -normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=10, -si_method='block_gcr', -si_preconditioner='pressure', -si_tolerance=1.0e-5, -split_w=.true., -/ -&mixing -leonard_term=.false., -smagorinsky=.false., -viscosity=.false., -viscosity_mu=0.0, -/ -&esm_couple -l_esm_couple_test=.false., -/ -&orography -orog_init_option='ancil', -/ -&partitioning -panel_decomposition='auto', -panel_xproc=1, -panel_yproc=1, -partitioner='cubedsphere', -/ -&physics -limit_drag_incs=.false., -sample_physics_scalars=.true., -sample_physics_winds=.true., -/ -&planet -cp=1005.0, -gravity=9.80665, -omega=7.292116E-5, -p_zero=100000.0, -rd=287.05, -scaling_factor=1.0, -/ -&radiative_gases -cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', -co_rad_opt='off', -cs_rad_opt='off', -h2_rad_opt='off', -h2o_rad_opt='prognostic', -hcfc22_rad_opt='off', -hcn_rad_opt='off', -he_rad_opt='off', -hfc134a_rad_opt='off', -k_rad_opt='off', -l_cts_fcg_rates=.false., -li_rad_opt='off', -n2_rad_opt='off', -n2o_rad_opt='off', -na_rad_opt='off', -nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', -rb_rad_opt='off', -so2_rad_opt='off', -tio_rad_opt='off', -vo_rad_opt='off', -/ -&solver -fail_on_non_converged=.false., -gcrk=18, -maximum_iterations=7, -method='chebyshev', -monitor_convergence=.false., -preconditioner='diagonal', -tolerance=1.0e-6, -/ -&time -calendar='timestep', -calendar_origin='2018-04-14 21:00:00', -calendar_start='2018-04-14 21:00:00', -calendar_type='gregorian', -timestep_end='13', -timestep_start='1', -/ -×tepping -alpha=0.55, -dt=3600, -inner_iterations=2, -method='semi_implicit', -outer_iterations=2, -runge_kutta_method='forward_euler', -spinup_alpha=.false., -tau_r=1.0, -tau_t=1.0, -tau_u=0.55, -/ -&transport -adjust_theta=.false., -adjust_vhv_wind=.false. -broken_w2_projection=.false., -calculate_detj='upwind', -cap_density_predictor=0.01, -cfl_mol_1d_stab=1.0, -cfl_mol_2d_stab=1.0, -cfl_mol_3d_stab=1.0, -cheap_update=.false., -consistent_metric=.false., -dep_pt_stencil_extent=3, -dry_field_name='density', -enforce_min_value=5*.false., -equation_form=1,2,2,2,2, -extended_mesh=.false., -ffsl_inner_order=2, -ffsl_outer_order=2, -ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', -fv_horizontal_order=2, -fv_vertical_order=2, -horizontal_method=5*1, -horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', -min_val_abs_tol=-1.0e-12, -min_val_max_iterations=10, -min_val_method='iterative', -min_value=0.0,0.0,-99999999.0,0.0,0.0, -oned_reconstruction=.false., -operators='fv', -profile_size=5, -reversible=5*.false., -runge_kutta_method='ssp3', -scheme=5*1, -si_outer_transport='none', -slice_order='parabola', -splitting=5*1, -substep_transport='off', -theta_dispersion_correction=.false., -theta_variable='dry', -use_density_predictor=.false., -vertical_method=5*1, -vertical_monotone=5*1, -vertical_monotone_order=5*1, -vertical_sl_order='cubic', -/ -&validity_test -number_gamma_values=2, -update_ls_frequency=1, -/ diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-default.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-default.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 478d6931..9a341733 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -568,7 +568,7 @@ coarse_orography_ancil=.false. coarse_ozone_ancil=.false. init_option='analytic' lbc_option='none' -ls_option='file' +ls_option='analytic' model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-default.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-default.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 1b704701..c6a2462b 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -568,7 +568,7 @@ coarse_orography_ancil=.false. coarse_ozone_ancil=.false. init_option='analytic' lbc_option='none' -ls_option='file' +ls_option='analytic' model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. From d67c2b9344e23274f820bcb467f184d40b7a11c7 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 10:28:22 +0000 Subject: [PATCH 51/68] Responding to SR --- .../opt/rose-app-nwp_gal9_c12.conf | 2 +- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 2 +- rose-stem/app/jedi_lfric_tests/file/iodef.xml | 2 +- .../jedi_lfric_tests/opt/rose-app-C12_MG.conf | 8 + .../opt/rose-app-nwp_gal9.conf | 3 - .../opt/rose-app-nwp_gal9_c12.conf | 20 ++ .../opt/rose-app-runge-kutta.conf | 31 +- rose-stem/app/jedi_lfric_tests/rose-app.conf | 199 +++++++------ .../opt/rose-app-C12_MG.conf | 8 + .../opt/rose-app-default.conf | 0 .../opt/rose-app-nwp_gal9_c12.conf | 28 ++ .../opt/rose-app-rrt_equals_dt.conf | 2 + .../opt/rose-app-semi_strict_solver.conf | 9 + .../app/jedi_tlm_forecast_tl/rose-app.conf | 265 ++++++++++-------- rose-stem/app/jedi_tlm_tests/rose-app.conf | 2 +- .../tasks_jedi_lfric_tests.cylc | 19 +- .../meto/groups/groups_jedi_lfric_tests.cylc | 12 +- 17 files changed, 375 insertions(+), 237 deletions(-) create mode 100644 rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf delete mode 100644 rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf create mode 100644 rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf create mode 100644 rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf delete mode 100644 rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-default.conf create mode 100644 rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf create mode 100644 rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf create mode 100644 rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf index ccd55de3..de473661 100644 --- a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -1,6 +1,6 @@ [file:iodef_temp.xml] mode=auto -source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml +source=$ROSE_SUITE_DIR/app/jedi_id_tlm_tests/file/iodef.xml [namelist:io] diagnostic_frequency=8 diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 9a341733..197eb0c5 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -569,7 +569,7 @@ coarse_ozone_ancil=.false. init_option='analytic' lbc_option='none' ls_option='analytic' -model_eos_height=100 +!!model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. sea_ice_source='ancillary' diff --git a/rose-stem/app/jedi_lfric_tests/file/iodef.xml b/rose-stem/app/jedi_lfric_tests/file/iodef.xml index be8ae024..d9d6303a 100644 --- a/rose-stem/app/jedi_lfric_tests/file/iodef.xml +++ b/rose-stem/app/jedi_lfric_tests/file/iodef.xml @@ -302,7 +302,7 @@ - + diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 00000000..125a4758 --- /dev/null +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf deleted file mode 100644 index 90d207a8..00000000 --- a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf +++ /dev/null @@ -1,3 +0,0 @@ -[file:iodef_temp.xml] -mode=auto -source=$ROSE_SUITE_DIR/app/jedi_lfric_tests/file/iodef.xml diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 00000000..feabdeff --- /dev/null +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,20 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_lfric_tests/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +ls_filename='final_ls' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2016-01-01 15:00:00' +calendar_start='2016-01-01 15:00:00' diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf index 6c3a2714..b90cd33b 100644 --- a/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf @@ -20,7 +20,6 @@ start_dump_directory='' start_dump_filename='' [namelist:finite_element] -coord_system='xyz' vorticity_in_w1=.true. [namelist:formulation] @@ -28,12 +27,28 @@ dlayer_on=.false. dry_static_adjust=.false. eos_method='projected' exner_from_eos=.true. +l_multigrid=.false. moisture_formulation='dry' !!theta_moist_source=.false. [namelist:helmholtz_solver] -gcrk=18 -si_pressure_tolerance=1.0e-6 +preconditioner='tridiagonal' + +[namelist:idealised] +test='gravity_wave' + +[namelist:initial_density] +r1=0.0 +r2=0.0 +x1=0.0 +x2=0.0 + +[namelist:initial_temperature] +pert_centre=-60.0 + +[namelist:initial_wind] +smp_init_wind=.false. +u0=0.0 [namelist:initialization] init_option='analytic' @@ -45,6 +60,7 @@ diagnostic_frequency=20 [namelist:linear] fixed_ls=.false. +l_stabilise_bl=.false. pert_option='analytic' [namelist:mixed_solver] @@ -52,9 +68,15 @@ gcrk=6 mixed_solver_a_tol=1.0e-6 si_tolerance=1.0e-3 +[!!namelist:multigrid] +chain_mesh_tags='','','','' + [namelist:orography] orog_init_option='none' +[namelist:partitioning] +generate_inner_halos=.true. + [namelist:planet] scaling_factor=125.0 @@ -74,9 +96,6 @@ method='rk' cfl_mol_1d_stab=2.0 cfl_mol_2d_stab=2.0 cfl_mol_3d_stab=2.0 -log_space=5*.false. max_vert_cfl_calc='uniform' -reversible=.false. runge_kutta_method='ssp4' -slice_order='cubic' !!wind_mono_top_depth=0 diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index fa1aced1..5937b6ec 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -20,17 +20,22 @@ source=namelist:jedi_lfric_tests = namelist:jedi_geometry = namelist:jedi_state = namelist:jedi_increment - = namelist:jedi_pseudo_model = namelist:jedi_linear_model - = namelist:jedi_model + = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -41,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -63,26 +69,31 @@ source=namelist:jedi_lfric_tests = (namelist:jules_vegetation) = namelist:linear = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -105,17 +116,17 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 @@ -185,7 +196,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +216,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -272,7 +283,7 @@ l_cosp=.false. [namelist:damping_layer] dl_base=40000.0 dl_str=0.05 -dl_type='latitude' +dl_type='standard' [namelist:departure_points] horizontal_limit='cap' @@ -317,7 +328,7 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/Quagga/${ancil_resolution}/n96e_l70' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' @@ -372,13 +383,13 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -388,8 +399,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -start_dump_filename='final_pert' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -410,7 +421,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -440,7 +451,7 @@ gcrk=8 method='prec_only' monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' +preconditioner='multigrid' si_pressure_a_tol=1.0e-8 si_pressure_maximum_iterations=400 si_pressure_tolerance=1.0e-4 @@ -453,7 +464,7 @@ si_pressure_tolerance=1.0e-4 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +511,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +531,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +556,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -574,7 +585,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,15 +601,15 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' -io_path_inc_read='' +io_calender_start='2021-06-02T00:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' @@ -610,19 +621,19 @@ forecast_length='P0DT6H0M0S' test_field='theta' [namelist:jedi_linear_model] -incremental_wind_interpolation=.true. +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_model] time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s' @@ -656,7 +667,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -695,8 +706,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -721,7 +732,7 @@ cor_mo_iter='improved' formdrag='dist_drag' l_anthrop_heat_src=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. +l_vary_z0m_soil=.true. srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -754,8 +765,10 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.false. +l_stabilise_bl=.true. ls_read_w2h=.false. +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 pert_option='file' [namelist:logging] @@ -784,9 +797,9 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 @@ -799,7 +812,7 @@ guess_np1=.false. mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. -reference_reset_time=3600. +reference_reset_time=3600.0 si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' @@ -809,15 +822,15 @@ split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -825,9 +838,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -922,7 +943,7 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 @@ -988,12 +1009,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1007,26 +1028,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1098,8 +1119,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1116,8 +1137,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1126,7 +1147,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1207,10 +1228,10 @@ tolerance=1.0e-6 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1263,9 +1284,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1310,7 +1331,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1341,8 +1362,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2016-01-01 15:00:00' -calendar_start='2016-01-01 15:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1350,7 +1371,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf new file mode 100644 index 00000000..125a4758 --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-default.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-default.conf deleted file mode 100644 index e69de29b..00000000 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 00000000..a83200b7 --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,28 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_forecast_tl/file/iodef.xml + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 00000000..3d974564 --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf new file mode 100644 index 00000000..d9c5499f --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf @@ -0,0 +1,9 @@ +[namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-3 + +[namelist:mixed_solver] +mixed_solver_a_tol=1.0e-21 +si_tolerance=1.0e-3 + +[namelist:timestepping] +outer_iterations=1 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index 3656987f..2a0803e6 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -62,25 +69,31 @@ source=namelist:jedi_lfric_tests = (namelist:jules_vegetation) = namelist:linear = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) + = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -103,24 +116,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -183,7 +196,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -203,14 +216,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -315,7 +328,7 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${ancil_resolution}' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' @@ -376,7 +389,7 @@ diag_stem_name='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -408,7 +421,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -418,7 +431,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -432,16 +445,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -451,7 +464,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -498,15 +511,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -518,22 +531,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -543,8 +556,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -572,7 +585,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -588,16 +601,16 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' +io_calender_start='2021-06-02T00:00:00' io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' -io_setup_increment=.true. +io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' -initialise_via_read=.true. +inc_time='2021-06-02 00:00:00' +initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' @@ -608,15 +621,16 @@ forecast_length='P0DT6H0M0S' test_field='theta' [namelist:jedi_linear_model] +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', ='m_v','m_cl','m_r','m_s' @@ -650,7 +664,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -689,8 +703,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -715,7 +729,7 @@ cor_mo_iter='improved' formdrag='dist_drag' l_anthrop_heat_src=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. +l_vary_z0m_soil=.true. srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -748,9 +762,11 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.false. +l_stabilise_bl=.true. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' [namelist:logging] log_to_rank_zero_only=.false. @@ -778,40 +794,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -819,9 +835,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -916,7 +940,7 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 @@ -931,15 +955,15 @@ configure_segments=.false. !!electric_placement='slow' !!evap_condense_placement='fast' !!gw_segment=0 -!!limit_drag_incs=.false. +limit_drag_incs=.false. !!lowest_level='gradient' !!ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' @@ -982,12 +1006,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1001,26 +1025,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1092,8 +1116,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1110,8 +1134,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1120,7 +1144,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1147,10 +1171,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1158,23 +1182,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1201,10 +1225,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1257,9 +1281,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1304,7 +1328,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1335,8 +1359,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1344,7 +1368,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1358,6 +1382,7 @@ tau_u=0.55 adjust_theta=.false. !!adjust_theta_above=30000.0 adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1374,14 +1399,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1391,7 +1417,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1401,10 +1427,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index c6a2462b..a79e1ecb 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -569,7 +569,7 @@ coarse_ozone_ancil=.false. init_option='analytic' lbc_option='none' ls_option='analytic' -model_eos_height=100 +!!model_eos_height=100 n_orog_smooth=0 read_w2h_wind=.true. sea_ice_source='ancillary' diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index 8b9d6809..b13cd70f 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -5,12 +5,11 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc") %} -{% if task_ns.conf_name == "nwp_gal9-C12" %} +{% if task_ns.conf_name == "nwp_gal9-C12_MG" %} {% do task_dict.update({ - "opt_confs": ["nwp_gal9"], - "resolution": "C12", - "ancil_resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "DT": 1800, "tsteps": 12, "mpi_parts": 6, @@ -21,7 +20,7 @@ {% do task_dict.update({ "opt_confs": ["runge-kutta"], "resolution": "C12", - "ancil_resolution": "C12", + "DT": 1, "tsteps": 20, }) %} @@ -61,12 +60,12 @@ "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12" %} +{% elif task_ns.conf_name == "tlm_forecast_tl_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_forecast_tl", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", "DT": 1800, "tsteps": 13, @@ -196,10 +195,10 @@ "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12_op" %} +{% elif task_ns.conf_name == "tlm_forecast_tl_nwp_gal9-C12_op" %} {% do task_dict.update({ "app_name": "jedi_tlm_forecast_tl", - "opt_confs": ["default"], + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], "resolution": "C12_op", "ancil_resolution": "C12", "DT": 1800, diff --git a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc index ce208279..8cb86a8f 100644 --- a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc +++ b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc @@ -8,7 +8,7 @@ {# Azspice Groups #} {% do site_groups.update({ "jedi_lfric_tests_azspice_developer": [ - "jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit", "jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit", @@ -16,7 +16,7 @@ "jedi_lfric_tests_forecast_pseudo_default-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_full-debug-64bit", - "jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", @@ -31,7 +31,7 @@ "jedi_lfric_tests_azspice_integration_tests", ], "jedi_lfric_tests_op_azspice_developer": [ - "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_op_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_op_azspice_gnu_fast-debug-64bit", ], "jedi_lfric_tests_azspice": [ @@ -52,12 +52,12 @@ {# EX1A Groups #} {% do site_groups.update({ "jedi_lfric_tests_ex1a_developer": [ - "jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_default-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", @@ -72,7 +72,7 @@ "jedi_lfric_tests_ex1a_integration_tests", ], "jedi_lfric_tests_op_ex1a_developer": [ - "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_op_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_op_ex1a_cce_fast-debug-64bit", ], "jedi_lfric_tests_ex1a": [ From 6360fc2875a3b606bb37d1f655c02839e4ae0921 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 10:30:12 +0000 Subject: [PATCH 52/68] Fixings versions.py --- applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py index 811c4faa..59927796 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py @@ -49,7 +49,7 @@ def upgrade(self, config, meta_config=None): class vn30_t132(MacroUpgrade): # Upgrade macro for #132 by Tom Hill - BEFORE_TAG = "vn3.0" + BEFORE_TAG = "vn3.0_t99" AFTER_TAG = "vn3.0_t132" def upgrade(self, config, meta_config=None): From f69bc9ac27f3586b2d777a80a903e3e7c7d78098 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 11:15:05 +0000 Subject: [PATCH 53/68] Updating canned configs --- .../example/configuration.nml | 160 +++++++++++---- .../jedi_lfric_tests/example/mesh_C12.nc | Bin 85708 -> 0 bytes .../example_id_tlm_tests/configuration.nml | 9 +- .../example_tlm_forecast_tl/configuration.nml | 192 +++++++++++------- .../example_tlm_forecast_tl/mesh_C12.nc | Bin 85708 -> 0 bytes .../example_tlm_tests/configuration.nml | 7 +- 6 files changed, 241 insertions(+), 127 deletions(-) delete mode 100644 applications/jedi_lfric_tests/example/mesh_C12.nc delete mode 100644 applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc diff --git a/applications/jedi_lfric_tests/example/configuration.nml b/applications/jedi_lfric_tests/example/configuration.nml index b2d3c1ff..d7a792df 100644 --- a/applications/jedi_lfric_tests/example/configuration.nml +++ b/applications/jedi_lfric_tests/example/configuration.nml @@ -1,13 +1,48 @@ +&jedi_lfric_tests +test_field='theta', +/ +&jedi_geometry +io_calender_start='2021-06-02T00:00:00', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_state_write='write_file', +io_setup_increment=.false., +io_time_step='P0DT1H0M0S', +/ +&jedi_state +state_time='2021-06-02 00:00:00', +use_pseudo_model=.true., +variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', +'m_v','m_cl','m_r','m_s', +/ +&jedi_increment +inc_time='2021-06-02 00:00:00', +initialise_via_read=.false., +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', +'m_cl','m_r','m_s', +/ +&jedi_linear_model +incremental_wind_interpolation=.false., +nl_time_step='P0DT1H0M0S', +/ +&jedi_pseudo_model +initial_time='2021-06-02 00:00:00', +number_of_steps=9, +time_step='P0DT1H0M0S', +/ +&jedi_lfric_settings +forecast_length='P0DT6H0M0S', +/ &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -29,16 +64,25 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, -dl_type='latitude', +dl_type='standard', / &departure_points horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -56,13 +100,13 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/Quagga/C12/n96e_l70', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='restart', diag_stem_name='diagGungho', -ls_directory='/data/users/lfric/data/tangent-linear/Ticket46', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', ls_filename='final_ls', -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid', -start_dump_directory='/data/users/lfric/data/tangent-linear/Ticket3590', +orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', / &finite_element @@ -79,10 +123,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -90,7 +134,7 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., use_physics=.true., use_wavedynamics=.true., @@ -101,15 +145,27 @@ gcrk=8, method='prec_only', monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', +preconditioner='multigrid', si_pressure_a_tol=1.0e-8, si_pressure_maximum_iterations=400, si_pressure_tolerance=1.0e-4, / +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau +/ &idealised f_lon_deg=0.0, -perturb_init=.false. -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -144,10 +200,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -159,7 +215,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -168,22 +224,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -196,11 +255,15 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.true., ls_read_w2h=.false., +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, pert_option='file', / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver @@ -211,7 +274,7 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600., +reference_reset_time=3600.0, si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', @@ -224,6 +287,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -231,16 +302,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=6, +panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., limit_drag_incs=.false., sample_physics_scalars=.true., sample_physics_winds=.true., -configure_segments=.false. +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -252,10 +325,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -268,11 +345,13 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', @@ -286,6 +365,8 @@ monitor_convergence=.false., preconditioner='diagonal', tolerance=1.0e-6, / +&specified_surface +/ &time calendar='timestep', calendar_origin='2016-01-01 15:00:00', @@ -297,7 +378,7 @@ timestep_start='1', ×tepping alpha=0.55, dt=1800, -inner_iterations=2, +inner_iterations=1, method='semi_implicit', outer_iterations=2, runge_kutta_method='forward_euler', @@ -341,8 +422,8 @@ min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', @@ -360,8 +441,7 @@ vertical_method=5*1, vertical_monotone=5*1, vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example/mesh_C12.nc b/applications/jedi_lfric_tests/example/mesh_C12.nc deleted file mode 100644 index f7ea6988e22a06194aac0d17b6e3be62cd539773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85708 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 Rwf*lmDjqBQ-|O@_{yzW$Qgi?S diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml index e2b6ea8b..df08139b 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml @@ -103,8 +103,6 @@ stretching_method='smooth', ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', -ls_directory='', -ls_filename='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='', start_dump_filename='', @@ -186,10 +184,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='', +init_option='analytic', lbc_option='none', -ls_option='', -model_eos_height=100, +ls_option='analytic', n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', @@ -274,7 +271,7 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., -reference_reset_time=1800, +reference_reset_time=3600.0, si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml index f61e5aab..8f493f2a 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml @@ -1,15 +1,12 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', -io_setup_increment=.true., +io_setup_increment=.false., io_time_step='P0DT1H0M0S', / &jedi_state @@ -20,11 +17,12 @@ variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', / &jedi_increment inc_time='2018-04-14 21:00:00', -initialise_via_read=.true., +initialise_via_read=.false., variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', 'm_cl','m_r','m_s', / &jedi_linear_model +incremental_wind_interpolation=.false., nl_time_step='P0DT1H0M0S', / &jedi_pseudo_model @@ -33,21 +31,19 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-3, forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -69,6 +65,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -78,7 +83,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -96,7 +101,7 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', @@ -117,10 +122,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -128,29 +133,38 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -174,7 +188,6 @@ coarse_ozone_ancil=.false., init_option='analytic', lbc_option='none', ls_option='analytic', -model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', @@ -185,10 +198,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -200,7 +213,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -209,22 +222,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -237,26 +253,30 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.true., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, +reference_reset_time=1800, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-3, split_w=.true., / &mixing @@ -265,6 +285,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -272,15 +300,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., limit_drag_incs=.false., sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -292,10 +323,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -308,24 +343,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -337,10 +375,10 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', -outer_iterations=2, +outer_iterations=1, runge_kutta_method='forward_euler', spinup_alpha=.false., tau_r=1.0, @@ -349,10 +387,11 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -362,28 +401,29 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', @@ -393,13 +433,13 @@ splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc b/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc deleted file mode 100644 index f7ea6988e22a06194aac0d17b6e3be62cd539773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85708 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 Rwf*lmDjqBQ-|O@_{yzW$Qgi?S diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 8085cc47..8f493f2a 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -104,8 +104,6 @@ stretching_method='smooth', ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', -ls_directory='', -ls_filename='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='', start_dump_filename='', @@ -187,10 +185,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='', +init_option='analytic', lbc_option='none', -ls_option='', -model_eos_height=100, +ls_option='analytic', n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', From 5dcf6ba2cd4d22c468f92cd614a5dc224fe0303b Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 11:39:59 +0000 Subject: [PATCH 54/68] Merge upstream --- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 44462470..197eb0c5 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -602,8 +602,8 @@ write_minmax_tseries=.false. [namelist:jedi_geometry] io_calender_start='2021-06-02T00:00:00' -io_path_inc_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_lfric_diag' -io_path_state_read='/data/users/tom.hill/LFRic/jedi_tlm_tests/C224_jedi_trajectory' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' From e6a5e46429f7da897ea2635e4be382dbfbe2814f Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 11:47:55 +0000 Subject: [PATCH 55/68] Fixing versions.py --- science/linear/rose-meta/lfric-linear/versions.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/science/linear/rose-meta/lfric-linear/versions.py b/science/linear/rose-meta/lfric-linear/versions.py index 1fc52b2e..a3dde99e 100644 --- a/science/linear/rose-meta/lfric-linear/versions.py +++ b/science/linear/rose-meta/lfric-linear/versions.py @@ -46,11 +46,11 @@ def upgrade(self, config, meta_config=None): return config, self.reports -class vn30_t129(MacroUpgrade): - # Upgrade macro for #129 by Tom Hill +class vn30_t182(MacroUpgrade): + # Upgrade macro for #182 by Tom Hill - BEFORE_TAG = "vn3.0" - AFTER_TAG = "vn3.0_t129" + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t182" def upgrade(self, config, meta_config=None): """Add linear boundary layer physics scheme""" From 55e7a2ee35cee4183dfca612aa983616b2e6c1d9 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 11:56:23 +0000 Subject: [PATCH 56/68] Remove erroneous file --- .../atlt_bl_inc_alg_mod.x90.bak | 189 ------------------ 1 file changed, 189 deletions(-) delete mode 100644 applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak deleted file mode 100644 index b23dfcbe..00000000 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90.bak +++ /dev/null @@ -1,189 +0,0 @@ -!----------------------------------------------------------------------------- -! (c) Crown copyright 2026 Met Office. All rights reserved. -! The file LICENCE, distributed with this code, contains details of the terms -! under which the code may be brief. -!----------------------------------------------------------------------------- -!> @brief Module containing adjoint test for atl_bl_inc_kernel -module atlt_bl_inc_alg_mod - - use sci_assign_field_random_range_alg_mod, & - only : assign_field_random_range - use sci_geometric_constants_mod, only: get_face_selector_ew, & - get_face_selector_ns - use integer_field_mod, only: integer_field_type - use field_mod, only : field_type - use function_space_mod, only : function_space_type - use log_mod, only : log_event, & - log_scratch_space, & - LOG_LEVEL_ERROR, & - LOG_LEVEL_DEBUG, & - LOG_LEVEL_INFO - use mesh_mod, only : mesh_type - use function_space_collection_mod, only : function_space_collection - use finite_element_config_mod, only : element_order_h, element_order_v - use fs_continuity_mod, only : W2, W3, Wtheta - use constants_mod, only : i_def, r_def - use quadrature_face_mod, only : quadrature_face_type - use quadrature_rule_gaussian_mod, only : quadrature_rule_gaussian_type - use reference_element_mod, only : reference_element_type - use planet_config_mod, only : cp - use adjoint_test_parameters_mod, only : ls_theta_range, & - ls_exner_range, & - ls_md1_range, & - ls_md2_range, & - ls_md3_range - - implicit none - - public - - contains - - !============================================================================= - !> @brief Adjoint test for atl_bl_inc. - !> @details Passes if adjoint is transpose of tangent linear. - !> Determined by testing the equality of inner products and , - !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh Mesh object - subroutine atlt_bl_inc_alg( mesh ) - - use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type - use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type - - use linear_config_mod, only: log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m - - implicit none - - ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - - ! Arguments for tl and adj calls - type( field_type) :: u_inc - type( field_type) :: u - type( field_type) :: auv - type( field_type) :: buv_inv - type(integer_field_type), pointer :: face_selector_ew => null() - type(integer_field_type), pointer :: face_selector_ns => null() - - ! Copies of input fields used in inner products - type( field_type) :: u_inc_input - type( field_type) :: u_input - - ! Pointers for initialising fields - type(function_space_type), pointer :: vector_space_wtheta_ptr - type(function_space_type), pointer :: vector_space_w2_ptr - type(function_space_type), pointer :: vector_space_w3_ptr - - ! Inner products - real(kind=r_def) :: ip1(2) - real(kind=r_def) :: ip2(2) - real(kind=r_def) :: sf(2) - real(kind=r_def) :: inner1 - real(kind=r_def) :: inner2 - - ! Test parameters and variables - real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def - real(kind=r_def) :: machine_tol - real(kind=r_def) :: relative_diff - real(kind=r_def), parameter :: eps = 1e-30_r_def - - vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) - vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) - vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) - - call auv % initialise( vector_space = vector_space_w2_ptr, name = 'auv' ) - call buv_inv % initialise( vector_space = vector_space_w2_ptr, name = 'buv_inv' ) - - call u_inc % initialise( vector_space = vector_space_w2_ptr, name = 'u_inc' ) - call u % initialise( vector_space = vector_space_w2_ptr, name = 'u' ) - - face_selector_ew => get_face_selector_ew(mesh%get_id()) - face_selector_ns => get_face_selector_ns(mesh%get_id()) - - - call u_inc % copy_field_properties( u_inc_input ) - call u % copy_field_properties( u_input ) - - - ! Initialise arguments and call the tangent-linear kernel. - call invoke( setval_random( u ), & - setval_x( u_input, u ), & - setval_random( u_inc ), & - setval_x( u_inc_input, u_inc ) ) - - - ! LS init - call assign_field_random_range( auv, -1.0_r_def, 1.0_r_def ) - call assign_field_random_range( buv_inv, 1.0_r_def, 2.0_r_def ) ! must avoid 0 - - - ! < Mx, Mx > - call invoke ( tl_bl_inc_kernel_type( u_inc, & - u, & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) - call invoke ( & - x_innerproduct_x( ip1(1), u_inc ), & - x_innerproduct_x( ip1(2), u ) ) - - - sf(1) = 1.0_r_def / (ip1(1) + eps) - sf(2) = 1.0_r_def / (ip1(2) + eps) - - inner1 = 0.0_r_def - inner1 = inner1 + ip1(1) * sf(1) - inner1 = inner1 + ip1(2) * sf(2) - - - ! Scaling fields - call invoke( inc_a_times_X( sf(1),u_inc ), & - inc_a_times_X( sf(2),u ) ) - - ! < AMx, x > - call invoke ( atl_bl_inc_kernel_type( u_inc, & - u, & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) - - call invoke ( & - x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & - x_innerproduct_y( ip2(2), u, u_input ) ) - - inner2 = 0.0_r_def - inner2 = inner2 + ip2(1) - inner2 = inner2 + ip2(2) - - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & - ip1(1)*sf(1),ip1(2)*sf(2) - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=',ip2 - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & - inner1,inner2 - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) - - ! Test the inner-product values for equality, allowing for the precision of the active variables - machine_tol = spacing( max( abs(inner1), abs(inner2) ) ) - relative_diff = abs(inner1 - inner2) / machine_tol - if (relative_diff < overall_tolerance) then - write(log_scratch_space, *) "PASSED tl_bl_inc:", inner1, inner2, relative_diff - call log_event(log_scratch_space, LOG_LEVEL_INFO) - else - write(log_scratch_space, *) "FAILED tl_bl_inc:", inner1, inner2, relative_diff - call log_event(log_scratch_space, LOG_LEVEL_ERROR) - end if - - end subroutine atlt_bl_inc_alg - -end module atlt_bl_inc_alg_mod From 5509e9c78a137bdc6ebe594aec44ec2afcd22afa Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 17:12:58 +0000 Subject: [PATCH 57/68] Responding to SR (not done) --- .../linear_physics/atlt_bdy_lyr_alg_mod.x90 | 38 +- .../linear_physics/atlt_bl_inc_alg_mod.x90 | 76 ++-- .../opt/rose-app-nwp_gal9_c12.conf | 4 +- rose-stem/app/jedi_lfric_tests/rose-app.conf | 13 +- .../linear_physics/atl_bdy_lyr_alg.x90 | 375 ++++++++--------- .../timestepping/atl_si_timestep_alg_mod.x90 | 90 ++-- .../linear_physics/atl_bl_inc_kernel_mod.F90 | 320 ++++++++------- .../linear_physics/tl_bdy_lyr_alg.x90 | 387 ++++++++---------- .../timestepping/tl_si_timestep_alg_mod.x90 | 59 ++- .../linear_physics/tl_bl_inc_kernel_mod.F90 | 225 +++++----- .../tl_compute_aubu_kernel_mod.F90 | 132 +++--- .../tl_compute_qe_kernel_mod.F90 | 255 ++++++------ 12 files changed, 950 insertions(+), 1024 deletions(-) diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 index 28e0d3be..b2656a25 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 @@ -26,6 +26,7 @@ module atlt_bdy_lyr_alg_mod use function_space_collection_mod, only : function_space_collection use adjoint_test_parameters_mod, only : ls_u_range, ls_theta_range, & ls_rho_range, ls_exner_range + use timing_mod, only : start_timing, stop_timing, tik, LPROF implicit none @@ -49,7 +50,7 @@ module atlt_bdy_lyr_alg_mod ! Arguments type(modeldb_type), target, intent(inout) :: modeldb - type(mesh_type), pointer, intent(in) :: mesh + type(mesh_type), pointer, intent(in) :: mesh ! Arguments for tl and atl calls ! Form of state is [u,theta,rho,exner] @@ -72,7 +73,6 @@ module atlt_bdy_lyr_alg_mod real(kind=r_def) :: ip1(2),ip2(2) real(kind=r_def) :: sf(2) - ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def real(kind=r_def) :: machine_tol @@ -82,6 +82,9 @@ module atlt_bdy_lyr_alg_mod ! Misc real(kind=r_def) :: dt + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'atlt_bdy_lyr_alg' ) ! Determining time constants dt = real(modeldb%clock%get_seconds_per_step(), r_def) @@ -90,7 +93,6 @@ module atlt_bdy_lyr_alg_mod call log_event( log_scratch_space, log_level_error ) end if - ! Initialising fields vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) @@ -113,7 +115,6 @@ module atlt_bdy_lyr_alg_mod call state(igh_d) % copy_field_properties( ls_state(igh_d) ) call state(igh_p) % copy_field_properties( ls_state(igh_p) ) - ! Initialise values and call the tangent-linear alg. call invoke( setval_random( u_bl_inc ), & setval_x(u_bl_inc_input, u_bl_inc ), & @@ -126,22 +127,18 @@ module atlt_bdy_lyr_alg_mod setval_random( state(igh_p) ), & setval_x( state_input(igh_p), state(igh_p) ) ) - ! LS init call assign_field_random_range( ls_state(igh_u), ls_u_range(1), ls_u_range(2) ) call assign_field_random_range( ls_state(igh_t), ls_theta_range(1), ls_theta_range(2) ) - call invoke( setval_random( ls_state(igh_d) ), & - setval_random( ls_state(igh_p) ) ) - + call invoke( setval_random( ls_state(igh_d) ), setval_random( ls_state(igh_p) ) ) ! Tangent linear - call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) ! < Mx, Mx > - call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & + call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & x_innerproduct_x( ip1(2), u_bl_inc ) ) - sf(1) = 1.0_r_def / (ip1(1) + eps) sf(2) = 1.0_r_def / (ip1(2) + eps) @@ -150,13 +147,13 @@ module atlt_bdy_lyr_alg_mod inner1 = inner1 + ip1(2) * sf(2) ! Scaling fields - call invoke( inc_a_times_X( sf(1), state(igh_u) ), & + call invoke( inc_a_times_X( sf(1), state(igh_u) ), & inc_a_times_X( sf(2), u_bl_inc ) ) ! Adjoint alg call and inner products ! Adjoint - call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) ! < AMx, x > call invoke( x_innerproduct_y( ip2(1), & @@ -166,17 +163,16 @@ module atlt_bdy_lyr_alg_mod u_bl_inc, & u_bl_inc_input ) ) - inner2 = 0.0_r_def inner2 = inner2 + ip2(1) inner2 = inner2 + ip2(2) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip1=',ip1(1)*sf(1),ip1(2)*sf(2) - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip2=',ip2 - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: s(ip1),s(ip2)=',inner1,inner2 - call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip1=', ip1(1) * sf(1), ip1(2) * sf(2) + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip2=', ip2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: s(ip1),s(ip2)=', inner1, inner2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) ! Test the inner-product values for equality, allowing for the precision of the active variables machine_tol = spacing( max( abs( inner1 ), abs( inner2 ) ) ) @@ -189,6 +185,8 @@ module atlt_bdy_lyr_alg_mod call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end if + if ( LPROF ) call stop_timing( id, 'atlt_bdy_lyr_alg' ) + end subroutine atlt_bdy_lyr_alg end module atlt_bdy_lyr_alg_mod diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 index 043485b6..3fd91536 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 @@ -32,6 +32,7 @@ module atlt_bl_inc_alg_mod ls_md1_range, & ls_md2_range, & ls_md3_range + use timing_mod, only : start_timing, stop_timing, tik, LPROF implicit none @@ -47,17 +48,16 @@ module atlt_bl_inc_alg_mod !> @param[in] mesh Mesh object subroutine atlt_bl_inc_alg( mesh ) - use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type - use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type - - use linear_config_mod, only: log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m + use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type + use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type + use linear_config_mod, only : log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m implicit none @@ -94,6 +94,10 @@ module atlt_bl_inc_alg_mod real(kind=r_def) :: relative_diff real(kind=r_def), parameter :: eps = 1e-30_r_def + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'atlt_bl_inc_alg' ) + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) @@ -107,23 +111,19 @@ module atlt_bl_inc_alg_mod face_selector_ew => get_face_selector_ew(mesh%get_id()) face_selector_ns => get_face_selector_ns(mesh%get_id()) - call u_inc % copy_field_properties( u_inc_input ) call u % copy_field_properties( u_input ) - ! Initialise arguments and call the tangent-linear kernel. call invoke( setval_random( u ), & setval_x( u_input, u ), & setval_random( u_inc ), & setval_x( u_inc_input, u_inc ) ) - ! LS init call assign_field_random_range( auv, -1.0_r_def, 1.0_r_def ) call assign_field_random_range( buv_inv, 1.0_r_def, 2.0_r_def ) ! must avoid 0 - ! < Mx, Mx > call invoke ( tl_bl_inc_kernel_type( u_inc, & u, & @@ -131,10 +131,8 @@ module atlt_bl_inc_alg_mod face_selector_ew, & face_selector_ns, & Blevs_m ) ) - call invoke ( & - x_innerproduct_x( ip1(1), u_inc ), & - x_innerproduct_x( ip1(2), u ) ) - + call invoke ( x_innerproduct_x( ip1(1), u_inc ), & + x_innerproduct_x( ip1(2), u ) ) sf(1) = 1.0_r_def / (ip1(1) + eps) sf(2) = 1.0_r_def / (ip1(2) + eps) @@ -143,35 +141,33 @@ module atlt_bl_inc_alg_mod inner1 = inner1 + ip1(1) * sf(1) inner1 = inner1 + ip1(2) * sf(2) - ! Scaling fields - call invoke( inc_a_times_X( sf(1),u_inc ), & - inc_a_times_X( sf(2),u ) ) + call invoke( inc_a_times_X( sf(1), u_inc ), & + inc_a_times_X( sf(2), u ) ) ! < AMx, x > - call invoke ( atl_bl_inc_kernel_type( u_inc, & - u, & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) + call invoke ( atl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) - call invoke ( & - x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & - x_innerproduct_y( ip2(2), u, u_input ) ) + call invoke ( x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & + x_innerproduct_y( ip2(2), u, u_input ) ) inner2 = 0.0_r_def inner2 = inner2 + ip2(1) inner2 = inner2 + ip2(2) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & - ip1(1)*sf(1),ip1(2)*sf(2) - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=',ip2 - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) - write(log_scratch_space,'(a,1x,2(e16.9,1x))') 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & - inner1,inner2 - call log_event(log_scratch_space, LOG_LEVEL_DEBUG) + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & + ip1(1) * sf(1), ip1(2) * sf(2) + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=', ip2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & + inner1, inner2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) ! Test the inner-product values for equality, allowing for the precision of the active variables machine_tol = spacing( max( abs(inner1), abs(inner2) ) ) @@ -184,6 +180,8 @@ module atlt_bl_inc_alg_mod call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if + if ( LPROF ) call stop_timing( id, 'atlt_bl_inc_alg' ) + end subroutine atlt_bl_inc_alg end module atlt_bl_inc_alg_mod diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf index feabdeff..657911fb 100644 --- a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/jedi_lfric_tests/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='/data/users/tim.payne/lfric_apps/files' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index ea01a212..59b9fc26 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -384,7 +384,7 @@ diag_stem_name='diagGungho' !!lbc_directory='' !!lbc_filename='' ls_directory='/data/users/tim.payne/lfric_apps/files' -ls_filename='final_ls_with_land' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' @@ -764,12 +764,21 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] +blevs_m=15 +e_folding_levs_m=10 fixed_ls=.true. -l_stabilise_bl=.true. +l_0_m=80.0 +l_boundary_layer=.true. +l_stabilise_bl=.false. +log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] log_to_rank_zero_only=.false. diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index 8a2b45b6..b36f4b98 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -3,76 +3,37 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be brief. !----------------------------------------------------------------------------- -!> @brief (Adjoint of) given TL state(igh_u) compute boundary layer increment u_bl_inc +!> @brief (Adjoint of) given TL state(igh_u) compute TLM boundary layer increment u_bl_inc module atl_bdy_lyr_alg_mod use constants_mod, only: r_def, i_def, l_def use field_collection_mod, only: field_collection_type use integer_field_mod, only: integer_field_type - use log_mod, only: log_event, & - log_scratch_space, & - LOG_LEVEL_ERROR, & - LOG_LEVEL_DEBUG use driver_modeldb_mod, only: modeldb_type - use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use sci_geometric_constants_mod, only: get_height_fe, get_coordinates, & - get_panel_id, & + use sci_geometric_constants_mod, only: get_height_fe, & + get_coordinates, & + get_panel_id, & get_face_selector_ew, & get_face_selector_ns - use sci_fem_constants_mod, only: get_mass_matrix_fe, & - get_inverse_mass_matrix_fe, & + use sci_fem_constants_mod, only: get_mass_matrix_fe, & get_rmultiplicity_fe - use dycore_constants_mod, only: get_coriolis, & - get_w2_mass_matrix, & - w2_damping_layer_matrix - use sci_field_bundle_builtins_mod, only: clone_bundle, & - bundle_axpy, & - add_bundle, & - copy_bundle, & - set_bundle_scalar, & - bundle_is_zero + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle use field_mod, only: field_type - - use formulation_config_mod, only: rotating, & - si_momentum_equation, & - vector_invariant, & - eos_method, & - eos_method_sampled, & - eos_method_projected - use linear_config_mod, only: log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m - - use planet_config_mod, only: cp, kappa, rd, p_zero - use tl_kinetic_energy_gradient_kernel_mod, & - only: tl_kinetic_energy_gradient_kernel_type - use matrix_vector_kernel_mod, only: matrix_vector_kernel_type - use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m use operator_mod, only: operator_type - use tl_hydrostatic_kernel_mod, only: tl_hydrostatic_kernel_type - use tl_pressure_gradient_bd_kernel_mod, only: tl_pressure_gradient_bd_kernel_type - use quadrature_xyoz_mod, only: quadrature_xyoz_type - use quadrature_face_mod, only: quadrature_face_type - use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - use tl_rhs_project_eos_kernel_mod, only: tl_rhs_project_eos_kernel_type - use tl_rhs_sample_eos_kernel_mod, only: tl_rhs_sample_eos_kernel_type - use moist_dyn_mod, only: num_moist_factors, gas_law - use dg_matrix_vector_kernel_mod, only: dg_matrix_vector_kernel_type + use timing_mod, only: start_timing, stop_timing, tik, LPROF use reference_element_mod, only: reference_element_type use mesh_mod, only: mesh_type - use tl_vorticity_advection_kernel_mod, only: tl_vorticity_advection_kernel_type - use compute_vorticity_alg_mod, only: compute_vorticity_alg use fs_continuity_mod, only: W1, W2, W3, Wtheta - use function_space_collection_mod, only: function_space_collection use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use atl_bl_inc_kernel_mod, only: atl_bl_inc_kernel_type @@ -84,167 +45,171 @@ module atl_bdy_lyr_alg_mod contains -!>@brief (Adjoint of) given TL state(igh_u) compute boundary layer increment u_bl_inc -!>@param[in,out] modeldb The modeldb instance -!>@param[in,out] u_bl_inc Increment to be computed -!>@param[in,out] state The current TL model prognostic state -!>@param[in] ls_state The current linearisation state -!>@param[in] dt The TL model timestep length +!> @brief (Adjoint of) given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +!> @details The stages are: +!> 1. Call tl_compute_qe_kernel_type: from LS, compute coefficients Q, E +!> 2. Call tl_compute_aubu_kernel_type: from Q,E, compute coefficients Auv, Buv_inv +!> 3. Call atl_bl_inc_kernel_type: (adjoint of) from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u_bl_inc TLM boundary layer increment +!> @param[in,out] state The current TL model prognostic state +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] dt The TL model timestep length subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) - implicit none - - - type(modeldb_type), target, intent(inout) :: modeldb - - ! Form of state and rhs is [u,theta,rho,exner] - type(field_type), target, intent(inout) :: state(bundle_size) - type(field_type), target, intent(in) :: ls_state(bundle_size) - real(kind=r_def), intent(in) :: dt - - type( field_type ), intent(inout) :: u_bl_inc - - - real(kind=r_def) :: alpha_dt - logical(kind=l_def) :: dlayer_rhs - logical(kind=l_def) :: compute_eos - - type(operator_type), pointer :: mm_vel => null(), & - mm_wtheta => null(), & - mm_w3_inv => null() - type(field_type), pointer :: chi(:) => null(), & - panel_id => null(), & - geopotential => null(), & - u => null(), & - theta => null(), & - rho => null(), & - u_base => null(), & - theta_base => null(), & - rho_base => null(), & - exner => null(), & - ls_u => null(), & - ls_theta => null(), & - ls_rho => null(), & - ls_exner => null() - - - class(reference_element_type), pointer :: reference_element => null() - type (mesh_type), pointer :: mesh => null() - - type( field_type ), pointer :: height_w1 => null() - type( field_type ), pointer :: height_w2 => null() - type( field_type ), pointer :: height_w3 => null() - type( field_type ), pointer :: height_wth => null() - type( field_type ), pointer :: w2_rmultiplicity => null() - - type( field_type ) :: state_initial(bundle_size) - - type( field_collection_type ), pointer :: ls_fields - type( field_type), pointer :: ls_land_fraction => null() - - type( field_type) :: Q - type( field_type) :: E - type( field_type) :: auv - type( field_type) :: buv_inv - - type(integer_field_type), pointer :: face_selector_ew => null() - type(integer_field_type), pointer :: face_selector_ns => null() - - integer(kind=i_def), parameter :: exner_stencil_depth = 1 - - if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') - - ls_fields => modeldb%fields%get_field_collection("ls_fields") - - call ls_fields%get_field('ls_land_fraction', ls_land_fraction) - - mesh => state(igh_u)%get_mesh() - - mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) - chi => get_coordinates(mesh%get_id()) - panel_id => get_panel_id(mesh%get_id()) - - - height_w1 => get_height_fe(W1, mesh%get_id()) - height_w2 => get_height_fe(W2, mesh%get_id()) - height_w3 => get_height_fe(W3, mesh%get_id()) - height_wth => get_height_fe(Wtheta,mesh%get_id() ) - - w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) - - face_selector_ew => get_face_selector_ew(mesh%get_id()) - face_selector_ns => get_face_selector_ns(mesh%get_id()) - - dlayer_rhs = .false. - alpha_dt = 0.5_r_def * dt - compute_eos = .false. - - u => state(igh_u) - theta => state(igh_t) - rho => state(igh_d) - exner => state(igh_p) - - u_base => state(igh_u) - theta_base => state(igh_t) - rho_base => state(igh_d) + implicit none - ls_u => ls_state(igh_u) - ls_theta => ls_state(igh_t) - ls_rho => ls_state(igh_d) - ls_exner => ls_state(igh_p) + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u_bl_inc + type(field_type), target, intent(inout) :: state(bundle_size) + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt - call clone_bundle(state,state_initial , bundle_size) - call copy_bundle(state, state_initial, bundle_size) + ! Local variables + real(kind=r_def) :: alpha_dt + logical(kind=l_def) :: dlayer_rhs + logical(kind=l_def) :: compute_eos - call rho%copy_field_properties( Q ) - call rho%copy_field_properties( E ) - - call invoke(setval_c(Q,0.0_r_def),& - setval_c(E,0.0_r_def) ) + type(operator_type), pointer :: mm_vel => null(), & + mm_wtheta => null(), & + mm_w3_inv => null() - call u%copy_field_properties( auv ) - call u%copy_field_properties( buv_inv ) - - call invoke(setval_c(auv,0.0_r_def),& - setval_c(buv_inv,0.0_r_def) ) - - call invoke ( tl_compute_qe_kernel_type(Q, & - E, & - ls_state(igh_d), & - height_w3, height_wth,& - ls_land_fraction, & - log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m ) ) + type(field_type), pointer :: chi(:) => null(), & + panel_id => null(), & + geopotential => null(), & + u => null(), & + theta => null(), & + rho => null(), & + u_base => null(), & + theta_base => null(), & + rho_base => null(), & + exner => null(), & + ls_u => null(), & + ls_theta => null(), & + ls_rho => null(), & + ls_exner => null() + + class(reference_element_type), pointer :: reference_element => null() + type (mesh_type), pointer :: mesh => null() + + type( field_type ), pointer :: height_w1 => null() + type( field_type ), pointer :: height_w2 => null() + type( field_type ), pointer :: height_w3 => null() + type( field_type ), pointer :: height_wth => null() + type( field_type ), pointer :: w2_rmultiplicity => null() + + type( field_type ) :: state_initial(bundle_size) + + type( field_collection_type ), pointer :: ls_fields + type( field_type), pointer :: ls_land_fraction => null() + + ! Coefficients computed from linearisation state + type( field_type ) :: Q + type( field_type ) :: E + type( field_type ) :: auv + type( field_type ) :: buv_inv + + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + integer(kind=i_def), parameter :: exner_stencil_depth = 1 + + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'atl_bdy_lyr_alg' ) + + ls_fields => modeldb%fields%get_field_collection("ls_fields") + + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => state(igh_u)%get_mesh() + + mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) + chi => get_coordinates(mesh%get_id()) + panel_id => get_panel_id(mesh%get_id()) + + height_w1 => get_height_fe(W1, mesh%get_id()) + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta,mesh%get_id() ) + + w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + dlayer_rhs = .false. + alpha_dt = 0.5_r_def * dt + compute_eos = .false. + + u => state(igh_u) + theta => state(igh_t) + rho => state(igh_d) + exner => state(igh_p) + + u_base => state(igh_u) + theta_base => state(igh_t) + rho_base => state(igh_d) + + ls_u => ls_state(igh_u) + ls_theta => ls_state(igh_t) + ls_rho => ls_state(igh_d) + ls_exner => ls_state(igh_p) + + call clone_bundle(state,state_initial , bundle_size) + call copy_bundle(state, state_initial, bundle_size) + + call rho%copy_field_properties( Q ) + call rho%copy_field_properties( E ) + + call invoke(setval_c(Q, 0.0_r_def), & + setval_c(E, 0.0_r_def) ) + + call u%copy_field_properties( auv ) + call u%copy_field_properties( buv_inv ) + + call invoke(setval_c(auv, 0.0_r_def), & + setval_c(buv_inv, 0.0_r_def) ) + + call invoke ( tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, height_wth,& + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m ) ) - call invoke ( tl_compute_aubu_kernel_type(auv, & - buv_inv, & - Q, & - E, & - height_w2, & - w2_rmultiplicity, & - dt, & - Blevs_m ) ) + call invoke ( tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m ) ) - call invoke ( atl_bl_inc_kernel_type( u_bl_inc, & - state(igh_u), & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) + call invoke ( atl_bl_inc_kernel_type( u_bl_inc, & + state(igh_u), & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) - nullify( mm_vel, mm_wtheta, mm_w3_inv, & - chi, panel_id, & - geopotential, u, theta, rho, exner, & - mesh, reference_element ) + nullify( mm_vel, mm_wtheta, mm_w3_inv, & + chi, panel_id, & + geopotential, u, theta, rho, exner, & + mesh, reference_element ) - if ( subroutine_timers ) call timer('atl_bdy_lyr_alg') + if ( LPROF ) call stop_timing( id, 'atl_bdy_lyr_alg' ) - end subroutine atl_bdy_lyr_alg +end subroutine atl_bdy_lyr_alg end module atl_bdy_lyr_alg_mod diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index 87b9518a..51070736 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -687,7 +687,7 @@ contains call add_bundle( self%state,self%state2 ,self%state, bundle_size ) call add_bundle( self%state,self%state1 ,self%state, bundle_size ) - end if + end if end do inner_dynamics_loop !------------------------------------------------------------------------- @@ -701,83 +701,83 @@ contains call u%copy_field_properties( du ) call u%copy_field_properties( u_star ) call u%copy_field_properties( u_star_physical ) - call self%rhs_adv(igh_u)%copy_field_properties(rhsu_np1 ) + call self%rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) call du%initialise( self%rhs_adv(igh_u)%get_function_space() ) call rhsu_np1%initialise( self%rhs_adv(igh_u)%get_function_space() ) - call clone_bundle(self%state,self%state_star, bundle_size) - call copy_bundle(self%state, self%state_star, bundle_size) ! Only state_star(igh_u) is used - call set_bundle_scalar(0.0_r_def,self%state_star, bundle_size) + call clone_bundle( self%state,self%state_star, bundle_size ) + call copy_bundle( self%state, self%state_star, bundle_size ) ! Only state_star(igh_u) is used + call set_bundle_scalar( 0.0_r_def,self%state_star, bundle_size ) dA => get_da_at_w2(mesh%get_id()) - call invoke( setval_c(u_bl_inc_flux, 0.0_r_def), & - setval_c(u_bl_inc, 0.0_r_def), & - setval_c(u_star, 0.0_r_def), & - setval_c(u_star_physical, 0.0_r_def), & - setval_c(du, 0.0_r_def), & - setval_c(rhsu_np1, 0.0_r_def) ) + call invoke( setval_c( u_bl_inc_flux, 0.0_r_def ), & + setval_c( u_bl_inc, 0.0_r_def ), & + setval_c( u_star, 0.0_r_def ), & + setval_c( u_star_physical, 0.0_r_def ), & + setval_c( du, 0.0_r_def ), & + setval_c( rhsu_np1, 0.0_r_def ) ) - call invoke( enforce_bc_kernel_type(self%rhs_phys(igh_u)), & - adj_matrix_vector_kernel_type(self%rhs_phys(igh_u),u_bl_inc_flux, mm_vel ) ) + call invoke( enforce_bc_kernel_type( self%rhs_phys(igh_u) ), & + adj_matrix_vector_kernel_type( self%rhs_phys(igh_u), u_bl_inc_flux, mm_vel ) ) - call set_bundle_scalar(0.0_r_def,self%rhs_phys, bundle_size) + call set_bundle_scalar( 0.0_r_def,self%rhs_phys, bundle_size ) ! Adj of u_bl_inc_flux = u_bl_inc * dA - call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & + call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & - setval_c(u_bl_inc_flux, 0.0_r_def) ) + setval_c( u_bl_inc_flux, 0.0_r_def ) ) - call atl_bdy_lyr_alg(modeldb, u_bl_inc, self%state_star, & - self%ls_state_itns(:,ls_outer,1), cast_dt ) + call atl_bdy_lyr_alg( modeldb, u_bl_inc, self%state_star, & + self%ls_state_itns(:,ls_outer,1), cast_dt ) ! Adj of state_star(igh_u) <- u_star_physical - call invoke( inc_x_plus_y(u_star_physical , self%state_star(igh_u) ), & - setval_c( self%state_star(igh_u), 0.0_r_def) ) + call invoke( inc_x_plus_y( u_star_physical, self%state_star(igh_u) ), & + setval_c( self%state_star(igh_u), 0.0_r_def ) ) ! Adj of u_star_physical = u_star / dA - call invoke( inc_x_divideby_y( u_star_physical, dA ), & + call invoke( inc_x_divideby_y( u_star_physical, dA ), & inc_x_plus_y( u_star, u_star_physical ), & - setval_c(u_star_physical, 0.0_r_def) ) + setval_c( u_star_physical, 0.0_r_def) ) ! Adj of u_star = du + state(igh_u) call invoke( inc_X_plus_Y( du, u_star ), & inc_X_plus_Y( self%state(igh_u), u_star ), & - setval_c(u_star, 0.0_r_def) ) + setval_c( u_star, 0.0_r_def ) ) ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) - call mass_matrix_solver_alg( rhsu_np1, du) + call mass_matrix_solver_alg( rhsu_np1, du ) ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) - call invoke( inc_X_plus_Y( self%rhs_adv(igh_u),rhsu_np1) ) + call invoke( inc_X_plus_Y( self%rhs_adv(igh_u), rhsu_np1 ) ) ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) - call invoke( inc_X_plus_bY(self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1), & - inc_X_plus_Y(self%rhs_n(igh_u), rhsu_np1), & - setval_c( rhsu_np1, 0.0_r_def) ) + call invoke( inc_X_plus_bY( self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1 ), & + inc_X_plus_Y( self%rhs_n(igh_u), rhsu_np1 ), & + setval_c( rhsu_np1, 0.0_r_def ) ) ! Adj of du <- 0 - call invoke( setval_c(du, 0.0_r_def)) + call invoke( setval_c( du, 0.0_r_def ) ) end if ! l_boundary_layer - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) - - call atl_rhs_alg( self%rhs_np1, & - -varalpha*cast_dt, & - self%state1, & - self%state2, & - moist_dyn, & - self%ls_state_itns(:,ls_outer,1), & - self%ls_moist_dyn_itns(:,ls_outer,1), & - .true., & - dlayer_on, & - modeldb%clock ) - - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state2, bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,1), & + self%ls_moist_dyn_itns(:,ls_outer,1), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state, self%state2, self%state, bundle_size ) + call add_bundle( self%state, self%state1, self%state, bundle_size ) call invoke( setval_c( self%theta_fv_inc, 0.0_r_def ), & adj_dg_inc_matrix_vector_kernel_type( self%rhs_adv(igh_t), & diff --git a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 index efbd602d..4685f594 100644 --- a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 +++ b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 @@ -3,18 +3,19 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- +!> @brief (Adjoint of) computes u_inc, the change in TLM velocity due to TLM boundary layer processes. module atl_bl_inc_kernel_mod - use argument_mod, only : arg_type, & - GH_FIELD, GH_OPERATOR, & - GH_SCALAR, GH_INTEGER, & - GH_READ, GH_INC, & - GH_REAL, CELL_COLUMN, & - ANY_DISCONTINUOUS_SPACE_1 - use constants_mod, only : r_def, i_def, r_um - use fs_continuity_mod, only : W1, W2, W3 - use kernel_mod, only : kernel_type - use reference_element_mod, only: N + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only : N implicit none @@ -25,160 +26,169 @@ module atl_bl_inc_kernel_mod !--------------------------------------------------------------------------- type, public, extends(kernel_type) :: atl_bl_inc_kernel_type - PRIVATE - TYPE(arg_type) :: meta_args(7) = (/ & - arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & - arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & - arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & - arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & - /) - INTEGER :: operates_on = CELL_COLUMN - CONTAINS - PROCEDURE, NOPASS :: atl_bl_inc_code - END TYPE + private + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & ! Blevs_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: atl_bl_inc_code + end type !--------------------------------------------------------------------------- ! Contained functions/subroutines !--------------------------------------------------------------------------- public :: atl_bl_inc_code - contains - - !> @brief (Adjoint of) computes boundary layer u inc - !! @param[in] nlayers Number of layers - !! @param[in,out] u_inc Output - !! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field - !! @param[in] undf_w2 Unique number of degrees of freedom for the output field - !! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field - subroutine atl_bl_inc_code( nlayers, & - u_inc, & - u, & - Auv, & - Buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m, & - ndf_w2, undf_w2, map_w2, & - ndf_w3_2d, undf_w3_2d, map_w3_2d ) +contains + +!> @brief (Adjoint of) computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +!> @details The algorithm uses coefficients Auv and Buv_inv computed in tl_compute_aubu_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] u_inc Change in TLM velocity due to TLM boundary layer processes +!! @param[in] u TLM velocity +!! @param[in] nlayers Number of layers +!! @param[in] Auv Coefficient for TLM boundary layer +!! @param[in] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] face_selector_ew 2D field indicating which W/E faces to loop over in this column +!! @param[in] face_selector_ns 2D field indicating which N/S faces to loop over in this column +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3_2d Number of DoFs for 2D W3 per cell +!! @param[in] undf_w3_2d Number of DoFs for this partition for 2D W3 +!! @param[in] map_w3_2d Map for 2D W3 +subroutine atl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) implicit none ! Arguments - integer(kind=i_def), intent(in) :: nlayers - integer(kind=i_def), intent(in) :: undf_w2 - integer(kind=i_def), intent(in) :: ndf_w2 - integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 - real(kind=r_def), dimension(undf_w2), intent(inout) :: u - real(kind=r_def), dimension(undf_w2), intent(in) :: auv - real(kind=r_def), dimension(undf_w2), intent(in) :: buv_inv - real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc - integer(kind=i_def), intent(in) :: ndf_w3_2d - integer(kind=i_def), intent(in) :: undf_w3_2d - integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d - integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew - integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns - integer(kind=i_def), intent(in) :: blevs_m - - ! Internal variables - integer(kind=i_def) :: df - integer(kind=i_def) :: k - integer(kind=i_def) :: j - real(kind=r_def), dimension(blevs_m) :: a0 - real(kind=r_def), dimension(blevs_m) :: a1 - real(kind=r_def), dimension(blevs_m) :: a2 - real(kind=r_def), dimension(blevs_m) :: u_rhs - real(kind=r_def), dimension(blevs_m) :: u_out - real(kind=r_def), dimension(blevs_m) :: factor_u - integer :: idx - integer :: idx_1 - - do j = face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)), 1, -1 - df = j - if (j == 3 .AND. face_selector_ns(map_w3_2d(1)) == 2 .AND. face_selector_ew(map_w3_2d(1)) == 1) then - df = n - end if - - u_out = 0.0_r_def - u_rhs = 0.0_r_def - a0(:) = 0.0_r_def - a1(:) = 0.0_r_def - a2(:) = 0.0_r_def - factor_u(:) = 0.0_r_def - -! ===================== set up coeffs a0,a1,a2,factor_u ===================== - - a0(1) = 1.0_r_def+(Auv(map_w2(df)+1)+Auv(map_w2(df)+0))/Buv_inv(map_w2(df)+1) - a1(1) = -Auv(map_w2(df)+1)/Buv_inv(map_w2(df)+1) - - DO k=2,BLevs_m-1 - a0(k) = 1.0_r_def+(Auv(map_w2(df)+k)+Auv(map_w2(df)+k-1))/Buv_inv(map_w2(df)+k) - a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) - a1(k) = -Auv(map_w2(df)+k)/Buv_inv(map_w2(df)+k) - end do - - a0(BLevs_m) = 1.0_r_def+Auv(map_w2(df)+BLevs_m-1)/Buv_inv(map_w2(df)+BLevs_m) - a2(BLevs_m) = -Auv(map_w2(df)+BLevs_m-1)/Buv_inv(map_w2(df)+BLevs_m) - - a0(1) = 1.0_r_def/a0(1) - - do k=2,BLevs_m - factor_u(k) = a2(k)*a0(k-1) - a0(k) = 1.0_r_def/(a0(k)-factor_u(k)*a1(k-1)) - END DO - -! ================ Adj of Solve for u_inc and transform to upper triangular form ============= - - do k = 1, blevs_m - 1 - - u_out(k) = u_out(k) + u_inc(map_w2(df) + k - 1) - u_inc(map_w2(df) + k - 1) = 0.0_r_def - - u_out(k + 1) = u_out(k + 1) + (-a0(k) * a1(k) * u_out(k)) - u_rhs(k) = u_rhs(k) + a0(k) * u_out(k) - u_out(k) = 0.0_r_def - enddo - - u_out(blevs_m) = u_out(blevs_m) + u_inc(map_w2(df) + blevs_m - 1) - u_inc(map_w2(df) + blevs_m - 1) = 0.0_r_def - - u_rhs(blevs_m) = u_rhs(blevs_m) + a0(blevs_m) * u_out(blevs_m) - u_out(blevs_m) = 0.0_r_def - - do k = blevs_m, 2, -1 - u_rhs(k - 1) = u_rhs(k - 1) + (-factor_u(k) * u_rhs(k)) - enddo - - u(blevs_m + map_w2(df) - 2) = u(blevs_m + map_w2(df) - 2) + & - auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) - u(blevs_m + map_w2(df) - 1) = u(blevs_m + map_w2(df) - 1) - & - auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) - u_rhs(blevs_m) = 0.0_r_def - - do k = blevs_m - 1, 2, -1 - u(k + map_w2(df)) = u(k + map_w2(df)) + auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) - u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) - u(k + map_w2(df) - 2) = u(k + map_w2(df) - 2) + auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) - u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) - u_rhs(k) = 0.0_r_def - enddo - - u(map_w2(df) + 1) = u(map_w2(df) + 1) + auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) - u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) - u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df)) * u_rhs(1) / buv_inv(map_w2(df) + 1) - u_rhs(1) = 0.0_r_def - - do idx_1 = blevs_m, 1, -1 - u_out(idx_1) = 0.0_r_def - enddo - do idx = blevs_m, 1, -1 - u_rhs(idx) = 0.0_r_def - enddo - - enddo - - end subroutine atl_bl_inc_code + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w2 + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + real(kind=r_def), dimension(undf_w2), intent(inout) :: u + integer(kind=i_def), intent(in) :: ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: auv + real(kind=r_def), dimension(undf_w2), intent(in) :: buv_inv + integer(kind=i_def), intent(in) :: ndf_w3_2d + integer(kind=i_def), intent(in) :: undf_w3_2d + integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns + integer(kind=i_def), intent(in) :: blevs_m + + ! Internal variables + integer(kind=i_def) :: df + integer(kind=i_def) :: k + integer(kind=i_def) :: j + real(kind=r_def), dimension(blevs_m) :: a0 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: a1 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: a2 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: u_rhs ! Local perturbation velocity variable + real(kind=r_def), dimension(blevs_m) :: u_out ! Local perturbation velocity variable + real(kind=r_def), dimension(blevs_m) :: factor_u + integer :: idx + integer :: idx_1 + + do j = face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)), 1, -1 + + df = j + if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 .and. face_selector_ew(map_w3_2d(1)) == 1) df = n + + u_out = 0.0_r_def + u_rhs = 0.0_r_def + a0(:) = 0.0_r_def + a1(:) = 0.0_r_def + a2(:) = 0.0_r_def + factor_u(:) = 0.0_r_def + + ! Set up coeffs a0, a1, a2, u_rhs + a0(1) = 1.0_r_def + (Auv(map_w2(df) + 1) + Auv(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + a1(1) = -Auv(map_w2(df) + 1) / Buv_inv(map_w2(df) + 1) + + do k = 2, BLevs_m - 1 + a0(k) = 1.0_r_def + (Auv(map_w2(df) + k) + Auv(map_w2(df) + k - 1)) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + a1(k) = -Auv(map_w2(df) + k) / Buv_inv(map_w2(df) + k) + end do + + a0(BLevs_m) = 1.0_r_def + Auv(map_w2(df) + BLevs_m - 1) / Buv_inv(map_w2(df) + BLevs_m) + a2(BLevs_m) = -Auv(map_w2(df) + BLevs_m - 1) / Buv_inv(map_w2(df) + BLevs_m) + + a0(1) = 1.0_r_def / a0(1) + + do k = 2, BLevs_m + factor_u(k) = a2(k) * a0(k - 1) + a0(k) = 1.0_r_def / (a0(k) - factor_u(k) * a1(k - 1)) + end do + + ! (Adjoint of) solve for u_inc and transform to upper triangular form + do k = 1, blevs_m - 1 + u_out(k) = u_out(k) + u_inc(map_w2(df) + k - 1) + u_inc(map_w2(df) + k - 1) = 0.0_r_def + + u_out(k + 1) = u_out(k + 1) + (-a0(k) * a1(k) * u_out(k)) + u_rhs(k) = u_rhs(k) + a0(k) * u_out(k) + u_out(k) = 0.0_r_def + end do + + u_out(blevs_m) = u_out(blevs_m) + u_inc(map_w2(df) + blevs_m - 1) + u_inc(map_w2(df) + blevs_m - 1) = 0.0_r_def + + u_rhs(blevs_m) = u_rhs(blevs_m) + a0(blevs_m) * u_out(blevs_m) + u_out(blevs_m) = 0.0_r_def + + do k = blevs_m, 2, -1 + u_rhs(k - 1) = u_rhs(k - 1) + (-factor_u(k) * u_rhs(k)) + end do + + u(blevs_m + map_w2(df) - 2) = u(blevs_m + map_w2(df) - 2) + & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + u(blevs_m + map_w2(df) - 1) = u(blevs_m + map_w2(df) - 1) - & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + u_rhs(blevs_m) = 0.0_r_def + + do k = blevs_m - 1, 2, -1 + u(k + map_w2(df)) = u(k + map_w2(df)) + auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 2) = u(k + map_w2(df) - 2) + auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + u_rhs(k) = 0.0_r_def + end do + + u(map_w2(df) + 1) = u(map_w2(df) + 1) + auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df)) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u_rhs(1) = 0.0_r_def + + do idx_1 = blevs_m, 1, -1 + u_out(idx_1) = 0.0_r_def + end do + do idx = blevs_m, 1, -1 + u_rhs(idx) = 0.0_r_def + end do + + end do + +end subroutine atl_bl_inc_code end module atl_bl_inc_kernel_mod diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index b176345e..82d5d442 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -3,254 +3,215 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be brief. !----------------------------------------------------------------------------- -!> @brief Given TL state(igh_u) compute boundary layer increment u_bl_inc +!> @brief Given TL state(igh_u) compute TLM boundary layer increment u_bl_inc module tl_bdy_lyr_alg_mod use constants_mod, only: r_def, i_def, l_def use field_collection_mod, only: field_collection_type use integer_field_mod, only: integer_field_type use driver_modeldb_mod, only: modeldb_type - use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use sci_geometric_constants_mod, only: get_height_fe, get_coordinates, & - get_panel_id, & + use sci_geometric_constants_mod, only: get_height_fe, & + get_coordinates, & + get_panel_id, & get_face_selector_ew, & get_face_selector_ns - use sci_fem_constants_mod, only: get_mass_matrix_fe, & - get_inverse_mass_matrix_fe, & + use sci_fem_constants_mod, only: get_mass_matrix_fe, & get_rmultiplicity_fe - use dycore_constants_mod, only: get_coriolis, & - get_w2_mass_matrix, & - w2_damping_layer_matrix - use sci_field_bundle_builtins_mod, only: clone_bundle, & - bundle_axpy, & - add_bundle, & - copy_bundle, & - set_bundle_scalar, & - bundle_is_zero + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle use field_mod, only: field_type - - use formulation_config_mod, only: rotating, & - si_momentum_equation, & - vector_invariant, & - eos_method, & - eos_method_sampled, & - eos_method_projected - use linear_config_mod, only: log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m - - use planet_config_mod, only: cp, kappa, rd, p_zero - use tl_kinetic_energy_gradient_kernel_mod, & - only: tl_kinetic_energy_gradient_kernel_type - use matrix_vector_kernel_mod, only: matrix_vector_kernel_type - use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use linear_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m use operator_mod, only: operator_type - use tl_hydrostatic_kernel_mod, only: tl_hydrostatic_kernel_type - use tl_pressure_gradient_bd_kernel_mod, only: tl_pressure_gradient_bd_kernel_type - use quadrature_xyoz_mod, only: quadrature_xyoz_type - use quadrature_face_mod, only: quadrature_face_type - use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - use tl_rhs_project_eos_kernel_mod, only: tl_rhs_project_eos_kernel_type - use tl_rhs_sample_eos_kernel_mod, only: tl_rhs_sample_eos_kernel_type - use moist_dyn_mod, only: num_moist_factors, gas_law - use dg_matrix_vector_kernel_mod, only: dg_matrix_vector_kernel_type + use timing_mod, only: start_timing, stop_timing, tik, LPROF use reference_element_mod, only: reference_element_type use mesh_mod, only: mesh_type - use tl_vorticity_advection_kernel_mod, only: tl_vorticity_advection_kernel_type - use compute_vorticity_alg_mod, only: compute_vorticity_alg use fs_continuity_mod, only: W1, W2, W3, Wtheta - use function_space_collection_mod, only: function_space_collection use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use tl_bl_inc_kernel_mod, only: tl_bl_inc_kernel_type - implicit none private public :: tl_bdy_lyr_alg -! Typical namelist parameters: -! INTEGER :: Log_layer = 2 -! INTEGER :: Blevs_m = 8 -! INTEGER :: BL_levels = 13 -! INTEGER :: e_folding_levs_m =5 -! REAL :: u_land_m =0.4 -! REAL :: u_sea_m =0.4 -! REAL :: z_land_m =0.05 -! REAL :: z_sea_m =0.0005 -! REAL :: L_0_m =80.0 - contains -!>@brief Given TL state(igh_u) compute boundary layer increment u_bl_inc -!>@param[in,out] modeldb The modeldb instance -!>@param[in,out] u_bl_inc Increment to be computed -!>@param[in,out] state The current TL model prognostic state -!>@param[in] ls_state The current linearisation state -!>@param[in] dt The TL model timestep length +!> @brief Given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +!> @details The stages are: +!> 1. Call tl_compute_qe_kernel_type: from LS, compute coefficients Q, E +!> 2. Call tl_compute_aubu_kernel_type: from Q,E, compute coefficients Auv, Buv_inv +!> 3. Call tl_bl_inc_kernel_type: from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u_bl_inc TLM boundary layer increment +!> @param[in,out] state The current TL model prognostic state +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] dt The TL model timestep length subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) - implicit none + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u_bl_inc + type(field_type), target, intent(inout) :: state(bundle_size) + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt + + ! Local variables + real(kind=r_def) :: alpha_dt + logical(kind=l_def) :: dlayer_rhs + logical(kind=l_def) :: compute_eos - type(modeldb_type), target, intent(inout) :: modeldb + type(operator_type), pointer :: mm_vel => null(), & + mm_wtheta => null(), & + mm_w3_inv => null() - ! Form of state and rhs is [u,theta,rho,exner] - type(field_type), target, intent(inout) :: state(bundle_size) - type(field_type), target, intent(in) :: ls_state(bundle_size) - real(kind=r_def), intent(in) :: dt + type(field_type), pointer :: chi(:) => null(), & + panel_id => null(), & + geopotential => null(), & + u => null(), & + theta => null(), & + rho => null(), & + u_base => null(), & + theta_base => null(), & + rho_base => null(), & + exner => null(), & + ls_u => null(), & + ls_theta => null(), & + ls_rho => null(), & + ls_exner => null() + + class(reference_element_type), pointer :: reference_element => null() + type (mesh_type), pointer :: mesh => null() + + type( field_type ), pointer :: height_w1 => null() + type( field_type ), pointer :: height_w2 => null() + type( field_type ), pointer :: height_w3 => null() + type( field_type ), pointer :: height_wth => null() + type( field_type ), pointer :: w2_rmultiplicity => null() + + type( field_type ) :: state_initial(bundle_size) + + type( field_collection_type ), pointer :: ls_fields + type( field_type), pointer :: ls_land_fraction => null() + + ! Coefficients computed from linearisation state + type( field_type ) :: Q + type( field_type ) :: E + type( field_type ) :: auv + type( field_type ) :: buv_inv + + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + integer(kind=i_def), parameter :: exner_stencil_depth = 1 + + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'tl_bdy_lyr_alg' ) + + ls_fields => modeldb%fields%get_field_collection("ls_fields") + + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => state(igh_u)%get_mesh() + + mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) + chi => get_coordinates(mesh%get_id()) + panel_id => get_panel_id(mesh%get_id()) + + height_w1 => get_height_fe(W1, mesh%get_id()) + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta,mesh%get_id() ) + + w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + dlayer_rhs = .false. + alpha_dt = 0.5_r_def * dt + compute_eos = .false. + + u => state(igh_u) + theta => state(igh_t) + rho => state(igh_d) + exner => state(igh_p) + + u_base => state(igh_u) + theta_base => state(igh_t) + rho_base => state(igh_d) + + ls_u => ls_state(igh_u) + ls_theta => ls_state(igh_t) + ls_rho => ls_state(igh_d) + ls_exner => ls_state(igh_p) + + call clone_bundle(state,state_initial , bundle_size) + call copy_bundle(state, state_initial, bundle_size) + call u%copy_field_properties( u_bl_inc ) + call invoke(setval_c(u_bl_inc,0.0_r_def)) + + call rho%copy_field_properties( Q ) + call rho%copy_field_properties( E ) + + call invoke(setval_c(Q, 0.0_r_def), & + setval_c(E, 0.0_r_def) ) + + call u%copy_field_properties( auv ) + call u%copy_field_properties( buv_inv ) + + call invoke(setval_c(auv, 0.0_r_def), & + setval_c(buv_inv, 0.0_r_def) ) + + call invoke ( tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, height_wth,& + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m ) ) - type( field_type ), intent(inout) :: u_bl_inc + call invoke ( tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m ) ) - real(kind=r_def) :: alpha_dt - logical(kind=l_def) :: dlayer_rhs - logical(kind=l_def) :: compute_eos + call invoke ( tl_bl_inc_kernel_type( u_bl_inc, & + state(igh_u), & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) - type(operator_type), pointer :: mm_vel => null(), & - mm_wtheta => null(), & - mm_w3_inv => null() - type(field_type), pointer :: chi(:) => null(), & - panel_id => null(), & - geopotential => null(), & - u => null(), & - theta => null(), & - rho => null(), & - u_base => null(), & - theta_base => null(), & - rho_base => null(), & - exner => null(), & - ls_u => null(), & - ls_theta => null(), & - ls_rho => null(), & - ls_exner => null() - - class(reference_element_type), pointer :: reference_element => null() - type (mesh_type), pointer :: mesh => null() - - type( field_type ), pointer :: height_w1 => null() - type( field_type ), pointer :: height_w2 => null() - type( field_type ), pointer :: height_w3 => null() - type( field_type ), pointer :: height_wth => null() - type( field_type ), pointer :: w2_rmultiplicity => null() - - type( field_type ) :: state_initial(bundle_size) - - type( field_collection_type ), pointer :: ls_fields - type( field_type), pointer :: ls_land_fraction => null() - - type( field_type) :: Q - type( field_type) :: E - type( field_type) :: auv - type( field_type) :: buv_inv - - type(integer_field_type), pointer :: face_selector_ew => null() - type(integer_field_type), pointer :: face_selector_ns => null() - - integer(kind=i_def), parameter :: exner_stencil_depth = 1 - - if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') - - ls_fields => modeldb%fields%get_field_collection("ls_fields") - - call ls_fields%get_field('ls_land_fraction', ls_land_fraction) - - mesh => state(igh_u)%get_mesh() - - mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) - chi => get_coordinates(mesh%get_id()) - panel_id => get_panel_id(mesh%get_id()) - - height_w1 => get_height_fe(W1, mesh%get_id()) - height_w2 => get_height_fe(W2, mesh%get_id()) - height_w3 => get_height_fe(W3, mesh%get_id()) - height_wth => get_height_fe(Wtheta,mesh%get_id() ) - - w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) - - face_selector_ew => get_face_selector_ew(mesh%get_id()) - face_selector_ns => get_face_selector_ns(mesh%get_id()) - - dlayer_rhs = .false. - alpha_dt = 0.5_r_def * dt - compute_eos = .false. - - u => state(igh_u) - theta => state(igh_t) - rho => state(igh_d) - exner => state(igh_p) - - u_base => state(igh_u) - theta_base => state(igh_t) - rho_base => state(igh_d) - - ls_u => ls_state(igh_u) - ls_theta => ls_state(igh_t) - ls_rho => ls_state(igh_d) - ls_exner => ls_state(igh_p) - - call clone_bundle(state,state_initial , bundle_size) - call copy_bundle(state, state_initial, bundle_size) - call u%copy_field_properties( u_bl_inc ) - call invoke(setval_c(u_bl_inc,0.0_r_def)) - - call rho%copy_field_properties( Q ) - call rho%copy_field_properties( E ) - - call invoke(setval_c(Q,0.0_r_def),& - setval_c(E,0.0_r_def) ) - - call u%copy_field_properties( auv ) - call u%copy_field_properties( buv_inv ) - - call invoke(setval_c(auv,0.0_r_def),& - setval_c(buv_inv,0.0_r_def) ) - - call invoke ( tl_compute_qe_kernel_type(Q, & - E, & - ls_state(igh_d), & - height_w3, height_wth,& - ls_land_fraction, & - log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m ) ) - - call invoke ( tl_compute_aubu_kernel_type(auv, & - buv_inv, & - Q, & - E, & - height_w2, & - w2_rmultiplicity, & - dt, & - Blevs_m ) ) - - call invoke ( tl_bl_inc_kernel_type( u_bl_inc, & - state(igh_u), & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) + nullify( mm_vel, mm_wtheta, mm_w3_inv, & + chi, panel_id, & + geopotential, u, theta, rho, exner, & + mesh, reference_element ) - nullify( mm_vel, mm_wtheta, mm_w3_inv, & - chi, panel_id, & - geopotential, u, theta, rho, exner, & - mesh, reference_element ) - - if ( subroutine_timers ) call timer('tl_bdy_lyr_alg') + if ( LPROF ) call stop_timing( id, 'tl_bdy_lyr_alg' ) - end subroutine tl_bdy_lyr_alg +end subroutine tl_bdy_lyr_alg end module tl_bdy_lyr_alg_mod diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index 155ccf55..b8bb5837 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -58,7 +58,7 @@ module tl_si_timestep_alg_mod use sci_set_any_dof_kernel_mod, only: set_any_dof_kernel_type use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type use matrix_vector_kernel_mod, only: matrix_vector_kernel_type - use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use stabilise_bl_u_kernel_mod, only: stabilise_bl_u_kernel_type ! Derived Types @@ -113,7 +113,6 @@ module tl_si_timestep_alg_mod use timing_mod, only: start_timing, stop_timing, tik, LPROF - implicit none private @@ -786,42 +785,42 @@ contains call u%copy_field_properties( u_star_physical ) call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) - ! Compute u_star = u_np1 + M^-1(-rhs_np1 + rhs_n + rhs_a) - ! du = M^-1(-rhs_np1 + rhs_n + rhs_a - call du%initialise( rhs_adv(igh_u)%get_function_space() ) - call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) - call invoke( setval_c(du, 0.0_r_def), & - aX_plus_Y(rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u)), & - inc_X_plus_Y(rhsu_np1, rhs_adv(igh_u)) ) + ! Compute u_star = u_np1 + M^-1(-rhs_np1 + rhs_n + rhs_a) + ! du = M^-1(-rhs_np1 + rhs_n + rhs_a + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + call invoke( setval_c( du, 0.0_r_def ), & + aX_plus_Y( rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u) ), & + inc_X_plus_Y( rhsu_np1, rhs_adv(igh_u) ) ) - call mass_matrix_solver_alg(du, rhsu_np1 ) + call mass_matrix_solver_alg( du, rhsu_np1 ) - call invoke( X_plus_Y(u_star, du, state(igh_u)) ) + call invoke( X_plus_Y( u_star, du, state(igh_u) ) ) - ! u_star_physical = u_star / dA - ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity - dA => get_da_at_w2(mesh%get_id()) - call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) + ! u_star_physical = u_star / dA + ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity + dA => get_da_at_w2(mesh%get_id()) + call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) - ! For convenience place u_star_physical as igh_u component of state_star - call clone_bundle(state,state_star, bundle_size) - call copy_bundle(state, state_star, bundle_size) - call invoke( setval_x(state_star(igh_u),u_star_physical ) ) + ! For convenience place u_star_physical as igh_u component of state_star + call clone_bundle( state,state_star, bundle_size ) + call copy_bundle( state, state_star, bundle_size ) + call invoke( setval_x( state_star(igh_u), u_star_physical ) ) - call tl_bdy_lyr_alg(modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) - ! u_bl_inc computed from state_star(igh_u) - ! NB use state_star + call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) + ! u_bl_inc computed from state_star(igh_u) + ! NB use state_star - ! u_bl_inc_flux = u_bl_inc * dA - ! i.e., multiply by dA to transform from velocity to flux - call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) + ! u_bl_inc_flux = u_bl_inc * dA + ! i.e., multiply by dA to transform from velocity to flux + call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) - call set_bundle_scalar(0.0_r_def,rhs_phys, bundle_size) - call invoke(name="update_rhs_phys_from_fast_physics", & - matrix_vector_kernel_type(rhs_phys(igh_u) ,u_bl_inc_flux, mm_vel ), & - enforce_bc_kernel_type(rhs_phys(igh_u)) ) + call set_bundle_scalar( 0.0_r_def,rhs_phys, bundle_size ) + call invoke( name="update_rhs_phys_from_fast_physics", & + matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ), & + enforce_bc_kernel_type( rhs_phys(igh_u) ) ) - end if ! l_boundary_layer + end if ! l_boundary_layer if (use_wavedynamics) then diff --git a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 index 45c2cd5f..3d69baf7 100644 --- a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 @@ -3,19 +3,19 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- - +!> @brief Computes u_inc, the change in TLM velocity due to TLM boundary layer processes. module tl_bl_inc_kernel_mod - use argument_mod, only : arg_type, & - GH_FIELD, GH_OPERATOR, & - GH_SCALAR, GH_INTEGER, & - GH_READ, GH_INC, & - GH_REAL, CELL_COLUMN, & - ANY_DISCONTINUOUS_SPACE_1 - use constants_mod, only : r_def, i_def, r_um - use fs_continuity_mod, only : W1, W2, W3 - use kernel_mod, only : kernel_type - use reference_element_mod, only: N + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only : N implicit none @@ -27,15 +27,15 @@ module tl_bl_inc_kernel_mod type, public, extends(kernel_type) :: tl_bl_inc_kernel_type private - type(arg_type) :: meta_args(7) = (/ & - arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ns - arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m - /) + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m + /) integer :: operates_on = CELL_COLUMN contains procedure, nopass :: tl_bl_inc_code @@ -48,117 +48,116 @@ module tl_bl_inc_kernel_mod contains -!> @brief Computes boundary layer u inc -!! @param[in] nlayers Number of layers -!! @param[in,out] u_inc Output -!! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field -!! @param[in] undf_w2 Unique number of degrees of freedom for the output field -!! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field -subroutine tl_bl_inc_code( nlayers, & - u_inc, & - u, & - Auv, & - Buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m, & - ndf_w2, undf_w2, map_w2, & - ndf_w3_2d, undf_w3_2d, map_w3_2d ) - +!> @brief Computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +!> @details The algorithm uses coefficients Auv and Buv_inv computed in tl_compute_aubu_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] u_inc Change in TLM velocity due to TLM boundary layer processes +!! @param[in] u TLM velocity +!! @param[in] nlayers Number of layers +!! @param[in] Auv Coefficient for TLM boundary layer +!! @param[in] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] face_selector_ew 2D field indicating which W/E faces to loop over in this column +!! @param[in] face_selector_ns 2D field indicating which N/S faces to loop over in this column +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3_2d Number of DoFs for 2D W3 per cell +!! @param[in] undf_w3_2d Number of DoFs for this partition for 2D W3 +!! @param[in] map_w3_2d Map for 2D W3 +subroutine tl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) implicit none ! Arguments - integer(kind=i_def), intent(in) :: nlayers - - integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 - integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 - - real(kind=r_def), dimension(undf_w2), intent(in) :: u - REAL(kind=r_def), dimension(undf_w2), intent(in) :: Auv - REAL(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv - - real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc - - integer(kind=i_def), intent(in) :: ndf_w3_2d, undf_w3_2d + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: u + real(kind=r_def), dimension(undf_w2), intent(in) :: Auv + real(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv + integer(kind=i_def), intent(in) :: ndf_w3_2d, undf_w3_2d integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d - integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns - - integer(kind=i_def), intent(in) :: Blevs_m + integer(kind=i_def), intent(in) :: Blevs_m ! Internal variables - integer(kind=i_def) :: df, k, j - - real(kind=r_def) :: a0(1:BLevs_m) - real(kind=r_def) :: a1(1:BLevs_m) - real(kind=r_def) :: a2(1:BLevs_m) - real(kind=r_def) :: u_rhs(1:BLevs_m) - real(kind=r_def) :: u_out(1:BLevs_m) - real(kind=r_def) :: factor_u(1:BLevs_m) + integer(kind=i_def) :: df, k, j + real(kind=r_def) :: a0(1:BLevs_m) ! Coefficient + real(kind=r_def) :: a1(1:BLevs_m) ! Coefficient + real(kind=r_def) :: a2(1:BLevs_m) ! Coefficient + real(kind=r_def) :: u_rhs(1:BLevs_m) ! Local perturbation velocity variable + real(kind=r_def) :: u_out(1:BLevs_m) ! Local perturbation velocity variable + real(kind=r_def) :: factor_u(1:BLevs_m) ! Loop over horizontal W2 DoFs do j = 1, face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)) df = j - if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 & - .and. face_selector_ew(map_w3_2d(1)) == 1) df = N - - a0=0.0_r_def - a1=0.0_r_def - a2=0.0_r_def - u_rhs=0.0_r_def - u_out=0.0_r_def - factor_u=0.0_r_def - -! ===================== set up coeffs a0,a1,a2,u_rhs ===================== - - DO k=1,BLevs_m - IF (k == 1) THEN - a0(1) = 1.0_r_def+(Auv(map_w2(df)+1)+Auv(map_w2(df)+0))/Buv_inv(map_w2(df)+1) - a1(k) = -Auv(map_w2(df)+1)/Buv_inv(map_w2(df)+1) - u_rhs(1) = (Auv(map_w2(df)+1) & - * (u(map_w2(df)+1)-u(map_w2(df)+0))-Auv(map_w2(df)+0)*u(map_w2(df)+0))/Buv_inv(map_w2(df)+1) - ELSE IF (k > 1 .AND. k < BLevs_m) THEN - a0(k) = 1.0_r_def+(Auv(map_w2(df)+k)+Auv(map_w2(df)+k-1))/Buv_inv(map_w2(df)+k) - a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) - a1(k) = -Auv(map_w2(df)+k)/Buv_inv(map_w2(df)+k) - u_rhs(k) = (Auv(map_w2(df)+k) & - * (u(map_w2(df)+k)-u(map_w2(df)+k-1)) & - - Auv(map_w2(df)+k-1)*(u(map_w2(df)+k-1)-u(map_w2(df)+k-2)))/Buv_inv(map_w2(df)+k) - ELSE - a0(k) = 1.0_r_def+Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) - a2(k) = -Auv(map_w2(df)+k-1)/Buv_inv(map_w2(df)+k) - u_rhs(k) = & - -(Auv(map_w2(df)+k-1)*(u(map_w2(df)+k-1)-u(map_w2(df)+k-2)))/Buv_inv(map_w2(df)+k) - END IF - END DO - -! ====================== transform to upper triangular form ====================== - - DO k=1,BLevs_m - IF (k == 1) THEN - a0(1) = 1.0_r_def/a0(1) - ELSE - factor_u(k) = a2(k)*a0(k-1) - a0(k) = 1.0_r_def/(a0(k)-factor_u(k)*a1(k-1)) - u_rhs(k) = u_rhs(k)-factor_u(k)*u_rhs(k-1) - END IF - END DO - -! ============================== Solve for u_inc ============================== - - u_out(BLevs_m) = a0(BLevs_m)*u_rhs(BLevs_m) - u_inc(map_w2(df)+BLevs_m-1) = u_out(BLevs_m) - - DO k=BLevs_m-1,1,-1 - u_out(k) = a0(k)*(u_rhs(k)-a1(k)*u_out(k+1)) - u_inc(map_w2(df)+k-1) = u_out(k) - END DO + if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 .and. face_selector_ew(map_w3_2d(1)) == 1) df = N + + a0 = 0.0_r_def + a1 = 0.0_r_def + a2 = 0.0_r_def + u_rhs = 0.0_r_def + u_out = 0.0_r_def + factor_u = 0.0_r_def + + ! Set up coeffs a0, a1, a2, u_rhs + do k = 1, BLevs_m + if (k == 1) then + a0(1) = 1.0_r_def + (Auv(map_w2(df) + 1) + Auv(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + a1(k) = -Auv(map_w2(df) + 1) / Buv_inv(map_w2(df) + 1) + u_rhs(1) = (Auv(map_w2(df) + 1) & + * (u(map_w2(df) + 1) - u(map_w2(df) + 0)) - Auv(map_w2(df) + 0) * u(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + else if (k > 1 .and. k < BLevs_m) then + a0(k) = 1.0_r_def + (Auv(map_w2(df) + k) + Auv(map_w2(df) + k - 1)) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + a1(k) = -Auv(map_w2(df) + k) / Buv_inv(map_w2(df) + k) + u_rhs(k) = (Auv(map_w2(df) + k) & + * (u(map_w2(df) + k) - u(map_w2(df) + k - 1)) & + - Auv(map_w2(df) + k - 1) * (u(map_w2(df) + k - 1) - u(map_w2(df) + k - 2))) / Buv_inv(map_w2(df) + k) + else + a0(k) = 1.0_r_def + Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + u_rhs(k) = -(Auv(map_w2(df) + k - 1) * (u(map_w2(df) + k - 1) - u(map_w2(df) + k - 2))) / Buv_inv(map_w2(df) + k) + end if + end do + + ! Transform to upper triangular form + do k = 1, BLevs_m + if (k == 1) then + a0(1) = 1.0_r_def / a0(1) + else + factor_u(k) = a2(k) * a0(k - 1) + a0(k) = 1.0_r_def / (a0(k) - factor_u(k) * a1(k - 1)) + u_rhs(k) = u_rhs(k) - factor_u(k) * u_rhs(k - 1) + end if + end do + + ! Solve for u_inc + u_out(BLevs_m) = a0(BLevs_m) * u_rhs(BLevs_m) + u_inc(map_w2(df) + BLevs_m - 1) = u_out(BLevs_m) + do k = BLevs_m - 1, 1, -1 + u_out(k) = a0(k) * (u_rhs(k) - a1(k) * u_out(k + 1)) + u_inc(map_w2(df) + k - 1) = u_out(k) + end do end do ! Loop over horizontal W2 DoFs end subroutine tl_bl_inc_code -end module tl_bl_inc_kernel_mod +end module tl_bl_inc_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 index 3a34b1d9..d4244fa1 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 @@ -3,13 +3,13 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- - +!> @brief Computes coefficients Auv and Buv_inv used in the TLM boundary layer scheme for momentum. module tl_compute_aubu_kernel_mod - use argument_mod, only : arg_type, func_type, & - GH_FIELD, GH_OPERATOR, & - GH_SCALAR, GH_INTEGER, & - GH_READ, GH_INC, GH_READWRITE, & + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & ANY_DISCONTINUOUS_SPACE_1 use constants_mod, only : r_def, i_def, r_um @@ -23,7 +23,6 @@ module tl_compute_aubu_kernel_mod !--------------------------------------------------------------------------- ! Public types !--------------------------------------------------------------------------- - type, public, extends(kernel_type) :: tl_compute_aubu_kernel_type private type(arg_type) :: meta_args(8) = (/ & @@ -36,7 +35,6 @@ module tl_compute_aubu_kernel_mod arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! dt arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m /) - integer :: operates_on = CELL_COLUMN contains procedure, nopass :: tl_compute_aubu_code @@ -49,75 +47,71 @@ module tl_compute_aubu_kernel_mod contains -!> @brief Computes coefficients Auv and Buv_inv -!! @param[in] nlayers Number of layers -!! @param[in] ndf_w2 Number of degrees of freedom per cell for the output field -!! @param[in] undf_w2 Unique number of degrees of freedom for the output field -!! @param[in] map_w2 Dofmap for the cell at the base of the column for the output field -subroutine tl_compute_aubu_code(nlayers, & - Auv, & - Buv_inv, & - Q, & - E, & - height_w2, & - w2_rmultiplicity, & - dt, & - Blevs_m, & - ndf_w2, undf_w2, map_w2, & - ndf_w3, undf_w3, map_w3) - +!> @brief Computes coefficients Auv and Buv_inv used in the TLM boundary layer scheme for momentum. +!> @details Auv and Buv_inv are derived from coefficients Q and E which are computed in tl_compute_qe_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] Auv Coefficient for TLM boundary layer +!! @param[in,out] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] Q Coefficient for TLM boundary layer +!! @param[in] E Coefficient for TLM boundary layer +!! @param[in] height_w2 Height of w2 space levels above the surface +!! @param[in] w2_rmultiplicity Reciprocal of multiplicity for W2 +!! @param[in] dt TLM time step +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3 Number of degrees of freedom per cell for w3 space +!! @param[in] undf_w3 Number of unique degrees of freedom for w3 space +!! @param[in] map_w3 Dofmap for the cell at column base for w3 +subroutine tl_compute_aubu_code( nlayers, & + Auv, & + Buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3, undf_w3, map_w3) implicit none ! Arguments - integer(kind=i_def), intent(in) :: nlayers - - integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 - integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 - - integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 - integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 - - real(kind=r_def), dimension(undf_w2), intent(in) :: w2_rmultiplicity - - REAL(kind=r_def), dimension(undf_w2), intent(inout) :: Auv !! (0:BLevs_m) - REAL(kind=r_def), dimension(undf_w2), intent(inout) :: Buv_inv !! Use inverse of Buv as this is what is averaged - - REAL(kind=r_def), dimension(undf_w3), intent(in) :: Q !! (0:BLevs_m) - REAL(kind=r_def), dimension(undf_w3), intent(in) :: E !! (BLevs_m) - - real(kind=r_def), dimension(undf_w2), intent(in) :: height_w2 - - real(kind=r_def), intent(in) :: dt - integer(kind=i_def), intent(in) :: Blevs_m + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: w2_rmultiplicity + real(kind=r_def), dimension(undf_w2), intent(inout) :: Auv !(0:BLevs_m) + real(kind=r_def), dimension(undf_w2), intent(inout) :: Buv_inv ! Use inverse of Buv as this is what is averaged + real(kind=r_def), dimension(undf_w3), intent(in) :: Q ! (0:BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(in) :: E ! (BLevs_m) + real(kind=r_def), dimension(undf_w2), intent(in) :: height_w2 + real(kind=r_def), intent(in) :: dt + integer(kind=i_def), intent(in) :: Blevs_m ! Internal variables - integer(kind=i_def) :: df, df3, k - -df3=1 - - do df = 1,4 - do k = 0, BLevs_m - - IF (k == 0) THEN - Auv(map_w2(df)+k) = Auv(map_w2(df)+k)+ & - w2_rmultiplicity(map_w2(df) ) * & - Q(map_w3(df3) ) - - ELSE ! 1 <= k <= BLevs_m - - Auv(map_w2(df)+k) = Auv(map_w2(df)+k)+ & - w2_rmultiplicity(map_w2(df)+k ) * & - Q(map_w3(df3) + k ) / ( height_w2(map_w2(df)+k) - height_w2(map_w2(df)+k-1) ) - - Buv_inv(map_w2(df)+k) = Buv_inv(map_w2(df)+k)+ & - ( w2_rmultiplicity(map_w2(df)+k ) * E( map_w3(df3) + k) ) / dt - - END IF - + integer(kind=i_def) :: df, df3, k + + df3 = 1 + + do df = 1, 4 + do k = 0, BLevs_m + if (k == 0) then + Auv(map_w2(df) + k) = Auv(map_w2(df) + k) + w2_rmultiplicity(map_w2(df)) * Q(map_w3(df3)) + else ! 1 <= k <= BLevs_m + Auv(map_w2(df) + k) = Auv(map_w2(df) + k) + & + w2_rmultiplicity(map_w2(df) + k) * Q(map_w3(df3) + k) / (height_w2(map_w2(df) + k) - height_w2(map_w2(df) + k - 1)) + Buv_inv(map_w2(df) + k) = Buv_inv(map_w2(df) + k) + ( w2_rmultiplicity(map_w2(df) + k) * E(map_w3(df3) + k) ) / dt + end if end do ! k = 0, BLevs_m - end do ! df = 1,4 + end do ! df = 1, 4 end subroutine tl_compute_aubu_code -end module tl_compute_aubu_kernel_mod +end module tl_compute_aubu_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 index ca6acf12..f56a1190 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -3,13 +3,13 @@ ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- - +!> @brief Computes coefficients Q and E used in the TLM boundary layer scheme for momentum. module tl_compute_qe_kernel_mod - use argument_mod, only : arg_type, func_type, & - GH_FIELD, GH_OPERATOR, & - GH_SCALAR, GH_INTEGER, & - GH_READ, GH_INC, GH_READWRITE, & + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & ANY_DISCONTINUOUS_SPACE_1 use constants_mod, only : r_def, i_def, r_um @@ -23,24 +23,23 @@ module tl_compute_qe_kernel_mod !--------------------------------------------------------------------------- ! Public types !--------------------------------------------------------------------------- - type, public, extends(kernel_type) :: tl_compute_qe_kernel_type private - type(arg_type) :: meta_args(14) = (/ & - arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! Q - arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! E - arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! ls_rho - arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! height_w3 - arg_type(GH_FIELD, GH_REAL, GH_READ, Wtheta), & ! height_wth + type(arg_type) :: meta_args(14) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! Q + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! E + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! ls_rho + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! height_w3 + arg_type(GH_FIELD, GH_REAL, GH_READ, Wtheta), & ! height_wth arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1 ), & ! ls_land_fraction - arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! log_layer - arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! Blevs_m - arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! e_folding_levs_m - arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_land_m - arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_sea_m - arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_land_m - arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_sea_m - arg_type(GH_SCALAR, GH_REAL, GH_READ ) & ! L_0_m + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! log_layer + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! Blevs_m + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! e_folding_levs_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ) & ! L_0_m /) integer :: operates_on = CELL_COLUMN contains @@ -54,123 +53,117 @@ module tl_compute_qe_kernel_mod contains -!> @brief Computes coefficients Q and E -!! @param[in] nlayers Number of layers -!! @param[in] ndf_w3 Number of degrees of freedom per cell for the output field -!! @param[in] undf_w3 Unique number of degrees of freedom for the output field -!! @param[in] map_w3 Dofmap for the cell at the base of the column for the output field -subroutine tl_compute_qe_code( nlayers, & - Q, & - E, & - ls_rho, & - height_w3, & - height_wth, & - ls_land_fraction, & - log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m, & - ndf_w3, undf_w3, map_w3, & - ndf_wtheta, undf_wtheta, map_wtheta, & - ndf_2d, undf_2d, map_2d ) - +!> @brief Computes coefficients Q and E used in the TLM boundary layer scheme for momentum. +!> @details The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] Q Coefficient for TLM boundary layer +!! @param[in,out] E Coefficient for TLM boundary layer +!! @param[in] ls_rho Linearisation state for density +!! @param[in] height_w3 Height of w3 space levels above the surface +!! @param[in] height_wth Height of wth space levels above surface +!! @param[in] ls_land_fraction Land area fraction +!! @param[in] log_layer Number of levels in log layer +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] e_folding_levs_m e-folding level in exchange coefficient for momemtum +!! @param[in] z_land_m Effective roughness length for momemtum over land +!! @param[in] z_sea_m Effective roughness length for momemtum over sea +!! @param[in] u_land_m Friction velocity for momemtum over land +!! @param[in] u_sea_m Friction velocity for momemtum over sea +!! @param[in] L_0_m Mixing length for momemtum +!! @param[in] ndf_w3 Number of degrees of freedom per cell for w3 space +!! @param[in] undf_w3 Number of unique degrees of freedom for w3 space +!! @param[in] map_w3 Dofmap for the cell at column base for w3 +!! @param[in] ndf_wtheta Number of degrees of freedom per cell for wtheta space +!! @param[in] undf_wtheta Number of unique degrees of freedom for wtheta space +!! @param[in] map_wtheta Dofmap for the cell at the base of the column for wtheta +!! @param[in] ndf_2d Number of degrees of freedom per cell for 2D field +!! @param[in] undf_2d Number of unique degrees of freedom for 2D field +!! @param[in] map_2d Dofmap for 2D field +subroutine tl_compute_qe_code( nlayers, & + Q, & + E, & + ls_rho, & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m, & + ndf_w3, undf_w3, map_w3, & + ndf_wtheta, undf_wtheta, map_wtheta, & + ndf_2d, undf_2d, map_2d ) implicit none ! Arguments - integer(kind=i_def), intent(in) :: nlayers - - integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 - integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 - - integer(kind=i_def), intent(in) :: undf_wtheta, ndf_wtheta - integer(kind=i_def), dimension(ndf_wtheta),intent(in) :: map_wtheta - - integer(kind=i_def), intent(in) :: undf_2d, ndf_2d - integer(kind=i_def), dimension(ndf_2d), intent(in) :: map_2d - - REAL(kind=r_def), dimension(undf_w3), intent(inout) :: Q !! (0:BLevs_m) - REAL(kind=r_def), dimension(undf_w3), intent(inout) :: E !! (BLevs_m) - - real(kind=r_def), dimension(undf_w3), intent(in) :: ls_rho - - real(kind=r_def), dimension(undf_w3), intent(in) :: height_w3 - real(kind=r_def), dimension(undf_wtheta), intent(in) :: height_wth - real(kind=r_def), dimension(undf_2d), intent(in) :: ls_land_fraction - - integer(kind=i_def), intent(in) :: log_layer,Blevs_m,e_folding_levs_m - real(kind=r_def), intent(in) :: u_land_m, u_sea_m, z_land_m, & - z_sea_m, L_0_m + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + integer(kind=i_def), intent(in) :: undf_wtheta, ndf_wtheta + integer(kind=i_def), dimension(ndf_wtheta), intent(in) :: map_wtheta + integer(kind=i_def), intent(in) :: undf_2d, ndf_2d + integer(kind=i_def), dimension(ndf_2d), intent(in) :: map_2d + real(kind=r_def), dimension(undf_w3), intent(inout) :: Q ! (0:BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(inout) :: E ! (BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(in) :: ls_rho + real(kind=r_def), dimension(undf_w3), intent(in) :: height_w3 + real(kind=r_def), dimension(undf_wtheta), intent(in) :: height_wth + real(kind=r_def), dimension(undf_2d), intent(in) :: ls_land_fraction + integer(kind=i_def), intent(in) :: log_layer,Blevs_m,e_folding_levs_m + real(kind=r_def), intent(in) :: u_land_m, u_sea_m, z_land_m, z_sea_m, L_0_m ! Internal variables - integer(kind=i_def) :: df, k - real(kind=r_def) :: roughness_length_m - - REAL(kind=r_def), PARAMETER :: Von_Karman=0.4_r_def - REAL(kind=r_def) :: L_diff_m(1:BLevs_m) - - real(kind=r_def) :: u1 - -! ============================== setup roughness_length_m ============================== - - df = 1 - roughness_length_m = z_land_m*ls_land_fraction(map_2d(df)) + & - z_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) - -! ============================== setup L_diff ============================== -! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above - -! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 -! L_diff_m(k) defined for 1 <= k <= BLevs_m - -df=1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell - -DO k = 1, BLevs_m - IF (k <= Log_layer) THEN - L_diff_m(k)=Von_Karman * ( height_w3(map_w3(df)+k) - height_w3(map_w3(df)+k-1)) & - / (LOG((height_w3(map_w3(df)+k)- height_wth(map_wtheta(df)) & - + roughness_length_m)/(height_w3(map_w3(df)+k-1) & - - height_wth(map_wtheta(df)) + roughness_length_m) )+Von_Karman & - * (height_w3(map_w3(df)+k)-height_w3(map_w3(df)+k-1))/L_0_m) - ELSE - L_diff_m(k)=Von_Karman * (( height_wth(map_wtheta(df)+k)- height_wth(map_wtheta(df)) & - + roughness_length_m)/(1.0_r_def +( height_wth(map_wtheta(df)+k) & - - height_wth(map_wtheta(df))+roughness_length_m)/L_0_m)) - END IF -END DO - -! ============================== Define Q and E ============================== -! E is on cell centres -! Q is on centre of horizontal faces - for convenience indexed by centre of cell above - -! vertical numbering (k index) matches that in PF_bdy_lyr.f90, in which centre of lowest cell is rho level 1 -! Q(k) defined for 0 <= k <= BLevs_m -! E(k) defined for 1 <= k <= BLevs_m - -df=1 -u1=u_land_m*ls_land_fraction(map_2d(df)) + & - u_sea_m*(1.0_r_def-ls_land_fraction(map_2d(df))) - -DO k=0,BLevs_m - IF (k == 0) THEN - Q( map_w3(df) + k)=Von_Karman * u1 & - / LOG(((height_w3(map_w3(df)+0) - height_wth(map_wtheta(df)+0) & ! - + roughness_length_m)/(roughness_length_m))) - ELSE ! ie k >= 1 - Q( map_w3(df) + k)=L_diff_m(k) * u1 & - * EXP( (height_wth(map_wtheta(df))-height_wth(map_wtheta(df)+k)) & - / (height_wth(map_wtheta(df)+e_folding_levs_m)-height_wth(map_wtheta(df)))) - - - E(map_w3(df) + k) = ls_rho( map_w3(df) + k-1 )*(height_wth(map_wtheta(df)+k)-height_wth(map_wtheta(df)+k-1)) - - END IF -END DO + integer(kind=i_def) :: df, k + real(kind=r_def) :: roughness_length_m + real(kind=r_def), parameter :: Von_Karman = 0.4_r_def + real(kind=r_def) :: L_diff_m(1:BLevs_m) + real(kind=r_def) :: u1 + + df = 1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell + roughness_length_m = z_land_m * ls_land_fraction(map_2d(df)) + z_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) + + ! Set up L_diff. + ! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above. + ! Vertical numbering (k index) matches that in old Var schemePF_bdy_lyr.f90 (see link above), + ! in which centre of lowest cell is rho level 1. + ! L_diff_m(k) defined for 1 <= k <= BLevs_m. + do k = 1, BLevs_m + if (k <= Log_layer) then + L_diff_m(k) = Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) & + / (log((height_w3(map_w3(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m) & + / (height_w3(map_w3(df) + k - 1) - height_wth(map_wtheta(df)) + roughness_length_m) ) & + + Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) / L_0_m) + else + L_diff_m(k) = Von_Karman * ((height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) & + + roughness_length_m) / (1.0_r_def + (height_wth(map_wtheta(df) + k) & + - height_wth(map_wtheta(df)) + roughness_length_m) / L_0_m)) + end if + end do + + ! Define Q and E + ! E is on cell centres + ! Q is on centre of horizontal faces - for convenience indexed by centre of cell above + ! Q(k) defined for 0 <= k <= BLevs_m + ! E(k) defined for 1 <= k <= BLevs_m + u1 = u_land_m * ls_land_fraction(map_2d(df)) + u_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) + do k = 0, BLevs_m + if (k == 0) then + Q(map_w3(df) + k) = Von_Karman * u1 & + / log(((height_w3(map_w3(df) + 0) - height_wth(map_wtheta(df) + 0) + roughness_length_m) / (roughness_length_m))) + else ! i.e., k >= 1 + Q(map_w3(df) + k) = L_diff_m(k) * u1 & + * exp((height_wth(map_wtheta(df)) - height_wth(map_wtheta(df) + k)) & + / (height_wth(map_wtheta(df) + e_folding_levs_m) - height_wth(map_wtheta(df)))) + E(map_w3(df) + k) = ls_rho(map_w3(df) + k - 1) * (height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df) + k - 1)) + end if + end do end subroutine tl_compute_qe_code -end module tl_compute_qe_kernel_mod +end module tl_compute_qe_kernel_mod From 4b9814f158ebb1ea4b419500084da68340c1bb43 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Wed, 28 Jan 2026 17:45:59 +0000 Subject: [PATCH 58/68] Refactor tl_compute_qe_kernel_mod --- .../linear_physics/atl_bdy_lyr_alg.x90 | 2 +- .../tl_compute_qe_kernel_mod.F90 | 33 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index b36f4b98..ad32e812 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -103,7 +103,7 @@ subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) type( field_type ) :: state_initial(bundle_size) type( field_collection_type ), pointer :: ls_fields - type( field_type), pointer :: ls_land_fraction => null() + type( field_type), pointer :: ls_land_fraction => null() ! Coefficients computed from linearisation state type( field_type ) :: Q diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 index f56a1190..a3ad4099 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -124,6 +124,8 @@ subroutine tl_compute_qe_code( nlayers, & real(kind=r_def), parameter :: Von_Karman = 0.4_r_def real(kind=r_def) :: L_diff_m(1:BLevs_m) real(kind=r_def) :: u1 + real(kind=r_def) :: num + real(kind=r_def) :: denom df = 1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell roughness_length_m = z_land_m * ls_land_fraction(map_2d(df)) + z_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) @@ -135,15 +137,17 @@ subroutine tl_compute_qe_code( nlayers, & ! L_diff_m(k) defined for 1 <= k <= BLevs_m. do k = 1, BLevs_m if (k <= Log_layer) then - L_diff_m(k) = Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) & - / (log((height_w3(map_w3(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m) & - / (height_w3(map_w3(df) + k - 1) - height_wth(map_wtheta(df)) + roughness_length_m) ) & - + Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) / L_0_m) + ! num and denom to take log of + num = height_w3(map_w3(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m + denom = height_w3(map_w3(df) + k - 1) - height_wth(map_wtheta(df)) + roughness_length_m + ! num and denom of final expression + denom = log(num / denom) + Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) / L_0_m + num = (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) else - L_diff_m(k) = Von_Karman * ((height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) & - + roughness_length_m) / (1.0_r_def + (height_wth(map_wtheta(df) + k) & - - height_wth(map_wtheta(df)) + roughness_length_m) / L_0_m)) + num = height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m + denom = 1.0_r_def + (height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m) / L_0_m end if + L_diff_m(k) = Von_Karman * num / denom end do ! Define Q and E @@ -154,12 +158,17 @@ subroutine tl_compute_qe_code( nlayers, & u1 = u_land_m * ls_land_fraction(map_2d(df)) + u_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) do k = 0, BLevs_m if (k == 0) then - Q(map_w3(df) + k) = Von_Karman * u1 & - / log(((height_w3(map_w3(df) + 0) - height_wth(map_wtheta(df) + 0) + roughness_length_m) / (roughness_length_m))) + ! num and denom to take log of + num = height_w3(map_w3(df) + 0) - height_wth(map_wtheta(df) + 0) + roughness_length_m + denom = roughness_length_m + ! num and denom of final expression + denom = log(num / denom) + num = Von_Karman * u1 + Q(map_w3(df) + k) = num / denom else ! i.e., k >= 1 - Q(map_w3(df) + k) = L_diff_m(k) * u1 & - * exp((height_wth(map_wtheta(df)) - height_wth(map_wtheta(df) + k)) & - / (height_wth(map_wtheta(df) + e_folding_levs_m) - height_wth(map_wtheta(df)))) + num = height_wth(map_wtheta(df)) - height_wth(map_wtheta(df) + k) + denom = height_wth(map_wtheta(df) + e_folding_levs_m) - height_wth(map_wtheta(df)) + Q(map_w3(df) + k) = L_diff_m(k) * u1 * exp(num / denom) E(map_w3(df) + k) = ls_rho(map_w3(df) + k - 1) * (height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df) + k - 1)) end if end do From 43529b03a97a68db1ad0e3df86568e80873bce0c Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 10:47:09 +0000 Subject: [PATCH 59/68] Responding to SR --- .../linear_physics/atlt_bdy_lyr_alg_mod.x90 | 4 +- .../linear_physics/atl_bdy_lyr_alg.x90 | 211 ++++++----------- .../timestepping/atl_si_timestep_alg_mod.x90 | 36 +-- .../linear_physics/tl_bdy_lyr_alg.x90 | 216 ++++++------------ .../timestepping/tl_si_timestep_alg_mod.x90 | 35 +-- 5 files changed, 181 insertions(+), 321 deletions(-) diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 index b2656a25..c1294aa5 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 @@ -133,7 +133,7 @@ module atlt_bdy_lyr_alg_mod call invoke( setval_random( ls_state(igh_d) ), setval_random( ls_state(igh_p) ) ) ! Tangent linear - call tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state(igh_u), ls_state, dt ) ! < Mx, Mx > call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & @@ -153,7 +153,7 @@ module atlt_bdy_lyr_alg_mod ! Adjoint alg call and inner products ! Adjoint - call atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt ) + call atl_bdy_lyr_alg(modeldb, u_bl_inc, state(igh_u), ls_state, dt ) ! < AMx, x > call invoke( x_innerproduct_y( ip2(1), & diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index ad32e812..fea5b27f 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -6,18 +6,14 @@ !> @brief (Adjoint of) given TL state(igh_u) compute TLM boundary layer increment u_bl_inc module atl_bdy_lyr_alg_mod - use constants_mod, only: r_def, i_def, l_def + use constants_mod, only: r_def use field_collection_mod, only: field_collection_type use integer_field_mod, only: integer_field_type use driver_modeldb_mod, only: modeldb_type use sci_geometric_constants_mod, only: get_height_fe, & - get_coordinates, & - get_panel_id, & get_face_selector_ew, & get_face_selector_ns - use sci_fem_constants_mod, only: get_mass_matrix_fe, & - get_rmultiplicity_fe - use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle + use sci_fem_constants_mod, only: get_rmultiplicity_fe use field_mod, only: field_type use linear_config_mod, only: log_layer, & Blevs_m, & @@ -27,13 +23,11 @@ module atl_bdy_lyr_alg_mod z_land_m, & z_sea_m, & L_0_m - use operator_mod, only: operator_type use derived_config_mod, only: bundle_size - use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + use field_indices_mod, only: igh_d use timing_mod, only: start_timing, stop_timing, tik, LPROF - use reference_element_mod, only: reference_element_type use mesh_mod, only: mesh_type - use fs_continuity_mod, only: W1, W2, W3, Wtheta + use fs_continuity_mod, only: W2, W3, Wtheta use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use atl_bl_inc_kernel_mod, only: atl_bl_inc_kernel_type @@ -54,161 +48,94 @@ contains !> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf !> @param[in,out] modeldb Structure containing the model state !> @param[in,out] u_bl_inc TLM boundary layer increment -!> @param[in,out] state The current TL model prognostic state +!> @param[in,out] u The current TL model prognostic u field, state(igh_u) !> @param[in] ls_state Lin state for Prognostic model state !> @param[in] dt The TL model timestep length -subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) +subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, u, ls_state, dt) implicit none type(modeldb_type), target, intent(inout) :: modeldb type(field_type), intent(inout) :: u_bl_inc - type(field_type), target, intent(inout) :: state(bundle_size) - type(field_type), target, intent(in) :: ls_state(bundle_size) + type(field_type), intent(inout) :: u + type(field_type), target, intent(in) :: ls_state(bundle_size) real(kind=r_def), intent(in) :: dt - ! Local variables - real(kind=r_def) :: alpha_dt - logical(kind=l_def) :: dlayer_rhs - logical(kind=l_def) :: compute_eos - - type(operator_type), pointer :: mm_vel => null(), & - mm_wtheta => null(), & - mm_w3_inv => null() - - type(field_type), pointer :: chi(:) => null(), & - panel_id => null(), & - geopotential => null(), & - u => null(), & - theta => null(), & - rho => null(), & - u_base => null(), & - theta_base => null(), & - rho_base => null(), & - exner => null(), & - ls_u => null(), & - ls_theta => null(), & - ls_rho => null(), & - ls_exner => null() - - class(reference_element_type), pointer :: reference_element => null() - type (mesh_type), pointer :: mesh => null() - - type( field_type ), pointer :: height_w1 => null() - type( field_type ), pointer :: height_w2 => null() - type( field_type ), pointer :: height_w3 => null() - type( field_type ), pointer :: height_wth => null() - type( field_type ), pointer :: w2_rmultiplicity => null() - - type( field_type ) :: state_initial(bundle_size) - - type( field_collection_type ), pointer :: ls_fields - type( field_type), pointer :: ls_land_fraction => null() + type(mesh_type), pointer :: mesh + type(field_type), pointer :: height_w2 + type(field_type), pointer :: height_w3 + type(field_type), pointer :: height_wth + type(field_type), pointer :: w2_rmultiplicity + type(integer_field_type), pointer :: face_selector_ew + type(integer_field_type), pointer :: face_selector_ns - ! Coefficients computed from linearisation state - type( field_type ) :: Q - type( field_type ) :: E - type( field_type ) :: auv - type( field_type ) :: buv_inv - - type(integer_field_type), pointer :: face_selector_ew => null() - type(integer_field_type), pointer :: face_selector_ns => null() + type(field_collection_type), pointer :: ls_fields + type(field_type), pointer :: ls_land_fraction - integer(kind=i_def), parameter :: exner_stencil_depth = 1 + ! Coefficients computed from linearisation state + type(field_type) :: Q + type(field_type) :: E + type(field_type) :: auv + type(field_type) :: buv_inv integer(kind=tik) :: id - if ( LPROF ) call start_timing( id, 'atl_bdy_lyr_alg' ) - - ls_fields => modeldb%fields%get_field_collection("ls_fields") + if (LPROF) call start_timing(id, 'atl_bdy_lyr_alg') + ls_fields => modeldb%fields%get_field_collection('ls_fields') call ls_fields%get_field('ls_land_fraction', ls_land_fraction) - mesh => state(igh_u)%get_mesh() - - mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) - chi => get_coordinates(mesh%get_id()) - panel_id => get_panel_id(mesh%get_id()) - - height_w1 => get_height_fe(W1, mesh%get_id()) + mesh => u%get_mesh() height_w2 => get_height_fe(W2, mesh%get_id()) - height_w3 => get_height_fe(W3, mesh%get_id()) - height_wth => get_height_fe(Wtheta,mesh%get_id() ) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta, mesh%get_id()) - w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + w2_rmultiplicity => get_rmultiplicity_fe(W2, mesh%get_id()) face_selector_ew => get_face_selector_ew(mesh%get_id()) face_selector_ns => get_face_selector_ns(mesh%get_id()) - dlayer_rhs = .false. - alpha_dt = 0.5_r_def * dt - compute_eos = .false. - - u => state(igh_u) - theta => state(igh_t) - rho => state(igh_d) - exner => state(igh_p) - - u_base => state(igh_u) - theta_base => state(igh_t) - rho_base => state(igh_d) - - ls_u => ls_state(igh_u) - ls_theta => ls_state(igh_t) - ls_rho => ls_state(igh_d) - ls_exner => ls_state(igh_p) - - call clone_bundle(state,state_initial , bundle_size) - call copy_bundle(state, state_initial, bundle_size) - - call rho%copy_field_properties( Q ) - call rho%copy_field_properties( E ) - - call invoke(setval_c(Q, 0.0_r_def), & - setval_c(E, 0.0_r_def) ) - - call u%copy_field_properties( auv ) - call u%copy_field_properties( buv_inv ) - - call invoke(setval_c(auv, 0.0_r_def), & - setval_c(buv_inv, 0.0_r_def) ) - - call invoke ( tl_compute_qe_kernel_type(Q, & - E, & - ls_state(igh_d), & - height_w3, height_wth,& - ls_land_fraction, & - log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m ) ) - - call invoke ( tl_compute_aubu_kernel_type(auv, & - buv_inv, & - Q, & - E, & - height_w2, & - w2_rmultiplicity, & - dt, & - Blevs_m ) ) - - call invoke ( atl_bl_inc_kernel_type( u_bl_inc, & - state(igh_u), & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) - - nullify( mm_vel, mm_wtheta, mm_w3_inv, & - chi, panel_id, & - geopotential, u, theta, rho, exner, & - mesh, reference_element ) - - if ( LPROF ) call stop_timing( id, 'atl_bdy_lyr_alg' ) + call ls_state(igh_d)%copy_field_properties(Q) + call ls_state(igh_d)%copy_field_properties(E) + call invoke(setval_c(Q, 0.0_r_def), setval_c(E, 0.0_r_def)) + + call u%copy_field_properties(auv) + call u%copy_field_properties(buv_inv) + call invoke(setval_c(auv, 0.0_r_def), setval_c(buv_inv, 0.0_r_def)) + + call invoke(tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m)) + + call invoke(tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m)) + + call invoke(atl_bl_inc_kernel_type(u_bl_inc, & + u, & + auv, & + buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m)) + + if (LPROF) call stop_timing(id, 'atl_bdy_lyr_alg') end subroutine atl_bdy_lyr_alg diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index 51070736..f01c5a84 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -339,7 +339,7 @@ contains type( field_type ) :: u_star type( field_type ) :: u_star_physical type( field_type ) :: rhsu_np1 - type( field_type ), pointer :: dA => null() + type( field_type ), pointer :: dA if ( LPROF ) call start_timing( id, 'atl_si_timestep_type::step' ) @@ -670,22 +670,26 @@ contains if (inner > 1) then - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + if (use_wavedynamics) then - call atl_rhs_alg( self%rhs_np1, & - -varalpha*cast_dt, & - self%state1, & - self%state2, & - moist_dyn, & - self%ls_state_itns(:,ls_outer,ls_inner), & - self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & - .true., & - dlayer_on, & - modeldb%clock ) + call set_bundle_scalar( 0.0_r_def, self%state1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state2, bundle_size ) - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,ls_inner), & + self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state, self%state2, self%state, bundle_size ) + call add_bundle( self%state, self%state1, self%state, bundle_size ) + + end if end if @@ -729,7 +733,7 @@ contains inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & setval_c( u_bl_inc_flux, 0.0_r_def ) ) - call atl_bdy_lyr_alg( modeldb, u_bl_inc, self%state_star, & + call atl_bdy_lyr_alg( modeldb, u_bl_inc, self%state_star(igh_u), & self%ls_state_itns(:,ls_outer,1), cast_dt ) ! Adj of state_star(igh_u) <- u_star_physical diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index 82d5d442..6296808f 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -6,18 +6,14 @@ !> @brief Given TL state(igh_u) compute TLM boundary layer increment u_bl_inc module tl_bdy_lyr_alg_mod - use constants_mod, only: r_def, i_def, l_def + use constants_mod, only: r_def use field_collection_mod, only: field_collection_type use integer_field_mod, only: integer_field_type use driver_modeldb_mod, only: modeldb_type use sci_geometric_constants_mod, only: get_height_fe, & - get_coordinates, & - get_panel_id, & get_face_selector_ew, & get_face_selector_ns - use sci_fem_constants_mod, only: get_mass_matrix_fe, & - get_rmultiplicity_fe - use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle + use sci_fem_constants_mod, only: get_rmultiplicity_fe use field_mod, only: field_type use linear_config_mod, only: log_layer, & Blevs_m, & @@ -27,13 +23,11 @@ module tl_bdy_lyr_alg_mod z_land_m, & z_sea_m, & L_0_m - use operator_mod, only: operator_type use derived_config_mod, only: bundle_size - use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p + use field_indices_mod, only: igh_d use timing_mod, only: start_timing, stop_timing, tik, LPROF - use reference_element_mod, only: reference_element_type use mesh_mod, only: mesh_type - use fs_continuity_mod, only: W1, W2, W3, Wtheta + use fs_continuity_mod, only: W2, W3, Wtheta use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type use tl_bl_inc_kernel_mod, only: tl_bl_inc_kernel_type @@ -54,163 +48,97 @@ contains !> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf !> @param[in,out] modeldb Structure containing the model state !> @param[in,out] u_bl_inc TLM boundary layer increment -!> @param[in,out] state The current TL model prognostic state +!> @param[in,out] u The current TL model prognostic u field, state(igh_u) !> @param[in] ls_state Lin state for Prognostic model state !> @param[in] dt The TL model timestep length -subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, state, ls_state, dt) +subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, u, ls_state, dt) implicit none type(modeldb_type), target, intent(inout) :: modeldb type(field_type), intent(inout) :: u_bl_inc - type(field_type), target, intent(inout) :: state(bundle_size) - type(field_type), target, intent(in) :: ls_state(bundle_size) + type(field_type), intent(inout) :: u + type(field_type), target, intent(in) :: ls_state(bundle_size) real(kind=r_def), intent(in) :: dt - ! Local variables - real(kind=r_def) :: alpha_dt - logical(kind=l_def) :: dlayer_rhs - logical(kind=l_def) :: compute_eos - - type(operator_type), pointer :: mm_vel => null(), & - mm_wtheta => null(), & - mm_w3_inv => null() - - type(field_type), pointer :: chi(:) => null(), & - panel_id => null(), & - geopotential => null(), & - u => null(), & - theta => null(), & - rho => null(), & - u_base => null(), & - theta_base => null(), & - rho_base => null(), & - exner => null(), & - ls_u => null(), & - ls_theta => null(), & - ls_rho => null(), & - ls_exner => null() - - class(reference_element_type), pointer :: reference_element => null() - type (mesh_type), pointer :: mesh => null() - - type( field_type ), pointer :: height_w1 => null() - type( field_type ), pointer :: height_w2 => null() - type( field_type ), pointer :: height_w3 => null() - type( field_type ), pointer :: height_wth => null() - type( field_type ), pointer :: w2_rmultiplicity => null() - - type( field_type ) :: state_initial(bundle_size) - - type( field_collection_type ), pointer :: ls_fields - type( field_type), pointer :: ls_land_fraction => null() + type(mesh_type), pointer :: mesh + type(field_type), pointer :: height_w2 + type(field_type), pointer :: height_w3 + type(field_type), pointer :: height_wth + type(field_type), pointer :: w2_rmultiplicity + type(integer_field_type), pointer :: face_selector_ew + type(integer_field_type), pointer :: face_selector_ns - ! Coefficients computed from linearisation state - type( field_type ) :: Q - type( field_type ) :: E - type( field_type ) :: auv - type( field_type ) :: buv_inv - - type(integer_field_type), pointer :: face_selector_ew => null() - type(integer_field_type), pointer :: face_selector_ns => null() + type(field_collection_type), pointer :: ls_fields + type(field_type), pointer :: ls_land_fraction - integer(kind=i_def), parameter :: exner_stencil_depth = 1 + ! Coefficients computed from linearisation state + type(field_type) :: Q + type(field_type) :: E + type(field_type) :: auv + type(field_type) :: buv_inv integer(kind=tik) :: id - if ( LPROF ) call start_timing( id, 'tl_bdy_lyr_alg' ) - - ls_fields => modeldb%fields%get_field_collection("ls_fields") + if (LPROF) call start_timing(id, 'tl_bdy_lyr_alg') + ls_fields => modeldb%fields%get_field_collection('ls_fields') call ls_fields%get_field('ls_land_fraction', ls_land_fraction) - mesh => state(igh_u)%get_mesh() - - mm_wtheta => get_mass_matrix_fe(Wtheta, mesh%get_id()) - chi => get_coordinates(mesh%get_id()) - panel_id => get_panel_id(mesh%get_id()) - - height_w1 => get_height_fe(W1, mesh%get_id()) + mesh => u%get_mesh() height_w2 => get_height_fe(W2, mesh%get_id()) - height_w3 => get_height_fe(W3, mesh%get_id()) - height_wth => get_height_fe(Wtheta,mesh%get_id() ) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta, mesh%get_id()) - w2_rmultiplicity => get_rmultiplicity_fe( W2, mesh%get_id() ) + w2_rmultiplicity => get_rmultiplicity_fe(W2, mesh%get_id()) face_selector_ew => get_face_selector_ew(mesh%get_id()) face_selector_ns => get_face_selector_ns(mesh%get_id()) - dlayer_rhs = .false. - alpha_dt = 0.5_r_def * dt - compute_eos = .false. - - u => state(igh_u) - theta => state(igh_t) - rho => state(igh_d) - exner => state(igh_p) - - u_base => state(igh_u) - theta_base => state(igh_t) - rho_base => state(igh_d) - - ls_u => ls_state(igh_u) - ls_theta => ls_state(igh_t) - ls_rho => ls_state(igh_d) - ls_exner => ls_state(igh_p) - - call clone_bundle(state,state_initial , bundle_size) - call copy_bundle(state, state_initial, bundle_size) - call u%copy_field_properties( u_bl_inc ) - call invoke(setval_c(u_bl_inc,0.0_r_def)) - - call rho%copy_field_properties( Q ) - call rho%copy_field_properties( E ) - - call invoke(setval_c(Q, 0.0_r_def), & - setval_c(E, 0.0_r_def) ) - - call u%copy_field_properties( auv ) - call u%copy_field_properties( buv_inv ) - - call invoke(setval_c(auv, 0.0_r_def), & - setval_c(buv_inv, 0.0_r_def) ) - - call invoke ( tl_compute_qe_kernel_type(Q, & - E, & - ls_state(igh_d), & - height_w3, height_wth,& - ls_land_fraction, & - log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m ) ) - - call invoke ( tl_compute_aubu_kernel_type(auv, & - buv_inv, & - Q, & - E, & - height_w2, & - w2_rmultiplicity, & - dt, & - Blevs_m ) ) - - call invoke ( tl_bl_inc_kernel_type( u_bl_inc, & - state(igh_u), & - auv,buv_inv, & - face_selector_ew, & - face_selector_ns, & - Blevs_m ) ) - - nullify( mm_vel, mm_wtheta, mm_w3_inv, & - chi, panel_id, & - geopotential, u, theta, rho, exner, & - mesh, reference_element ) - - if ( LPROF ) call stop_timing( id, 'tl_bdy_lyr_alg' ) + call u%copy_field_properties(u_bl_inc) + call invoke(setval_c(u_bl_inc, 0.0_r_def)) + + call ls_state(igh_d)%copy_field_properties(Q) + call ls_state(igh_d)%copy_field_properties(E) + call invoke(setval_c(Q, 0.0_r_def), setval_c(E, 0.0_r_def)) + + call u%copy_field_properties(auv) + call u%copy_field_properties(buv_inv) + call invoke(setval_c(auv, 0.0_r_def), setval_c(buv_inv, 0.0_r_def)) + + call invoke(tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m)) + + call invoke(tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m)) + + call invoke(tl_bl_inc_kernel_type(u_bl_inc, & + u, & + auv, & + buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m)) + + if (LPROF) call stop_timing(id, 'tl_bdy_lyr_alg') end subroutine tl_bdy_lyr_alg diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index b8bb5837..976823ce 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -387,7 +387,7 @@ contains type( field_type ) :: u_star type( field_type ) :: u_star_physical type( field_type ) :: rhsu_np1 - type( field_type ), pointer :: dA => null() + type( field_type ), pointer :: dA type( mesh_type ), intent( in ), pointer :: mesh type( mesh_type ), intent( in ), pointer :: twod_mesh @@ -763,17 +763,18 @@ contains ! It still is called there for inner_iterations > 1. ! For the first inner loop, it needs to be called before entering. ! This is because rhs_np1 is used to calculate u_star in tl_bdy_lyr_alg. - call tl_rhs_alg( rhs_np1, & - -varalpha*cast_dt, & - state, & - state, & - moist_dyn, & - ls_state_itns( :, ls_outer, 1 ), & - ls_moist_dyn_itns( :, ls_outer, 1 ), & - .true., & - dlayer_on, & - modeldb%clock ) - + if (use_wavedynamics) then + call tl_rhs_alg( rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns( :, ls_outer, 1 ), & + ls_moist_dyn_itns( :, ls_outer, 1 ), & + .true., & + dlayer_on, & + modeldb%clock ) + end if if (l_boundary_layer) then ! Run linear boundary layer scheme to compute increment to u perturbation @@ -785,8 +786,9 @@ contains call u%copy_field_properties( u_star_physical ) call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) - ! Compute u_star = u_np1 + M^-1(-rhs_np1 + rhs_n + rhs_a) - ! du = M^-1(-rhs_np1 + rhs_n + rhs_a + ! Compute u_star = u_np1 + du + ! where du = M^-1(-rhs_np1 + rhs_n + rhs_a) + ! This mirrors the calc_phys_predictors_alg in gungho call du%initialise( rhs_adv(igh_u)%get_function_space() ) call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) call invoke( setval_c( du, 0.0_r_def ), & @@ -807,12 +809,11 @@ contains call copy_bundle( state, state_star, bundle_size ) call invoke( setval_x( state_star(igh_u), u_star_physical ) ) - call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star, ls_state_itns(:,ls_outer,1), cast_dt ) ! u_bl_inc computed from state_star(igh_u) - ! NB use state_star + call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), ls_state_itns(:,ls_outer,1), cast_dt ) ! u_bl_inc_flux = u_bl_inc * dA - ! i.e., multiply by dA to transform from velocity to flux + ! i.e., multiply by cell face area dA to transform from velocity to flux call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) call set_bundle_scalar( 0.0_r_def,rhs_phys, bundle_size ) From e0c2518fb71ebba50033552f3a91865a6334fbfd Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 14:39:15 +0000 Subject: [PATCH 60/68] Factor out TL/AD physics and new NML variable help/description sections --- .../linear_physics/atl_bdy_lyr_alg.x90 | 1 + .../linear_physics/atl_physics_alg.x90 | 155 ++++++++++++++++++ .../timestepping/atl_si_timestep_alg_mod.x90 | 90 ++-------- .../lfric-linear/HEAD/rose-meta.conf | 36 ++-- .../linear_physics/tl_bdy_lyr_alg.x90 | 1 + .../linear_physics/tl_physics_alg.x90 | 135 +++++++++++++++ .../timestepping/tl_si_timestep_alg_mod.x90 | 69 ++------ 7 files changed, 336 insertions(+), 151 deletions(-) create mode 100644 science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 create mode 100644 science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index fea5b27f..d77d28db 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -46,6 +46,7 @@ contains !> 3. Call atl_bl_inc_kernel_type: (adjoint of) from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc !> The TLM BL scheme is described in Var Scientific Documentation Paper 55, !> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> The original code is at https://wwwspice/~frva/VAR/view/var-2022.12.2/doc/PF_bdy_lyr.html !> @param[in,out] modeldb Structure containing the model state !> @param[in,out] u_bl_inc TLM boundary layer increment !> @param[in,out] u The current TL model prognostic u field, state(igh_u) diff --git a/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 new file mode 100644 index 00000000..4738829c --- /dev/null +++ b/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 @@ -0,0 +1,155 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Wrapper for adjoint physics code +module atl_physics_alg_mod + + use constants_mod, only: r_def + use driver_modeldb_mod, only: modeldb_type + use field_mod, only: field_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2 + use sci_geometric_constants_mod, only: get_da_at_w2 + use sci_fem_constants_mod, only: get_mass_matrix_fe + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type + use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg + use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, set_bundle_scalar + use operator_mod, only: operator_type + + implicit none + + private + public :: atl_physics_alg + +contains + +!> @brief Wrapper for adjoint physics code, currently just atl_bdy_lyr_alg +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u The TL model u field to be incremented +!> @param[in,out] state_star TL model prognostic fields for physics calculations +!> @param[in,out] rhs_phys Residuals +!> @param[in] state The current TL model prognostic fields +!> @param[in] rhs_n Residuals +!> @param[in] rhs_np1 Residuals +!> @param[in] rhs_adv Advective terms +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] mesh The current mesh +!> @param[in] dt The TL model timestep length +subroutine atl_physics_alg(modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state, & + mesh, & + dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u + type(field_type), intent(inout) :: state_star(bundle_size) + type(field_type), intent(inout) :: rhs_phys(bundle_size) + type(field_type), intent(in) :: state(bundle_size) + type(field_type), intent(in) :: rhs_n(bundle_size) + type(field_type), intent(in) :: rhs_np1(bundle_size) + type(field_type), intent(in) :: rhs_adv(bundle_size) + type(field_type), intent(in) :: ls_state(bundle_size) + type(mesh_type), pointer, intent(in) :: mesh + real(kind=r_def), intent(in) :: dt + + type(field_type) :: u_bl_inc + type(field_type) :: u_bl_inc_flux + type(field_type) :: du + type(field_type) :: u_star + type(field_type) :: u_star_physical + type(field_type) :: rhsu_np1 + + type(operator_type), pointer :: mm_vel + type(field_type), pointer :: dA + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'atl_physics_alg') + + mm_vel => get_mass_matrix_fe(W2, mesh%get_id()) + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + + call clone_bundle( state, state_star, bundle_size ) + call copy_bundle( state, state_star, bundle_size ) ! Only state_star(igh_u) is used + call set_bundle_scalar( 0.0_r_def, state_star, bundle_size ) + + dA => get_da_at_w2(mesh%get_id()) + + call invoke( setval_c( u_bl_inc_flux, 0.0_r_def ), & + setval_c( u_bl_inc, 0.0_r_def ), & + setval_c( u_star, 0.0_r_def ), & + setval_c( u_star_physical, 0.0_r_def ), & + setval_c( du, 0.0_r_def ), & + setval_c( rhsu_np1, 0.0_r_def ) ) + + call invoke( enforce_bc_kernel_type( rhs_phys(igh_u) ), & + adj_matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ) ) + + call set_bundle_scalar( 0.0_r_def, rhs_phys, bundle_size ) + + ! Adj of u_bl_inc_flux = u_bl_inc * dA + call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & + inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & + setval_c( u_bl_inc_flux, 0.0_r_def ) ) + + call atl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), & + ls_state, dt ) + + ! Adj of state_star(igh_u) <- u_star_physical + call invoke( inc_x_plus_y( u_star_physical, state_star(igh_u) ), & + setval_c( state_star(igh_u), 0.0_r_def ) ) + + ! Adj of u_star_physical = u_star / dA + call invoke( inc_x_divideby_y( u_star_physical, dA ), & + inc_x_plus_y( u_star, u_star_physical ), & + setval_c( u_star_physical, 0.0_r_def) ) + + ! Adj of u_star = du + state(igh_u) + call invoke( inc_X_plus_Y( du, u_star ), & + inc_X_plus_Y( state(igh_u), u_star ), & + setval_c( u_star, 0.0_r_def ) ) + + ! Adj of call mass_matrix_solver_alg(du, rhsu_np1) + call mass_matrix_solver_alg( rhsu_np1, du ) + + ! Adj of inc_X_plus_Y(rhsu_np1, rhs_adv(igh_u)) + call invoke( inc_X_plus_Y( rhs_adv(igh_u), rhsu_np1 ) ) + + ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) + call invoke( inc_X_plus_bY( rhs_np1(igh_u), -1.0_r_def, rhsu_np1 ), & + inc_X_plus_Y( rhs_n(igh_u), rhsu_np1 ), & + setval_c( rhsu_np1, 0.0_r_def ) ) + + ! Adj of du <- 0 + call invoke( setval_c( du, 0.0_r_def ) ) + + if (LPROF) call stop_timing(id, 'atl_physics_alg') + +end subroutine atl_physics_alg + +end module atl_physics_alg_mod diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index f01c5a84..effa9c9f 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -35,7 +35,6 @@ module atl_si_timestep_alg_mod use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type use adj_dg_inc_matrix_vector_kernel_mod, only: adj_dg_inc_matrix_vector_kernel_type - use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type use adj_stabilise_bl_u_kernel_mod, only: adj_stabilise_bl_u_kernel_type use field_mod, only: field_type use mesh_collection_mod, only: mesh_collection @@ -53,13 +52,12 @@ module atl_si_timestep_alg_mod use derive_exner_from_eos_alg_mod, only: derive_exner_from_eos use atl_derive_exner_from_eos_alg_mod, only: atl_derive_exner_from_eos use update_prognostic_scalars_alg_mod, only: update_prognostic_scalars_alg - use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg + use atl_physics_alg_mod, only: atl_physics_alg use mr_indices_mod, only: nummr use moist_dyn_mod, only: num_moist_factors, gas_law use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p use mixing_config_mod, only: smagorinsky use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use sci_geometric_constants_mod, only: get_da_at_w2 use timing_mod, only: start_timing, stop_timing, & tik, LPROF use transport_enumerated_types_mod, only: direction_3d, direction_h, direction_v @@ -332,15 +330,6 @@ contains character(len=str_def) :: prime_mesh_name integer(tik) :: id - ! Local variables for boundary layer - type( field_type ) :: u_bl_inc - type( field_type ) :: u_bl_inc_flux - type( field_type ) :: du - type( field_type ) :: u_star - type( field_type ) :: u_star_physical - type( field_type ) :: rhsu_np1 - type( field_type ), pointer :: dA - if ( LPROF ) call start_timing( id, 'atl_si_timestep_type::step' ) cast_dt = real( modeldb%clock%get_seconds_per_step(), r_def ) @@ -699,71 +688,18 @@ contains !------------------------------------------------------------------------- if (l_boundary_layer) then - - call u%copy_field_properties( u_bl_inc ) - call u%copy_field_properties( u_bl_inc_flux ) - call u%copy_field_properties( du ) - call u%copy_field_properties( u_star ) - call u%copy_field_properties( u_star_physical ) - call self%rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) - - call du%initialise( self%rhs_adv(igh_u)%get_function_space() ) - call rhsu_np1%initialise( self%rhs_adv(igh_u)%get_function_space() ) - - call clone_bundle( self%state,self%state_star, bundle_size ) - call copy_bundle( self%state, self%state_star, bundle_size ) ! Only state_star(igh_u) is used - call set_bundle_scalar( 0.0_r_def,self%state_star, bundle_size ) - - dA => get_da_at_w2(mesh%get_id()) - - call invoke( setval_c( u_bl_inc_flux, 0.0_r_def ), & - setval_c( u_bl_inc, 0.0_r_def ), & - setval_c( u_star, 0.0_r_def ), & - setval_c( u_star_physical, 0.0_r_def ), & - setval_c( du, 0.0_r_def ), & - setval_c( rhsu_np1, 0.0_r_def ) ) - - call invoke( enforce_bc_kernel_type( self%rhs_phys(igh_u) ), & - adj_matrix_vector_kernel_type( self%rhs_phys(igh_u), u_bl_inc_flux, mm_vel ) ) - - call set_bundle_scalar( 0.0_r_def,self%rhs_phys, bundle_size ) - - ! Adj of u_bl_inc_flux = u_bl_inc * dA - call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & - inc_x_plus_y( u_bl_inc, u_bl_inc_flux ), & - setval_c( u_bl_inc_flux, 0.0_r_def ) ) - - call atl_bdy_lyr_alg( modeldb, u_bl_inc, self%state_star(igh_u), & - self%ls_state_itns(:,ls_outer,1), cast_dt ) - - ! Adj of state_star(igh_u) <- u_star_physical - call invoke( inc_x_plus_y( u_star_physical, self%state_star(igh_u) ), & - setval_c( self%state_star(igh_u), 0.0_r_def ) ) - - ! Adj of u_star_physical = u_star / dA - call invoke( inc_x_divideby_y( u_star_physical, dA ), & - inc_x_plus_y( u_star, u_star_physical ), & - setval_c( u_star_physical, 0.0_r_def) ) - - ! Adj of u_star = du + state(igh_u) - call invoke( inc_X_plus_Y( du, u_star ), & - inc_X_plus_Y( self%state(igh_u), u_star ), & - setval_c( u_star, 0.0_r_def ) ) - - ! Adj of call mass_matrix_solver_alg(du, rhsu_np1 ) - call mass_matrix_solver_alg( rhsu_np1, du ) - - ! Adj of inc_X_plus_Y(rhsu_np1, self%rhs_adv(igh_u)) - call invoke( inc_X_plus_Y( self%rhs_adv(igh_u), rhsu_np1 ) ) - - ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) - call invoke( inc_X_plus_bY( self%rhs_np1(igh_u), -1.0_r_def, rhsu_np1 ), & - inc_X_plus_Y( self%rhs_n(igh_u), rhsu_np1 ), & - setval_c( rhsu_np1, 0.0_r_def ) ) - - ! Adj of du <- 0 - call invoke( setval_c( du, 0.0_r_def ) ) - + ! Linear boundary layer scheme is currently the only linear physics scheme + call atl_physics_alg( modeldb, & + u, & + self%state_star, & + self%rhs_phys, & + self%rhs_np1, & + self%rhs_n, & + self%state, & + self%rhs_adv, & + self%ls_state_itns(:,ls_outer,1), & + mesh, & + cast_dt ) end if ! l_boundary_layer call set_bundle_scalar( 0.0_r_def, self%state1, bundle_size ) diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index 770a9290..db209b1a 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -10,9 +10,9 @@ title=Linear [namelist:linear=Blevs_m] compulsory=false -description=?????? +description=Number of momentum boundary layer levels in TLM boundary layer scheme. fail-if=this < 1 ; -help=Number of boundary layers levels in linear model +help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=1: @@ -20,9 +20,9 @@ type=integer [namelist:linear=L_0_m] compulsory=false -description=?????? +description=Height parameter for TLM boundary layer scheme. fail-if=this < 0.0 -help=height parameter for BL in TLM +help=Mixing length for momentum. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: @@ -30,9 +30,9 @@ type=real [namelist:linear=e_folding_levs_m] compulsory=false -description=?????? +description=e-folding level in TLM boundary layer scheme. fail-if=this < 1 ; -help=Number of e-folding boundary layers levels in linear model +help=Number of e-folding levels in exchange coefficient for momentum. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=1: @@ -47,8 +47,8 @@ type=logical [namelist:linear=l_boundary_layer] compulsory=false -description=?????? -help=If true then turn on boundary layer in linear model +description=Logical switch for TLM boundary layer scheme. +help=If true then turn on boundary layer in linear model and adjoint. !kind=default ns=namelist/Job/Timestepping/semi-implicit type=logical @@ -63,9 +63,9 @@ type=logical [namelist:linear=log_layer] compulsory=false -description=?????? +description=Number of levels in log layer in TLM boundary layer scheme. fail-if=this < 1 ; -help=Number of boundary layers levels in log layer in linear model +help=Number of levels in log layer in TLM boundary layer scheme. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=1: @@ -119,9 +119,9 @@ values='analytic', 'random', 'file', 'zero' [namelist:linear=u_land_m] compulsory=false -description=?????? +description=Land friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 -help=friction velocity over land +help=Friction velocity for momentum over land. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: @@ -129,9 +129,9 @@ type=real [namelist:linear=u_sea_m] compulsory=false -description=?????? +description=Sea friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 -help=friction velocity over sea +help=Friction velocity for momentum over sea. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: @@ -139,9 +139,9 @@ type=real [namelist:linear=z_land_m] compulsory=false -description=?????? +description=Friction height over land in TLM boundary layer scheme. fail-if=this < 0.0 -help=friction height over land +help=Effective roughness length for momentum over land. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: @@ -149,9 +149,9 @@ type=real [namelist:linear=z_sea_m] compulsory=false -description=?????? +description=Friction height over sea in TLM boundary layer scheme. fail-if=this < 0.0 -help=friction height over sea +help=Effective roughness length for momentum over sea. !kind=default ns=namelist/Job/Timestepping/semi-implicit range=0.0: diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index 6296808f..9276a8be 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -46,6 +46,7 @@ contains !> 3. Call tl_bl_inc_kernel_type: from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc !> The TLM BL scheme is described in Var Scientific Documentation Paper 55, !> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> The original code is at https://wwwspice/~frva/VAR/view/var-2022.12.2/doc/PF_bdy_lyr.html !> @param[in,out] modeldb Structure containing the model state !> @param[in,out] u_bl_inc TLM boundary layer increment !> @param[in,out] u The current TL model prognostic u field, state(igh_u) diff --git a/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 new file mode 100644 index 00000000..5289776e --- /dev/null +++ b/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 @@ -0,0 +1,135 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Wrapper for tangent linear physics code +module tl_physics_alg_mod + + use constants_mod, only: r_def + use driver_modeldb_mod, only: modeldb_type + use field_mod, only: field_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2 + use sci_geometric_constants_mod, only: get_da_at_w2 + use sci_fem_constants_mod, only: get_mass_matrix_fe + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use tl_bdy_lyr_alg_mod, only: tl_bdy_lyr_alg + use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, set_bundle_scalar + use operator_mod, only: operator_type + + implicit none + + private + public :: tl_physics_alg + +contains + +!> @brief Wrapper for tangent linear physics code, currently just tl_bdy_lyr_alg +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u The TL model u field to be incremented +!> @param[in,out] state_star TL model prognostic fields for physics calculations +!> @param[in,out] rhs_phys Residuals +!> @param[in] state The current TL model prognostic fields +!> @param[in] rhs_n Residuals +!> @param[in] rhs_np1 Residuals +!> @param[in] rhs_adv Advective terms +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] mesh The current mesh +!> @param[in] dt The TL model timestep length +subroutine tl_physics_alg(modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state, & + mesh, & + dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u + type(field_type), intent(inout) :: state_star(bundle_size) + type(field_type), intent(inout) :: rhs_phys(bundle_size) + type(field_type), intent(in) :: state(bundle_size) + type(field_type), intent(in) :: rhs_n(bundle_size) + type(field_type), intent(in) :: rhs_np1(bundle_size) + type(field_type), intent(in) :: rhs_adv(bundle_size) + type(field_type), intent(in) :: ls_state(bundle_size) + type(mesh_type), pointer, intent(in) :: mesh + real(kind=r_def), intent(in) :: dt + + type(field_type) :: u_bl_inc + type(field_type) :: u_bl_inc_flux + type(field_type) :: du + type(field_type) :: u_star + type(field_type) :: u_star_physical + type(field_type) :: rhsu_np1 + + type(operator_type), pointer :: mm_vel + type(field_type), pointer :: dA + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'tl_physics_alg') + + mm_vel => get_mass_matrix_fe(W2, mesh%get_id()) + + ! Run linear boundary layer scheme to compute increment to u perturbation + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + ! Compute u_star = u_np1 + du + ! where du = M^-1(-rhs_np1 + rhs_n + rhs_a) + ! This mirrors the calc_phys_predictors_alg in gungho + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + call invoke( setval_c( du, 0.0_r_def ), & + aX_plus_Y( rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u) ), & + inc_X_plus_Y( rhsu_np1, rhs_adv(igh_u) ) ) + + call mass_matrix_solver_alg( du, rhsu_np1 ) + + call invoke( X_plus_Y( u_star, du, state(igh_u) ) ) + + ! u_star_physical = u_star / dA + ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity + dA => get_da_at_w2(mesh%get_id()) + call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) + + ! For convenience place u_star_physical as igh_u component of state_star + call clone_bundle( state,state_star, bundle_size ) + call copy_bundle( state, state_star, bundle_size ) + call invoke( setval_x( state_star(igh_u), u_star_physical ) ) + + ! u_bl_inc computed from state_star(igh_u) + call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), ls_state, dt ) + + ! u_bl_inc_flux = u_bl_inc * dA + ! i.e., multiply by cell face area dA to transform from velocity to flux + call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) + + call set_bundle_scalar( 0.0_r_def, rhs_phys, bundle_size ) + call invoke( name="update_rhs_phys_from_fast_physics", & + matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ), & + enforce_bc_kernel_type( rhs_phys(igh_u) ) ) + + if (LPROF) call stop_timing(id, 'tl_physics_alg') + +end subroutine tl_physics_alg + +end module tl_physics_alg_mod diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index 976823ce..112a327a 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -49,7 +49,6 @@ module tl_si_timestep_alg_mod copy_bundle, & set_bundle_scalar, & bundle_is_zero - use sci_geometric_constants_mod, only: get_da_at_w2 use fs_continuity_mod, only: Wtheta, W2 ! PsyKAl PSYClone kernels @@ -57,8 +56,6 @@ module tl_si_timestep_alg_mod use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg use sci_set_any_dof_kernel_mod, only: set_any_dof_kernel_type use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type - use matrix_vector_kernel_mod, only: matrix_vector_kernel_type - use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use stabilise_bl_u_kernel_mod, only: stabilise_bl_u_kernel_type ! Derived Types @@ -99,7 +96,7 @@ module tl_si_timestep_alg_mod use map_physics_fields_alg_mod, only: map_physics_fields_alg - use tl_bdy_lyr_alg_mod, only: tl_bdy_lyr_alg + use tl_physics_alg_mod, only: tl_physics_alg ! Moisture species use mr_indices_mod, only: nummr, imr_v, imr_cl @@ -380,14 +377,6 @@ contains type( field_type ), intent( in ) :: ls_moist_dyn(num_moist_factors) ! field groups type( field_collection_type ), intent( inout ) :: derived_fields - ! Linear boundary layer scheme - type( field_type ) :: u_bl_inc - type( field_type ) :: u_bl_inc_flux - type( field_type ) :: du - type( field_type ) :: u_star - type( field_type ) :: u_star_physical - type( field_type ) :: rhsu_np1 - type( field_type ), pointer :: dA type( mesh_type ), intent( in ), pointer :: mesh type( mesh_type ), intent( in ), pointer :: twod_mesh @@ -777,50 +766,18 @@ contains end if if (l_boundary_layer) then - ! Run linear boundary layer scheme to compute increment to u perturbation - - call u%copy_field_properties( u_bl_inc ) - call u%copy_field_properties( u_bl_inc_flux ) - call u%copy_field_properties( du ) - call u%copy_field_properties( u_star ) - call u%copy_field_properties( u_star_physical ) - call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) - - ! Compute u_star = u_np1 + du - ! where du = M^-1(-rhs_np1 + rhs_n + rhs_a) - ! This mirrors the calc_phys_predictors_alg in gungho - call du%initialise( rhs_adv(igh_u)%get_function_space() ) - call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) - call invoke( setval_c( du, 0.0_r_def ), & - aX_plus_Y( rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u) ), & - inc_X_plus_Y( rhsu_np1, rhs_adv(igh_u) ) ) - - call mass_matrix_solver_alg( du, rhsu_np1 ) - - call invoke( X_plus_Y( u_star, du, state(igh_u) ) ) - - ! u_star_physical = u_star / dA - ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity - dA => get_da_at_w2(mesh%get_id()) - call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) - - ! For convenience place u_star_physical as igh_u component of state_star - call clone_bundle( state,state_star, bundle_size ) - call copy_bundle( state, state_star, bundle_size ) - call invoke( setval_x( state_star(igh_u), u_star_physical ) ) - - ! u_bl_inc computed from state_star(igh_u) - call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), ls_state_itns(:,ls_outer,1), cast_dt ) - - ! u_bl_inc_flux = u_bl_inc * dA - ! i.e., multiply by cell face area dA to transform from velocity to flux - call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) - - call set_bundle_scalar( 0.0_r_def,rhs_phys, bundle_size ) - call invoke( name="update_rhs_phys_from_fast_physics", & - matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ), & - enforce_bc_kernel_type( rhs_phys(igh_u) ) ) - + ! Linear boundary layer scheme is currently the only linear physics scheme + call tl_physics_alg( modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state_itns(:,ls_outer,1), & + mesh, & + cast_dt ) end if ! l_boundary_layer if (use_wavedynamics) then From b766beaef9a4768cf5a4782e381f925eef251551 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 15:29:10 +0000 Subject: [PATCH 61/68] Linear physics namelist variables in their own section --- .../adjoint_tests/example/configuration.nml | 12 +- .../linear_physics/atlt_bl_inc_alg_mod.x90 | 20 +-- rose-stem/app/adjoint_tests/rose-app.conf | 13 +- rose-stem/app/jedi_id_tlm_tests/rose-app.conf | 13 +- rose-stem/app/jedi_lfric_tests/rose-app.conf | 13 +- .../app/jedi_tlm_forecast_tl/rose-app.conf | 14 ++- rose-stem/app/jedi_tlm_tests/rose-app.conf | 13 +- rose-stem/app/linear_model/rose-app.conf | 13 +- .../linear_physics/atl_bdy_lyr_alg.x90 | 2 +- .../timestepping/atl_si_timestep_alg_mod.x90 | 4 +- .../lfric-linear/HEAD/rose-meta.conf | 119 +++++++++--------- .../linear_physics/tl_bdy_lyr_alg.x90 | 2 +- .../timestepping/tl_si_timestep_alg_mod.x90 | 4 +- 13 files changed, 139 insertions(+), 103 deletions(-) diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 0f7e8e20..9864e064 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -220,17 +220,19 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -blevs_m=15, -e_folding_levs_m=10, fixed_ls=.true., -l_0_m=80.0, -l_boundary_layer=.true., l_stabilise_bl=.false., -log_layer=2, ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', +/ +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, u_land_m=0.4, u_sea_m=0.4, z_land_m=0.05, diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 index 3fd91536..d20707fd 100644 --- a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 @@ -48,16 +48,16 @@ module atlt_bl_inc_alg_mod !> @param[in] mesh Mesh object subroutine atlt_bl_inc_alg( mesh ) - use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type - use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type - use linear_config_mod, only : log_layer, & - Blevs_m, & - e_folding_levs_m, & - u_land_m, & - u_sea_m, & - z_land_m, & - z_sea_m, & - L_0_m + use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type + use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type + use linear_physics_config_mod, only : log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m implicit none diff --git a/rose-stem/app/adjoint_tests/rose-app.conf b/rose-stem/app/adjoint_tests/rose-app.conf index 36391d7b..ccaedcb3 100644 --- a/rose-stem/app/adjoint_tests/rose-app.conf +++ b/rose-stem/app/adjoint_tests/rose-app.conf @@ -61,6 +61,7 @@ source=(namelist:aerosol) = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -719,17 +720,19 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] -blevs_m=15 -e_folding_levs_m=10 fixed_ls=.true. -l_0_m=80.0 -l_boundary_layer=.true. l_stabilise_bl=.false. -log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index f14f74c5..a55ee3b0 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -68,6 +68,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -761,17 +762,19 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] -blevs_m=15 -e_folding_levs_m=10 fixed_ls=.true. -l_0_m=80.0 -l_boundary_layer=.true. l_stabilise_bl=.false. -log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index 59b9fc26..b25767e4 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -68,6 +68,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -764,17 +765,19 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] -blevs_m=15 -e_folding_levs_m=10 fixed_ls=.true. -l_0_m=80.0 -l_boundary_layer=.true. l_stabilise_bl=.false. -log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index e61dc951..1486fab0 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -68,6 +68,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -762,12 +763,23 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.true. +l_stabilise_bl=.false. ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 + [namelist:logging] log_to_rank_zero_only=.false. run_log_level='info' diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index f0d6873c..f29a80da 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -68,6 +68,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -762,17 +763,19 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] -blevs_m=15 -e_folding_levs_m=10 fixed_ls=.true. -l_0_m=80.0 -l_boundary_layer=.true. l_stabilise_bl=.false. -log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 diff --git a/rose-stem/app/linear_model/rose-app.conf b/rose-stem/app/linear_model/rose-app.conf index f0565754..60f76519 100644 --- a/rose-stem/app/linear_model/rose-app.conf +++ b/rose-stem/app/linear_model/rose-app.conf @@ -61,6 +61,7 @@ source=(namelist:aerosol) = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -719,17 +720,19 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:linear] -blevs_m=15 -e_folding_levs_m=10 fixed_ls=.true. -l_0_m=80.0 -l_boundary_layer=.true. l_stabilise_bl=.false. -log_layer=2 ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 u_land_m=0.4 u_sea_m=0.4 z_land_m=0.05 diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 index d77d28db..30665009 100644 --- a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -15,7 +15,7 @@ module atl_bdy_lyr_alg_mod get_face_selector_ns use sci_fem_constants_mod, only: get_rmultiplicity_fe use field_mod, only: field_type - use linear_config_mod, only: log_layer, & + use linear_physics_config_mod, only: log_layer, & Blevs_m, & e_folding_levs_m, & u_land_m, & diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index effa9c9f..1e32b54c 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -23,8 +23,8 @@ module atl_si_timestep_alg_mod use linear_config_mod, only: fixed_ls, & l_stabilise_bl, & n_bl_levels_to_stabilise, & - max_bl_stabilisation, & - l_boundary_layer + max_bl_stabilisation + use linear_physics_config_mod, only: l_boundary_layer use derived_config_mod, only: bundle_size use boundaries_config_mod, only: limited_area use sci_fem_constants_mod, only: get_mass_matrix_fe, get_qr_fe diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index db209b1a..cc2f6f6a 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -8,36 +8,6 @@ ns=namelist/Linear/Initial sort-key=Section-A07 title=Linear -[namelist:linear=Blevs_m] -compulsory=false -description=Number of momentum boundary layer levels in TLM boundary layer scheme. -fail-if=this < 1 ; -help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -range=1: -type=integer - -[namelist:linear=L_0_m] -compulsory=false -description=Height parameter for TLM boundary layer scheme. -fail-if=this < 0.0 -help=Mixing length for momentum. -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -range=0.0: -type=real - -[namelist:linear=e_folding_levs_m] -compulsory=false -description=e-folding level in TLM boundary layer scheme. -fail-if=this < 1 ; -help=Number of e-folding levels in exchange coefficient for momentum. -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -range=1: -type=integer - [namelist:linear=fixed_ls] compulsory=true description=Do not update the linearisation state during the timestep. @@ -45,14 +15,6 @@ help=The linearisation state is the same for every outer and inner loop. !kind=default type=logical -[namelist:linear=l_boundary_layer] -compulsory=false -description=Logical switch for TLM boundary layer scheme. -help=If true then turn on boundary layer in linear model and adjoint. -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -type=logical - [namelist:linear=l_stabilise_bl] compulsory=true description=?????? @@ -61,16 +23,6 @@ help=If true then turn on boundary layer stabilisation in linear model ns=namelist/Job/Timestepping/semi-implicit type=logical -[namelist:linear=log_layer] -compulsory=false -description=Number of levels in log layer in TLM boundary layer scheme. -fail-if=this < 1 ; -help=Number of levels in log layer in TLM boundary layer scheme. -!kind=default -ns=namelist/Job/Timestepping/semi-implicit -range=1: -type=integer - [namelist:linear=ls_read_w2h] compulsory=true !default=kind @@ -117,43 +69,98 @@ value-titles=analytic, =zero values='analytic', 'random', 'file', 'zero' -[namelist:linear=u_land_m] +[namelist:linear_physics] +compulsory=false +description=Settings for TLM physics schemes. +ns=namelist/Linear/Physics +sort-key=Section-A07 +title=Linear Physics + +[namelist:linear_physics=Blevs_m] +compulsory=false +description=Number of momentum boundary layer levels in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=L_0_m] +compulsory=false +description=Height parameter for TLM boundary layer scheme. +fail-if=this < 0.0 +help=Mixing length for momentum. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=e_folding_levs_m] +compulsory=false +description=e-folding level in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of e-folding levels in exchange coefficient for momentum. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=l_boundary_layer] +compulsory=false +description=Logical switch for TLM boundary layer scheme. +help=If true then turn on boundary layer in linear model and adjoint. +!kind=default +ns=namelist/Linear/Physics +type=logical + +[namelist:linear_physics=log_layer] +compulsory=false +description=Number of levels in log layer in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of levels in log layer in TLM boundary layer scheme. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=u_land_m] compulsory=false description=Land friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 help=Friction velocity for momentum over land. !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/Physics range=0.0: type=real -[namelist:linear=u_sea_m] +[namelist:linear_physics=u_sea_m] compulsory=false description=Sea friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 help=Friction velocity for momentum over sea. !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/Physics range=0.0: type=real -[namelist:linear=z_land_m] +[namelist:linear_physics=z_land_m] compulsory=false description=Friction height over land in TLM boundary layer scheme. fail-if=this < 0.0 help=Effective roughness length for momentum over land. !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/Physics range=0.0: type=real -[namelist:linear=z_sea_m] +[namelist:linear_physics=z_sea_m] compulsory=false description=Friction height over sea in TLM boundary layer scheme. fail-if=this < 0.0 help=Effective roughness length for momentum over sea. !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/Physics range=0.0: type=real diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 index 9276a8be..8668de57 100644 --- a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -15,7 +15,7 @@ module tl_bdy_lyr_alg_mod get_face_selector_ns use sci_fem_constants_mod, only: get_rmultiplicity_fe use field_mod, only: field_type - use linear_config_mod, only: log_layer, & + use linear_physics_config_mod, only: log_layer, & Blevs_m, & e_folding_levs_m, & u_land_m, & diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index 112a327a..561e615e 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -29,8 +29,8 @@ module tl_si_timestep_alg_mod use linear_config_mod, only: fixed_ls, & l_stabilise_bl, & n_bl_levels_to_stabilise, & - max_bl_stabilisation, & - l_boundary_layer + max_bl_stabilisation + use linear_physics_config_mod, only: l_boundary_layer use mixed_solver_config_mod, only: guess_np1, & reference_reset_time use timestepping_config_mod, only: alpha, & From f4eb769352afa861a0d85dccc8a83794243f2430 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 16:17:24 +0000 Subject: [PATCH 62/68] No boundary layer scheme for semi-implicit and dcmip tests --- .../linear_model/opt/rose-app-dcmip301.conf | 5 ++-- .../opt/rose-app-semi-implicit.conf | 5 ++-- .../linear/rose-meta/lfric-linear/versions.py | 24 ++++++++++++------- .../algorithm/linear_data_algorithm_mod.x90 | 7 +----- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf index 07cb3c61..22d190a1 100644 --- a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf +++ b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf @@ -58,12 +58,13 @@ ls_option='analytic' diagnostic_frequency=36 [namelist:linear] -blevs_m=4 -e_folding_levs_m=3 fixed_ls=.false. l_stabilise_bl=.false. pert_option='analytic' +[namelist:linear_physics] +l_boundary_layer=.false. + [!!namelist:multigrid] chain_mesh_tags='','','','' diff --git a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf index b32e014c..a706971e 100644 --- a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf +++ b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf @@ -58,11 +58,12 @@ ls_option='analytic' diagnostic_frequency=20 [namelist:linear] -blevs_m=4 -e_folding_levs_m=3 l_stabilise_bl=.false. pert_option='analytic' +[namelist:linear_physics] +l_boundary_layer=.false. + [namelist:mixed_solver] gcrk=6 mixed_solver_a_tol=1.0e-6 diff --git a/science/linear/rose-meta/lfric-linear/versions.py b/science/linear/rose-meta/lfric-linear/versions.py index a3dde99e..2395e05f 100644 --- a/science/linear/rose-meta/lfric-linear/versions.py +++ b/science/linear/rose-meta/lfric-linear/versions.py @@ -54,13 +54,19 @@ class vn30_t182(MacroUpgrade): def upgrade(self, config, meta_config=None): """Add linear boundary layer physics scheme""" - self.add_setting(config, ["namelist:linear", "Blevs_m"], "15") - self.add_setting(config, ["namelist:linear", "e_folding_levs_m"], "10") - self.add_setting(config, ["namelist:linear", "l_0_m"], "80.0") - self.add_setting(config, ["namelist:linear", "l_boundary_layer"], ".true.") - self.add_setting(config, ["namelist:linear", "log_layer"], "2") - self.add_setting(config, ["namelist:linear", "u_land_m"], "0.4") - self.add_setting(config, ["namelist:linear", "u_sea_m"], "0.4") - self.add_setting(config, ["namelist:linear", "z_land_m"], "0.05") - self.add_setting(config, ["namelist:linear", "z_sea_m"], "0.0005") + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting(config, ["namelist:linear_physics", "l_boundary_layer"], ".false.") + else: + self.add_setting(config, ["namelist:linear_physics", "l_boundary_layer"], ".true.") + self.add_setting(config, ["namelist:linear_physics", "Blevs_m"], "15") + self.add_setting(config, ["namelist:linear_physics", "e_folding_levs_m"], "10") + self.add_setting(config, ["namelist:linear_physics", "l_0_m"], "80.0") + self.add_setting(config, ["namelist:linear_physics", "log_layer"], "2") + self.add_setting(config, ["namelist:linear_physics", "u_land_m"], "0.4") + self.add_setting(config, ["namelist:linear_physics", "u_sea_m"], "0.4") + self.add_setting(config, ["namelist:linear_physics", "z_land_m"], "0.05") + self.add_setting(config, ["namelist:linear_physics", "z_sea_m"], "0.0005") return config, self.reports diff --git a/science/linear/source/algorithm/linear_data_algorithm_mod.x90 b/science/linear/source/algorithm/linear_data_algorithm_mod.x90 index 46927bd2..400293b4 100644 --- a/science/linear/source/algorithm/linear_data_algorithm_mod.x90 +++ b/science/linear/source/algorithm/linear_data_algorithm_mod.x90 @@ -590,7 +590,6 @@ module linear_data_algorithm_mod init_mr_fields use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type use idealised_config_mod, only: test - use sci_assign_field_random_kernel_mod, only: assign_field_random_kernel_type implicit none @@ -603,7 +602,6 @@ module linear_data_algorithm_mod type( field_type ), pointer :: ls_mr(:) => null() type( field_type ), pointer :: ls_moist_dyn(:) => null() - type( field_type ), pointer :: ls_land_fraction => null() type( field_collection_type ), pointer :: ls_fields @@ -623,7 +621,6 @@ module linear_data_algorithm_mod call ls_fields%get_field('ls_u', ls_u) call ls_fields%get_field('ls_rho', ls_rho) call ls_fields%get_field('ls_exner', ls_exner) - call ls_fields%get_field('ls_land_fraction', ls_land_fraction ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") call moisture_fields%get_field("ls_mr",ls_mr_array) @@ -648,9 +645,7 @@ module linear_data_algorithm_mod call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - call invoke( assign_field_random_kernel_type( ls_land_fraction, 1.0_r_def )) - - nullify( ls_theta, ls_rho, ls_u, ls_exner, ls_moist_dyn, ls_mr, ls_land_fraction ) + nullify( ls_theta, ls_rho, ls_u, ls_exner, ls_moist_dyn, ls_mr ) nullify( chi, panel_id ) end subroutine linear_init_reference_ls From b2b3085e4ecda94335f6ebdc7ce6649fdf195c17 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 17:46:05 +0000 Subject: [PATCH 63/68] Trigger for TLM BL options --- rose-stem/app/jedi_forecast/rose-app.conf | 12 +++++ .../app/jedi_forecast_pseudo/rose-app.conf | 12 +++++ .../linear_model/opt/rose-app-dcmip301.conf | 8 ++++ .../opt/rose-app-semi-implicit.conf | 8 ++++ .../lfric-linear/HEAD/rose-meta.conf | 48 +++++++++++-------- .../linear_physics/tl_bl_inc_kernel_mod.F90 | 4 +- .../tl_compute_qe_kernel_mod.F90 | 5 +- 7 files changed, 74 insertions(+), 23 deletions(-) diff --git a/rose-stem/app/jedi_forecast/rose-app.conf b/rose-stem/app/jedi_forecast/rose-app.conf index 1ad81377..ba87e6b5 100644 --- a/rose-stem/app/jedi_forecast/rose-app.conf +++ b/rose-stem/app/jedi_forecast/rose-app.conf @@ -61,6 +61,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = namelist:mixed_solver = (namelist:mixing) @@ -748,6 +749,17 @@ l_stabilise_bl=.false. ls_read_w2h=.false. pert_option='analytic' +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 + [namelist:logging] log_to_rank_zero_only=.false. run_log_level='info' diff --git a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf index 90ef89ae..28aab9fa 100644 --- a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf +++ b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf @@ -59,6 +59,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = namelist:mixed_solver = (namelist:mixing) @@ -742,6 +743,17 @@ l_stabilise_bl=.false. ls_read_w2h=.false. pert_option='analytic' +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 + [namelist:logging] log_to_rank_zero_only=.false. run_log_level='info' diff --git a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf index 22d190a1..8bf78b63 100644 --- a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf +++ b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf @@ -63,7 +63,15 @@ l_stabilise_bl=.false. pert_option='analytic' [namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 [!!namelist:multigrid] chain_mesh_tags='','','','' diff --git a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf index a706971e..d770f11a 100644 --- a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf +++ b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf @@ -62,7 +62,15 @@ l_stabilise_bl=.false. pert_option='analytic' [namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 [namelist:mixed_solver] gcrk=6 diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index cc2f6f6a..af6d92a6 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -70,14 +70,14 @@ value-titles=analytic, values='analytic', 'random', 'file', 'zero' [namelist:linear_physics] -compulsory=false +compulsory=true description=Settings for TLM physics schemes. ns=namelist/Linear/Physics sort-key=Section-A07 title=Linear Physics -[namelist:linear_physics=Blevs_m] -compulsory=false +[namelist:linear_physics=blevs_m] +compulsory=true description=Number of momentum boundary layer levels in TLM boundary layer scheme. fail-if=this < 1 ; help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. @@ -86,18 +86,8 @@ ns=namelist/Linear/Physics range=1: type=integer -[namelist:linear_physics=L_0_m] -compulsory=false -description=Height parameter for TLM boundary layer scheme. -fail-if=this < 0.0 -help=Mixing length for momentum. -!kind=default -ns=namelist/Linear/Physics -range=0.0: -type=real - [namelist:linear_physics=e_folding_levs_m] -compulsory=false +compulsory=true description=e-folding level in TLM boundary layer scheme. fail-if=this < 1 ; help=Number of e-folding levels in exchange coefficient for momentum. @@ -106,16 +96,34 @@ ns=namelist/Linear/Physics range=1: type=integer +[namelist:linear_physics=l_0_m] +compulsory=true +description=Height parameter for TLM boundary layer scheme. +fail-if=this < 0.0 +help=Mixing length for momentum. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + [namelist:linear_physics=l_boundary_layer] -compulsory=false +compulsory=true description=Logical switch for TLM boundary layer scheme. help=If true then turn on boundary layer in linear model and adjoint. !kind=default ns=namelist/Linear/Physics +trigger=namelist:linear_physics=blevs_m: .true. ; + =namelist:linear_physics=l_0_m: .true. ; + =namelist:linear_physics=e_folding_levs_m: .true. ; + =namelist:linear_physics=log_layer: .true. ; + =namelist:linear_physics=u_land_m: .true. ; + =namelist:linear_physics=u_sea_m: .true. ; + =namelist:linear_physics=z_land_m: .true. ; + =namelist:linear_physics=z_sea_m: .true. ; type=logical [namelist:linear_physics=log_layer] -compulsory=false +compulsory=true description=Number of levels in log layer in TLM boundary layer scheme. fail-if=this < 1 ; help=Number of levels in log layer in TLM boundary layer scheme. @@ -125,7 +133,7 @@ range=1: type=integer [namelist:linear_physics=u_land_m] -compulsory=false +compulsory=true description=Land friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 help=Friction velocity for momentum over land. @@ -135,7 +143,7 @@ range=0.0: type=real [namelist:linear_physics=u_sea_m] -compulsory=false +compulsory=true description=Sea friction velocity in TLM boundary layer scheme. fail-if=this < 0.0 help=Friction velocity for momentum over sea. @@ -145,7 +153,7 @@ range=0.0: type=real [namelist:linear_physics=z_land_m] -compulsory=false +compulsory=true description=Friction height over land in TLM boundary layer scheme. fail-if=this < 0.0 help=Effective roughness length for momentum over land. @@ -155,7 +163,7 @@ range=0.0: type=real [namelist:linear_physics=z_sea_m] -compulsory=false +compulsory=true description=Friction height over sea in TLM boundary layer scheme. fail-if=this < 0.0 help=Effective roughness length for momentum over sea. diff --git a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 index 3d69baf7..9141565c 100644 --- a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 @@ -103,7 +103,9 @@ subroutine tl_bl_inc_code( nlayers, & real(kind=r_def) :: u_out(1:BLevs_m) ! Local perturbation velocity variable real(kind=r_def) :: factor_u(1:BLevs_m) - ! Loop over horizontal W2 DoFs + ! Loop over horizontal W2 DoFs whilst minimising double counting. + ! (Looping over all dofs would mean that faces are visited twice – for the cells on both sides. + ! So here the loop is only for a specific selection of dofs.) do j = 1, face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)) df = j diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 index a3ad4099..89c6a771 100644 --- a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -130,10 +130,11 @@ subroutine tl_compute_qe_code( nlayers, & df = 1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell roughness_length_m = z_land_m * ls_land_fraction(map_2d(df)) + z_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) - ! Set up L_diff. + ! Define the mixing length, L_diff ! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above. ! Vertical numbering (k index) matches that in old Var schemePF_bdy_lyr.f90 (see link above), - ! in which centre of lowest cell is rho level 1. + ! in which centre of lowest cell is rho level 1 (allowing for the fact that the PF model is for New Dynamics, + ! which has an extra rho level which means that W3 k=0 in LFRic is equivalent to rho levels k=1 in VAR). ! L_diff_m(k) defined for 1 <= k <= BLevs_m. do k = 1, BLevs_m if (k <= Log_layer) then From 85d05207ce4e0411ac020606b7779e6d1c875400 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 18:33:03 +0000 Subject: [PATCH 64/68] More SR changes --- .../example/configuration.nml | 35 ------------------- .../example_tlm_forecast_tl/configuration.nml | 4 +-- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/applications/jedi_lfric_tests/example/configuration.nml b/applications/jedi_lfric_tests/example/configuration.nml index d7a792df..48735639 100644 --- a/applications/jedi_lfric_tests/example/configuration.nml +++ b/applications/jedi_lfric_tests/example/configuration.nml @@ -1,38 +1,3 @@ -&jedi_lfric_tests -test_field='theta', -/ -&jedi_geometry -io_calender_start='2021-06-02T00:00:00', -io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', -io_path_state_write='write_file', -io_setup_increment=.false., -io_time_step='P0DT1H0M0S', -/ -&jedi_state -state_time='2021-06-02 00:00:00', -use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', -/ -&jedi_increment -inc_time='2021-06-02 00:00:00', -initialise_via_read=.false., -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', -'m_cl','m_r','m_s', -/ -&jedi_linear_model -incremental_wind_interpolation=.false., -nl_time_step='P0DT1H0M0S', -/ -&jedi_pseudo_model -initial_time='2021-06-02 00:00:00', -number_of_steps=9, -time_step='P0DT1H0M0S', -/ -&jedi_lfric_settings -forecast_length='P0DT6H0M0S', -/ &base_mesh file_prefix='mesh_C12_MG', geometry='spherical', diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml index 8f493f2a..f78e63da 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml @@ -6,7 +6,7 @@ io_calender_start='2018-04-14T21:00:00', io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', -io_setup_increment=.false., +io_setup_increment=.true., io_time_step='P0DT1H0M0S', / &jedi_state @@ -17,7 +17,7 @@ variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', / &jedi_increment inc_time='2018-04-14 21:00:00', -initialise_via_read=.false., +initialise_via_read=.true., variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', 'm_cl','m_r','m_s', / From 978324fbb9fe97ed7ca42f833ceeeab6204faaef Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 18:44:03 +0000 Subject: [PATCH 65/68] jelf canned nmls --- .../jedi_lfric_tests/example/configuration.nml | 17 ++++++++++++++--- .../example_id_tlm_tests/configuration.nml | 15 +++++++++++++-- .../example_tlm_forecast_tl/configuration.nml | 15 +++++++++++++-- .../example_tlm_tests/configuration.nml | 15 +++++++++++++-- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/applications/jedi_lfric_tests/example/configuration.nml b/applications/jedi_lfric_tests/example/configuration.nml index 48735639..3beedb5a 100644 --- a/applications/jedi_lfric_tests/example/configuration.nml +++ b/applications/jedi_lfric_tests/example/configuration.nml @@ -68,8 +68,8 @@ stretching_method='smooth', ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='restart', diag_stem_name='diagGungho', -ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', -ls_filename='final_ls', +ls_directory='/data/users/tim.payne/lfric_apps/files', +ls_filename='final_ls_with_land', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', @@ -221,12 +221,23 @@ write_minmax_tseries=.false., / &linear fixed_ls=.true., -l_stabilise_bl=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', / +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, +/ &logging log_to_rank_zero_only=.false., run_log_level='info', diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml index df08139b..c211dbe4 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml @@ -13,7 +13,7 @@ io_time_step='P0DT1H0M0S', state_time='2018-04-14 21:00:00', use_pseudo_model=.true., variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +'m_v','m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', @@ -253,12 +253,23 @@ write_minmax_tseries=.false., / &linear fixed_ls=.true., -l_stabilise_bl=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', / +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, +/ &logging log_to_rank_zero_only=.false., run_log_level='info', diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml index f78e63da..956d7337 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml @@ -13,7 +13,7 @@ io_time_step='P0DT1H0M0S', state_time='2018-04-14 21:00:00', use_pseudo_model=.true., variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +'m_v','m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', @@ -254,12 +254,23 @@ write_minmax_tseries=.false., / &linear fixed_ls=.true., -l_stabilise_bl=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', / +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, +/ &logging log_to_rank_zero_only=.false., run_log_level='info', diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 8f493f2a..50ad2783 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -13,7 +13,7 @@ io_time_step='P0DT1H0M0S', state_time='2018-04-14 21:00:00', use_pseudo_model=.true., variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +'m_v','m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', @@ -254,12 +254,23 @@ write_minmax_tseries=.false., / &linear fixed_ls=.true., -l_stabilise_bl=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., max_bl_stabilisation=0.75, n_bl_levels_to_stabilise=15, pert_option='file', / +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, +/ &logging log_to_rank_zero_only=.false., run_log_level='info', From 5898833087d385348b05937455436f85f0e7bce6 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Thu, 29 Jan 2026 19:21:13 +0000 Subject: [PATCH 66/68] Refactor how 2D LS are handled in jedi_lfric --- .../jedi_id_linear_model_mod.f90 | 2 +- .../jedi-interface/jedi_linear_model_mod.f90 | 2 +- .../source/jedi-interface/jedi_state_mod.f90 | 9 ++---- .../field/atlas_field_interface_mod.F90 | 19 +------------ .../field/jedi_lfric_linear_fields_mod.f90 | 28 +++++++++++++++++-- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 index 991c69c7..2cc8af08 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 @@ -185,7 +185,7 @@ subroutine set_trajectory( self, jedi_state ) ! Create field collection that contains the linear state fields ! without "ls_" prepended. - call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) + call create_linear_fields(jedi_state%geometry%get_mesh(), jedi_state%geometry%get_twod_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state call jedi_state%get_to_field_collection( ls_variable_names, & diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 index 364ee384..79720112 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 @@ -183,7 +183,7 @@ subroutine set_trajectory( self, jedi_state ) ! Create field collection that contains the linear state fields ! without "ls_" prepended. - call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) + call create_linear_fields(jedi_state%geometry%get_mesh(), jedi_state%geometry%get_twod_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state call jedi_state%get_to_field_collection( ls_variable_names, & diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 index 4464fadf..4b464f16 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_state_mod.f90 @@ -382,7 +382,6 @@ subroutine setup_interface_to_modeldb( self ) real(real64), pointer :: atlas_data_ptr(:,:) integer(i_def), pointer :: horizontal_map_ptr(:) integer(i_def) :: n_variables - logical(l_def) :: is_2d type( field_collection_type ), pointer :: depository @@ -407,11 +406,9 @@ subroutine setup_interface_to_modeldb( self ) atlas_data_ptr => self%fields(ivar)%get_data() - is_2d = self%field_meta_data%get_variable_is_2d(ivar) - call self%fields_to_modeldb(ivar)%initialise( atlas_data_ptr, & horizontal_map_ptr, & - lfric_field_ptr, is_2d=is_2d ) + lfric_field_ptr ) end do @@ -469,7 +466,6 @@ subroutine setup_interface_to_field_collection( self, & integer(i_def), pointer :: horizontal_map_ptr(:) integer(i_def) :: n_variables logical :: all_variables_exists - logical(l_def) :: is_2d ! Check that the state contains all the required fields all_variables_exists = & @@ -489,10 +485,9 @@ subroutine setup_interface_to_field_collection( self, & call get_model_field( variable_names(ivar), & field_collection, lfric_field_ptr ) call self%get_field_data(variable_names(ivar), atlas_data_ptr) - is_2d = self%field_meta_data%get_variable_is_2d(ivar) call interface_fields(ivar)%initialise( atlas_data_ptr, & horizontal_map_ptr, & - lfric_field_ptr, is_2d=is_2d ) + lfric_field_ptr ) end do end subroutine setup_interface_to_field_collection diff --git a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 index a5472835..c630b998 100644 --- a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 @@ -134,10 +134,9 @@ module atlas_field_interface_mod !> @param [in] atlas_name Optional name of the atlas field !> @param [in] fill_direction_up Optional logical set false if the atlas field !> data is orientated from top-bottom -!> @param [in] is_2d Optional logical set true if the field is 2D subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & lfric_field_ptr, surface_level_type, & - atlas_name, fill_direction_up, is_2d ) + atlas_name, fill_direction_up ) implicit none @@ -148,7 +147,6 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & integer(i_def), optional, intent(in) :: surface_level_type character( len=* ), optional, intent(in) :: atlas_name logical( kind=l_def ), optional, intent(in) :: fill_direction_up - logical( kind=l_def ), optional, intent(in) :: is_2d ! locals logical( kind=l_def ), allocatable :: check_map(:) @@ -159,7 +157,6 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & type( field_proxy_type ) :: field_proxy class(field_parent_type), pointer :: cast_field logical( kind=l_def ) :: fill_direction_up_local - logical( kind=l_def ) :: is_2d_local ! Initialise the abstract parent ! @@ -201,12 +198,6 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & fill_direction_up_local = .true. end if - if (present(is_2d)) then - is_2d_local = is_2d - else - is_2d_local = .false. - end if - ! Setup data sizes and indices self%n_horizontal = size(atlas_data_ptr,dim=2) self%n_vertical = size(atlas_data_ptr,dim=1) @@ -249,16 +240,8 @@ subroutine field_initialiser( self, atlas_data_ptr, map_horizontal_ptr, & " function space is not supported by the atlas_field_interface class." call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end select - n_horizontal_lfric = field_proxy%vspace%get_last_dof_owned()/n_vertical_lfric - ! n_vertical_lfric is set above based on function space and assuming a 3D field - ! This is then used to correctly calculate n_horizontal_lfric - ! However, this does not take into account 2D fields - ! Here we override n_vertical_lfric to 1 in the case of 2D fields - ! n_horizontal_lfric remains correct - if (is_2d_local) n_vertical_lfric = 1 - ! 1. Vertical points if ( n_vertical_lfric /= self%n_vertical_lfric ) then write(log_scratch_space, '(A,I0,A,I0,A)') & diff --git a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 index 267a85c3..9f7185cd 100644 --- a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 @@ -21,7 +21,7 @@ !> ii) all three "moist_dyn" fields. !> module jedi_lfric_linear_fields_mod - use constants_mod, only : i_def, str_def, r_def + use constants_mod, only : i_def, str_def, r_def, l_def use field_mod, only : field_type use field_collection_mod, only : field_collection_type use fs_continuity_mod, only : W3, Wtheta, W2 @@ -84,6 +84,19 @@ module jedi_lfric_linear_fields_mod Wtheta, & W3/) + logical( kind=l_def ), parameter, public :: & + ls_variable_is_2d(ls_nvars) = (/.false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .true./) + public :: create_linear_fields !------------------------------------------------------------------------------- @@ -94,17 +107,20 @@ module jedi_lfric_linear_fields_mod !> @brief Create a field collection that includes the linear model variables !> !> @param [in] mesh Pointer to a mesh object +!> @param [in] twod_mesh Pointer to a 2D mesh object !> @param [out] linear_fields A field collection that includes the linear !> fields -subroutine create_linear_fields( mesh, linear_fields ) +subroutine create_linear_fields( mesh, twod_mesh, linear_fields ) implicit none type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), intent(out) :: linear_fields ! Local type( field_type ) :: field + type( mesh_type ), pointer :: mesh_for_field character( len=str_def ) :: variable_name integer :: i @@ -116,8 +132,14 @@ subroutine create_linear_fields( mesh, linear_fields ) variable_name = trim(ls_variable_names(i)) + if (ls_variable_is_2d(i)) then + mesh_for_field => twod_mesh + else + mesh_for_field => mesh + end if + call field%initialise( & - vector_space = function_space_collection%get_fs(mesh, & + vector_space = function_space_collection%get_fs(mesh_for_field, & element_order_h, & element_order_v, & ls_variable_function_spaces(i)), & From b70722d68625be287ddaf8a94d6ca3bd78096245 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 30 Jan 2026 10:53:17 +0000 Subject: [PATCH 67/68] SR 3 --- .../app/linear_model/opt/rose-app-nwp_gal9_c224.conf | 11 +++++++++++ .../linear/rose-meta/lfric-linear/HEAD/rose-meta.conf | 1 + 2 files changed, 12 insertions(+) diff --git a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf index 58d8d1d0..a5cd03ba 100644 --- a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf +++ b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf @@ -1,3 +1,14 @@ [file:iodef_temp.xml] mode=auto source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml + +[namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 +l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index af6d92a6..30ec1a9c 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -112,6 +112,7 @@ description=Logical switch for TLM boundary layer scheme. help=If true then turn on boundary layer in linear model and adjoint. !kind=default ns=namelist/Linear/Physics +sort-key=Panel-A00 trigger=namelist:linear_physics=blevs_m: .true. ; =namelist:linear_physics=l_0_m: .true. ; =namelist:linear_physics=e_folding_levs_m: .true. ; From 6aad6a4c10c416774c03304e2068112b5f0b61c5 Mon Sep 17 00:00:00 2001 From: tom-j-h Date: Fri, 30 Jan 2026 11:44:08 +0000 Subject: [PATCH 68/68] Revert unnecessary change --- .../app/linear_model/opt/rose-app-nwp_gal9_c224.conf | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf index a5cd03ba..58d8d1d0 100644 --- a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf +++ b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c224.conf @@ -1,14 +1,3 @@ [file:iodef_temp.xml] mode=auto source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml - -[namelist:linear_physics] -!!blevs_m=15 -!!e_folding_levs_m=10 -!!l_0_m=80.0 -l_boundary_layer=.false. -!!log_layer=2 -!!u_land_m=0.4 -!!u_sea_m=0.4 -!!z_land_m=0.05 -!!z_sea_m=0.0005